14fee23f9Smrg// <utility> -*- C++ -*- 24fee23f9Smrg 3b1e83836Smrg// Copyright (C) 2001-2022 Free Software Foundation, Inc. 44fee23f9Smrg// 54fee23f9Smrg// This file is part of the GNU ISO C++ Library. This library is free 64fee23f9Smrg// software; you can redistribute it and/or modify it under the 74fee23f9Smrg// terms of the GNU General Public License as published by the 84fee23f9Smrg// Free Software Foundation; either version 3, or (at your option) 94fee23f9Smrg// any later version. 104fee23f9Smrg 114fee23f9Smrg// This library is distributed in the hope that it will be useful, 124fee23f9Smrg// but WITHOUT ANY WARRANTY; without even the implied warranty of 134fee23f9Smrg// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 144fee23f9Smrg// GNU General Public License for more details. 154fee23f9Smrg 164fee23f9Smrg// Under Section 7 of GPL version 3, you are granted additional 174fee23f9Smrg// permissions described in the GCC Runtime Library Exception, version 184fee23f9Smrg// 3.1, as published by the Free Software Foundation. 194fee23f9Smrg 204fee23f9Smrg// You should have received a copy of the GNU General Public License and 214fee23f9Smrg// a copy of the GCC Runtime Library Exception along with this program; 224fee23f9Smrg// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 234fee23f9Smrg// <http://www.gnu.org/licenses/>. 244fee23f9Smrg 254fee23f9Smrg/* 264fee23f9Smrg * 274fee23f9Smrg * Copyright (c) 1994 284fee23f9Smrg * Hewlett-Packard Company 294fee23f9Smrg * 304fee23f9Smrg * Permission to use, copy, modify, distribute and sell this software 314fee23f9Smrg * and its documentation for any purpose is hereby granted without fee, 324fee23f9Smrg * provided that the above copyright notice appear in all copies and 334fee23f9Smrg * that both that copyright notice and this permission notice appear 344fee23f9Smrg * in supporting documentation. Hewlett-Packard Company makes no 354fee23f9Smrg * representations about the suitability of this software for any 364fee23f9Smrg * purpose. It is provided "as is" without express or implied warranty. 374fee23f9Smrg * 384fee23f9Smrg * 394fee23f9Smrg * Copyright (c) 1996,1997 404fee23f9Smrg * Silicon Graphics Computer Systems, Inc. 414fee23f9Smrg * 424fee23f9Smrg * Permission to use, copy, modify, distribute and sell this software 434fee23f9Smrg * and its documentation for any purpose is hereby granted without fee, 444fee23f9Smrg * provided that the above copyright notice appear in all copies and 454fee23f9Smrg * that both that copyright notice and this permission notice appear 464fee23f9Smrg * in supporting documentation. Silicon Graphics makes no 474fee23f9Smrg * representations about the suitability of this software for any 484fee23f9Smrg * purpose. It is provided "as is" without express or implied warranty. 494fee23f9Smrg */ 504fee23f9Smrg 514fee23f9Smrg/** @file include/utility 524fee23f9Smrg * This is a Standard C++ Library header. 534fee23f9Smrg */ 544fee23f9Smrg 554fee23f9Smrg#ifndef _GLIBCXX_UTILITY 564fee23f9Smrg#define _GLIBCXX_UTILITY 1 574fee23f9Smrg 584fee23f9Smrg#pragma GCC system_header 594fee23f9Smrg 604fee23f9Smrg/** 614fee23f9Smrg * @defgroup utilities Utilities 624fee23f9Smrg * 63b1e83836Smrg * Basic function and class templates used with the rest of the library. 64b1e83836Smrg * Includes pair, swap, forward/move helpers, declval, integer_sequence. 654fee23f9Smrg */ 664fee23f9Smrg 674fee23f9Smrg#include <bits/c++config.h> 684fee23f9Smrg#include <bits/stl_relops.h> 694fee23f9Smrg#include <bits/stl_pair.h> 704fee23f9Smrg 7148fb7bfaSmrg#if __cplusplus >= 201103L 724d5abbe8Smrg 73b1e83836Smrg#include <initializer_list> 74f9a78e0eSmrg#include <type_traits> 754fee23f9Smrg#include <bits/move.h> 76b1e83836Smrg#include <bits/utility.h> 7748fb7bfaSmrg 78b1e83836Smrg#if __cplusplus >= 202002L 79b1e83836Smrg#include <ext/numeric_traits.h> // __is_standard_integer, __int_traits 80fb8a8121Smrg#endif 81fb8a8121Smrg 8248fb7bfaSmrgnamespace std _GLIBCXX_VISIBILITY(default) 8348fb7bfaSmrg{ 8448fb7bfaSmrg_GLIBCXX_BEGIN_NAMESPACE_VERSION 8548fb7bfaSmrg 86181254a7Smrg#if __cplusplus >= 201402L 87b1e83836Smrg#define __cpp_lib_exchange_function 201304L 884d5abbe8Smrg 89*0a307195Smrg#if __cplusplus > 201703L 90*0a307195Smrg# define __cpp_lib_constexpr_algorithms 201806L 91*0a307195Smrg#endif 92*0a307195Smrg 934d5abbe8Smrg /// Assign @p __new_val to @p __obj and return its previous value. 944d5abbe8Smrg template <typename _Tp, typename _Up = _Tp> 95fb8a8121Smrg _GLIBCXX20_CONSTEXPR 964d5abbe8Smrg inline _Tp 974d5abbe8Smrg exchange(_Tp& __obj, _Up&& __new_val) 98b1e83836Smrg noexcept(__and_<is_nothrow_move_constructible<_Tp>, 99b1e83836Smrg is_nothrow_assignable<_Tp&, _Up>>::value) 1004d5abbe8Smrg { return std::__exchange(__obj, std::forward<_Up>(__new_val)); } 101fb8a8121Smrg 102b1e83836Smrg#if __cplusplus >= 201703L 1034d5abbe8Smrg 104b1e83836Smrg#define __cpp_lib_as_const 201510L 105b17d1066Smrg template<typename _Tp> 106b1e83836Smrg [[nodiscard]] 107b1e83836Smrg constexpr add_const_t<_Tp>& 108b1e83836Smrg as_const(_Tp& __t) noexcept 109b1e83836Smrg { return __t; } 110b17d1066Smrg 111b17d1066Smrg template<typename _Tp> 112b17d1066Smrg void as_const(const _Tp&&) = delete; 113b17d1066Smrg 114fb8a8121Smrg#if __cplusplus > 201703L 115fb8a8121Smrg#define __cpp_lib_integer_comparison_functions 202002L 116fb8a8121Smrg 117fb8a8121Smrg template<typename _Tp, typename _Up> 118fb8a8121Smrg constexpr bool 119fb8a8121Smrg cmp_equal(_Tp __t, _Up __u) noexcept 120fb8a8121Smrg { 121fb8a8121Smrg static_assert(__is_standard_integer<_Tp>::value); 122fb8a8121Smrg static_assert(__is_standard_integer<_Up>::value); 123fb8a8121Smrg 124fb8a8121Smrg if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>) 125fb8a8121Smrg return __t == __u; 126fb8a8121Smrg else if constexpr (is_signed_v<_Tp>) 127fb8a8121Smrg return __t >= 0 && make_unsigned_t<_Tp>(__t) == __u; 128fb8a8121Smrg else 129fb8a8121Smrg return __u >= 0 && __t == make_unsigned_t<_Up>(__u); 130fb8a8121Smrg } 131fb8a8121Smrg 132fb8a8121Smrg template<typename _Tp, typename _Up> 133fb8a8121Smrg constexpr bool 134fb8a8121Smrg cmp_not_equal(_Tp __t, _Up __u) noexcept 135fb8a8121Smrg { return !std::cmp_equal(__t, __u); } 136fb8a8121Smrg 137fb8a8121Smrg template<typename _Tp, typename _Up> 138fb8a8121Smrg constexpr bool 139fb8a8121Smrg cmp_less(_Tp __t, _Up __u) noexcept 140fb8a8121Smrg { 141fb8a8121Smrg static_assert(__is_standard_integer<_Tp>::value); 142fb8a8121Smrg static_assert(__is_standard_integer<_Up>::value); 143fb8a8121Smrg 144fb8a8121Smrg if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>) 145fb8a8121Smrg return __t < __u; 146fb8a8121Smrg else if constexpr (is_signed_v<_Tp>) 147fb8a8121Smrg return __t < 0 || make_unsigned_t<_Tp>(__t) < __u; 148fb8a8121Smrg else 149fb8a8121Smrg return __u >= 0 && __t < make_unsigned_t<_Up>(__u); 150fb8a8121Smrg } 151fb8a8121Smrg 152fb8a8121Smrg template<typename _Tp, typename _Up> 153fb8a8121Smrg constexpr bool 154fb8a8121Smrg cmp_greater(_Tp __t, _Up __u) noexcept 155fb8a8121Smrg { return std::cmp_less(__u, __t); } 156fb8a8121Smrg 157fb8a8121Smrg template<typename _Tp, typename _Up> 158fb8a8121Smrg constexpr bool 159fb8a8121Smrg cmp_less_equal(_Tp __t, _Up __u) noexcept 160fb8a8121Smrg { return !std::cmp_less(__u, __t); } 161fb8a8121Smrg 162fb8a8121Smrg template<typename _Tp, typename _Up> 163fb8a8121Smrg constexpr bool 164fb8a8121Smrg cmp_greater_equal(_Tp __t, _Up __u) noexcept 165fb8a8121Smrg { return !std::cmp_less(__t, __u); } 166fb8a8121Smrg 167*0a307195Smrg template<typename _Res, typename _Tp> 168fb8a8121Smrg constexpr bool 169fb8a8121Smrg in_range(_Tp __t) noexcept 170fb8a8121Smrg { 171*0a307195Smrg static_assert(__is_standard_integer<_Res>::value); 172fb8a8121Smrg static_assert(__is_standard_integer<_Tp>::value); 173fb8a8121Smrg using __gnu_cxx::__int_traits; 174fb8a8121Smrg 175*0a307195Smrg if constexpr (is_signed_v<_Tp> == is_signed_v<_Res>) 176*0a307195Smrg return __int_traits<_Res>::__min <= __t 177*0a307195Smrg && __t <= __int_traits<_Res>::__max; 178fb8a8121Smrg else if constexpr (is_signed_v<_Tp>) 179fb8a8121Smrg return __t >= 0 180*0a307195Smrg && make_unsigned_t<_Tp>(__t) <= __int_traits<_Res>::__max; 181fb8a8121Smrg else 182*0a307195Smrg return __t <= make_unsigned_t<_Res>(__int_traits<_Res>::__max); 183fb8a8121Smrg } 184b1e83836Smrg 185b1e83836Smrg#if __cplusplus > 202002L 186b1e83836Smrg#define __cpp_lib_to_underlying 202102L 187b1e83836Smrg /// Convert an object of enumeration type to its underlying type. 188b1e83836Smrg template<typename _Tp> 189b1e83836Smrg [[nodiscard]] 190b1e83836Smrg constexpr underlying_type_t<_Tp> 191b1e83836Smrg to_underlying(_Tp __value) noexcept 192b1e83836Smrg { return static_cast<underlying_type_t<_Tp>>(__value); } 193b1e83836Smrg 194b1e83836Smrg#define __cpp_lib_unreachable 202202L 195b1e83836Smrg /// Informs the compiler that program control flow never reaches this point. 196b1e83836Smrg /** 197b1e83836Smrg * Evaluating a call to this function results in undefined behaviour. 198b1e83836Smrg * This can be used as an assertion informing the compiler that certain 199b1e83836Smrg * conditions are impossible, for when the compiler is unable to determine 200b1e83836Smrg * that by itself. 201b1e83836Smrg * 202b1e83836Smrg * For example, it can be used to prevent warnings about reaching the 203b1e83836Smrg * end of a non-void function without returning. 204b1e83836Smrg * 205b1e83836Smrg * @since C++23 206b1e83836Smrg */ 207b1e83836Smrg [[noreturn,__gnu__::__always_inline__]] 208b1e83836Smrg inline void 209b1e83836Smrg unreachable() 210b1e83836Smrg { 211b1e83836Smrg#ifdef _GLIBCXX_DEBUG 212b1e83836Smrg std::__glibcxx_assert_fail(nullptr, 0, "std::unreachable()", nullptr); 213b1e83836Smrg#elif defined _GLIBCXX_ASSERTIONS 214b1e83836Smrg __builtin_trap(); 215b1e83836Smrg#else 216b1e83836Smrg __builtin_unreachable(); 217b1e83836Smrg#endif 218b1e83836Smrg } 219b1e83836Smrg#endif // C++23 220fb8a8121Smrg#endif // C++20 221b17d1066Smrg#endif // C++17 222b1e83836Smrg#endif // C++14 223b17d1066Smrg 22448fb7bfaSmrg_GLIBCXX_END_NAMESPACE_VERSION 22548fb7bfaSmrg} // namespace 22648fb7bfaSmrg 2274fee23f9Smrg#endif 2284fee23f9Smrg 2294fee23f9Smrg#endif /* _GLIBCXX_UTILITY */ 230