// <array> -*- C++ -*-

// Copyright (C) 2007-2025 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/** @file include/array
 *  This is a Standard C++ Library header.
 */

#ifndef _GLIBCXX_ARRAY
#define _GLIBCXX_ARRAY 1

#ifdef _GLIBCXX_SYSHDR
#pragma GCC system_header
#endif

#if __cplusplus < 201103L
# include <bits/c++0x_warning.h>
#else

#include <compare>
#include <initializer_list>

#include <type_traits>
#include <bits/functexcept.h>
#include <bits/stl_algobase.h>
#include <bits/range_access.h> // std::begin, std::end etc.
#include <bits/utility.h>      // std::index_sequence, std::tuple_size
#include <debug/assertions.h>

#define __glibcxx_want_array_constexpr
#define __glibcxx_want_freestanding_array
#define __glibcxx_want_nonmember_container_access
#define __glibcxx_want_to_array
#include <bits/version.h>

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  template<typename _Tp, size_t _Nm>
    struct __array_traits
    {
      using _Type = _Tp[_Nm];
      using _Is_swappable = __is_swappable<_Tp>;
      using _Is_nothrow_swappable = __is_nothrow_swappable<_Tp>;
    };

 template<typename _Tp>
   struct __array_traits<_Tp, 0>
   {
     // Empty type used instead of _Tp[0] for std::array<_Tp, 0>.
     struct _Type
     {
       // Indexing is undefined.
       __attribute__((__always_inline__,__noreturn__))
       _Tp& operator[](size_t) const noexcept { __builtin_trap(); }

       // Conversion to a pointer produces a null pointer.
       __attribute__((__always_inline__))
       constexpr explicit operator _Tp*() const noexcept { return nullptr; }
     };

     using _Is_swappable = true_type;
     using _Is_nothrow_swappable = true_type;
   };

  /**
   *  @brief A standard container for storing a fixed size sequence of elements.
   *
   *  @ingroup sequences
   *
   *  Meets the requirements of a <a href="tables.html#65">container</a>, a
   *  <a href="tables.html#66">reversible container</a>, and a
   *  <a href="tables.html#67">sequence</a>.
   *
   *  Sets support random access iterators.
   *
   *  @tparam  Tp  Type of element. Required to be a complete type.
   *  @tparam  Nm  Number of elements.
  */
  template<typename _Tp, std::size_t _Nm>
    struct array
    {
      typedef _Tp 	    			      value_type;
      typedef value_type*			      pointer;
      typedef const value_type*                       const_pointer;
      typedef value_type&                   	      reference;
      typedef const value_type&             	      const_reference;
      typedef value_type*          		      iterator;
      typedef const value_type*			      const_iterator;
      typedef std::size_t                    	      size_type;
      typedef std::ptrdiff_t                   	      difference_type;
      typedef std::reverse_iterator<iterator>	      reverse_iterator;
      typedef std::reverse_iterator<const_iterator>   const_reverse_iterator;

      // Support for zero-sized arrays mandatory.
      typename __array_traits<_Tp, _Nm>::_Type        _M_elems;

      // No explicit construct/copy/destroy for aggregate type.

      // DR 776.
      _GLIBCXX20_CONSTEXPR void
      fill(const value_type& __u)
      { std::fill_n(begin(), size(), __u); }

      _GLIBCXX20_CONSTEXPR void
      swap(array& __other)
      noexcept(__array_traits<_Tp, _Nm>::_Is_nothrow_swappable::value)
      { std::swap_ranges(begin(), end(), __other.begin()); }

      // Iterators.
      [[__gnu__::__const__, __nodiscard__]]
      _GLIBCXX17_CONSTEXPR iterator
      begin() noexcept
      { return iterator(data()); }

      [[__nodiscard__]]
      _GLIBCXX17_CONSTEXPR const_iterator
      begin() const noexcept
      { return const_iterator(data()); }

      [[__gnu__::__const__, __nodiscard__]]
      _GLIBCXX17_CONSTEXPR iterator
      end() noexcept
      { return iterator(data() + _Nm); }

      [[__nodiscard__]]
      _GLIBCXX17_CONSTEXPR const_iterator
      end() const noexcept
      { return const_iterator(data() + _Nm); }

      [[__gnu__::__const__, __nodiscard__]]
      _GLIBCXX17_CONSTEXPR reverse_iterator
      rbegin() noexcept
      { return reverse_iterator(end()); }

      [[__nodiscard__]]
      _GLIBCXX17_CONSTEXPR const_reverse_iterator
      rbegin() const noexcept
      { return const_reverse_iterator(end()); }

      [[__gnu__::__const__, __nodiscard__]]
      _GLIBCXX17_CONSTEXPR reverse_iterator
      rend() noexcept
      { return reverse_iterator(begin()); }

      [[__nodiscard__]]
      _GLIBCXX17_CONSTEXPR const_reverse_iterator
      rend() const noexcept
      { return const_reverse_iterator(begin()); }

      [[__nodiscard__]]
      _GLIBCXX17_CONSTEXPR const_iterator
      cbegin() const noexcept
      { return const_iterator(data()); }

      [[__nodiscard__]]
      _GLIBCXX17_CONSTEXPR const_iterator
      cend() const noexcept
      { return const_iterator(data() + _Nm); }

      [[__nodiscard__]]
      _GLIBCXX17_CONSTEXPR const_reverse_iterator
      crbegin() const noexcept
      { return const_reverse_iterator(end()); }

      [[__nodiscard__]]
      _GLIBCXX17_CONSTEXPR const_reverse_iterator
      crend() const noexcept
      { return const_reverse_iterator(begin()); }

      // Capacity.
      [[__nodiscard__, __gnu__::__const__, __gnu__::__always_inline__]]
      constexpr size_type
      size() const noexcept { return _Nm; }

      [[__nodiscard__, __gnu__::__const__, __gnu__::__always_inline__]]
      constexpr size_type
      max_size() const noexcept { return _Nm; }

      [[__nodiscard__, __gnu__::__const__, __gnu__::__always_inline__]]
      constexpr bool
      empty() const noexcept { return size() == 0; }

      // Element access.
      [[__nodiscard__]]
      _GLIBCXX17_CONSTEXPR reference
      operator[](size_type __n) noexcept
      {
	__glibcxx_requires_subscript(__n);
	return _M_elems[__n];
      }

      [[__nodiscard__]]
      constexpr const_reference
      operator[](size_type __n) const noexcept
      {
#if __cplusplus >= 201402L
	__glibcxx_requires_subscript(__n);
#endif
	return _M_elems[__n];
      }

      _GLIBCXX17_CONSTEXPR reference
      at(size_type __n)
      {
	if (__n >= _Nm)
	  std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) "
					    ">= _Nm (which is %zu)"),
					__n, _Nm);
	return _M_elems[__n];
      }

      constexpr const_reference
      at(size_type __n) const
      {
	// Result of conditional expression must be an lvalue so use
	// boolean ? lvalue : (throw-expr, lvalue)
	return __n < _Nm ? _M_elems[__n]
	  : (std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) "
					       ">= _Nm (which is %zu)"),
					   __n, _Nm),
	     _M_elems[__n]);
      }

      [[__nodiscard__]]
      _GLIBCXX17_CONSTEXPR reference
      front() noexcept
      {
	__glibcxx_requires_nonempty();
	return _M_elems[(size_type)0];
      }

      [[__nodiscard__]]
      constexpr const_reference
      front() const noexcept
      {
#if __cplusplus >= 201402L
	__glibcxx_requires_nonempty();
#endif
	return _M_elems[(size_type)0];
      }

      [[__nodiscard__]]
      _GLIBCXX17_CONSTEXPR reference
      back() noexcept
      {
	__glibcxx_requires_nonempty();
	return _M_elems[_Nm - 1];
      }

      [[__nodiscard__]]
      constexpr const_reference
      back() const noexcept
      {
#if __cplusplus >= 201402L
	__glibcxx_requires_nonempty();
#endif
	return _M_elems[_Nm - 1];
      }

      [[__nodiscard__, __gnu__::__const__, __gnu__::__always_inline__]]
      _GLIBCXX17_CONSTEXPR pointer
      data() noexcept
      { return static_cast<pointer>(_M_elems); }

      [[__nodiscard__]]
      _GLIBCXX17_CONSTEXPR const_pointer
      data() const noexcept
      { return static_cast<const_pointer>(_M_elems); }
    };

