// <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/stdexcept_throw.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
  // _GLIBCXX_RESOLVE_LIB_DEFECTS
  // 2766. Swapping non-swappable types
  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
