// Debugging array implementation -*- C++ -*-

// Copyright (C) 2012-2020 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 debug/array
 *  This is a Standard C++ Library header.
 */

#ifndef _GLIBCXX_DEBUG_ARRAY
#define _GLIBCXX_DEBUG_ARRAY 1

#pragma GCC system_header

#include <array>

#include <debug/formatter.h>
#include <debug/macros.h>

namespace std _GLIBCXX_VISIBILITY(default)
{
namespace __debug
{
  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.
      typedef _GLIBCXX_STD_C::__array_traits<_Tp, _Nm> _AT_Type;
      typename _AT_Type::_Type                         _M_elems;

      template<std::size_t _Size>
	struct _Array_check_subscript
 	{
	  std::size_t size() { return _Size; }

	  _Array_check_subscript(std::size_t __index)
	  { __glibcxx_check_subscript(__index); }
        };

      template<std::size_t _Size>
	struct _Array_check_nonempty
 	{
	  _GLIBCXX_NODISCARD bool empty() { return _Size == 0; }

	  _Array_check_nonempty()
	  { __glibcxx_check_nonempty(); }
        };

      // 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(_AT_Type::_Is_nothrow_swappable::value)
      { std::swap_ranges(begin(), end(), __other.begin()); }

      // Iterators.
      _GLIBCXX17_CONSTEXPR iterator
      begin() noexcept
      { return iterator(data()); }

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

      _GLIBCXX17_CONSTEXPR iterator
      end() noexcept
      { return iterator(data() + _Nm); }

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

      _GLIBCXX17_CONSTEXPR reverse_iterator
      rbegin() noexcept
      { return reverse_iterator(end()); }

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

      _GLIBCXX17_CONSTEXPR reverse_iterator
      rend() noexcept
      { return reverse_iterator(begin()); }

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

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

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

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

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

      // Capacity.
      constexpr size_type
      size() const noexcept { return _Nm; }

      constexpr size_type
      max_size() const noexcept { return _Nm; }

      _GLIBCXX_NODISCARD constexpr bool
      empty() const noexcept { return size() == 0; }

      // Element access.
      _GLIBCXX17_CONSTEXPR reference
      operator[](size_type __n) noexcept
      {
	__glibcxx_check_subscript(__n);
	return _AT_Type::_S_ref(_M_elems, __n);
      }

      constexpr const_reference
      operator[](size_type __n) const noexcept
      {
	return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n)
	 : (_GLIBCXX_THROW_OR_ABORT(_Array_check_subscript<_Nm>(__n)),
	    _AT_Type::_S_ref(_M_elems, 0));
      }

      _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 _AT_Type::_S_ref(_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 ? _AT_Type::_S_ref(_M_elems, __n)
	  : (std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) "
					       ">= _Nm (which is %zu)"),
					   __n, _Nm),
	     _AT_Type::_S_ref(_M_elems, 0));
      }

      _GLIBCXX17_CONSTEXPR reference
      front() noexcept
      {
	__glibcxx_check_nonempty();
	return *begin();
      }

      constexpr const_reference
      front() const noexcept
      {
	return _Nm ? _AT_Type::_S_ref(_M_elems, 0)
	  : (_GLIBCXX_THROW_OR_ABORT(_Array_check_nonempty<_Nm>()),
	     _AT_Type::_S_ref(_M_elems, 0));
      }

      _GLIBCXX17_CONSTEXPR reference
      back() noexcept
      {
	__glibcxx_check_nonempty();
	return _Nm ? *(end() - 1) : *end();
      }

      constexpr const_reference
      back() const noexcept
      {
	return _Nm ? _AT_Type::_S_ref(_M_elems, _Nm - 1)
	  : (_GLIBCXX_THROW_OR_ABORT(_Array_check_nonempty<_Nm>()),
	     _AT_Type::_S_ref(_M_elems, 0));
      }

      _GLIBCXX17_CONSTEXPR pointer
      data() noexcept
      { return _AT_Type::_S_ptr(_M_elems); }

      _GLIBCXX17_CONSTEXPR const_pointer
      data() const noexcept
      { return _AT_Type::_S_ptr(_M_elems); }
    };

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

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

#if __cpp_lib_three_way_comparison && __cpp_lib_concepts
  template<typename _Tp, size_t _Nm>
    constexpr __detail::__synth3way_t<_Tp>
    operator<=>(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
    {
      if constexpr (_Nm && __is_byte<_Tp>::__value)
	return __builtin_memcmp(__a.data(), __b.data(), _Nm) <=> 0;
      else
	{
	  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>
    _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>
    _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>
    _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>
    _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>
    _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.

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

  template<typename _Tp, std::size_t _Nm>
    _GLIBCXX20_CONSTEXPR
    inline void
    swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two)
    noexcept(noexcept(__one.swap(__two)))
    { __one.swap(__two); }

  template<std::size_t _Int, typename _Tp, std::size_t _Nm>
    constexpr _Tp&
    get(array<_Tp, _Nm>& __arr) noexcept
    {
      static_assert(_Int < _Nm, "index is out of bounds");
      return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::
	_S_ref(__arr._M_elems, _Int);
    }

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

  template<std::size_t _Int, typename _Tp, std::size_t _Nm>
    constexpr const _Tp&
    get(const array<_Tp, _Nm>& __arr) noexcept
    {
      static_assert(_Int < _Nm, "index is out of bounds");
      return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::
	_S_ref(__arr._M_elems, _Int);
    }

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

#if __cplusplus > 201703L
#define __cpp_lib_to_array 201907L

  template<bool _Move = false, typename _Tp, size_t... _Idx>
    constexpr array<remove_cv_t<_Tp>, sizeof...(_Idx)>
    __to_array(_Tp (&__a)[sizeof...(_Idx)], index_sequence<_Idx...>)
    {
      if constexpr (_Move)
	return {{std::move(__a[_Idx])...}};
      else
	return {{__a[_Idx]...}};
    }

  template<typename _Tp, size_t _Nm>
    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&>)
	return __debug::__to_array(__a, make_index_sequence<_Nm>{});
      __builtin_unreachable(); // FIXME: see PR c++/91388
    }

  template<typename _Tp, size_t _Nm>
    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>)
	return __debug::__to_array<1>(__a, make_index_sequence<_Nm>{});
      __builtin_unreachable(); // FIXME: see PR c++/91388
    }
#endif // C++20

} // namespace __debug

_GLIBCXX_BEGIN_NAMESPACE_VERSION
  // Tuple interface to class template array.

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

  /// tuple_element
  template<std::size_t _Int, typename _Tp, std::size_t _Nm>
    struct tuple_element<_Int, std::__debug::array<_Tp, _Nm>>
    {
      static_assert(_Int < _Nm, "index is out of bounds");
      typedef _Tp type;
    };

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

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std

#endif // _GLIBCXX_DEBUG_ARRAY
