libstdc++
array
Go to the documentation of this file.
00001 // <array> -*- C++ -*-
00002 
00003 // Copyright (C) 2007-2015 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 #if __cplusplus < 201103L
00035 # include <bits/c++0x_warning.h>
00036 #else
00037 
00038 #include <stdexcept>
00039 #include <bits/stl_algobase.h>
00040 #include <bits/range_access.h>
00041 
00042 namespace std _GLIBCXX_VISIBILITY(default)
00043 {
00044 _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
00045 
00046   template<typename _Tp, std::size_t _Nm>
00047     struct __array_traits
00048     {
00049       typedef _Tp _Type[_Nm];
00050 
00051       static constexpr _Tp&
00052       _S_ref(const _Type& __t, std::size_t __n) noexcept
00053       { return const_cast<_Tp&>(__t[__n]); }
00054 
00055       static constexpr _Tp*
00056       _S_ptr(const _Type& __t) noexcept
00057       { return const_cast<_Tp*>(__t); }
00058     };
00059 
00060  template<typename _Tp>
00061    struct __array_traits<_Tp, 0>
00062    {
00063      struct _Type { };
00064 
00065      static constexpr _Tp&
00066      _S_ref(const _Type&, std::size_t) noexcept
00067      { return *static_cast<_Tp*>(nullptr); }
00068 
00069      static constexpr _Tp*
00070      _S_ptr(const _Type&) noexcept
00071      { return nullptr; }
00072    };
00073 
00074   /**
00075    *  @brief A standard container for storing a fixed size sequence of elements.
00076    *
00077    *  @ingroup sequences
00078    *
00079    *  Meets the requirements of a <a href="tables.html#65">container</a>, a
00080    *  <a href="tables.html#66">reversible container</a>, and a
00081    *  <a href="tables.html#67">sequence</a>.
00082    *
00083    *  Sets support random access iterators.
00084    *
00085    *  @tparam  Tp  Type of element. Required to be a complete type.
00086    *  @tparam  N  Number of elements.
00087   */
00088   template<typename _Tp, std::size_t _Nm>
00089     struct array
00090     {
00091       typedef _Tp                                     value_type;
00092       typedef value_type*                             pointer;
00093       typedef const value_type*                       const_pointer;
00094       typedef value_type&                             reference;
00095       typedef const value_type&                       const_reference;
00096       typedef value_type*                             iterator;
00097       typedef const value_type*                       const_iterator;
00098       typedef std::size_t                             size_type;
00099       typedef std::ptrdiff_t                          difference_type;
00100       typedef std::reverse_iterator<iterator>         reverse_iterator;
00101       typedef std::reverse_iterator<const_iterator>   const_reverse_iterator;
00102 
00103       // Support for zero-sized arrays mandatory.
00104       typedef _GLIBCXX_STD_C::__array_traits<_Tp, _Nm> _AT_Type;
00105       typename _AT_Type::_Type                         _M_elems;
00106 
00107       // No explicit construct/copy/destroy for aggregate type.
00108 
00109       // DR 776.
00110       void
00111       fill(const value_type& __u)
00112       { std::fill_n(begin(), size(), __u); }
00113 
00114       void
00115       swap(array& __other)
00116       noexcept(noexcept(swap(std::declval<_Tp&>(), std::declval<_Tp&>())))
00117       { std::swap_ranges(begin(), end(), __other.begin()); }
00118 
00119       // Iterators.
00120       iterator
00121       begin() noexcept
00122       { return iterator(data()); }
00123 
00124       const_iterator
00125       begin() const noexcept
00126       { return const_iterator(data()); }
00127 
00128       iterator
00129       end() noexcept
00130       { return iterator(data() + _Nm); }
00131 
00132       const_iterator
00133       end() const noexcept
00134       { return const_iterator(data() + _Nm); }
00135 
00136       reverse_iterator 
00137       rbegin() noexcept
00138       { return reverse_iterator(end()); }
00139 
00140       const_reverse_iterator 
00141       rbegin() const noexcept
00142       { return const_reverse_iterator(end()); }
00143 
00144       reverse_iterator 
00145       rend() noexcept
00146       { return reverse_iterator(begin()); }
00147 
00148       const_reverse_iterator 
00149       rend() const noexcept
00150       { return const_reverse_iterator(begin()); }
00151 
00152       const_iterator
00153       cbegin() const noexcept
00154       { return const_iterator(data()); }
00155 
00156       const_iterator
00157       cend() const noexcept
00158       { return const_iterator(data() + _Nm); }
00159 
00160       const_reverse_iterator 
00161       crbegin() const noexcept
00162       { return const_reverse_iterator(end()); }
00163 
00164       const_reverse_iterator 
00165       crend() const noexcept
00166       { return const_reverse_iterator(begin()); }
00167 
00168       // Capacity.
00169       constexpr size_type 
00170       size() const noexcept { return _Nm; }
00171 
00172       constexpr size_type 
00173       max_size() const noexcept { return _Nm; }
00174 
00175       constexpr bool 
00176       empty() const noexcept { return size() == 0; }
00177 
00178       // Element access.
00179       reference
00180       operator[](size_type __n) noexcept
00181       { return _AT_Type::_S_ref(_M_elems, __n); }
00182 
00183       constexpr const_reference
00184       operator[](size_type __n) const noexcept
00185       { return _AT_Type::_S_ref(_M_elems, __n); }
00186 
00187       reference
00188       at(size_type __n)
00189       {
00190         if (__n >= _Nm)
00191           std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) "
00192                                             ">= _Nm (which is %zu)"),
00193                                         __n, _Nm);
00194         return _AT_Type::_S_ref(_M_elems, __n);
00195       }
00196 
00197       constexpr const_reference
00198       at(size_type __n) const
00199       {
00200         // Result of conditional expression must be an lvalue so use
00201         // boolean ? lvalue : (throw-expr, lvalue)
00202         return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n)
00203           : (std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) "
00204                                                ">= _Nm (which is %zu)"),
00205                                            __n, _Nm),
00206              _AT_Type::_S_ref(_M_elems, 0));
00207       }
00208 
00209       reference 
00210       front() noexcept
00211       { return *begin(); }
00212 
00213       constexpr const_reference 
00214       front() const noexcept
00215       { return _AT_Type::_S_ref(_M_elems, 0); }
00216 
00217       reference 
00218       back() noexcept
00219       { return _Nm ? *(end() - 1) : *end(); }
00220 
00221       constexpr const_reference 
00222       back() const noexcept
00223       { 
00224         return _Nm ? _AT_Type::_S_ref(_M_elems, _Nm - 1) 
00225                    : _AT_Type::_S_ref(_M_elems, 0);
00226       }
00227 
00228       pointer
00229       data() noexcept
00230       { return _AT_Type::_S_ptr(_M_elems); }
00231 
00232       const_pointer
00233       data() const noexcept
00234       { return _AT_Type::_S_ptr(_M_elems); }
00235     };
00236 
00237   // Array comparisons.
00238   template<typename _Tp, std::size_t _Nm>
00239     inline bool 
00240     operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
00241     { return std::equal(__one.begin(), __one.end(), __two.begin()); }
00242 
00243   template<typename _Tp, std::size_t _Nm>
00244     inline bool
00245     operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
00246     { return !(__one == __two); }
00247 
00248   template<typename _Tp, std::size_t _Nm>
00249     inline bool
00250     operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
00251     { 
00252       return std::lexicographical_compare(__a.begin(), __a.end(),
00253                                           __b.begin(), __b.end()); 
00254     }
00255 
00256   template<typename _Tp, std::size_t _Nm>
00257     inline bool
00258     operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
00259     { return __two < __one; }
00260 
00261   template<typename _Tp, std::size_t _Nm>
00262     inline bool
00263     operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
00264     { return !(__one > __two); }
00265 
00266   template<typename _Tp, std::size_t _Nm>
00267     inline bool
00268     operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
00269     { return !(__one < __two); }
00270 
00271   // Specialized algorithms.
00272   template<typename _Tp, std::size_t _Nm>
00273     inline void
00274     swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two)
00275     noexcept(noexcept(__one.swap(__two)))
00276     { __one.swap(__two); }
00277 
00278   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
00279     constexpr _Tp&
00280     get(array<_Tp, _Nm>& __arr) noexcept
00281     {
00282       static_assert(_Int < _Nm, "index is out of bounds");
00283       return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::
00284         _S_ref(__arr._M_elems, _Int);
00285     }
00286 
00287   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
00288     constexpr _Tp&&
00289     get(array<_Tp, _Nm>&& __arr) noexcept
00290     {
00291       static_assert(_Int < _Nm, "index is out of bounds");
00292       return std::move(_GLIBCXX_STD_C::get<_Int>(__arr));
00293     }
00294 
00295   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
00296     constexpr const _Tp&
00297     get(const array<_Tp, _Nm>& __arr) noexcept
00298     {
00299       static_assert(_Int < _Nm, "index is out of bounds");
00300       return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::
00301         _S_ref(__arr._M_elems, _Int);
00302     }
00303 
00304 _GLIBCXX_END_NAMESPACE_CONTAINER
00305 } // namespace std
00306 
00307 namespace std _GLIBCXX_VISIBILITY(default)
00308 {
00309 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00310 
00311   // Tuple interface to class template array.
00312 
00313   /// tuple_size
00314   template<typename _Tp> 
00315     class tuple_size;
00316 
00317   /// Partial specialization for std::array
00318   template<typename _Tp, std::size_t _Nm>
00319     struct tuple_size<_GLIBCXX_STD_C::array<_Tp, _Nm>>
00320     : public integral_constant<std::size_t, _Nm> { };
00321 
00322   /// tuple_element
00323   template<std::size_t _Int, typename _Tp>
00324     class tuple_element;
00325 
00326   /// Partial specialization for std::array
00327   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
00328     struct tuple_element<_Int, _GLIBCXX_STD_C::array<_Tp, _Nm>>
00329     {
00330       static_assert(_Int < _Nm, "index is out of bounds");
00331       typedef _Tp type;
00332     };
00333 
00334 _GLIBCXX_END_NAMESPACE_VERSION
00335 } // namespace std
00336 
00337 #ifdef _GLIBCXX_DEBUG
00338 # include <debug/array>
00339 #endif
00340 
00341 #ifdef _GLIBCXX_PROFILE
00342 # include <profile/array>
00343 #endif
00344 
00345 #endif // C++11
00346 
00347 #endif // _GLIBCXX_ARRAY