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