// Utilities used throughout the library -*- C++ -*- // Copyright (C) 2004-2026 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 // . /** @file include/bits/utility.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{utility} * * This file contains the parts of `` needed by other headers, * so they don't need to include the whole of ``. */ #ifndef _GLIBCXX_UTILITY_H #define _GLIBCXX_UTILITY_H 1 #ifdef _GLIBCXX_SYSHDR #pragma GCC system_header #endif #if __cplusplus >= 201103L #include #include #ifdef __glibcxx_constant_wrapper // C++ >= 26 # include #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /// Finds the size of a given tuple type. template struct tuple_size; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2313. tuple_size should always derive from integral_constant // 2770. tuple_size specialization is not SFINAE compatible template::type, typename = typename enable_if::value>::type, size_t = tuple_size<_Tp>::value> using __enable_if_has_tuple_size = _Tp; template struct tuple_size> : public tuple_size<_Tp> { }; template struct tuple_size> : public tuple_size<_Tp> { }; template struct tuple_size> : public tuple_size<_Tp> { }; #if __cplusplus >= 201703L template inline constexpr size_t tuple_size_v = tuple_size<_Tp>::value; #endif /// Gives the type of the ith element of a given tuple type. template struct tuple_element; // Duplicate of C++14's tuple_element_t for internal use in C++11 mode template using __tuple_element_t = typename tuple_element<__i, _Tp>::type; template struct tuple_element<__i, const _Tp> { using type = const __tuple_element_t<__i, _Tp>; }; template struct tuple_element<__i, volatile _Tp> { using type = volatile __tuple_element_t<__i, _Tp>; }; template struct tuple_element<__i, const volatile _Tp> { using type = const volatile __tuple_element_t<__i, _Tp>; }; #if __cplusplus >= 201402L // Return the index of _Tp in _Types, if it occurs exactly once. // Otherwise, return sizeof...(_Types). template constexpr size_t __find_uniq_type_in_pack() { constexpr size_t __sz = sizeof...(_Types); constexpr bool __found[__sz] = { __is_same(_Tp, _Types) ... }; size_t __n = __sz; for (size_t __i = 0; __i < __sz; ++__i) { if (__found[__i]) { if (__n < __sz) // more than one _Tp found return __sz; __n = __i; } } return __n; } #endif // C++14 // The standard says this macro and alias template should be in but we // define them here, to be available in , and too. // _GLIBCXX_RESOLVE_LIB_DEFECTS // 3378. tuple_size_v/tuple_element_t should be available when // tuple_size/tuple_element are #ifdef __glibcxx_tuple_element_t // C++ >= 14 template using tuple_element_t = typename tuple_element<__i, _Tp>::type; #endif #ifdef __glibcxx_constant_wrapper // C++ >= 26 template struct _CwFixedValue { using __type = _Tp; constexpr _CwFixedValue(__type __v) noexcept : _M_data(__v) { } __type _M_data; }; template struct _CwFixedValue<_Tp[_Extent]> { using __type = _Tp[_Extent]; constexpr _CwFixedValue(_Tp (&__arr)[_Extent]) noexcept : _CwFixedValue(__arr, typename _Build_index_tuple<_Extent>::__type()) { } template constexpr _CwFixedValue(_Tp (&__arr)[_Extent], _Index_tuple<_Indices...>) noexcept : _M_data{__arr[_Indices]...} { } _Tp _M_data[_Extent]; }; template _CwFixedValue(_Tp (&)[_Extent]) -> _CwFixedValue<_Tp[_Extent]>; template<_CwFixedValue _Xv, typename = typename decltype(_CwFixedValue(_Xv))::__type> struct constant_wrapper; template concept _ConstExprParam = requires { typename constant_wrapper<_Tp::value>; }; struct _CwOperators { template<_ConstExprParam _Tp> friend constexpr auto operator+(_Tp) noexcept -> constant_wrapper<(+_Tp::value)> { return {}; } template<_ConstExprParam _Tp> friend constexpr auto operator-(_Tp) noexcept -> constant_wrapper<(-_Tp::value)> { return {}; } template<_ConstExprParam _Tp> friend constexpr auto operator~(_Tp) noexcept -> constant_wrapper<(~_Tp::value)> { return {}; } template<_ConstExprParam _Tp> friend constexpr auto operator!(_Tp) noexcept -> constant_wrapper<(!_Tp::value)> { return {}; } template<_ConstExprParam _Tp> friend constexpr auto operator&(_Tp) noexcept -> constant_wrapper<(&_Tp::value)> { return {}; } template<_ConstExprParam _Tp> friend constexpr auto operator*(_Tp) noexcept -> constant_wrapper<(*_Tp::value)> { return {}; } template<_ConstExprParam _Left, _ConstExprParam _Right> friend constexpr auto operator+(_Left, _Right) noexcept -> constant_wrapper<(_Left::value + _Right::value)> { return {}; } template<_ConstExprParam _Left, _ConstExprParam _Right> friend constexpr auto operator-(_Left, _Right) noexcept -> constant_wrapper<(_Left::value - _Right::value)> { return {}; } template<_ConstExprParam _Left, _ConstExprParam _Right> friend constexpr auto operator*(_Left, _Right) noexcept -> constant_wrapper<(_Left::value * _Right::value)> { return {}; } template<_ConstExprParam _Left, _ConstExprParam _Right> friend constexpr auto operator/(_Left, _Right) noexcept -> constant_wrapper<(_Left::value / _Right::value)> { return {}; } template<_ConstExprParam _Left, _ConstExprParam _Right> friend constexpr auto operator%(_Left, _Right) noexcept -> constant_wrapper<(_Left::value % _Right::value)> { return {}; } template<_ConstExprParam _Left, _ConstExprParam _Right> friend constexpr auto operator<<(_Left, _Right) noexcept -> constant_wrapper<(_Left::value << _Right::value)> { return {}; } template<_ConstExprParam _Left, _ConstExprParam _Right> friend constexpr auto operator>>(_Left, _Right) noexcept -> constant_wrapper<(_Left::value >> _Right::value)> { return {}; } template<_ConstExprParam _Left, _ConstExprParam _Right> friend constexpr auto operator&(_Left, _Right) noexcept -> constant_wrapper<(_Left::value & _Right::value)> { return {}; } template<_ConstExprParam _Left, _ConstExprParam _Right> friend constexpr auto operator|(_Left, _Right) noexcept -> constant_wrapper<(_Left::value | _Right::value)> { return {}; } template<_ConstExprParam _Left, _ConstExprParam _Right> friend constexpr auto operator^(_Left, _Right) noexcept -> constant_wrapper<(_Left::value ^ _Right::value)> { return {}; } template<_ConstExprParam _Left, _ConstExprParam _Right> requires (!is_constructible_v || !is_constructible_v) friend constexpr auto operator&&(_Left, _Right) noexcept -> constant_wrapper<(_Left::value && _Right::value)> { return {}; } template<_ConstExprParam _Left, _ConstExprParam _Right> requires (!is_constructible_v || !is_constructible_v) friend constexpr auto operator||(_Left, _Right) noexcept -> constant_wrapper<(_Left::value || _Right::value)> { return {}; } template<_ConstExprParam _Left, _ConstExprParam _Right> friend constexpr auto operator<=>(_Left, _Right) noexcept -> constant_wrapper<(_Left::value <=> _Right::value)> { return {}; } template<_ConstExprParam _Left, _ConstExprParam _Right> friend constexpr auto operator<(_Left, _Right) noexcept -> constant_wrapper<(_Left::value < _Right::value)> { return {}; } template<_ConstExprParam _Left, _ConstExprParam _Right> friend constexpr auto operator<=(_Left, _Right) noexcept -> constant_wrapper<(_Left::value <= _Right::value)> { return {}; } template<_ConstExprParam _Left, _ConstExprParam _Right> friend constexpr auto operator==(_Left, _Right) noexcept -> constant_wrapper<(_Left::value == _Right::value)> { return {}; } template<_ConstExprParam _Left, _ConstExprParam _Right> friend constexpr auto operator!=(_Left, _Right) noexcept -> constant_wrapper<(_Left::value != _Right::value)> { return {}; } template<_ConstExprParam _Left, _ConstExprParam _Right> friend constexpr auto operator>(_Left, _Right) noexcept -> constant_wrapper<(_Left::value > _Right::value)> { return {}; } template<_ConstExprParam _Left, _ConstExprParam _Right> friend constexpr auto operator>=(_Left, _Right) noexcept -> constant_wrapper<(_Left::value >= _Right::value)> { return {}; } template<_ConstExprParam _Left, _ConstExprParam _Right> friend constexpr auto operator,(_Left, _Right) noexcept = delete; template<_ConstExprParam _Left, _ConstExprParam _Right> friend constexpr auto operator->*(_Left, _Right) noexcept -> constant_wrapper<_Left::value->*(_Right::value)> { return {}; } template<_ConstExprParam _Tp> constexpr auto operator++(this _Tp) noexcept -> constant_wrapper<(++_Tp::value)> { return {}; } template<_ConstExprParam _Tp> constexpr auto operator++(this _Tp, int) noexcept -> constant_wrapper<(_Tp::value++)> { return {}; } template<_ConstExprParam _Tp> constexpr auto operator--(this _Tp) noexcept -> constant_wrapper<(--_Tp::value)> { return {}; } template<_ConstExprParam _Tp> constexpr auto operator--(this _Tp, int) noexcept -> constant_wrapper<(_Tp::value--)> { return {}; } template<_ConstExprParam _Tp, _ConstExprParam _Right> constexpr auto operator+=(this _Tp, _Right) noexcept -> constant_wrapper<(_Tp::value += _Right::value)> { return {}; } template<_ConstExprParam _Tp, _ConstExprParam _Right> constexpr auto operator-=(this _Tp, _Right) noexcept -> constant_wrapper<(_Tp::value -= _Right::value)> { return {}; } template<_ConstExprParam _Tp, _ConstExprParam _Right> constexpr auto operator*=(this _Tp, _Right) noexcept -> constant_wrapper<(_Tp::value *= _Right::value)> { return {}; } template<_ConstExprParam _Tp, _ConstExprParam _Right> constexpr auto operator/=(this _Tp, _Right) noexcept -> constant_wrapper<(_Tp::value /= _Right::value)> { return {}; } template<_ConstExprParam _Tp, _ConstExprParam _Right> constexpr auto operator%=(this _Tp, _Right) noexcept -> constant_wrapper<(_Tp::value %= _Right::value)> { return {}; } template<_ConstExprParam _Tp, _ConstExprParam _Right> constexpr auto operator&=(this _Tp, _Right) noexcept -> constant_wrapper<(_Tp::value &= _Right::value)> { return {}; } template<_ConstExprParam _Tp, _ConstExprParam _Right> constexpr auto operator|=(this _Tp, _Right) noexcept -> constant_wrapper<(_Tp::value |= _Right::value)> { return {}; } template<_ConstExprParam _Tp, _ConstExprParam _Right> constexpr auto operator^=(this _Tp, _Right) noexcept -> constant_wrapper<(_Tp::value ^= _Right::value)> { return {}; } template<_ConstExprParam _Tp, _ConstExprParam _Right> constexpr auto operator<<=(this _Tp, _Right) noexcept -> constant_wrapper<(_Tp::value <<= _Right::value)> { return {}; } template<_ConstExprParam _Tp, _ConstExprParam _Right> constexpr auto operator>>=(this _Tp, _Right) noexcept -> constant_wrapper<(_Tp::value >>= _Right::value)> { return {}; } }; template<_CwFixedValue _Xv, typename> struct constant_wrapper : _CwOperators { static constexpr const auto& value = _Xv._M_data; using type = constant_wrapper; using value_type = typename decltype(_Xv)::__type; template<_ConstExprParam _Right> constexpr auto operator=(_Right) const noexcept -> constant_wrapper<(value = _Right::value)> { return {}; } template> && ...); typename constant_wrapper::value...)>; }> requires _ConstExprInvocable || is_invocable_v static constexpr decltype(auto) operator()(_Args&&... __args) noexcept(requires { requires _ConstExprInvocable || is_nothrow_invocable_v; }) { if constexpr (_ConstExprInvocable) return constant_wrapper::value...)>{}; else return std::__invoke(value, std::forward<_Args>(__args)...); } template> && ...); typename constant_wrapper::value...]>; }> requires _ConstExprSubscriptable || requires { value[std::declval<_Args>()...]; } static constexpr decltype(auto) operator[](_Args&&... __args) noexcept(requires { requires _ConstExprSubscriptable || noexcept(value[std::declval<_Args>()...]); }) { if constexpr (_ConstExprSubscriptable) return constant_wrapper::value...]>{}; else return value[std::forward<_Args>(__args)...]; } constexpr operator decltype(value)() const noexcept { return value; } }; template constexpr bool __is_constant_wrapper_v = false; template constexpr bool __is_constant_wrapper_v> = true; template<_CwFixedValue _Tp> constexpr auto cw = constant_wrapper<_Tp>{}; #endif #ifdef __glibcxx_integer_sequence // C++ >= 14 /// Class template integer_sequence template struct integer_sequence { #if __cplusplus >= 202002L static_assert(is_integral_v<_Tp>); #endif typedef _Tp value_type; static constexpr size_t size() noexcept { return sizeof...(_Idx); } }; #if __glibcxx_integer_sequence >= 202511L // C++ >= 26 /** @brief Structured binding support for `integer_sequence` * @since C++26 * @{ */ /// Structured binding support template struct tuple_size> : integral_constant { }; template struct tuple_element<__i, integer_sequence<_Tp, _Idx...>> { static_assert(__i < sizeof...(_Idx)); using type = _Tp; }; template struct tuple_element<__i, const integer_sequence<_Tp, _Idx...>> { static_assert(__i < sizeof...(_Idx)); using type = _Tp; }; template [[nodiscard]] constexpr _Tp get(integer_sequence<_Tp, _Idx...>) noexcept { static_assert(__i < sizeof...(_Idx)); return _Idx...[__i]; } /// @} #endif // __glibcxx_integer_sequence >= 202511L /// Alias template make_integer_sequence template using make_integer_sequence #if __has_builtin(__make_integer_seq) = __make_integer_seq; #else = integer_sequence<_Tp, __integer_pack(_Num)...>; #endif /// Alias template index_sequence template using index_sequence = integer_sequence; /// Alias template make_index_sequence template using make_index_sequence = make_integer_sequence; /// Alias template index_sequence_for template using index_sequence_for = make_index_sequence; #endif // __glibcxx_integer_sequence #if __cpp_structured_bindings >= 202411L #if __has_builtin(__integer_pack) template inline constexpr _Tp _IotaArray[_Num] = {__integer_pack(_Tp(_Num))...}; #elif defined __glibcxx_integer_sequence template > inline constexpr _Tp _IotaArray[_Num]; template inline constexpr _Tp _IotaArray<_Num, _Tp, integer_sequence<_Tp, _Is...>>[_Num] = {_Is...}; #endif // __integer_pack #endif // __cpp_structured_bindings >= 202411L #if __cplusplus >= 201703L struct in_place_t { explicit in_place_t() = default; }; inline constexpr in_place_t in_place{}; template struct in_place_type_t { explicit in_place_type_t() = default; }; template inline constexpr in_place_type_t<_Tp> in_place_type{}; template struct in_place_index_t { explicit in_place_index_t() = default; }; template inline constexpr in_place_index_t<_Idx> in_place_index{}; template inline constexpr bool __is_in_place_type_v = false; template inline constexpr bool __is_in_place_type_v> = true; template inline constexpr bool __is_in_place_index_v = false; template inline constexpr bool __is_in_place_index_v> = true; #endif // C++17 #if _GLIBCXX_USE_BUILTIN_TRAIT(__type_pack_element) template struct _Nth_type { using type = __type_pack_element<_Np, _Types...>; }; #else template struct _Nth_type { }; template struct _Nth_type<0, _Tp0, _Rest...> { using type = _Tp0; }; template struct _Nth_type<1, _Tp0, _Tp1, _Rest...> { using type = _Tp1; }; template struct _Nth_type<2, _Tp0, _Tp1, _Tp2, _Rest...> { using type = _Tp2; }; template #if __cpp_concepts requires (_Np >= 3) #endif struct _Nth_type<_Np, _Tp0, _Tp1, _Tp2, _Rest...> : _Nth_type<_Np - 3, _Rest...> { }; #if ! __cpp_concepts // Need additional specializations to avoid ambiguities. template struct _Nth_type<0, _Tp0, _Tp1, _Tp2, _Rest...> { using type = _Tp0; }; template struct _Nth_type<1, _Tp0, _Tp1, _Tp2, _Rest...> { using type = _Tp1; }; #endif #endif #if __glibcxx_ranges namespace ranges::__detail { template inline constexpr bool __is_subrange = false; } // namespace __detail #endif // A class (and instance) which can be used in 'tie' when an element // of a tuple is not required. struct _Swallow_assign { template constexpr const _Swallow_assign& operator=(const _Tp&) const noexcept { return *this; } }; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2773. Making std::ignore constexpr /** Used with `std::tie` to ignore an element of a tuple * * When using `std::tie` to assign the elements of a tuple to variables, * unwanted elements can be ignored by using `std::ignore`. For example: * * ``` * int x, y; * std::tie(x, std::ignore, y) = std::make_tuple(1, 2, 3); * ``` * * This assignment will perform `x=1; std::ignore=2; y=3;` which results * in the second element being ignored. * * @since C++11 */ _GLIBCXX17_INLINE constexpr _Swallow_assign ignore{}; #if __glibcxx_flat_map || __glibcxx_flat_set // >= C++23 struct sorted_unique_t { explicit sorted_unique_t() = default; }; inline constexpr sorted_unique_t sorted_unique{}; struct sorted_equivalent_t { explicit sorted_equivalent_t() = default; }; inline constexpr sorted_equivalent_t sorted_equivalent{}; #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // C++11 #endif /* _GLIBCXX_UTILITY_H */