libstdc++
array
Go to the documentation of this file.
00001 // <array> -*- C++ -*-
00002 
00003 // Copyright (C) 2007-2013 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)
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(__N("array::at"));
00184     return _AT_Type::_S_ref(_M_elems, __n);
00185       }
00186 
00187       constexpr const_reference
00188       at(size_type __n) const
00189       {
00190     // Result of conditional expression must be an lvalue so use
00191     // boolean ? lvalue : (throw-expr, lvalue)
00192     return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n)
00193       : (std::__throw_out_of_range(__N("array::at")),
00194          _AT_Type::_S_ref(_M_elems, 0));
00195       }
00196 
00197       reference 
00198       front()
00199       { return *begin(); }
00200 
00201       constexpr const_reference 
00202       front() const
00203       { return _AT_Type::_S_ref(_M_elems, 0); }
00204 
00205       reference 
00206       back()
00207       { return _Nm ? *(end() - 1) : *end(); }
00208 
00209       constexpr const_reference 
00210       back() const
00211       { 
00212     return _Nm ? _AT_Type::_S_ref(_M_elems, _Nm - 1) 
00213                : _AT_Type::_S_ref(_M_elems, 0);
00214       }
00215 
00216       pointer
00217       data() noexcept
00218       { return std::__addressof(_AT_Type::_S_ref(_M_elems, 0)); }
00219 
00220       const_pointer
00221       data() const noexcept
00222       { return std::__addressof(_AT_Type::_S_ref(_M_elems, 0)); }
00223     };
00224 
00225   // Array comparisons.
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 std::equal(__one.begin(), __one.end(), __two.begin()); }
00230 
00231   template<typename _Tp, std::size_t _Nm>
00232     inline bool
00233     operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
00234     { return !(__one == __two); }
00235 
00236   template<typename _Tp, std::size_t _Nm>
00237     inline bool
00238     operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
00239     { 
00240       return std::lexicographical_compare(__a.begin(), __a.end(),
00241                       __b.begin(), __b.end()); 
00242     }
00243 
00244   template<typename _Tp, std::size_t _Nm>
00245     inline bool
00246     operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
00247     { return __two < __one; }
00248 
00249   template<typename _Tp, std::size_t _Nm>
00250     inline bool
00251     operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
00252     { return !(__one > __two); }
00253 
00254   template<typename _Tp, std::size_t _Nm>
00255     inline bool
00256     operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
00257     { return !(__one < __two); }
00258 
00259   // Specialized algorithms.
00260   template<typename _Tp, std::size_t _Nm>
00261     inline void
00262     swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two)
00263     noexcept(noexcept(__one.swap(__two)))
00264     { __one.swap(__two); }
00265 
00266   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
00267     constexpr _Tp&
00268     get(array<_Tp, _Nm>& __arr) noexcept
00269     {
00270       static_assert(_Int < _Nm, "index is out of bounds");
00271       return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::
00272     _S_ref(__arr._M_elems, _Int);
00273     }
00274 
00275   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
00276     constexpr _Tp&&
00277     get(array<_Tp, _Nm>&& __arr) noexcept
00278     {
00279       static_assert(_Int < _Nm, "index is out of bounds");
00280       return std::move(get<_Int>(__arr));
00281     }
00282 
00283   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
00284     constexpr const _Tp&
00285     get(const array<_Tp, _Nm>& __arr) noexcept
00286     {
00287       static_assert(_Int < _Nm, "index is out of bounds");
00288       return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::
00289     _S_ref(__arr._M_elems, _Int);
00290     }
00291 
00292 _GLIBCXX_END_NAMESPACE_CONTAINER
00293 } // namespace std
00294 
00295 namespace std _GLIBCXX_VISIBILITY(default)
00296 {
00297 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00298 
00299   // Tuple interface to class template array.
00300 
00301   /// tuple_size
00302   template<typename _Tp> 
00303     class tuple_size;
00304 
00305   template<typename _Tp, std::size_t _Nm>
00306     struct tuple_size<_GLIBCXX_STD_C::array<_Tp, _Nm>>
00307     : public integral_constant<std::size_t, _Nm> { };
00308 
00309   /// tuple_element
00310   template<std::size_t _Int, typename _Tp>
00311     class tuple_element;
00312 
00313   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
00314     struct tuple_element<_Int, _GLIBCXX_STD_C::array<_Tp, _Nm>>
00315     {
00316       static_assert(_Int < _Nm, "index is out of bounds");
00317       typedef _Tp type;
00318     };
00319 
00320 _GLIBCXX_END_NAMESPACE_VERSION
00321 } // namespace std
00322 
00323 #ifdef _GLIBCXX_DEBUG
00324 # include <debug/array>
00325 #endif
00326 
00327 #ifdef _GLIBCXX_PROFILE
00328 # include <profile/array>
00329 #endif
00330 
00331 #endif // C++11
00332 
00333 #endif // _GLIBCXX_ARRAY