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