#if __cpp_deduction_guides >= 201606
  template<typename _Tp, typename... _Up>
    array(_Tp, _Up...)
      -> array<enable_if_t<(is_same_v<_Tp, _Up> && ...), _Tp>,
	       1 + sizeof...(_Up)>;
#endif

  // Array comparisons.
  template<typename _Tp, std::size_t _Nm>
    [[__nodiscard__]]
    _GLIBCXX20_CONSTEXPR
    inline bool
    operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
    { return std::__equal_aux1(__one.begin(), __one.end(), __two.begin()); }

#if __cpp_lib_three_way_comparison // C++ >= 20 && lib_concepts
  template<typename _Tp, size_t _Nm>
    [[nodiscard]]
    constexpr __detail::__synth3way_t<_Tp>
    operator<=>(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
    {
      if constexpr (_Nm && __is_memcmp_ordered<_Tp>::__value)
	if (!std::__is_constant_evaluated())
	  {
	    constexpr size_t __n = _Nm * sizeof(_Tp);
	    return __builtin_memcmp(__a.data(), __b.data(), __n) <=> 0;
	  }

      for (size_t __i = 0; __i < _Nm; ++__i)
	{
	  auto __c = __detail::__synth3way(__a[__i], __b[__i]);
	  if (__c != 0)
	    return __c;
	}
      return strong_ordering::equal;
    }
#else
  template<typename _Tp, std::size_t _Nm>
    [[__nodiscard__]]
    _GLIBCXX20_CONSTEXPR
    inline bool
    operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
    { return !(__one == __two); }

  template<typename _Tp, std::size_t _Nm>
    [[__nodiscard__]]
    _GLIBCXX20_CONSTEXPR
    inline bool
    operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
    {
      return std::lexicographical_compare(__a.begin(), __a.end(),
					  __b.begin(), __b.end());
    }

  template<typename _Tp, std::size_t _Nm>
    [[__nodiscard__]]
    _GLIBCXX20_CONSTEXPR
    inline bool
    operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
    { return __two < __one; }

  template<typename _Tp, std::size_t _Nm>
    [[__nodiscard__]]
    _GLIBCXX20_CONSTEXPR
    inline bool
    operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
    { return !(__one > __two); }

  template<typename _Tp, std::size_t _Nm>
    [[__nodiscard__]]
    _GLIBCXX20_CONSTEXPR
    inline bool
    operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
    { return !(__one < __two); }
#endif // three_way_comparison && concepts

  // Specialized algorithms.
  template<typename _Tp, std::size_t _Nm>
    _GLIBCXX20_CONSTEXPR
    inline
#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
    // Constrained free swap overload, see p0185r1
    __enable_if_t<__array_traits<_Tp, _Nm>::_Is_swappable::value>
#else
    void
#endif
    swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two)
    noexcept(noexcept(__one.swap(__two)))
    { __one.swap(__two); }

