xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/std/array (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
11debfc3dSmrg// <array> -*- C++ -*-
21debfc3dSmrg
3*8feb0f0bSmrg// Copyright (C) 2007-2020 Free Software Foundation, Inc.
41debfc3dSmrg//
51debfc3dSmrg// This file is part of the GNU ISO C++ Library.  This library is free
61debfc3dSmrg// software; you can redistribute it and/or modify it under the
71debfc3dSmrg// terms of the GNU General Public License as published by the
81debfc3dSmrg// Free Software Foundation; either version 3, or (at your option)
91debfc3dSmrg// any later version.
101debfc3dSmrg
111debfc3dSmrg// This library is distributed in the hope that it will be useful,
121debfc3dSmrg// but WITHOUT ANY WARRANTY; without even the implied warranty of
131debfc3dSmrg// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
141debfc3dSmrg// GNU General Public License for more details.
151debfc3dSmrg
161debfc3dSmrg// Under Section 7 of GPL version 3, you are granted additional
171debfc3dSmrg// permissions described in the GCC Runtime Library Exception, version
181debfc3dSmrg// 3.1, as published by the Free Software Foundation.
191debfc3dSmrg
201debfc3dSmrg// You should have received a copy of the GNU General Public License and
211debfc3dSmrg// a copy of the GCC Runtime Library Exception along with this program;
221debfc3dSmrg// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
231debfc3dSmrg// <http://www.gnu.org/licenses/>.
241debfc3dSmrg
251debfc3dSmrg/** @file include/array
261debfc3dSmrg *  This is a Standard C++ Library header.
271debfc3dSmrg */
281debfc3dSmrg
291debfc3dSmrg#ifndef _GLIBCXX_ARRAY
301debfc3dSmrg#define _GLIBCXX_ARRAY 1
311debfc3dSmrg
321debfc3dSmrg#pragma GCC system_header
331debfc3dSmrg
341debfc3dSmrg#if __cplusplus < 201103L
351debfc3dSmrg# include <bits/c++0x_warning.h>
361debfc3dSmrg#else
371debfc3dSmrg
381debfc3dSmrg#include <utility>
39*8feb0f0bSmrg#include <bits/functexcept.h>
401debfc3dSmrg#include <bits/stl_algobase.h>
411debfc3dSmrg#include <bits/range_access.h>
421debfc3dSmrg
431debfc3dSmrgnamespace std _GLIBCXX_VISIBILITY(default)
441debfc3dSmrg{
451debfc3dSmrg_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
461debfc3dSmrg
471debfc3dSmrg  template<typename _Tp, std::size_t _Nm>
481debfc3dSmrg    struct __array_traits
491debfc3dSmrg    {
501debfc3dSmrg      typedef _Tp _Type[_Nm];
511debfc3dSmrg      typedef __is_swappable<_Tp> _Is_swappable;
521debfc3dSmrg      typedef __is_nothrow_swappable<_Tp> _Is_nothrow_swappable;
531debfc3dSmrg
541debfc3dSmrg      static constexpr _Tp&
551debfc3dSmrg      _S_ref(const _Type& __t, std::size_t __n) noexcept
561debfc3dSmrg      { return const_cast<_Tp&>(__t[__n]); }
571debfc3dSmrg
581debfc3dSmrg      static constexpr _Tp*
591debfc3dSmrg      _S_ptr(const _Type& __t) noexcept
601debfc3dSmrg      { return const_cast<_Tp*>(__t); }
611debfc3dSmrg    };
621debfc3dSmrg
631debfc3dSmrg template<typename _Tp>
641debfc3dSmrg   struct __array_traits<_Tp, 0>
651debfc3dSmrg   {
661debfc3dSmrg     struct _Type { };
671debfc3dSmrg     typedef true_type _Is_swappable;
681debfc3dSmrg     typedef true_type _Is_nothrow_swappable;
691debfc3dSmrg
701debfc3dSmrg     static constexpr _Tp&
711debfc3dSmrg     _S_ref(const _Type&, std::size_t) noexcept
721debfc3dSmrg     { return *static_cast<_Tp*>(nullptr); }
731debfc3dSmrg
741debfc3dSmrg     static constexpr _Tp*
751debfc3dSmrg     _S_ptr(const _Type&) noexcept
761debfc3dSmrg     { return nullptr; }
771debfc3dSmrg   };
781debfc3dSmrg
791debfc3dSmrg  /**
801debfc3dSmrg   *  @brief A standard container for storing a fixed size sequence of elements.
811debfc3dSmrg   *
821debfc3dSmrg   *  @ingroup sequences
831debfc3dSmrg   *
841debfc3dSmrg   *  Meets the requirements of a <a href="tables.html#65">container</a>, a
851debfc3dSmrg   *  <a href="tables.html#66">reversible container</a>, and a
861debfc3dSmrg   *  <a href="tables.html#67">sequence</a>.
871debfc3dSmrg   *
881debfc3dSmrg   *  Sets support random access iterators.
891debfc3dSmrg   *
901debfc3dSmrg   *  @tparam  Tp  Type of element. Required to be a complete type.
91*8feb0f0bSmrg   *  @tparam  Nm  Number of elements.
921debfc3dSmrg  */
931debfc3dSmrg  template<typename _Tp, std::size_t _Nm>
941debfc3dSmrg    struct array
951debfc3dSmrg    {
961debfc3dSmrg      typedef _Tp 	    			      value_type;
971debfc3dSmrg      typedef value_type*			      pointer;
981debfc3dSmrg      typedef const value_type*                       const_pointer;
991debfc3dSmrg      typedef value_type&                   	      reference;
1001debfc3dSmrg      typedef const value_type&             	      const_reference;
1011debfc3dSmrg      typedef value_type*          		      iterator;
1021debfc3dSmrg      typedef const value_type*			      const_iterator;
1031debfc3dSmrg      typedef std::size_t                    	      size_type;
1041debfc3dSmrg      typedef std::ptrdiff_t                   	      difference_type;
1051debfc3dSmrg      typedef std::reverse_iterator<iterator>	      reverse_iterator;
1061debfc3dSmrg      typedef std::reverse_iterator<const_iterator>   const_reverse_iterator;
1071debfc3dSmrg
1081debfc3dSmrg      // Support for zero-sized arrays mandatory.
1091debfc3dSmrg      typedef _GLIBCXX_STD_C::__array_traits<_Tp, _Nm> _AT_Type;
1101debfc3dSmrg      typename _AT_Type::_Type                         _M_elems;
1111debfc3dSmrg
1121debfc3dSmrg      // No explicit construct/copy/destroy for aggregate type.
1131debfc3dSmrg
1141debfc3dSmrg      // DR 776.
115*8feb0f0bSmrg      _GLIBCXX20_CONSTEXPR void
1161debfc3dSmrg      fill(const value_type& __u)
1171debfc3dSmrg      { std::fill_n(begin(), size(), __u); }
1181debfc3dSmrg
119*8feb0f0bSmrg      _GLIBCXX20_CONSTEXPR void
1201debfc3dSmrg      swap(array& __other)
1211debfc3dSmrg      noexcept(_AT_Type::_Is_nothrow_swappable::value)
1221debfc3dSmrg      { std::swap_ranges(begin(), end(), __other.begin()); }
1231debfc3dSmrg
1241debfc3dSmrg      // Iterators.
1251debfc3dSmrg      _GLIBCXX17_CONSTEXPR iterator
1261debfc3dSmrg      begin() noexcept
1271debfc3dSmrg      { return iterator(data()); }
1281debfc3dSmrg
1291debfc3dSmrg      _GLIBCXX17_CONSTEXPR const_iterator
1301debfc3dSmrg      begin() const noexcept
1311debfc3dSmrg      { return const_iterator(data()); }
1321debfc3dSmrg
1331debfc3dSmrg      _GLIBCXX17_CONSTEXPR iterator
1341debfc3dSmrg      end() noexcept
1351debfc3dSmrg      { return iterator(data() + _Nm); }
1361debfc3dSmrg
1371debfc3dSmrg      _GLIBCXX17_CONSTEXPR const_iterator
1381debfc3dSmrg      end() const noexcept
1391debfc3dSmrg      { return const_iterator(data() + _Nm); }
1401debfc3dSmrg
1411debfc3dSmrg      _GLIBCXX17_CONSTEXPR reverse_iterator
1421debfc3dSmrg      rbegin() noexcept
1431debfc3dSmrg      { return reverse_iterator(end()); }
1441debfc3dSmrg
1451debfc3dSmrg      _GLIBCXX17_CONSTEXPR const_reverse_iterator
1461debfc3dSmrg      rbegin() const noexcept
1471debfc3dSmrg      { return const_reverse_iterator(end()); }
1481debfc3dSmrg
1491debfc3dSmrg      _GLIBCXX17_CONSTEXPR reverse_iterator
1501debfc3dSmrg      rend() noexcept
1511debfc3dSmrg      { return reverse_iterator(begin()); }
1521debfc3dSmrg
1531debfc3dSmrg      _GLIBCXX17_CONSTEXPR const_reverse_iterator
1541debfc3dSmrg      rend() const noexcept
1551debfc3dSmrg      { return const_reverse_iterator(begin()); }
1561debfc3dSmrg
1571debfc3dSmrg      _GLIBCXX17_CONSTEXPR const_iterator
1581debfc3dSmrg      cbegin() const noexcept
1591debfc3dSmrg      { return const_iterator(data()); }
1601debfc3dSmrg
1611debfc3dSmrg      _GLIBCXX17_CONSTEXPR const_iterator
1621debfc3dSmrg      cend() const noexcept
1631debfc3dSmrg      { return const_iterator(data() + _Nm); }
1641debfc3dSmrg
1651debfc3dSmrg      _GLIBCXX17_CONSTEXPR const_reverse_iterator
1661debfc3dSmrg      crbegin() const noexcept
1671debfc3dSmrg      { return const_reverse_iterator(end()); }
1681debfc3dSmrg
1691debfc3dSmrg      _GLIBCXX17_CONSTEXPR const_reverse_iterator
1701debfc3dSmrg      crend() const noexcept
1711debfc3dSmrg      { return const_reverse_iterator(begin()); }
1721debfc3dSmrg
1731debfc3dSmrg      // Capacity.
1741debfc3dSmrg      constexpr size_type
1751debfc3dSmrg      size() const noexcept { return _Nm; }
1761debfc3dSmrg
1771debfc3dSmrg      constexpr size_type
1781debfc3dSmrg      max_size() const noexcept { return _Nm; }
1791debfc3dSmrg
180c0a68be4Smrg      _GLIBCXX_NODISCARD constexpr bool
1811debfc3dSmrg      empty() const noexcept { return size() == 0; }
1821debfc3dSmrg
1831debfc3dSmrg      // Element access.
1841debfc3dSmrg      _GLIBCXX17_CONSTEXPR reference
1851debfc3dSmrg      operator[](size_type __n) noexcept
1861debfc3dSmrg      { return _AT_Type::_S_ref(_M_elems, __n); }
1871debfc3dSmrg
1881debfc3dSmrg      constexpr const_reference
1891debfc3dSmrg      operator[](size_type __n) const noexcept
1901debfc3dSmrg      { return _AT_Type::_S_ref(_M_elems, __n); }
1911debfc3dSmrg
1921debfc3dSmrg      _GLIBCXX17_CONSTEXPR reference
1931debfc3dSmrg      at(size_type __n)
1941debfc3dSmrg      {
1951debfc3dSmrg	if (__n >= _Nm)
1961debfc3dSmrg	  std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) "
1971debfc3dSmrg					    ">= _Nm (which is %zu)"),
1981debfc3dSmrg					__n, _Nm);
1991debfc3dSmrg	return _AT_Type::_S_ref(_M_elems, __n);
2001debfc3dSmrg      }
2011debfc3dSmrg
2021debfc3dSmrg      constexpr const_reference
2031debfc3dSmrg      at(size_type __n) const
2041debfc3dSmrg      {
2051debfc3dSmrg	// Result of conditional expression must be an lvalue so use
2061debfc3dSmrg	// boolean ? lvalue : (throw-expr, lvalue)
2071debfc3dSmrg	return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n)
2081debfc3dSmrg	  : (std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) "
2091debfc3dSmrg					       ">= _Nm (which is %zu)"),
2101debfc3dSmrg					   __n, _Nm),
2111debfc3dSmrg	     _AT_Type::_S_ref(_M_elems, 0));
2121debfc3dSmrg      }
2131debfc3dSmrg
2141debfc3dSmrg      _GLIBCXX17_CONSTEXPR reference
2151debfc3dSmrg      front() noexcept
2161debfc3dSmrg      { return *begin(); }
2171debfc3dSmrg
2181debfc3dSmrg      constexpr const_reference
2191debfc3dSmrg      front() const noexcept
2201debfc3dSmrg      { return _AT_Type::_S_ref(_M_elems, 0); }
2211debfc3dSmrg
2221debfc3dSmrg      _GLIBCXX17_CONSTEXPR reference
2231debfc3dSmrg      back() noexcept
2241debfc3dSmrg      { return _Nm ? *(end() - 1) : *end(); }
2251debfc3dSmrg
2261debfc3dSmrg      constexpr const_reference
2271debfc3dSmrg      back() const noexcept
2281debfc3dSmrg      {
2291debfc3dSmrg	return _Nm ? _AT_Type::_S_ref(_M_elems, _Nm - 1)
2301debfc3dSmrg 	           : _AT_Type::_S_ref(_M_elems, 0);
2311debfc3dSmrg      }
2321debfc3dSmrg
2331debfc3dSmrg      _GLIBCXX17_CONSTEXPR pointer
2341debfc3dSmrg      data() noexcept
2351debfc3dSmrg      { return _AT_Type::_S_ptr(_M_elems); }
2361debfc3dSmrg
2371debfc3dSmrg      _GLIBCXX17_CONSTEXPR const_pointer
2381debfc3dSmrg      data() const noexcept
2391debfc3dSmrg      { return _AT_Type::_S_ptr(_M_elems); }
2401debfc3dSmrg    };
2411debfc3dSmrg
2421debfc3dSmrg#if __cpp_deduction_guides >= 201606
2431debfc3dSmrg  template<typename _Tp, typename... _Up>
2441debfc3dSmrg    array(_Tp, _Up...)
2451debfc3dSmrg      -> array<enable_if_t<(is_same_v<_Tp, _Up> && ...), _Tp>,
2461debfc3dSmrg	       1 + sizeof...(_Up)>;
2471debfc3dSmrg#endif
2481debfc3dSmrg
2491debfc3dSmrg  // Array comparisons.
2501debfc3dSmrg  template<typename _Tp, std::size_t _Nm>
251*8feb0f0bSmrg    _GLIBCXX20_CONSTEXPR
2521debfc3dSmrg    inline bool
2531debfc3dSmrg    operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
2541debfc3dSmrg    { return std::equal(__one.begin(), __one.end(), __two.begin()); }
2551debfc3dSmrg
256*8feb0f0bSmrg#if __cpp_lib_three_way_comparison && __cpp_lib_concepts
257*8feb0f0bSmrg  template<typename _Tp, size_t _Nm>
258*8feb0f0bSmrg    constexpr __detail::__synth3way_t<_Tp>
259*8feb0f0bSmrg    operator<=>(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
260*8feb0f0bSmrg    {
261*8feb0f0bSmrg#ifdef __cpp_lib_is_constant_evaluated
262*8feb0f0bSmrg      if constexpr (_Nm && __is_memcmp_ordered<_Tp>::__value)
263*8feb0f0bSmrg	if (!std::is_constant_evaluated())
264*8feb0f0bSmrg	  {
265*8feb0f0bSmrg	    constexpr size_t __n = _Nm * sizeof(_Tp);
266*8feb0f0bSmrg	    return __builtin_memcmp(__a.data(), __b.data(), __n) <=> 0;
267*8feb0f0bSmrg	  }
268*8feb0f0bSmrg#endif
269*8feb0f0bSmrg
270*8feb0f0bSmrg      for (size_t __i = 0; __i < _Nm; ++__i)
271*8feb0f0bSmrg	{
272*8feb0f0bSmrg	  auto __c = __detail::__synth3way(__a[__i], __b[__i]);
273*8feb0f0bSmrg	  if (__c != 0)
274*8feb0f0bSmrg	    return __c;
275*8feb0f0bSmrg	}
276*8feb0f0bSmrg      return strong_ordering::equal;
277*8feb0f0bSmrg    }
278*8feb0f0bSmrg#else
2791debfc3dSmrg  template<typename _Tp, std::size_t _Nm>
280*8feb0f0bSmrg    _GLIBCXX20_CONSTEXPR
2811debfc3dSmrg    inline bool
2821debfc3dSmrg    operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
2831debfc3dSmrg    { return !(__one == __two); }
2841debfc3dSmrg
2851debfc3dSmrg  template<typename _Tp, std::size_t _Nm>
286*8feb0f0bSmrg    _GLIBCXX20_CONSTEXPR
2871debfc3dSmrg    inline bool
2881debfc3dSmrg    operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
2891debfc3dSmrg    {
2901debfc3dSmrg      return std::lexicographical_compare(__a.begin(), __a.end(),
2911debfc3dSmrg					  __b.begin(), __b.end());
2921debfc3dSmrg    }
2931debfc3dSmrg
2941debfc3dSmrg  template<typename _Tp, std::size_t _Nm>
295*8feb0f0bSmrg    _GLIBCXX20_CONSTEXPR
2961debfc3dSmrg    inline bool
2971debfc3dSmrg    operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
2981debfc3dSmrg    { return __two < __one; }
2991debfc3dSmrg
3001debfc3dSmrg  template<typename _Tp, std::size_t _Nm>
301*8feb0f0bSmrg    _GLIBCXX20_CONSTEXPR
3021debfc3dSmrg    inline bool
3031debfc3dSmrg    operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
3041debfc3dSmrg    { return !(__one > __two); }
3051debfc3dSmrg
3061debfc3dSmrg  template<typename _Tp, std::size_t _Nm>
307*8feb0f0bSmrg    _GLIBCXX20_CONSTEXPR
3081debfc3dSmrg    inline bool
3091debfc3dSmrg    operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
3101debfc3dSmrg    { return !(__one < __two); }
311*8feb0f0bSmrg#endif // three_way_comparison && concepts
3121debfc3dSmrg
3131debfc3dSmrg  // Specialized algorithms.
3141debfc3dSmrg  template<typename _Tp, std::size_t _Nm>
315*8feb0f0bSmrg    _GLIBCXX20_CONSTEXPR
3161debfc3dSmrg    inline
3171debfc3dSmrg#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
3181debfc3dSmrg    // Constrained free swap overload, see p0185r1
3191debfc3dSmrg    typename enable_if<
3201debfc3dSmrg      _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::_Is_swappable::value
3211debfc3dSmrg    >::type
3221debfc3dSmrg#else
3231debfc3dSmrg    void
3241debfc3dSmrg#endif
3251debfc3dSmrg    swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two)
3261debfc3dSmrg    noexcept(noexcept(__one.swap(__two)))
3271debfc3dSmrg    { __one.swap(__two); }
3281debfc3dSmrg
3291debfc3dSmrg#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
3301debfc3dSmrg  template<typename _Tp, std::size_t _Nm>
3311debfc3dSmrg    typename enable_if<
3321debfc3dSmrg      !_GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::_Is_swappable::value>::type
3331debfc3dSmrg    swap(array<_Tp, _Nm>&, array<_Tp, _Nm>&) = delete;
3341debfc3dSmrg#endif
3351debfc3dSmrg
3361debfc3dSmrg  template<std::size_t _Int, typename _Tp, std::size_t _Nm>
3371debfc3dSmrg    constexpr _Tp&
3381debfc3dSmrg    get(array<_Tp, _Nm>& __arr) noexcept
3391debfc3dSmrg    {
3401debfc3dSmrg      static_assert(_Int < _Nm, "array index is within bounds");
3411debfc3dSmrg      return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::
3421debfc3dSmrg	_S_ref(__arr._M_elems, _Int);
3431debfc3dSmrg    }
3441debfc3dSmrg
3451debfc3dSmrg  template<std::size_t _Int, typename _Tp, std::size_t _Nm>
3461debfc3dSmrg    constexpr _Tp&&
3471debfc3dSmrg    get(array<_Tp, _Nm>&& __arr) noexcept
3481debfc3dSmrg    {
3491debfc3dSmrg      static_assert(_Int < _Nm, "array index is within bounds");
3501debfc3dSmrg      return std::move(_GLIBCXX_STD_C::get<_Int>(__arr));
3511debfc3dSmrg    }
3521debfc3dSmrg
3531debfc3dSmrg  template<std::size_t _Int, typename _Tp, std::size_t _Nm>
3541debfc3dSmrg    constexpr const _Tp&
3551debfc3dSmrg    get(const array<_Tp, _Nm>& __arr) noexcept
3561debfc3dSmrg    {
3571debfc3dSmrg      static_assert(_Int < _Nm, "array index is within bounds");
3581debfc3dSmrg      return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::
3591debfc3dSmrg	_S_ref(__arr._M_elems, _Int);
3601debfc3dSmrg    }
3611debfc3dSmrg
362a2dc1f3fSmrg  template<std::size_t _Int, typename _Tp, std::size_t _Nm>
363a2dc1f3fSmrg    constexpr const _Tp&&
364a2dc1f3fSmrg    get(const array<_Tp, _Nm>&& __arr) noexcept
365a2dc1f3fSmrg    {
366a2dc1f3fSmrg      static_assert(_Int < _Nm, "array index is within bounds");
367a2dc1f3fSmrg      return std::move(_GLIBCXX_STD_C::get<_Int>(__arr));
368a2dc1f3fSmrg    }
369a2dc1f3fSmrg
370*8feb0f0bSmrg#if __cplusplus > 201703L
371*8feb0f0bSmrg#define __cpp_lib_to_array 201907L
372*8feb0f0bSmrg
373*8feb0f0bSmrg  template<bool _Move = false, typename _Tp, size_t... _Idx>
374*8feb0f0bSmrg    constexpr array<remove_cv_t<_Tp>, sizeof...(_Idx)>
375*8feb0f0bSmrg    __to_array(_Tp (&__a)[sizeof...(_Idx)], index_sequence<_Idx...>)
376*8feb0f0bSmrg    {
377*8feb0f0bSmrg      if constexpr (_Move)
378*8feb0f0bSmrg	return {{std::move(__a[_Idx])...}};
379*8feb0f0bSmrg      else
380*8feb0f0bSmrg	return {{__a[_Idx]...}};
381*8feb0f0bSmrg    }
382*8feb0f0bSmrg
383*8feb0f0bSmrg  template<typename _Tp, size_t _Nm>
384*8feb0f0bSmrg    constexpr array<remove_cv_t<_Tp>, _Nm>
385*8feb0f0bSmrg    to_array(_Tp (&__a)[_Nm])
386*8feb0f0bSmrg    noexcept(is_nothrow_constructible_v<_Tp, _Tp&>)
387*8feb0f0bSmrg    {
388*8feb0f0bSmrg      static_assert(!is_array_v<_Tp>);
389*8feb0f0bSmrg      static_assert(is_constructible_v<_Tp, _Tp&>);
390*8feb0f0bSmrg      if constexpr (is_constructible_v<_Tp, _Tp&>)
391*8feb0f0bSmrg	return _GLIBCXX_STD_C::__to_array(__a, make_index_sequence<_Nm>{});
392*8feb0f0bSmrg      __builtin_unreachable(); // FIXME: see PR c++/91388
393*8feb0f0bSmrg    }
394*8feb0f0bSmrg
395*8feb0f0bSmrg  template<typename _Tp, size_t _Nm>
396*8feb0f0bSmrg    constexpr array<remove_cv_t<_Tp>, _Nm>
397*8feb0f0bSmrg    to_array(_Tp (&&__a)[_Nm])
398*8feb0f0bSmrg    noexcept(is_nothrow_move_constructible_v<_Tp>)
399*8feb0f0bSmrg    {
400*8feb0f0bSmrg      static_assert(!is_array_v<_Tp>);
401*8feb0f0bSmrg      static_assert(is_move_constructible_v<_Tp>);
402*8feb0f0bSmrg      if constexpr (is_move_constructible_v<_Tp>)
403*8feb0f0bSmrg	return _GLIBCXX_STD_C::__to_array<1>(__a, make_index_sequence<_Nm>{});
404*8feb0f0bSmrg      __builtin_unreachable(); // FIXME: see PR c++/91388
405*8feb0f0bSmrg    }
406*8feb0f0bSmrg#endif // C++20
407*8feb0f0bSmrg
4081debfc3dSmrg_GLIBCXX_END_NAMESPACE_CONTAINER
4091debfc3dSmrg} // namespace std
4101debfc3dSmrg
4111debfc3dSmrgnamespace std _GLIBCXX_VISIBILITY(default)
4121debfc3dSmrg{
4131debfc3dSmrg_GLIBCXX_BEGIN_NAMESPACE_VERSION
4141debfc3dSmrg
4151debfc3dSmrg  // Tuple interface to class template array.
4161debfc3dSmrg
4171debfc3dSmrg  /// tuple_size
4181debfc3dSmrg  template<typename _Tp>
419a2dc1f3fSmrg    struct tuple_size;
4201debfc3dSmrg
4211debfc3dSmrg  /// Partial specialization for std::array
4221debfc3dSmrg  template<typename _Tp, std::size_t _Nm>
4231debfc3dSmrg    struct tuple_size<_GLIBCXX_STD_C::array<_Tp, _Nm>>
4241debfc3dSmrg    : public integral_constant<std::size_t, _Nm> { };
4251debfc3dSmrg
4261debfc3dSmrg  /// tuple_element
4271debfc3dSmrg  template<std::size_t _Int, typename _Tp>
428a2dc1f3fSmrg    struct tuple_element;
4291debfc3dSmrg
4301debfc3dSmrg  /// Partial specialization for std::array
4311debfc3dSmrg  template<std::size_t _Int, typename _Tp, std::size_t _Nm>
4321debfc3dSmrg    struct tuple_element<_Int, _GLIBCXX_STD_C::array<_Tp, _Nm>>
4331debfc3dSmrg    {
4341debfc3dSmrg      static_assert(_Int < _Nm, "index is out of bounds");
4351debfc3dSmrg      typedef _Tp type;
4361debfc3dSmrg    };
4371debfc3dSmrg
4381debfc3dSmrg  template<typename _Tp, std::size_t _Nm>
4391debfc3dSmrg    struct __is_tuple_like_impl<_GLIBCXX_STD_C::array<_Tp, _Nm>> : true_type
4401debfc3dSmrg    { };
4411debfc3dSmrg
4421debfc3dSmrg_GLIBCXX_END_NAMESPACE_VERSION
4431debfc3dSmrg} // namespace std
4441debfc3dSmrg
4451debfc3dSmrg#ifdef _GLIBCXX_DEBUG
4461debfc3dSmrg# include <debug/array>
4471debfc3dSmrg#endif
4481debfc3dSmrg
4491debfc3dSmrg#endif // C++11
4501debfc3dSmrg
4511debfc3dSmrg#endif // _GLIBCXX_ARRAY
452