[1/2] libstdc++: Move constant_wrapper from <type_traits> to <utility>
Commit Message
Change placement of constant_wrapper and related classes per
P3978R3: constant_wrapper should unwrap on call and subscript
libstdc++-v3/ChangeLog:
* include/bits/utility.h (std::_CwFixedValue, std::_ConstExprParam)
(std::_CwOperators, std::constant_wrapper): Moved from...
* include/std/type_traits (std::_CwFixedValue, std::_ConstExprParam)
(std::_CwOperators, std::constant_wrapper): Moved to bits_utility.
Disable __cpp_lib_constant_wrapper defintion.
* include/std/utility: Define __cpp_lib_constant_wrapper.
* testsuite/20_util/constant_wrapper/adl.cc: Updated header includes.
* testsuite/20_util/constant_wrapper/ex.cc: Likewise.
* testsuite/20_util/constant_wrapper/generic.cc: Likewise.
* testsuite/20_util/constant_wrapper/instantiate.cc: Likewise.
* testsuite/20_util/constant_wrapper/op_comma_neg.cc: Likewise.
* testsuite/20_util/constant_wrapper/other_wrappers.cc: Likewise.
* testsuite/20_util/constant_wrapper/version.cc: Likewise.
---
Testing on x86_64-linux. *constant_wrapper* test passed.
OK for trunk when all test passes?
libstdc++-v3/include/bits/utility.h | 325 +++++++++++++++++
libstdc++-v3/include/std/type_traits | 326 ------------------
libstdc++-v3/include/std/utility | 1 +
.../testsuite/20_util/constant_wrapper/adl.cc | 2 +-
.../testsuite/20_util/constant_wrapper/ex.cc | 2 +-
.../20_util/constant_wrapper/generic.cc | 1 -
.../20_util/constant_wrapper/instantiate.cc | 1 -
.../20_util/constant_wrapper/op_comma_neg.cc | 2 +-
.../constant_wrapper/other_wrappers.cc | 2 +-
.../20_util/constant_wrapper/version.cc | 4 +-
10 files changed, 332 insertions(+), 334 deletions(-)
Comments
OK
On Tue, 7 Apr 2026, 17:55 Tomasz KamiĆski, <tkaminsk@redhat.com> wrote:
> Change placement of constant_wrapper and related classes per
> P3978R3: constant_wrapper should unwrap on call and subscript
>
> libstdc++-v3/ChangeLog:
>
> * include/bits/utility.h (std::_CwFixedValue, std::_ConstExprParam)
> (std::_CwOperators, std::constant_wrapper): Moved from...
> * include/std/type_traits (std::_CwFixedValue,
> std::_ConstExprParam)
> (std::_CwOperators, std::constant_wrapper): Moved to bits_utility.
> Disable __cpp_lib_constant_wrapper defintion.
> * include/std/utility: Define __cpp_lib_constant_wrapper.
> * testsuite/20_util/constant_wrapper/adl.cc: Updated header
> includes.
> * testsuite/20_util/constant_wrapper/ex.cc: Likewise.
> * testsuite/20_util/constant_wrapper/generic.cc: Likewise.
> * testsuite/20_util/constant_wrapper/instantiate.cc: Likewise.
> * testsuite/20_util/constant_wrapper/op_comma_neg.cc: Likewise.
> * testsuite/20_util/constant_wrapper/other_wrappers.cc: Likewise.
> * testsuite/20_util/constant_wrapper/version.cc: Likewise.
> ---
> Testing on x86_64-linux. *constant_wrapper* test passed.
> OK for trunk when all test passes?
>
> libstdc++-v3/include/bits/utility.h | 325 +++++++++++++++++
> libstdc++-v3/include/std/type_traits | 326 ------------------
> libstdc++-v3/include/std/utility | 1 +
> .../testsuite/20_util/constant_wrapper/adl.cc | 2 +-
> .../testsuite/20_util/constant_wrapper/ex.cc | 2 +-
> .../20_util/constant_wrapper/generic.cc | 1 -
> .../20_util/constant_wrapper/instantiate.cc | 1 -
> .../20_util/constant_wrapper/op_comma_neg.cc | 2 +-
> .../constant_wrapper/other_wrappers.cc | 2 +-
> .../20_util/constant_wrapper/version.cc | 4 +-
> 10 files changed, 332 insertions(+), 334 deletions(-)
>
> diff --git a/libstdc++-v3/include/bits/utility.h
> b/libstdc++-v3/include/bits/utility.h
> index bd6b18d54dd..970e63e8170 100644
> --- a/libstdc++-v3/include/bits/utility.h
> +++ b/libstdc++-v3/include/bits/utility.h
> @@ -137,6 +137,331 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> using tuple_element_t = typename tuple_element<__i, _Tp>::type;
> #endif
>
> +#ifdef __glibcxx_constant_wrapper // C++ >= 26
> + template<typename _Tp>
> + struct _CwFixedValue
> + {
> + using __type = _Tp;
> +
> + constexpr
> + _CwFixedValue(__type __v) noexcept
> + : _M_data(__v) { }
> +
> + __type _M_data;
> + };
> +
> + template<typename _Tp, size_t _Extent>
> + struct _CwFixedValue<_Tp[_Extent]>
> + {
> + using __type = _Tp[_Extent];
> +
> + constexpr
> + _CwFixedValue(_Tp (&__arr)[_Extent]) noexcept
> + : _CwFixedValue(__arr, typename
> _Build_index_tuple<_Extent>::__type())
> + { }
> +
> + template<size_t... _Indices>
> + constexpr
> + _CwFixedValue(_Tp (&__arr)[_Extent], _Index_tuple<_Indices...>)
> noexcept
> + : _M_data{__arr[_Indices]...}
> + { }
> +
> + _Tp _M_data[_Extent];
> + };
> +
> + template<typename _Tp, size_t _Extent>
> + _CwFixedValue(_Tp (&)[_Extent]) -> _CwFixedValue<_Tp[_Extent]>;
> +
> + template<_CwFixedValue _Xv,
> + typename = typename decltype(_CwFixedValue(_Xv))::__type>
> + struct constant_wrapper;
> +
> + template<typename _Tp>
> + 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<bool, decltype(_Left::value)>
> + || !is_constructible_v<bool, decltype(_Right::value)>)
> + friend constexpr auto
> + operator&&(_Left, _Right) noexcept
> + -> constant_wrapper<(_Left::value && _Right::value)>
> + { return {}; }
> +
> + template<_ConstExprParam _Left, _ConstExprParam _Right>
> + requires (!is_constructible_v<bool, decltype(_Left::value)>
> + || !is_constructible_v<bool, decltype(_Right::value)>)
> + 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, _ConstExprParam... _Args>
> + constexpr auto
> + operator()(this _Tp, _Args...) noexcept
> + requires
> + requires(_Args...) {
> constant_wrapper<_Tp::value(_Args::value...)>(); }
> + { return constant_wrapper<_Tp::value(_Args::value...)>{}; }
> +
> + template<_ConstExprParam _Tp, _ConstExprParam... _Args>
> + constexpr auto
> + operator[](this _Tp, _Args...) noexcept
> + -> constant_wrapper<(_Tp::value[_Args::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 {}; }
> +
> + constexpr
> + operator decltype(value)() const noexcept
> + { return value; }
> + };
> +
> + template<_CwFixedValue _Tp>
> + constexpr auto cw = constant_wrapper<_Tp>{};
> +#endif
> +
> #ifdef __glibcxx_integer_sequence // C++ >= 14
>
> /// Class template integer_sequence
> diff --git a/libstdc++-v3/include/std/type_traits
> b/libstdc++-v3/include/std/type_traits
> index 38be1b0e09d..d10cbde19cc 100644
> --- a/libstdc++-v3/include/std/type_traits
> +++ b/libstdc++-v3/include/std/type_traits
> @@ -42,7 +42,6 @@
> #define __glibcxx_want_bool_constant
> #define __glibcxx_want_bounded_array_traits
> #define __glibcxx_want_common_reference
> -#define __glibcxx_want_constant_wrapper
> #define __glibcxx_want_has_unique_object_representations
> #define __glibcxx_want_integral_constant_callable
> #define __glibcxx_want_is_aggregate
> @@ -4403,331 +4402,6 @@ template<typename _Ret, typename _Fn, typename...
> _Args>
> };
> #endif // C++11
>
> -#ifdef __cpp_lib_constant_wrapper // C++ >= 26
> - template<typename _Tp>
> - struct _CwFixedValue
> - {
> - using __type = _Tp;
> -
> - constexpr
> - _CwFixedValue(__type __v) noexcept
> - : _M_data(__v) { }
> -
> - __type _M_data;
> - };
> -
> - template<typename _Tp, size_t _Extent>
> - struct _CwFixedValue<_Tp[_Extent]>
> - {
> - using __type = _Tp[_Extent];
> -
> - constexpr
> - _CwFixedValue(_Tp (&__arr)[_Extent]) noexcept
> - : _CwFixedValue(__arr, typename
> _Build_index_tuple<_Extent>::__type())
> - { }
> -
> - template<size_t... _Indices>
> - constexpr
> - _CwFixedValue(_Tp (&__arr)[_Extent], _Index_tuple<_Indices...>)
> noexcept
> - : _M_data{__arr[_Indices]...}
> - { }
> -
> - _Tp _M_data[_Extent];
> - };
> -
> - template<typename _Tp, size_t _Extent>
> - _CwFixedValue(_Tp (&)[_Extent]) -> _CwFixedValue<_Tp[_Extent]>;
> -
> - template<_CwFixedValue _Xv,
> - typename = typename decltype(_CwFixedValue(_Xv))::__type>
> - struct constant_wrapper;
> -
> - template<typename _Tp>
> - 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<bool, decltype(_Left::value)>
> - || !is_constructible_v<bool, decltype(_Right::value)>)
> - friend constexpr auto
> - operator&&(_Left, _Right) noexcept
> - -> constant_wrapper<(_Left::value && _Right::value)>
> - { return {}; }
> -
> - template<_ConstExprParam _Left, _ConstExprParam _Right>
> - requires (!is_constructible_v<bool, decltype(_Left::value)>
> - || !is_constructible_v<bool, decltype(_Right::value)>)
> - 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, _ConstExprParam... _Args>
> - constexpr auto
> - operator()(this _Tp, _Args...) noexcept
> - requires
> - requires(_Args...) {
> constant_wrapper<_Tp::value(_Args::value...)>(); }
> - { return constant_wrapper<_Tp::value(_Args::value...)>{}; }
> -
> - template<_ConstExprParam _Tp, _ConstExprParam... _Args>
> - constexpr auto
> - operator[](this _Tp, _Args...) noexcept
> - -> constant_wrapper<(_Tp::value[_Args::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 {}; }
> -
> - constexpr
> - operator decltype(value)() const noexcept
> - { return value; }
> - };
> -
> - template<_CwFixedValue _Tp>
> - constexpr auto cw = constant_wrapper<_Tp>{};
> -#endif
> -
> /// @} group metaprogramming
>
> _GLIBCXX_END_NAMESPACE_VERSION
> diff --git a/libstdc++-v3/include/std/utility
> b/libstdc++-v3/include/std/utility
> index 7d9d3653cd0..2e1775bf6b3 100644
> --- a/libstdc++-v3/include/std/utility
> +++ b/libstdc++-v3/include/std/utility
> @@ -87,6 +87,7 @@
>
> #define __glibcxx_want_addressof_constexpr
> #define __glibcxx_want_as_const
> +#define __glibcxx_want_constant_wrapper
> #define __glibcxx_want_constexpr_algorithms
> #define __glibcxx_want_constexpr_utility
> #define __glibcxx_want_exchange_function
> diff --git a/libstdc++-v3/testsuite/20_util/constant_wrapper/adl.cc
> b/libstdc++-v3/testsuite/20_util/constant_wrapper/adl.cc
> index 3cdc09c1eb7..3629e4fc559 100644
> --- a/libstdc++-v3/testsuite/20_util/constant_wrapper/adl.cc
> +++ b/libstdc++-v3/testsuite/20_util/constant_wrapper/adl.cc
> @@ -1,5 +1,5 @@
> // { dg-do compile { target c++26 } }
> -#include <type_traits>
> +#include <utility>
> #include <concepts>
>
> #include <testsuite_hooks.h>
> diff --git a/libstdc++-v3/testsuite/20_util/constant_wrapper/ex.cc
> b/libstdc++-v3/testsuite/20_util/constant_wrapper/ex.cc
> index a4d967b9634..a5d19fd8132 100644
> --- a/libstdc++-v3/testsuite/20_util/constant_wrapper/ex.cc
> +++ b/libstdc++-v3/testsuite/20_util/constant_wrapper/ex.cc
> @@ -1,5 +1,5 @@
> // { dg-do compile { target c++26 } }
> -#include <type_traits>
> +#include <utility>
> #include <iostream>
>
> #include <testsuite_hooks.h>
> diff --git a/libstdc++-v3/testsuite/20_util/constant_wrapper/generic.cc
> b/libstdc++-v3/testsuite/20_util/constant_wrapper/generic.cc
> index de4334b64f5..1c7770d7a89 100644
> --- a/libstdc++-v3/testsuite/20_util/constant_wrapper/generic.cc
> +++ b/libstdc++-v3/testsuite/20_util/constant_wrapper/generic.cc
> @@ -1,5 +1,4 @@
> // { dg-do run { target c++26 } }
> -#include <type_traits>
> #include <utility>
> #include <string_view>
>
> diff --git
> a/libstdc++-v3/testsuite/20_util/constant_wrapper/instantiate.cc
> b/libstdc++-v3/testsuite/20_util/constant_wrapper/instantiate.cc
> index 5adf6fda5a3..452f01fadcd 100644
> --- a/libstdc++-v3/testsuite/20_util/constant_wrapper/instantiate.cc
> +++ b/libstdc++-v3/testsuite/20_util/constant_wrapper/instantiate.cc
> @@ -1,5 +1,4 @@
> // { dg-do run { target c++26 } }
> -#include <type_traits>
> #include <utility>
>
> #include <testsuite_hooks.h>
> diff --git
> a/libstdc++-v3/testsuite/20_util/constant_wrapper/op_comma_neg.cc
> b/libstdc++-v3/testsuite/20_util/constant_wrapper/op_comma_neg.cc
> index 4384e920ea5..2fc8c78c2da 100644
> --- a/libstdc++-v3/testsuite/20_util/constant_wrapper/op_comma_neg.cc
> +++ b/libstdc++-v3/testsuite/20_util/constant_wrapper/op_comma_neg.cc
> @@ -1,5 +1,5 @@
> // { dg-do compile { target c++26 } }
> -#include <type_traits>
> +#include <utility>
>
> constexpr void
> test_comma_same_types()
> diff --git
> a/libstdc++-v3/testsuite/20_util/constant_wrapper/other_wrappers.cc
> b/libstdc++-v3/testsuite/20_util/constant_wrapper/other_wrappers.cc
> index 3c3cfafd6ed..fe45c5a8516 100644
> --- a/libstdc++-v3/testsuite/20_util/constant_wrapper/other_wrappers.cc
> +++ b/libstdc++-v3/testsuite/20_util/constant_wrapper/other_wrappers.cc
> @@ -1,5 +1,5 @@
> // { dg-do run { target c++26 } }
> -#include <type_traits>
> +#include <utility>
> #include <concepts>
>
> #include <testsuite_hooks.h>
> diff --git a/libstdc++-v3/testsuite/20_util/constant_wrapper/version.cc
> b/libstdc++-v3/testsuite/20_util/constant_wrapper/version.cc
> index 4fee6159141..776d80c576a 100644
> --- a/libstdc++-v3/testsuite/20_util/constant_wrapper/version.cc
> +++ b/libstdc++-v3/testsuite/20_util/constant_wrapper/version.cc
> @@ -1,10 +1,10 @@
> // { dg-do preprocess { target c++26 } }
> // { dg-add-options no_pch }
>
> -#include <type_traits>
> +#include <utility>
>
> #ifndef __cpp_lib_constant_wrapper
> -#error "Feature test macro __cpp_lib_constant_wrapper is missing for
> <type_traits>"
> +#error "Feature test macro __cpp_lib_constant_wrapper is missing for
> <utility>"
> #if __cpp_lib_constant_wrapper < 202506L
> #error "Feature test macro __cpp_lib_constant_wrapper has the wrong value"
> #endif
> --
> 2.53.0
>
>
@@ -137,6 +137,331 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using tuple_element_t = typename tuple_element<__i, _Tp>::type;
#endif
+#ifdef __glibcxx_constant_wrapper // C++ >= 26
+ template<typename _Tp>
+ struct _CwFixedValue
+ {
+ using __type = _Tp;
+
+ constexpr
+ _CwFixedValue(__type __v) noexcept
+ : _M_data(__v) { }
+
+ __type _M_data;
+ };
+
+ template<typename _Tp, size_t _Extent>
+ struct _CwFixedValue<_Tp[_Extent]>
+ {
+ using __type = _Tp[_Extent];
+
+ constexpr
+ _CwFixedValue(_Tp (&__arr)[_Extent]) noexcept
+ : _CwFixedValue(__arr, typename _Build_index_tuple<_Extent>::__type())
+ { }
+
+ template<size_t... _Indices>
+ constexpr
+ _CwFixedValue(_Tp (&__arr)[_Extent], _Index_tuple<_Indices...>) noexcept
+ : _M_data{__arr[_Indices]...}
+ { }
+
+ _Tp _M_data[_Extent];
+ };
+
+ template<typename _Tp, size_t _Extent>
+ _CwFixedValue(_Tp (&)[_Extent]) -> _CwFixedValue<_Tp[_Extent]>;
+
+ template<_CwFixedValue _Xv,
+ typename = typename decltype(_CwFixedValue(_Xv))::__type>
+ struct constant_wrapper;
+
+ template<typename _Tp>
+ 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<bool, decltype(_Left::value)>
+ || !is_constructible_v<bool, decltype(_Right::value)>)
+ friend constexpr auto
+ operator&&(_Left, _Right) noexcept
+ -> constant_wrapper<(_Left::value && _Right::value)>
+ { return {}; }
+
+ template<_ConstExprParam _Left, _ConstExprParam _Right>
+ requires (!is_constructible_v<bool, decltype(_Left::value)>
+ || !is_constructible_v<bool, decltype(_Right::value)>)
+ 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, _ConstExprParam... _Args>
+ constexpr auto
+ operator()(this _Tp, _Args...) noexcept
+ requires
+ requires(_Args...) { constant_wrapper<_Tp::value(_Args::value...)>(); }
+ { return constant_wrapper<_Tp::value(_Args::value...)>{}; }
+
+ template<_ConstExprParam _Tp, _ConstExprParam... _Args>
+ constexpr auto
+ operator[](this _Tp, _Args...) noexcept
+ -> constant_wrapper<(_Tp::value[_Args::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 {}; }
+
+ constexpr
+ operator decltype(value)() const noexcept
+ { return value; }
+ };
+
+ template<_CwFixedValue _Tp>
+ constexpr auto cw = constant_wrapper<_Tp>{};
+#endif
+
#ifdef __glibcxx_integer_sequence // C++ >= 14
/// Class template integer_sequence
@@ -42,7 +42,6 @@
#define __glibcxx_want_bool_constant
#define __glibcxx_want_bounded_array_traits
#define __glibcxx_want_common_reference
-#define __glibcxx_want_constant_wrapper
#define __glibcxx_want_has_unique_object_representations
#define __glibcxx_want_integral_constant_callable
#define __glibcxx_want_is_aggregate
@@ -4403,331 +4402,6 @@ template<typename _Ret, typename _Fn, typename... _Args>
};
#endif // C++11
-#ifdef __cpp_lib_constant_wrapper // C++ >= 26
- template<typename _Tp>
- struct _CwFixedValue
- {
- using __type = _Tp;
-
- constexpr
- _CwFixedValue(__type __v) noexcept
- : _M_data(__v) { }
-
- __type _M_data;
- };
-
- template<typename _Tp, size_t _Extent>
- struct _CwFixedValue<_Tp[_Extent]>
- {
- using __type = _Tp[_Extent];
-
- constexpr
- _CwFixedValue(_Tp (&__arr)[_Extent]) noexcept
- : _CwFixedValue(__arr, typename _Build_index_tuple<_Extent>::__type())
- { }
-
- template<size_t... _Indices>
- constexpr
- _CwFixedValue(_Tp (&__arr)[_Extent], _Index_tuple<_Indices...>) noexcept
- : _M_data{__arr[_Indices]...}
- { }
-
- _Tp _M_data[_Extent];
- };
-
- template<typename _Tp, size_t _Extent>
- _CwFixedValue(_Tp (&)[_Extent]) -> _CwFixedValue<_Tp[_Extent]>;
-
- template<_CwFixedValue _Xv,
- typename = typename decltype(_CwFixedValue(_Xv))::__type>
- struct constant_wrapper;
-
- template<typename _Tp>
- 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<bool, decltype(_Left::value)>
- || !is_constructible_v<bool, decltype(_Right::value)>)
- friend constexpr auto
- operator&&(_Left, _Right) noexcept
- -> constant_wrapper<(_Left::value && _Right::value)>
- { return {}; }
-
- template<_ConstExprParam _Left, _ConstExprParam _Right>
- requires (!is_constructible_v<bool, decltype(_Left::value)>
- || !is_constructible_v<bool, decltype(_Right::value)>)
- 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, _ConstExprParam... _Args>
- constexpr auto
- operator()(this _Tp, _Args...) noexcept
- requires
- requires(_Args...) { constant_wrapper<_Tp::value(_Args::value...)>(); }
- { return constant_wrapper<_Tp::value(_Args::value...)>{}; }
-
- template<_ConstExprParam _Tp, _ConstExprParam... _Args>
- constexpr auto
- operator[](this _Tp, _Args...) noexcept
- -> constant_wrapper<(_Tp::value[_Args::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 {}; }
-
- constexpr
- operator decltype(value)() const noexcept
- { return value; }
- };
-
- template<_CwFixedValue _Tp>
- constexpr auto cw = constant_wrapper<_Tp>{};
-#endif
-
/// @} group metaprogramming
_GLIBCXX_END_NAMESPACE_VERSION
@@ -87,6 +87,7 @@
#define __glibcxx_want_addressof_constexpr
#define __glibcxx_want_as_const
+#define __glibcxx_want_constant_wrapper
#define __glibcxx_want_constexpr_algorithms
#define __glibcxx_want_constexpr_utility
#define __glibcxx_want_exchange_function
@@ -1,5 +1,5 @@
// { dg-do compile { target c++26 } }
-#include <type_traits>
+#include <utility>
#include <concepts>
#include <testsuite_hooks.h>
@@ -1,5 +1,5 @@
// { dg-do compile { target c++26 } }
-#include <type_traits>
+#include <utility>
#include <iostream>
#include <testsuite_hooks.h>
@@ -1,5 +1,4 @@
// { dg-do run { target c++26 } }
-#include <type_traits>
#include <utility>
#include <string_view>
@@ -1,5 +1,4 @@
// { dg-do run { target c++26 } }
-#include <type_traits>
#include <utility>
#include <testsuite_hooks.h>
@@ -1,5 +1,5 @@
// { dg-do compile { target c++26 } }
-#include <type_traits>
+#include <utility>
constexpr void
test_comma_same_types()
@@ -1,5 +1,5 @@
// { dg-do run { target c++26 } }
-#include <type_traits>
+#include <utility>
#include <concepts>
#include <testsuite_hooks.h>
@@ -1,10 +1,10 @@
// { dg-do preprocess { target c++26 } }
// { dg-add-options no_pch }
-#include <type_traits>
+#include <utility>
#ifndef __cpp_lib_constant_wrapper
-#error "Feature test macro __cpp_lib_constant_wrapper is missing for <type_traits>"
+#error "Feature test macro __cpp_lib_constant_wrapper is missing for <utility>"
#if __cpp_lib_constant_wrapper < 202506L
#error "Feature test macro __cpp_lib_constant_wrapper has the wrong value"
#endif