// <utility> -*- C++ -*-

// Copyright (C) 2001-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/>.

/*
 *
 * Copyright (c) 1994
 * Hewlett-Packard Company
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.  Hewlett-Packard Company makes no
 * representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 *
 *
 * Copyright (c) 1996,1997
 * Silicon Graphics Computer Systems, Inc.
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.  Silicon Graphics makes no
 * representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 */

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

#ifndef _GLIBCXX_UTILITY
#define _GLIBCXX_UTILITY 1

#ifdef _GLIBCXX_SYSHDR
#pragma GCC system_header
#endif

/**
 * @defgroup utilities Utilities
 *
 * Basic function and class templates used with the rest of the library.
 * Includes pair, swap, forward/move helpers, declval, integer_sequence.
 */

#include <bits/c++config.h>
#include <bits/stl_relops.h>
#include <bits/stl_pair.h>

#if __cplusplus >= 201103L

#include <initializer_list>
#include <type_traits>
#include <bits/move.h>
#include <bits/utility.h>

#if __cplusplus >= 202002L
#include <ext/numeric_traits.h> // __is_standard_integer, __int_traits
#endif

#if __cplusplus > 202302L
# include <bits/monostate.h>
#endif

#define __glibcxx_want_addressof_constexpr
#define __glibcxx_want_as_const
#define __glibcxx_want_constexpr_algorithms
#define __glibcxx_want_constexpr_utility
#define __glibcxx_want_exchange_function
#define __glibcxx_want_forward_like
#define __glibcxx_want_integer_comparison_functions
#define __glibcxx_want_integer_sequence
#define __glibcxx_want_ranges_zip
#define __glibcxx_want_to_underlying
#define __glibcxx_want_tuple_element_t
#define __glibcxx_want_tuples_by_type
#define __glibcxx_want_unreachable
#define __glibcxx_want_tuple_like
#define __glibcxx_want_constrained_equality
#include <bits/version.h>

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

#ifdef __cpp_lib_exchange_function // C++ >= 14
  /// Assign @p __new_val to @p __obj and return its previous value.
  template <typename _Tp, typename _Up = _Tp>
    _GLIBCXX20_CONSTEXPR
    inline _Tp
    exchange(_Tp& __obj, _Up&& __new_val)
    noexcept(__and_<is_nothrow_move_constructible<_Tp>,
		    is_nothrow_assignable<_Tp&, _Up>>::value)
    { return std::__exchange(__obj, std::forward<_Up>(__new_val)); }
#endif

#ifdef  __cpp_lib_as_const // C++ >= 17
  template<typename _Tp>
    [[nodiscard]]
    constexpr add_const_t<_Tp>&
    as_const(_Tp& __t) noexcept
    { return __t; }

  template<typename _Tp>
    void as_const(const _Tp&&) = delete;
#endif

#ifdef __cpp_lib_integer_comparison_functions // C++ >= 20
  template<typename _Tp, typename _Up>
    constexpr bool
    cmp_equal(_Tp __t, _Up __u) noexcept
    {
      static_assert(__is_standard_integer<_Tp>::value);
      static_assert(__is_standard_integer<_Up>::value);

      if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
	return __t == __u;
      else if constexpr (is_signed_v<_Tp>)
	return __t >= 0 && make_unsigned_t<_Tp>(__t) == __u;
      else
	return __u >= 0 && __t == make_unsigned_t<_Up>(__u);
    }

  template<typename _Tp, typename _Up>
    constexpr bool
    cmp_not_equal(_Tp __t, _Up __u) noexcept
    { return !std::cmp_equal(__t, __u); }

  template<typename _Tp, typename _Up>
    constexpr bool
    cmp_less(_Tp __t, _Up __u) noexcept
    {
      static_assert(__is_standard_integer<_Tp>::value);
      static_assert(__is_standard_integer<_Up>::value);

      if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
	return __t < __u;
      else if constexpr (is_signed_v<_Tp>)
	return __t < 0 || make_unsigned_t<_Tp>(__t) < __u;
      else
	return __u >= 0 && __t < make_unsigned_t<_Up>(__u);
    }

  template<typename _Tp, typename _Up>
    constexpr bool
    cmp_greater(_Tp __t, _Up __u) noexcept
    { return std::cmp_less(__u, __t); }

  template<typename _Tp, typename _Up>
    constexpr bool
    cmp_less_equal(_Tp __t, _Up __u) noexcept
    { return !std::cmp_less(__u, __t); }

  template<typename _Tp, typename _Up>
    constexpr bool
    cmp_greater_equal(_Tp __t, _Up __u) noexcept
    { return !std::cmp_less(__t, __u); }

  template<typename _Res, typename _Tp>
    constexpr bool
    in_range(_Tp __t) noexcept
    {
      static_assert(__is_standard_integer<_Res>::value);
      static_assert(__is_standard_integer<_Tp>::value);
      using __gnu_cxx::__int_traits;

      if constexpr (is_signed_v<_Tp> == is_signed_v<_Res>)
	return __int_traits<_Res>::__min <= __t
	  && __t <= __int_traits<_Res>::__max;
      else if constexpr (is_signed_v<_Tp>)
	return __t >= 0
	  && make_unsigned_t<_Tp>(__t) <= __int_traits<_Res>::__max;
      else
	return __t <= make_unsigned_t<_Res>(__int_traits<_Res>::__max);
    }
#endif // __cpp_lib_integer_comparison_functions

#ifdef __cpp_lib_to_underlying // C++ >= 23
  /// Convert an object of enumeration type to its underlying type.
  template<typename _Tp>
    [[nodiscard]]
    constexpr underlying_type_t<_Tp>
    to_underlying(_Tp __value) noexcept
    { return static_cast<underlying_type_t<_Tp>>(__value); }
#endif

#ifdef __cpp_lib_unreachable // C++ >= 23
  /// Informs the compiler that program control flow never reaches this point.
  /**
   * Evaluating a call to this function results in undefined behaviour.
   * This can be used as an assertion informing the compiler that certain
   * conditions are impossible, for when the compiler is unable to determine
   * that by itself.
   *
   * For example, it can be used to prevent warnings about reaching the
   * end of a non-void function without returning.
   *
   * @since C++23
   */
  [[noreturn,__gnu__::__always_inline__]]
  inline void
  unreachable()
  {
#ifdef _GLIBCXX_DEBUG
    std::__glibcxx_assert_fail(nullptr, 0, "std::unreachable()", nullptr);
#elif defined _GLIBCXX_ASSERTIONS
    __builtin_trap();
#else
    __builtin_unreachable();
#endif
  }
#endif

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

#endif

#endif /* _GLIBCXX_UTILITY */