#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
  template<typename _Tp, std::size_t _Nm>
    __enable_if_t<!__array_traits<_Tp, _Nm>::_Is_swappable::value>
    swap(array<_Tp, _Nm>&, array<_Tp, _Nm>&) = delete;
#endif

  template<std::size_t _Int, typename _Tp, std::size_t _Nm>
    [[__nodiscard__]]
    constexpr _Tp&
    get(array<_Tp, _Nm>& __arr) noexcept
    {
      static_assert(_Int < _Nm, "array index is within bounds");
      return __arr._M_elems[_Int];
    }

  template<std::size_t _Int, typename _Tp, std::size_t _Nm>
    [[__nodiscard__]]
    constexpr _Tp&&
    get(array<_Tp, _Nm>&& __arr) noexcept
    {
      static_assert(_Int < _Nm, "array index is within bounds");
      return std::move(std::get<_Int>(__arr));
    }

  template<std::size_t _Int, typename _Tp, std::size_t _Nm>
    [[__nodiscard__]]
    constexpr const _Tp&
    get(const array<_Tp, _Nm>& __arr) noexcept
    {
      static_assert(_Int < _Nm, "array index is within bounds");
      return __arr._M_elems[_Int];
    }

  template<std::size_t _Int, typename _Tp, std::size_t _Nm>
    [[__nodiscard__]]
    constexpr const _Tp&&
    get(const array<_Tp, _Nm>&& __arr) noexcept
    {
      static_assert(_Int < _Nm, "array index is within bounds");
      return std::move(std::get<_Int>(__arr));
    }

