Home | History | Annotate | Download | only in tr1_impl
      1 // class template array -*- C++ -*-
      2 
      3 // Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
      4 //
      5 // This file is part of the GNU ISO C++ Library.  This library is free
      6 // software; you can redistribute it and/or modify it under the
      7 // terms of the GNU General Public License as published by the
      8 // Free Software Foundation; either version 3, or (at your option)
      9 // any later version.
     10 
     11 // This library is distributed in the hope that it will be useful,
     12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 // GNU General Public License for more details.
     15 
     16 // Under Section 7 of GPL version 3, you are granted additional
     17 // permissions described in the GCC Runtime Library Exception, version
     18 // 3.1, as published by the Free Software Foundation.
     19 
     20 // You should have received a copy of the GNU General Public License and
     21 // a copy of the GCC Runtime Library Exception along with this program;
     22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23 // <http://www.gnu.org/licenses/>.
     24 
     25 /** @file tr1_impl/array
     26  *  This is an internal header file, included by other library headers.
     27  *  You should not attempt to use it directly.
     28  */
     29 
     30 namespace std
     31 {
     32 _GLIBCXX_BEGIN_NAMESPACE_TR1
     33 
     34   /**
     35    *  @brief A standard container for storing a fixed size sequence of elements.
     36    *
     37    *  @ingroup sequences
     38    *
     39    *  Meets the requirements of a <a href="tables.html#65">container</a>, a
     40    *  <a href="tables.html#66">reversible container</a>, and a
     41    *  <a href="tables.html#67">sequence</a>.
     42    *
     43    *  Sets support random access iterators.
     44    *
     45    *  @param  Tp  Type of element. Required to be a complete type.
     46    *  @param  N  Number of elements.
     47   */
     48   template<typename _Tp, std::size_t _Nm>
     49     struct array
     50     {
     51       typedef _Tp 	    			      value_type;
     52       typedef value_type&                   	      reference;
     53       typedef const value_type&             	      const_reference;
     54       typedef value_type*          		      iterator;
     55       typedef const value_type*			      const_iterator;
     56       typedef std::size_t                    	      size_type;
     57       typedef std::ptrdiff_t                   	      difference_type;
     58       typedef std::reverse_iterator<iterator>	      reverse_iterator;
     59       typedef std::reverse_iterator<const_iterator>   const_reverse_iterator;
     60 
     61       // Support for zero-sized arrays mandatory.
     62       value_type _M_instance[_Nm ? _Nm : 1];
     63 
     64       // No explicit construct/copy/destroy for aggregate type.
     65 
     66       void
     67 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
     68       // DR 776.
     69       fill(const value_type& __u)
     70 #else
     71       assign(const value_type& __u)
     72 #endif
     73       { std::fill_n(begin(), size(), __u); }
     74 
     75       void
     76       swap(array& __other)
     77       { std::swap_ranges(begin(), end(), __other.begin()); }
     78 
     79       // Iterators.
     80       iterator
     81       begin()
     82       { return iterator(&_M_instance[0]); }
     83 
     84       const_iterator
     85       begin() const 
     86       { return const_iterator(&_M_instance[0]); }
     87 
     88       iterator
     89       end()
     90       { return iterator(&_M_instance[_Nm]); }
     91 
     92       const_iterator
     93       end() const
     94       { return const_iterator(&_M_instance[_Nm]); }
     95 
     96       reverse_iterator 
     97       rbegin()
     98       { return reverse_iterator(end()); }
     99 
    100       const_reverse_iterator 
    101       rbegin() const
    102       { return const_reverse_iterator(end()); }
    103 
    104       reverse_iterator 
    105       rend()
    106       { return reverse_iterator(begin()); }
    107 
    108       const_reverse_iterator 
    109       rend() const
    110       { return const_reverse_iterator(begin()); }
    111 
    112 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
    113       const_iterator
    114       cbegin() const 
    115       { return const_iterator(&_M_instance[0]); }
    116 
    117       const_iterator
    118       cend() const
    119       { return const_iterator(&_M_instance[_Nm]); }
    120 
    121       const_reverse_iterator 
    122       crbegin() const
    123       { return const_reverse_iterator(end()); }
    124 
    125       const_reverse_iterator 
    126       crend() const
    127       { return const_reverse_iterator(begin()); }
    128 #endif
    129 
    130       // Capacity.
    131       size_type 
    132       size() const { return _Nm; }
    133 
    134       size_type 
    135       max_size() const { return _Nm; }
    136 
    137       bool 
    138       empty() const { return size() == 0; }
    139 
    140       // Element access.
    141       reference
    142       operator[](size_type __n)
    143       { return _M_instance[__n]; }
    144 
    145       const_reference
    146       operator[](size_type __n) const
    147       { return _M_instance[__n]; }
    148 
    149       reference
    150       at(size_type __n)
    151       {
    152 	if (__builtin_expect(__n >= _Nm, false))
    153 	  std::__throw_out_of_range(__N("array::at"));
    154 	return _M_instance[__n];
    155       }
    156 
    157       const_reference
    158       at(size_type __n) const
    159       {
    160 	if (__builtin_expect(__n >= _Nm, false))
    161 	  std::__throw_out_of_range(__N("array::at"));
    162 	return _M_instance[__n];
    163       }
    164 
    165       reference 
    166       front()
    167       { return *begin(); }
    168 
    169       const_reference 
    170       front() const
    171       { return *begin(); }
    172 
    173       reference 
    174       back()
    175       { return _Nm ? *(end() - 1) : *end(); }
    176 
    177       const_reference 
    178       back() const
    179       { return _Nm ? *(end() - 1) : *end(); }
    180 
    181       _Tp* 
    182       data()
    183       { return &_M_instance[0]; }
    184 
    185       const _Tp* 
    186       data() const
    187       { return &_M_instance[0]; }
    188     };
    189 
    190   // Array comparisons.
    191   template<typename _Tp, std::size_t _Nm>
    192     inline bool 
    193     operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
    194     { return std::equal(__one.begin(), __one.end(), __two.begin()); }
    195 
    196   template<typename _Tp, std::size_t _Nm>
    197     inline bool
    198     operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
    199     { return !(__one == __two); }
    200 
    201   template<typename _Tp, std::size_t _Nm>
    202     inline bool
    203     operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
    204     { 
    205       return std::lexicographical_compare(__a.begin(), __a.end(),
    206 					  __b.begin(), __b.end()); 
    207     }
    208 
    209   template<typename _Tp, std::size_t _Nm>
    210     inline bool
    211     operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
    212     { return __two < __one; }
    213 
    214   template<typename _Tp, std::size_t _Nm>
    215     inline bool
    216     operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
    217     { return !(__one > __two); }
    218 
    219   template<typename _Tp, std::size_t _Nm>
    220     inline bool
    221     operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
    222     { return !(__one < __two); }
    223 
    224   // Specialized algorithms [6.2.2.2].
    225   template<typename _Tp, std::size_t _Nm>
    226     inline void
    227     swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two)
    228     { std::swap_ranges(__one.begin(), __one.end(), __two.begin()); }
    229 
    230   // Tuple interface to class template array [6.2.2.5].
    231 
    232   /// tuple_size
    233   template<typename _Tp> 
    234     class tuple_size;
    235 
    236   /// tuple_element
    237 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
    238   template<std::size_t _Int, typename _Tp>
    239 #else
    240   template<int _Int, typename _Tp>
    241 #endif
    242     class tuple_element;
    243 
    244   template<typename _Tp, std::size_t _Nm>
    245     struct tuple_size<array<_Tp, _Nm> >
    246 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
    247     { static const std::size_t value = _Nm; };
    248 #else
    249     { static const int value = _Nm; };
    250 #endif
    251 
    252   template<typename _Tp, std::size_t _Nm>
    253 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
    254     const std::size_t
    255 #else
    256     const int
    257 #endif
    258     tuple_size<array<_Tp, _Nm> >::value;  
    259 
    260 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
    261   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
    262 #else
    263   template<int _Int, typename _Tp, std::size_t _Nm>
    264 #endif
    265     struct tuple_element<_Int, array<_Tp, _Nm> >
    266     { typedef _Tp type; };
    267 
    268 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
    269   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
    270 #else
    271   template<int _Int, typename _Tp, std::size_t _Nm>
    272 #endif
    273     inline _Tp&
    274     get(array<_Tp, _Nm>& __arr)
    275     { return __arr[_Int]; }
    276 
    277 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
    278   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
    279 #else
    280   template<int _Int, typename _Tp, std::size_t _Nm>
    281 #endif
    282     inline const _Tp&
    283     get(const array<_Tp, _Nm>& __arr)
    284     { return __arr[_Int]; }
    285 
    286 _GLIBCXX_END_NAMESPACE_TR1
    287 }
    288