libstdc++
array
Go to the documentation of this file.
00001 // <array> -*- C++ -*-
00002 
00003 // Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 3, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file include/array
00026  *  This is a Standard C++ Library header.
00027  */
00028 
00029 #ifndef _GLIBCXX_ARRAY
00030 #define _GLIBCXX_ARRAY 1
00031 
00032 #pragma GCC system_header
00033 
00034 #ifndef __GXX_EXPERIMENTAL_CXX0X__
00035 # include <bits/c++0x_warning.h>
00036 #else
00037 
00038 #include <bits/stl_algobase.h>
00039 #include <bits/range_access.h>
00040 
00041 namespace std _GLIBCXX_VISIBILITY(default)
00042 {
00043 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00044 
00045   /**
00046    *  @brief A standard container for storing a fixed size sequence of elements.
00047    *
00048    *  @ingroup sequences
00049    *
00050    *  Meets the requirements of a <a href="tables.html#65">container</a>, a
00051    *  <a href="tables.html#66">reversible container</a>, and a
00052    *  <a href="tables.html#67">sequence</a>.
00053    *
00054    *  Sets support random access iterators.
00055    *
00056    *  @param  Tp  Type of element. Required to be a complete type.
00057    *  @param  N  Number of elements.
00058   */
00059   template<typename _Tp, std::size_t _Nm>
00060     struct array
00061     {
00062       typedef _Tp                         value_type;
00063       typedef _Tp*                                    pointer;
00064       typedef const _Tp*                              const_pointer;
00065       typedef value_type&                             reference;
00066       typedef const value_type&                       const_reference;
00067       typedef value_type*                     iterator;
00068       typedef const value_type*               const_iterator;
00069       typedef std::size_t                             size_type;
00070       typedef std::ptrdiff_t                          difference_type;
00071       typedef std::reverse_iterator<iterator>         reverse_iterator;
00072       typedef std::reverse_iterator<const_iterator>   const_reverse_iterator;
00073 
00074       // Support for zero-sized arrays mandatory.
00075       value_type _M_instance[_Nm ? _Nm : 1];
00076 
00077       // No explicit construct/copy/destroy for aggregate type.
00078 
00079       // DR 776.
00080       void
00081       fill(const value_type& __u)
00082       { std::fill_n(begin(), size(), __u); }
00083 
00084       void
00085       swap(array& __other)
00086       { std::swap_ranges(begin(), end(), __other.begin()); }
00087 
00088       // Iterators.
00089       iterator
00090       begin()
00091       { return iterator(std::__addressof(_M_instance[0])); }
00092 
00093       const_iterator
00094       begin() const 
00095       { return const_iterator(std::__addressof(_M_instance[0])); }
00096 
00097       iterator
00098       end()
00099       { return iterator(std::__addressof(_M_instance[_Nm])); }
00100 
00101       const_iterator
00102       end() const
00103       { return const_iterator(std::__addressof(_M_instance[_Nm])); }
00104 
00105       reverse_iterator 
00106       rbegin()
00107       { return reverse_iterator(end()); }
00108 
00109       const_reverse_iterator 
00110       rbegin() const
00111       { return const_reverse_iterator(end()); }
00112 
00113       reverse_iterator 
00114       rend()
00115       { return reverse_iterator(begin()); }
00116 
00117       const_reverse_iterator 
00118       rend() const
00119       { return const_reverse_iterator(begin()); }
00120 
00121       const_iterator
00122       cbegin() const 
00123       { return const_iterator(std::__addressof(_M_instance[0])); }
00124 
00125       const_iterator
00126       cend() const
00127       { return const_iterator(std::__addressof(_M_instance[_Nm])); }
00128 
00129       const_reverse_iterator 
00130       crbegin() const
00131       { return const_reverse_iterator(end()); }
00132 
00133       const_reverse_iterator 
00134       crend() const
00135       { return const_reverse_iterator(begin()); }
00136 
00137       // Capacity.
00138       constexpr size_type 
00139       size() const { return _Nm; }
00140 
00141       constexpr size_type 
00142       max_size() const { return _Nm; }
00143 
00144       constexpr bool 
00145       empty() const { return size() == 0; }
00146 
00147       // Element access.
00148       reference
00149       operator[](size_type __n)
00150       { return _M_instance[__n]; }
00151 
00152       const_reference
00153       operator[](size_type __n) const
00154       { return _M_instance[__n]; }
00155 
00156       reference
00157       at(size_type __n)
00158       {
00159     if (__n >= _Nm)
00160       std::__throw_out_of_range(__N("array::at"));
00161     return _M_instance[__n];
00162       }
00163 
00164       const_reference
00165       at(size_type __n) const
00166       {
00167     if (__n >= _Nm)
00168       std::__throw_out_of_range(__N("array::at"));
00169     return _M_instance[__n];
00170       }
00171 
00172       reference 
00173       front()
00174       { return *begin(); }
00175 
00176       const_reference 
00177       front() const
00178       { return *begin(); }
00179 
00180       reference 
00181       back()
00182       { return _Nm ? *(end() - 1) : *end(); }
00183 
00184       const_reference 
00185       back() const
00186       { return _Nm ? *(end() - 1) : *end(); }
00187 
00188       _Tp*
00189       data()
00190       { return std::__addressof(_M_instance[0]); }
00191 
00192       const _Tp*
00193       data() const
00194       { return std::__addressof(_M_instance[0]); }
00195     };
00196 
00197   // Array comparisons.
00198   template<typename _Tp, std::size_t _Nm>
00199     inline bool 
00200     operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
00201     { return std::equal(__one.begin(), __one.end(), __two.begin()); }
00202 
00203   template<typename _Tp, std::size_t _Nm>
00204     inline bool
00205     operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
00206     { return !(__one == __two); }
00207 
00208   template<typename _Tp, std::size_t _Nm>
00209     inline bool
00210     operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
00211     { 
00212       return std::lexicographical_compare(__a.begin(), __a.end(),
00213                       __b.begin(), __b.end()); 
00214     }
00215 
00216   template<typename _Tp, std::size_t _Nm>
00217     inline bool
00218     operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
00219     { return __two < __one; }
00220 
00221   template<typename _Tp, std::size_t _Nm>
00222     inline bool
00223     operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
00224     { return !(__one > __two); }
00225 
00226   template<typename _Tp, std::size_t _Nm>
00227     inline bool
00228     operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
00229     { return !(__one < __two); }
00230 
00231   // Specialized algorithms [6.2.2.2].
00232   template<typename _Tp, std::size_t _Nm>
00233     inline void
00234     swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two)
00235     { __one.swap(__two); }
00236 
00237   // Tuple interface to class template array [6.2.2.5].
00238 
00239   /// tuple_size
00240   template<typename _Tp> 
00241     class tuple_size;
00242 
00243   /// tuple_element
00244   template<std::size_t _Int, typename _Tp>
00245     class tuple_element;
00246 
00247   template<typename _Tp, std::size_t _Nm>
00248     struct tuple_size<array<_Tp, _Nm> >
00249     { static const std::size_t value = _Nm; };
00250 
00251   template<typename _Tp, std::size_t _Nm>
00252     const std::size_t
00253     tuple_size<array<_Tp, _Nm> >::value;  
00254 
00255   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
00256     struct tuple_element<_Int, array<_Tp, _Nm> >
00257     { typedef _Tp type; };
00258 
00259   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
00260     inline _Tp&
00261     get(array<_Tp, _Nm>& __arr)
00262     { return __arr[_Int]; }
00263 
00264   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
00265     inline const _Tp&
00266     get(const array<_Tp, _Nm>& __arr)
00267     { return __arr[_Int]; }
00268 
00269 _GLIBCXX_END_NAMESPACE_VERSION
00270 } // namespace
00271 
00272 #endif // __GXX_EXPERIMENTAL_CXX0X__
00273 
00274 #endif // _GLIBCXX_ARRAY