// <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
  // _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