#ifdef __cpp_lib_to_array // C++ >= 20 && __cpp_generic_lambdas >= 201707L
  template<typename _Tp, size_t _Nm>
    [[nodiscard]]
    constexpr array<remove_cv_t<_Tp>, _Nm>
    to_array(_Tp (&__a)[_Nm])
    noexcept(is_nothrow_constructible_v<_Tp, _Tp&>)
    {
      static_assert(!is_array_v<_Tp>);
      static_assert(is_constructible_v<_Tp, _Tp&>);
      if constexpr (is_constructible_v<_Tp, _Tp&>)
	{
	  if constexpr (is_trivially_copyable_v<_Tp>
			  && is_trivially_default_constructible_v<_Tp>
			  && is_copy_assignable_v<_Tp>)
	    {
	      array<remove_cv_t<_Tp>, _Nm> __arr;
	      if (!__is_constant_evaluated() && _Nm != 0)
		__builtin_memcpy((void*)__arr.data(), (void*)__a, sizeof(__a));
	      else
		for (size_t __i = 0; __i < _Nm; ++__i)
		  __arr._M_elems[__i] = __a[__i];
	      return __arr;
	    }
	  else
	    return [&__a]<size_t... _Idx>(index_sequence<_Idx...>) {
	      return array<remove_cv_t<_Tp>, _Nm>{{ __a[_Idx]... }};
	    }(make_index_sequence<_Nm>{});
	}
      else
	__builtin_unreachable(); // FIXME: see PR c++/91388
    }

  template<typename _Tp, size_t _Nm>
    [[nodiscard]]
    constexpr array<remove_cv_t<_Tp>, _Nm>
    to_array(_Tp (&&__a)[_Nm])
    noexcept(is_nothrow_move_constructible_v<_Tp>)
    {
      static_assert(!is_array_v<_Tp>);
      static_assert(is_move_constructible_v<_Tp>);
      if constexpr (is_move_constructible_v<_Tp>)
	{
	  if constexpr (is_trivially_copyable_v<_Tp>
			  && is_trivially_default_constructible_v<_Tp>
			  && is_copy_assignable_v<_Tp>)
	    {
	      array<remove_cv_t<_Tp>, _Nm> __arr;
	      if (!__is_constant_evaluated() && _Nm != 0)
		__builtin_memcpy((void*)__arr.data(), (void*)__a, sizeof(__a));
	      else
		for (size_t __i = 0; __i < _Nm; ++__i)
		  __arr._M_elems[__i] = __a[__i];
	      return __arr;
	    }
	  else
	    return [&__a]<size_t... _Idx>(index_sequence<_Idx...>) {
	      return array<remove_cv_t<_Tp>, _Nm>{{ std::move(__a[_Idx])... }};
	    }(make_index_sequence<_Nm>{});
	}
      else
	__builtin_unreachable(); // FIXME: see PR c++/91388
    }
#endif // __cpp_lib_to_array

  // Tuple interface to class template array.

  /// Partial specialization for std::array
  template<typename _Tp, size_t _Nm>
    struct tuple_size<array<_Tp, _Nm>>
    : public integral_constant<size_t, _Nm> { };

  /// Partial specialization for std::array
  template<size_t _Ind, typename _Tp, size_t _Nm>
    struct tuple_element<_Ind, array<_Tp, _Nm>>
    {
      static_assert(_Ind < _Nm, "array index is in range");
      using type = _Tp;
    };

#if __cplusplus >= 201703L
  template<typename _Tp, size_t _Nm>
    inline constexpr size_t tuple_size_v<array<_Tp, _Nm>> = _Nm;

  template<typename _Tp, size_t _Nm>
    inline constexpr size_t tuple_size_v<const array<_Tp, _Nm>> = _Nm;
#endif

  template<typename _Tp, size_t _Nm>
    struct __is_tuple_like_impl<array<_Tp, _Nm>> : true_type
    { };

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std

#endif // C++11

#endif // _GLIBCXX_ARRAY
