Home | History | Annotate | Line # | Download | only in std
      1       1.1  mrg // <array> -*- C++ -*-
      2       1.1  mrg 
      3  1.1.1.14  mrg // Copyright (C) 2007-2024 Free Software Foundation, Inc.
      4       1.1  mrg //
      5       1.1  mrg // This file is part of the GNU ISO C++ Library.  This library is free
      6       1.1  mrg // software; you can redistribute it and/or modify it under the
      7       1.1  mrg // terms of the GNU General Public License as published by the
      8       1.1  mrg // Free Software Foundation; either version 3, or (at your option)
      9       1.1  mrg // any later version.
     10       1.1  mrg 
     11       1.1  mrg // This library is distributed in the hope that it will be useful,
     12       1.1  mrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
     13       1.1  mrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14       1.1  mrg // GNU General Public License for more details.
     15       1.1  mrg 
     16       1.1  mrg // Under Section 7 of GPL version 3, you are granted additional
     17       1.1  mrg // permissions described in the GCC Runtime Library Exception, version
     18       1.1  mrg // 3.1, as published by the Free Software Foundation.
     19       1.1  mrg 
     20       1.1  mrg // You should have received a copy of the GNU General Public License and
     21       1.1  mrg // a copy of the GCC Runtime Library Exception along with this program;
     22       1.1  mrg // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23       1.1  mrg // <http://www.gnu.org/licenses/>.
     24       1.1  mrg 
     25       1.1  mrg /** @file include/array
     26       1.1  mrg  *  This is a Standard C++ Library header.
     27       1.1  mrg  */
     28       1.1  mrg 
     29       1.1  mrg #ifndef _GLIBCXX_ARRAY
     30       1.1  mrg #define _GLIBCXX_ARRAY 1
     31       1.1  mrg 
     32       1.1  mrg #pragma GCC system_header
     33       1.1  mrg 
     34   1.1.1.2  mrg #if __cplusplus < 201103L
     35       1.1  mrg # include <bits/c++0x_warning.h>
     36       1.1  mrg #else
     37       1.1  mrg 
     38  1.1.1.11  mrg #include <compare>
     39  1.1.1.11  mrg #include <initializer_list>
     40  1.1.1.11  mrg 
     41  1.1.1.11  mrg #include <type_traits>
     42  1.1.1.10  mrg #include <bits/functexcept.h>
     43       1.1  mrg #include <bits/stl_algobase.h>
     44  1.1.1.11  mrg #include <bits/range_access.h> // std::begin, std::end etc.
     45  1.1.1.11  mrg #include <bits/utility.h>      // std::index_sequence, std::tuple_size
     46  1.1.1.11  mrg #include <debug/assertions.h>
     47       1.1  mrg 
     48  1.1.1.14  mrg #define __glibcxx_want_array_constexpr
     49  1.1.1.14  mrg #define __glibcxx_want_freestanding_array
     50  1.1.1.14  mrg #define __glibcxx_want_nonmember_container_access
     51  1.1.1.14  mrg #define __glibcxx_want_to_array
     52  1.1.1.14  mrg #include <bits/version.h>
     53  1.1.1.14  mrg 
     54   1.1.1.2  mrg namespace std _GLIBCXX_VISIBILITY(default)
     55   1.1.1.2  mrg {
     56  1.1.1.11  mrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
     57   1.1.1.2  mrg 
     58  1.1.1.14  mrg   template<typename _Tp, size_t _Nm>
     59   1.1.1.2  mrg     struct __array_traits
     60   1.1.1.2  mrg     {
     61  1.1.1.14  mrg       using _Type = _Tp[_Nm];
     62  1.1.1.14  mrg       using _Is_swappable = __is_swappable<_Tp>;
     63  1.1.1.14  mrg       using _Is_nothrow_swappable = __is_nothrow_swappable<_Tp>;
     64   1.1.1.2  mrg     };
     65   1.1.1.2  mrg 
     66   1.1.1.2  mrg  template<typename _Tp>
     67   1.1.1.2  mrg    struct __array_traits<_Tp, 0>
     68   1.1.1.2  mrg    {
     69  1.1.1.14  mrg      // Empty type used instead of _Tp[0] for std::array<_Tp, 0>.
     70  1.1.1.14  mrg      struct _Type
     71  1.1.1.14  mrg      {
     72  1.1.1.14  mrg        // Indexing is undefined.
     73  1.1.1.14  mrg        __attribute__((__always_inline__,__noreturn__))
     74  1.1.1.14  mrg        _Tp& operator[](size_t) const noexcept { __builtin_trap(); }
     75  1.1.1.14  mrg 
     76  1.1.1.14  mrg        // Conversion to a pointer produces a null pointer.
     77  1.1.1.14  mrg        __attribute__((__always_inline__))
     78  1.1.1.14  mrg        constexpr explicit operator _Tp*() const noexcept { return nullptr; }
     79  1.1.1.14  mrg      };
     80  1.1.1.14  mrg 
     81  1.1.1.14  mrg      using _Is_swappable = true_type;
     82  1.1.1.14  mrg      using _Is_nothrow_swappable = true_type;
     83   1.1.1.2  mrg    };
     84   1.1.1.2  mrg 
     85   1.1.1.2  mrg   /**
     86   1.1.1.2  mrg    *  @brief A standard container for storing a fixed size sequence of elements.
     87   1.1.1.2  mrg    *
     88   1.1.1.2  mrg    *  @ingroup sequences
     89   1.1.1.2  mrg    *
     90   1.1.1.2  mrg    *  Meets the requirements of a <a href="tables.html#65">container</a>, a
     91   1.1.1.2  mrg    *  <a href="tables.html#66">reversible container</a>, and a
     92   1.1.1.2  mrg    *  <a href="tables.html#67">sequence</a>.
     93   1.1.1.2  mrg    *
     94   1.1.1.2  mrg    *  Sets support random access iterators.
     95   1.1.1.2  mrg    *
     96   1.1.1.2  mrg    *  @tparam  Tp  Type of element. Required to be a complete type.
     97  1.1.1.10  mrg    *  @tparam  Nm  Number of elements.
     98   1.1.1.2  mrg   */
     99   1.1.1.2  mrg   template<typename _Tp, std::size_t _Nm>
    100   1.1.1.2  mrg     struct array
    101   1.1.1.2  mrg     {
    102   1.1.1.2  mrg       typedef _Tp 	    			      value_type;
    103   1.1.1.2  mrg       typedef value_type*			      pointer;
    104   1.1.1.2  mrg       typedef const value_type*                       const_pointer;
    105   1.1.1.2  mrg       typedef value_type&                   	      reference;
    106   1.1.1.2  mrg       typedef const value_type&             	      const_reference;
    107   1.1.1.2  mrg       typedef value_type*          		      iterator;
    108   1.1.1.2  mrg       typedef const value_type*			      const_iterator;
    109   1.1.1.2  mrg       typedef std::size_t                    	      size_type;
    110   1.1.1.2  mrg       typedef std::ptrdiff_t                   	      difference_type;
    111   1.1.1.2  mrg       typedef std::reverse_iterator<iterator>	      reverse_iterator;
    112   1.1.1.2  mrg       typedef std::reverse_iterator<const_iterator>   const_reverse_iterator;
    113   1.1.1.2  mrg 
    114   1.1.1.2  mrg       // Support for zero-sized arrays mandatory.
    115  1.1.1.14  mrg       typename __array_traits<_Tp, _Nm>::_Type        _M_elems;
    116   1.1.1.2  mrg 
    117   1.1.1.2  mrg       // No explicit construct/copy/destroy for aggregate type.
    118   1.1.1.2  mrg 
    119   1.1.1.2  mrg       // DR 776.
    120  1.1.1.10  mrg       _GLIBCXX20_CONSTEXPR void
    121   1.1.1.2  mrg       fill(const value_type& __u)
    122   1.1.1.2  mrg       { std::fill_n(begin(), size(), __u); }
    123   1.1.1.2  mrg 
    124  1.1.1.10  mrg       _GLIBCXX20_CONSTEXPR void
    125   1.1.1.2  mrg       swap(array& __other)
    126  1.1.1.14  mrg       noexcept(__array_traits<_Tp, _Nm>::_Is_nothrow_swappable::value)
    127   1.1.1.2  mrg       { std::swap_ranges(begin(), end(), __other.begin()); }
    128   1.1.1.2  mrg 
    129   1.1.1.2  mrg       // Iterators.
    130  1.1.1.11  mrg       [[__gnu__::__const__, __nodiscard__]]
    131   1.1.1.5  mrg       _GLIBCXX17_CONSTEXPR iterator
    132   1.1.1.2  mrg       begin() noexcept
    133   1.1.1.2  mrg       { return iterator(data()); }
    134   1.1.1.2  mrg 
    135  1.1.1.11  mrg       [[__nodiscard__]]
    136   1.1.1.5  mrg       _GLIBCXX17_CONSTEXPR const_iterator
    137   1.1.1.2  mrg       begin() const noexcept
    138   1.1.1.2  mrg       { return const_iterator(data()); }
    139   1.1.1.2  mrg 
    140  1.1.1.11  mrg       [[__gnu__::__const__, __nodiscard__]]
    141   1.1.1.5  mrg       _GLIBCXX17_CONSTEXPR iterator
    142   1.1.1.2  mrg       end() noexcept
    143   1.1.1.2  mrg       { return iterator(data() + _Nm); }
    144   1.1.1.2  mrg 
    145  1.1.1.11  mrg       [[__nodiscard__]]
    146   1.1.1.5  mrg       _GLIBCXX17_CONSTEXPR const_iterator
    147   1.1.1.2  mrg       end() const noexcept
    148   1.1.1.2  mrg       { return const_iterator(data() + _Nm); }
    149   1.1.1.2  mrg 
    150  1.1.1.11  mrg       [[__gnu__::__const__, __nodiscard__]]
    151   1.1.1.5  mrg       _GLIBCXX17_CONSTEXPR reverse_iterator
    152   1.1.1.2  mrg       rbegin() noexcept
    153   1.1.1.2  mrg       { return reverse_iterator(end()); }
    154   1.1.1.2  mrg 
    155  1.1.1.11  mrg       [[__nodiscard__]]
    156   1.1.1.5  mrg       _GLIBCXX17_CONSTEXPR const_reverse_iterator
    157   1.1.1.2  mrg       rbegin() const noexcept
    158   1.1.1.2  mrg       { return const_reverse_iterator(end()); }
    159   1.1.1.2  mrg 
    160  1.1.1.11  mrg       [[__gnu__::__const__, __nodiscard__]]
    161   1.1.1.5  mrg       _GLIBCXX17_CONSTEXPR reverse_iterator
    162   1.1.1.2  mrg       rend() noexcept
    163   1.1.1.2  mrg       { return reverse_iterator(begin()); }
    164   1.1.1.2  mrg 
    165  1.1.1.11  mrg       [[__nodiscard__]]
    166   1.1.1.5  mrg       _GLIBCXX17_CONSTEXPR const_reverse_iterator
    167   1.1.1.2  mrg       rend() const noexcept
    168   1.1.1.2  mrg       { return const_reverse_iterator(begin()); }
    169   1.1.1.2  mrg 
    170  1.1.1.11  mrg       [[__nodiscard__]]
    171   1.1.1.5  mrg       _GLIBCXX17_CONSTEXPR const_iterator
    172   1.1.1.2  mrg       cbegin() const noexcept
    173   1.1.1.2  mrg       { return const_iterator(data()); }
    174   1.1.1.2  mrg 
    175  1.1.1.11  mrg       [[__nodiscard__]]
    176   1.1.1.5  mrg       _GLIBCXX17_CONSTEXPR const_iterator
    177   1.1.1.2  mrg       cend() const noexcept
    178   1.1.1.2  mrg       { return const_iterator(data() + _Nm); }
    179   1.1.1.2  mrg 
    180  1.1.1.11  mrg       [[__nodiscard__]]
    181   1.1.1.5  mrg       _GLIBCXX17_CONSTEXPR const_reverse_iterator
    182   1.1.1.2  mrg       crbegin() const noexcept
    183   1.1.1.2  mrg       { return const_reverse_iterator(end()); }
    184   1.1.1.2  mrg 
    185  1.1.1.11  mrg       [[__nodiscard__]]
    186   1.1.1.5  mrg       _GLIBCXX17_CONSTEXPR const_reverse_iterator
    187   1.1.1.2  mrg       crend() const noexcept
    188   1.1.1.2  mrg       { return const_reverse_iterator(begin()); }
    189   1.1.1.2  mrg 
    190   1.1.1.2  mrg       // Capacity.
    191  1.1.1.14  mrg       [[__nodiscard__, __gnu__::__const__, __gnu__::__always_inline__]]
    192   1.1.1.5  mrg       constexpr size_type
    193   1.1.1.2  mrg       size() const noexcept { return _Nm; }
    194   1.1.1.2  mrg 
    195  1.1.1.14  mrg       [[__nodiscard__, __gnu__::__const__, __gnu__::__always_inline__]]
    196   1.1.1.5  mrg       constexpr size_type
    197   1.1.1.2  mrg       max_size() const noexcept { return _Nm; }
    198   1.1.1.2  mrg 
    199  1.1.1.14  mrg       [[__nodiscard__, __gnu__::__const__, __gnu__::__always_inline__]]
    200  1.1.1.11  mrg       constexpr bool
    201   1.1.1.2  mrg       empty() const noexcept { return size() == 0; }
    202   1.1.1.2  mrg 
    203   1.1.1.2  mrg       // Element access.
    204  1.1.1.11  mrg       [[__nodiscard__]]
    205   1.1.1.5  mrg       _GLIBCXX17_CONSTEXPR reference
    206   1.1.1.3  mrg       operator[](size_type __n) noexcept
    207  1.1.1.11  mrg       {
    208  1.1.1.11  mrg 	__glibcxx_requires_subscript(__n);
    209  1.1.1.14  mrg 	return _M_elems[__n];
    210  1.1.1.11  mrg       }
    211   1.1.1.2  mrg 
    212  1.1.1.11  mrg       [[__nodiscard__]]
    213   1.1.1.2  mrg       constexpr const_reference
    214   1.1.1.2  mrg       operator[](size_type __n) const noexcept
    215  1.1.1.11  mrg       {
    216  1.1.1.11  mrg #if __cplusplus >= 201402L
    217  1.1.1.11  mrg 	__glibcxx_requires_subscript(__n);
    218  1.1.1.11  mrg #endif
    219  1.1.1.14  mrg 	return _M_elems[__n];
    220  1.1.1.11  mrg       }
    221   1.1.1.2  mrg 
    222   1.1.1.5  mrg       _GLIBCXX17_CONSTEXPR reference
    223   1.1.1.2  mrg       at(size_type __n)
    224   1.1.1.2  mrg       {
    225   1.1.1.2  mrg 	if (__n >= _Nm)
    226   1.1.1.3  mrg 	  std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) "
    227   1.1.1.3  mrg 					    ">= _Nm (which is %zu)"),
    228   1.1.1.3  mrg 					__n, _Nm);
    229  1.1.1.14  mrg 	return _M_elems[__n];
    230   1.1.1.2  mrg       }
    231   1.1.1.2  mrg 
    232   1.1.1.2  mrg       constexpr const_reference
    233   1.1.1.2  mrg       at(size_type __n) const
    234   1.1.1.2  mrg       {
    235   1.1.1.2  mrg 	// Result of conditional expression must be an lvalue so use
    236   1.1.1.2  mrg 	// boolean ? lvalue : (throw-expr, lvalue)
    237  1.1.1.14  mrg 	return __n < _Nm ? _M_elems[__n]
    238   1.1.1.3  mrg 	  : (std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) "
    239   1.1.1.3  mrg 					       ">= _Nm (which is %zu)"),
    240   1.1.1.3  mrg 					   __n, _Nm),
    241  1.1.1.14  mrg 	     _M_elems[__n]);
    242   1.1.1.2  mrg       }
    243   1.1.1.2  mrg 
    244  1.1.1.11  mrg       [[__nodiscard__]]
    245   1.1.1.5  mrg       _GLIBCXX17_CONSTEXPR reference
    246   1.1.1.3  mrg       front() noexcept
    247  1.1.1.11  mrg       {
    248  1.1.1.11  mrg 	__glibcxx_requires_nonempty();
    249  1.1.1.14  mrg 	return _M_elems[(size_type)0];
    250  1.1.1.11  mrg       }
    251   1.1.1.2  mrg 
    252  1.1.1.11  mrg       [[__nodiscard__]]
    253   1.1.1.5  mrg       constexpr const_reference
    254   1.1.1.3  mrg       front() const noexcept
    255  1.1.1.11  mrg       {
    256  1.1.1.11  mrg #if __cplusplus >= 201402L
    257  1.1.1.11  mrg 	__glibcxx_requires_nonempty();
    258  1.1.1.11  mrg #endif
    259  1.1.1.14  mrg 	return _M_elems[(size_type)0];
    260  1.1.1.11  mrg       }
    261   1.1.1.2  mrg 
    262  1.1.1.11  mrg       [[__nodiscard__]]
    263   1.1.1.5  mrg       _GLIBCXX17_CONSTEXPR reference
    264   1.1.1.3  mrg       back() noexcept
    265  1.1.1.11  mrg       {
    266  1.1.1.11  mrg 	__glibcxx_requires_nonempty();
    267  1.1.1.14  mrg 	return _M_elems[_Nm - 1];
    268  1.1.1.11  mrg       }
    269   1.1.1.2  mrg 
    270  1.1.1.11  mrg       [[__nodiscard__]]
    271   1.1.1.5  mrg       constexpr const_reference
    272   1.1.1.3  mrg       back() const noexcept
    273   1.1.1.5  mrg       {
    274  1.1.1.11  mrg #if __cplusplus >= 201402L
    275  1.1.1.11  mrg 	__glibcxx_requires_nonempty();
    276  1.1.1.11  mrg #endif
    277  1.1.1.14  mrg 	return _M_elems[_Nm - 1];
    278   1.1.1.2  mrg       }
    279   1.1.1.2  mrg 
    280  1.1.1.14  mrg       [[__nodiscard__, __gnu__::__const__, __gnu__::__always_inline__]]
    281   1.1.1.5  mrg       _GLIBCXX17_CONSTEXPR pointer
    282   1.1.1.2  mrg       data() noexcept
    283  1.1.1.14  mrg       { return static_cast<pointer>(_M_elems); }
    284   1.1.1.2  mrg 
    285  1.1.1.11  mrg       [[__nodiscard__]]
    286   1.1.1.5  mrg       _GLIBCXX17_CONSTEXPR const_pointer
    287   1.1.1.2  mrg       data() const noexcept
    288  1.1.1.14  mrg       { return static_cast<const_pointer>(_M_elems); }
    289   1.1.1.2  mrg     };
    290   1.1.1.2  mrg 
    291   1.1.1.5  mrg #if __cpp_deduction_guides >= 201606
    292   1.1.1.5  mrg   template<typename _Tp, typename... _Up>
    293   1.1.1.5  mrg     array(_Tp, _Up...)
    294   1.1.1.5  mrg       -> array<enable_if_t<(is_same_v<_Tp, _Up> && ...), _Tp>,
    295   1.1.1.5  mrg 	       1 + sizeof...(_Up)>;
    296   1.1.1.5  mrg #endif
    297   1.1.1.5  mrg 
    298   1.1.1.2  mrg   // Array comparisons.
    299   1.1.1.2  mrg   template<typename _Tp, std::size_t _Nm>
    300  1.1.1.11  mrg     [[__nodiscard__]]
    301  1.1.1.10  mrg     _GLIBCXX20_CONSTEXPR
    302   1.1.1.5  mrg     inline bool
    303   1.1.1.2  mrg     operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
    304  1.1.1.13  mrg     { return std::__equal_aux1(__one.begin(), __one.end(), __two.begin()); }
    305   1.1.1.2  mrg 
    306  1.1.1.14  mrg #if __cpp_lib_three_way_comparison // C++ >= 20 && lib_concepts
    307  1.1.1.10  mrg   template<typename _Tp, size_t _Nm>
    308  1.1.1.11  mrg     [[nodiscard]]
    309  1.1.1.10  mrg     constexpr __detail::__synth3way_t<_Tp>
    310  1.1.1.10  mrg     operator<=>(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
    311  1.1.1.10  mrg     {
    312  1.1.1.10  mrg       if constexpr (_Nm && __is_memcmp_ordered<_Tp>::__value)
    313  1.1.1.11  mrg 	if (!std::__is_constant_evaluated())
    314  1.1.1.10  mrg 	  {
    315  1.1.1.10  mrg 	    constexpr size_t __n = _Nm * sizeof(_Tp);
    316  1.1.1.10  mrg 	    return __builtin_memcmp(__a.data(), __b.data(), __n) <=> 0;
    317  1.1.1.10  mrg 	  }
    318  1.1.1.10  mrg 
    319  1.1.1.10  mrg       for (size_t __i = 0; __i < _Nm; ++__i)
    320  1.1.1.10  mrg 	{
    321  1.1.1.10  mrg 	  auto __c = __detail::__synth3way(__a[__i], __b[__i]);
    322  1.1.1.10  mrg 	  if (__c != 0)
    323  1.1.1.10  mrg 	    return __c;
    324  1.1.1.10  mrg 	}
    325  1.1.1.10  mrg       return strong_ordering::equal;
    326  1.1.1.10  mrg     }
    327  1.1.1.10  mrg #else
    328   1.1.1.2  mrg   template<typename _Tp, std::size_t _Nm>
    329  1.1.1.11  mrg     [[__nodiscard__]]
    330  1.1.1.10  mrg     _GLIBCXX20_CONSTEXPR
    331   1.1.1.2  mrg     inline bool
    332   1.1.1.2  mrg     operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
    333   1.1.1.2  mrg     { return !(__one == __two); }
    334   1.1.1.2  mrg 
    335   1.1.1.2  mrg   template<typename _Tp, std::size_t _Nm>
    336  1.1.1.11  mrg     [[__nodiscard__]]
    337  1.1.1.10  mrg     _GLIBCXX20_CONSTEXPR
    338   1.1.1.2  mrg     inline bool
    339   1.1.1.2  mrg     operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
    340   1.1.1.5  mrg     {
    341   1.1.1.2  mrg       return std::lexicographical_compare(__a.begin(), __a.end(),
    342   1.1.1.5  mrg 					  __b.begin(), __b.end());
    343   1.1.1.2  mrg     }
    344   1.1.1.2  mrg 
    345   1.1.1.2  mrg   template<typename _Tp, std::size_t _Nm>
    346  1.1.1.11  mrg     [[__nodiscard__]]
    347  1.1.1.10  mrg     _GLIBCXX20_CONSTEXPR
    348   1.1.1.2  mrg     inline bool
    349   1.1.1.2  mrg     operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
    350   1.1.1.2  mrg     { return __two < __one; }
    351   1.1.1.2  mrg 
    352   1.1.1.2  mrg   template<typename _Tp, std::size_t _Nm>
    353  1.1.1.11  mrg     [[__nodiscard__]]
    354  1.1.1.10  mrg     _GLIBCXX20_CONSTEXPR
    355   1.1.1.2  mrg     inline bool
    356   1.1.1.2  mrg     operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
    357   1.1.1.2  mrg     { return !(__one > __two); }
    358   1.1.1.2  mrg 
    359   1.1.1.2  mrg   template<typename _Tp, std::size_t _Nm>
    360  1.1.1.11  mrg     [[__nodiscard__]]
    361  1.1.1.10  mrg     _GLIBCXX20_CONSTEXPR
    362   1.1.1.2  mrg     inline bool
    363   1.1.1.2  mrg     operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
    364   1.1.1.2  mrg     { return !(__one < __two); }
    365  1.1.1.10  mrg #endif // three_way_comparison && concepts
    366   1.1.1.2  mrg 
    367   1.1.1.2  mrg   // Specialized algorithms.
    368   1.1.1.2  mrg   template<typename _Tp, std::size_t _Nm>
    369  1.1.1.10  mrg     _GLIBCXX20_CONSTEXPR
    370   1.1.1.5  mrg     inline
    371   1.1.1.5  mrg #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
    372   1.1.1.5  mrg     // Constrained free swap overload, see p0185r1
    373  1.1.1.14  mrg     __enable_if_t<__array_traits<_Tp, _Nm>::_Is_swappable::value>
    374   1.1.1.5  mrg #else
    375   1.1.1.5  mrg     void
    376   1.1.1.5  mrg #endif
    377   1.1.1.2  mrg     swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two)
    378   1.1.1.2  mrg     noexcept(noexcept(__one.swap(__two)))
    379   1.1.1.2  mrg     { __one.swap(__two); }
    380   1.1.1.2  mrg 
    381   1.1.1.5  mrg #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
    382   1.1.1.5  mrg   template<typename _Tp, std::size_t _Nm>
    383  1.1.1.14  mrg     __enable_if_t<!__array_traits<_Tp, _Nm>::_Is_swappable::value>
    384   1.1.1.5  mrg     swap(array<_Tp, _Nm>&, array<_Tp, _Nm>&) = delete;
    385   1.1.1.5  mrg #endif
    386   1.1.1.5  mrg 
    387   1.1.1.2  mrg   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
    388  1.1.1.11  mrg     [[__nodiscard__]]
    389   1.1.1.2  mrg     constexpr _Tp&
    390   1.1.1.2  mrg     get(array<_Tp, _Nm>& __arr) noexcept
    391   1.1.1.2  mrg     {
    392   1.1.1.5  mrg       static_assert(_Int < _Nm, "array index is within bounds");
    393  1.1.1.14  mrg       return __arr._M_elems[_Int];
    394   1.1.1.2  mrg     }
    395   1.1.1.2  mrg 
    396   1.1.1.2  mrg   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
    397  1.1.1.11  mrg     [[__nodiscard__]]
    398   1.1.1.2  mrg     constexpr _Tp&&
    399   1.1.1.2  mrg     get(array<_Tp, _Nm>&& __arr) noexcept
    400   1.1.1.2  mrg     {
    401   1.1.1.5  mrg       static_assert(_Int < _Nm, "array index is within bounds");
    402  1.1.1.11  mrg       return std::move(std::get<_Int>(__arr));
    403   1.1.1.2  mrg     }
    404   1.1.1.2  mrg 
    405   1.1.1.2  mrg   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
    406  1.1.1.11  mrg     [[__nodiscard__]]
    407   1.1.1.2  mrg     constexpr const _Tp&
    408   1.1.1.2  mrg     get(const array<_Tp, _Nm>& __arr) noexcept
    409   1.1.1.2  mrg     {
    410   1.1.1.5  mrg       static_assert(_Int < _Nm, "array index is within bounds");
    411  1.1.1.14  mrg       return __arr._M_elems[_Int];
    412   1.1.1.2  mrg     }
    413   1.1.1.2  mrg 
    414   1.1.1.8  mrg   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
    415  1.1.1.11  mrg     [[__nodiscard__]]
    416   1.1.1.8  mrg     constexpr const _Tp&&
    417   1.1.1.8  mrg     get(const array<_Tp, _Nm>&& __arr) noexcept
    418   1.1.1.8  mrg     {
    419   1.1.1.8  mrg       static_assert(_Int < _Nm, "array index is within bounds");
    420  1.1.1.11  mrg       return std::move(std::get<_Int>(__arr));
    421   1.1.1.8  mrg     }
    422   1.1.1.8  mrg 
    423  1.1.1.14  mrg #ifdef __cpp_lib_to_array // C++ >= 20 && __cpp_generic_lambdas >= 201707L
    424  1.1.1.10  mrg   template<typename _Tp, size_t _Nm>
    425  1.1.1.11  mrg     [[nodiscard]]
    426  1.1.1.10  mrg     constexpr array<remove_cv_t<_Tp>, _Nm>
    427  1.1.1.10  mrg     to_array(_Tp (&__a)[_Nm])
    428  1.1.1.10  mrg     noexcept(is_nothrow_constructible_v<_Tp, _Tp&>)
    429  1.1.1.10  mrg     {
    430  1.1.1.10  mrg       static_assert(!is_array_v<_Tp>);
    431  1.1.1.10  mrg       static_assert(is_constructible_v<_Tp, _Tp&>);
    432  1.1.1.10  mrg       if constexpr (is_constructible_v<_Tp, _Tp&>)
    433  1.1.1.12  mrg 	{
    434  1.1.1.14  mrg 	  if constexpr (is_trivially_copyable_v<_Tp>
    435  1.1.1.14  mrg 			  && is_trivially_default_constructible_v<_Tp>
    436  1.1.1.14  mrg 			  && is_copy_assignable_v<_Tp>)
    437  1.1.1.12  mrg 	    {
    438  1.1.1.12  mrg 	      array<remove_cv_t<_Tp>, _Nm> __arr;
    439  1.1.1.12  mrg 	      if (!__is_constant_evaluated() && _Nm != 0)
    440  1.1.1.12  mrg 		__builtin_memcpy((void*)__arr.data(), (void*)__a, sizeof(__a));
    441  1.1.1.12  mrg 	      else
    442  1.1.1.12  mrg 		for (size_t __i = 0; __i < _Nm; ++__i)
    443  1.1.1.12  mrg 		  __arr._M_elems[__i] = __a[__i];
    444  1.1.1.12  mrg 	      return __arr;
    445  1.1.1.12  mrg 	    }
    446  1.1.1.12  mrg 	  else
    447  1.1.1.12  mrg 	    return [&__a]<size_t... _Idx>(index_sequence<_Idx...>) {
    448  1.1.1.12  mrg 	      return array<remove_cv_t<_Tp>, _Nm>{{ __a[_Idx]... }};
    449  1.1.1.12  mrg 	    }(make_index_sequence<_Nm>{});
    450  1.1.1.12  mrg 	}
    451  1.1.1.12  mrg       else
    452  1.1.1.12  mrg 	__builtin_unreachable(); // FIXME: see PR c++/91388
    453  1.1.1.10  mrg     }
    454  1.1.1.10  mrg 
    455  1.1.1.10  mrg   template<typename _Tp, size_t _Nm>
    456  1.1.1.11  mrg     [[nodiscard]]
    457  1.1.1.10  mrg     constexpr array<remove_cv_t<_Tp>, _Nm>
    458  1.1.1.10  mrg     to_array(_Tp (&&__a)[_Nm])
    459  1.1.1.10  mrg     noexcept(is_nothrow_move_constructible_v<_Tp>)
    460  1.1.1.10  mrg     {
    461  1.1.1.10  mrg       static_assert(!is_array_v<_Tp>);
    462  1.1.1.10  mrg       static_assert(is_move_constructible_v<_Tp>);
    463  1.1.1.10  mrg       if constexpr (is_move_constructible_v<_Tp>)
    464  1.1.1.12  mrg 	{
    465  1.1.1.14  mrg 	  if constexpr (is_trivially_copyable_v<_Tp>
    466  1.1.1.14  mrg 			  && is_trivially_default_constructible_v<_Tp>
    467  1.1.1.14  mrg 			  && is_copy_assignable_v<_Tp>)
    468  1.1.1.12  mrg 	    {
    469  1.1.1.12  mrg 	      array<remove_cv_t<_Tp>, _Nm> __arr;
    470  1.1.1.12  mrg 	      if (!__is_constant_evaluated() && _Nm != 0)
    471  1.1.1.12  mrg 		__builtin_memcpy((void*)__arr.data(), (void*)__a, sizeof(__a));
    472  1.1.1.12  mrg 	      else
    473  1.1.1.12  mrg 		for (size_t __i = 0; __i < _Nm; ++__i)
    474  1.1.1.12  mrg 		  __arr._M_elems[__i] = __a[__i];
    475  1.1.1.12  mrg 	      return __arr;
    476  1.1.1.12  mrg 	    }
    477  1.1.1.12  mrg 	  else
    478  1.1.1.12  mrg 	    return [&__a]<size_t... _Idx>(index_sequence<_Idx...>) {
    479  1.1.1.12  mrg 	      return array<remove_cv_t<_Tp>, _Nm>{{ std::move(__a[_Idx])... }};
    480  1.1.1.12  mrg 	    }(make_index_sequence<_Nm>{});
    481  1.1.1.12  mrg 	}
    482  1.1.1.12  mrg       else
    483  1.1.1.12  mrg 	__builtin_unreachable(); // FIXME: see PR c++/91388
    484  1.1.1.10  mrg     }
    485  1.1.1.14  mrg #endif // __cpp_lib_to_array
    486  1.1.1.10  mrg 
    487   1.1.1.2  mrg   // Tuple interface to class template array.
    488   1.1.1.2  mrg 
    489   1.1.1.3  mrg   /// Partial specialization for std::array
    490  1.1.1.11  mrg   template<typename _Tp, size_t _Nm>
    491  1.1.1.11  mrg     struct tuple_size<array<_Tp, _Nm>>
    492  1.1.1.11  mrg     : public integral_constant<size_t, _Nm> { };
    493   1.1.1.2  mrg 
    494   1.1.1.3  mrg   /// Partial specialization for std::array
    495  1.1.1.11  mrg   template<size_t _Ind, typename _Tp, size_t _Nm>
    496  1.1.1.11  mrg     struct tuple_element<_Ind, array<_Tp, _Nm>>
    497   1.1.1.2  mrg     {
    498  1.1.1.11  mrg       static_assert(_Ind < _Nm, "array index is in range");
    499  1.1.1.11  mrg       using type = _Tp;
    500   1.1.1.2  mrg     };
    501   1.1.1.2  mrg 
    502  1.1.1.11  mrg #if __cplusplus >= 201703L
    503  1.1.1.11  mrg   template<typename _Tp, size_t _Nm>
    504  1.1.1.11  mrg     inline constexpr size_t tuple_size_v<array<_Tp, _Nm>> = _Nm;
    505  1.1.1.11  mrg 
    506  1.1.1.11  mrg   template<typename _Tp, size_t _Nm>
    507  1.1.1.11  mrg     inline constexpr size_t tuple_size_v<const array<_Tp, _Nm>> = _Nm;
    508  1.1.1.11  mrg #endif
    509  1.1.1.11  mrg 
    510  1.1.1.11  mrg   template<typename _Tp, size_t _Nm>
    511  1.1.1.11  mrg     struct __is_tuple_like_impl<array<_Tp, _Nm>> : true_type
    512   1.1.1.4  mrg     { };
    513   1.1.1.4  mrg 
    514   1.1.1.2  mrg _GLIBCXX_END_NAMESPACE_VERSION
    515   1.1.1.2  mrg } // namespace std
    516   1.1.1.2  mrg 
    517   1.1.1.2  mrg #endif // C++11
    518       1.1  mrg 
    519       1.1  mrg #endif // _GLIBCXX_ARRAY
    520