Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use requires-clauses and concepts for miscellaneous C++20/23 components #4637

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions stl/inc/algorithm
Original file line number Diff line number Diff line change
Expand Up @@ -5799,7 +5799,8 @@ constexpr _FwdIt shift_left(
return _First;
}

_EXPORT_STD template <class _ExPo, class _FwdIt, _Enable_if_execution_policy_t<_ExPo> = 0>
_EXPORT_STD template <class _ExPo, class _FwdIt>
requires requires { typename _Enable_if_execution_policy_t<_ExPo>; }
_FwdIt shift_left(_ExPo&&, _FwdIt _First, _FwdIt _Last,
typename iterator_traits<_FwdIt>::difference_type _Pos_to_shift) noexcept /* terminates */ {
// shift [_First, _Last) left by _Pos_to_shift positions
Expand Down Expand Up @@ -5883,7 +5884,8 @@ constexpr _FwdIt shift_right(
}
}

_EXPORT_STD template <class _ExPo, class _FwdIt, _Enable_if_execution_policy_t<_ExPo> = 0>
_EXPORT_STD template <class _ExPo, class _FwdIt>
requires requires { typename _Enable_if_execution_policy_t<_ExPo>; }
_FwdIt shift_right(_ExPo&&, _FwdIt _First, _FwdIt _Last,
typename iterator_traits<_FwdIt>::difference_type _Pos_to_shift) noexcept /* terminates */ {
// shift [_First, _Last) right by _Pos_to_shift positions
Expand Down
38 changes: 20 additions & 18 deletions stl/inc/bit
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,8 @@ _STL_DISABLE_CLANG_WARNINGS

_STD_BEGIN

_EXPORT_STD template <class _To, class _From,
enable_if_t<conjunction_v<bool_constant<sizeof(_To) == sizeof(_From)>, is_trivially_copyable<_To>,
is_trivially_copyable<_From>>,
int> = 0>
_EXPORT_STD template <class _To, class _From>
requires (sizeof(_To) == sizeof(_From)) && is_trivially_copyable_v<_To> && is_trivially_copyable_v<_From>
_NODISCARD constexpr _To bit_cast(const _From& _Val) noexcept {
return __builtin_bit_cast(_To, _Val);
}
Expand Down Expand Up @@ -61,7 +59,8 @@ _NODISCARD constexpr unsigned long long _Byteswap_uint64(const unsigned long lon
}
}

_EXPORT_STD template <class _Ty, enable_if_t<is_integral_v<_Ty>, int> = 0>
_EXPORT_STD template <class _Ty>
requires is_integral_v<_Ty>
_NODISCARD constexpr _Ty byteswap(const _Ty _Val) noexcept {
if constexpr (sizeof(_Ty) == 1) {
return _Val;
Expand All @@ -77,17 +76,20 @@ _NODISCARD constexpr _Ty byteswap(const _Ty _Val) noexcept {
}
#endif // _HAS_CXX23

_EXPORT_STD template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> = 0>
template <class _Ty>
concept _Standard_unsigned_integral = _Is_standard_unsigned_integer<_Ty>;

_EXPORT_STD template <_Standard_unsigned_integral _Ty>
_NODISCARD constexpr int countl_zero(_Ty _Val) noexcept;

_EXPORT_STD template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> = 0>
_EXPORT_STD template <_Standard_unsigned_integral _Ty>
_NODISCARD constexpr bool has_single_bit(const _Ty _Val) noexcept {
return _Val != 0 && (_Val & (_Val - 1)) == 0;
}

inline void _Precondition_violation_in_bit_ceil() noexcept {}

_EXPORT_STD template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> = 0>
_EXPORT_STD template <_Standard_unsigned_integral _Ty>
_NODISCARD constexpr _Ty bit_ceil(const _Ty _Val) noexcept /* strengthened */ {
if (_Val <= 1u) {
return _Ty{1};
Expand Down Expand Up @@ -115,7 +117,7 @@ _NODISCARD constexpr _Ty bit_ceil(const _Ty _Val) noexcept /* strengthened */ {
return static_cast<_Ty>(_Ty{1} << _Num);
}

_EXPORT_STD template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> = 0>
_EXPORT_STD template <_Standard_unsigned_integral _Ty>
_NODISCARD constexpr _Ty bit_floor(const _Ty _Val) noexcept {
if (_Val == 0) {
return 0;
Expand All @@ -124,15 +126,15 @@ _NODISCARD constexpr _Ty bit_floor(const _Ty _Val) noexcept {
return static_cast<_Ty>(_Ty{1} << (_Unsigned_integer_digits<_Ty> - 1 - _STD countl_zero(_Val)));
}

_EXPORT_STD template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> = 0>
_EXPORT_STD template <_Standard_unsigned_integral _Ty>
_NODISCARD constexpr int bit_width(const _Ty _Val) noexcept {
return _Unsigned_integer_digits<_Ty> - _STD countl_zero(_Val);
}

_EXPORT_STD template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> = 0>
_EXPORT_STD template <_Standard_unsigned_integral _Ty>
_NODISCARD constexpr _Ty rotr(_Ty _Val, int _Rotation) noexcept;

_EXPORT_STD template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> = 0>
_EXPORT_STD template <_Standard_unsigned_integral _Ty>
_NODISCARD constexpr _Ty rotl(const _Ty _Val, const int _Rotation) noexcept {
constexpr auto _Digits = _Unsigned_integer_digits<_Ty>;

Expand Down Expand Up @@ -160,7 +162,7 @@ _NODISCARD constexpr _Ty rotl(const _Ty _Val, const int _Rotation) noexcept {
}
}

_EXPORT_STD template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> /* = 0 */>
_EXPORT_STD template <_Standard_unsigned_integral _Ty>
_NODISCARD constexpr _Ty rotr(const _Ty _Val, const int _Rotation) noexcept {
constexpr auto _Digits = _Unsigned_integer_digits<_Ty>;

Expand Down Expand Up @@ -188,7 +190,7 @@ _NODISCARD constexpr _Ty rotr(const _Ty _Val, const int _Rotation) noexcept {
}
}

_EXPORT_STD template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> /* = 0 */>
_EXPORT_STD template <_Standard_unsigned_integral _Ty>
_NODISCARD constexpr int countl_zero(const _Ty _Val) noexcept {
#if _HAS_COUNTL_ZERO_INTRINSICS
#if (defined(_M_IX86) && !defined(_M_HYBRID_X86_ARM64)) || (defined(_M_X64) && !defined(_M_ARM64EC))
Expand All @@ -205,22 +207,22 @@ _NODISCARD constexpr int countl_zero(const _Ty _Val) noexcept {
return _Countl_zero_fallback(_Val);
}

_EXPORT_STD template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> = 0>
_EXPORT_STD template <_Standard_unsigned_integral _Ty>
_NODISCARD constexpr int countl_one(const _Ty _Val) noexcept {
return _STD countl_zero(static_cast<_Ty>(~_Val));
}

_EXPORT_STD template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> = 0>
_EXPORT_STD template <_Standard_unsigned_integral _Ty>
_NODISCARD constexpr int countr_zero(const _Ty _Val) noexcept {
return _Countr_zero(_Val);
}

_EXPORT_STD template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> = 0>
_EXPORT_STD template <_Standard_unsigned_integral _Ty>
_NODISCARD constexpr int countr_one(const _Ty _Val) noexcept {
return _Countr_zero(static_cast<_Ty>(~_Val));
}

_EXPORT_STD template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> = 0>
_EXPORT_STD template <_Standard_unsigned_integral _Ty>
_NODISCARD constexpr int popcount(const _Ty _Val) noexcept {
return _Popcount(_Val);
}
Expand Down
34 changes: 12 additions & 22 deletions stl/inc/chrono
Original file line number Diff line number Diff line change
Expand Up @@ -2881,9 +2881,8 @@ namespace chrono {

template <class _SourceClock>
struct clock_time_conversion<system_clock, _SourceClock> {
template <class _Duration, class _SourceClock2 = _SourceClock,
class =
void_t<decltype(_SourceClock2::to_sys(_STD declval<const time_point<_SourceClock2, _Duration>&>()))>>
template <class _Duration>
requires requires(const time_point<_SourceClock, _Duration>& _Time) { _SourceClock::to_sys(_Time); }
_NODISCARD auto operator()(const time_point<_SourceClock, _Duration>& _Time) const
noexcept(noexcept(_SourceClock::to_sys(_Time))) /* strengthened */ {
static_assert(_Is_time_point_for_clock<decltype(_SourceClock::to_sys(_Time)), system_clock>,
Expand All @@ -2895,8 +2894,8 @@ namespace chrono {

template <class _DestClock>
struct clock_time_conversion<_DestClock, system_clock> {
template <class _Duration, class _DestClock2 = _DestClock,
class = void_t<decltype(_DestClock2::from_sys(_STD declval<const sys_time<_Duration>&>()))>>
template <class _Duration>
requires requires(const sys_time<_Duration>& _Time) { _DestClock::from_sys(_Time); }
_NODISCARD auto operator()(const sys_time<_Duration>& _Time) const
noexcept(noexcept(_DestClock::from_sys(_Time))) /* strengthened */ {
static_assert(_Is_time_point_for_clock<decltype(_DestClock::from_sys(_Time)), _DestClock>,
Expand All @@ -2910,9 +2909,8 @@ namespace chrono {

template <class _SourceClock>
struct clock_time_conversion<utc_clock, _SourceClock> {
template <class _Duration, class _SourceClock2 = _SourceClock,
class =
void_t<decltype(_SourceClock2::to_utc(_STD declval<const time_point<_SourceClock2, _Duration>&>()))>>
template <class _Duration>
requires requires(const time_point<_SourceClock, _Duration>& _Time) { _SourceClock::to_utc(_Time); }
_NODISCARD auto operator()(const time_point<_SourceClock, _Duration>& _Time) const
noexcept(noexcept(_SourceClock::to_utc(_Time))) /* strengthened */ {
static_assert(_Is_time_point_for_clock<decltype(_SourceClock::to_utc(_Time)), utc_clock>,
Expand All @@ -2924,8 +2922,8 @@ namespace chrono {

template <class _DestClock>
struct clock_time_conversion<_DestClock, utc_clock> {
template <class _Duration, class _DestClock2 = _DestClock,
class = void_t<decltype(_DestClock2::from_utc(_STD declval<const utc_time<_Duration>&>()))>>
template <class _Duration>
requires requires(const utc_time<_Duration>& _Time) { _DestClock::from_utc(_Time); }
_NODISCARD auto operator()(const utc_time<_Duration>& _Time) const
noexcept(noexcept(_DestClock::from_utc(_Time))) /* strengthened */ {
static_assert(_Is_time_point_for_clock<decltype(_DestClock::from_utc(_Time)), _DestClock>,
Expand All @@ -2948,19 +2946,11 @@ namespace chrono {
_None,
};

template <class _Conv1, class _Conv2, class _Tp, class = void>
constexpr bool _Has_two_step_conversion = false;

template <class _Conv1, class _Conv2, class _Tp>
constexpr bool
_Has_two_step_conversion<_Conv1, _Conv2, _Tp, void_t<decltype(_Conv1{}(_Conv2{}(_STD declval<_Tp>())))>> = true;

template <class _Conv1, class _Conv2, class _Conv3, class _Tp, class = void>
constexpr bool _Has_three_step_conversion = false;
constexpr bool _Has_two_step_conversion = requires { _Conv1{}(_Conv2{}(_STD declval<_Tp>())); };

template <class _Conv1, class _Conv2, class _Conv3, class _Tp>
constexpr bool _Has_three_step_conversion<_Conv1, _Conv2, _Conv3, _Tp,
void_t<decltype(_Conv1{}(_Conv2{}(_Conv3{}(_STD declval<_Tp>()))))>> = true;
constexpr bool _Has_three_step_conversion = requires { _Conv1{}(_Conv2{}(_Conv3{}(_STD declval<_Tp>()))); };

template <class _DestClock, class _SourceClock, class _Duration>
_NODISCARD consteval _Clock_cast_strategy _Choose_clock_cast() noexcept {
Expand Down Expand Up @@ -3008,8 +2998,8 @@ namespace chrono {
template <class _DestClock, class _SourceClock, class _Duration>
constexpr auto _Clock_cast_choice = _Choose_clock_cast<_DestClock, _SourceClock, _Duration>();

_EXPORT_STD template <class _DestClock, class _SourceClock, class _Duration,
enable_if_t<_Clock_cast_choice<_DestClock, _SourceClock, _Duration> != _Clock_cast_strategy::_None, int> = 0>
_EXPORT_STD template <class _DestClock, class _SourceClock, class _Duration>
requires (_Clock_cast_choice<_DestClock, _SourceClock, _Duration> != _Clock_cast_strategy::_None)
_NODISCARD auto clock_cast(const time_point<_SourceClock, _Duration>& _Time) {
constexpr auto _Strat = _Clock_cast_choice<_DestClock, _SourceClock, _Duration>;

Expand Down
4 changes: 2 additions & 2 deletions stl/inc/cmath
Original file line number Diff line number Diff line change
Expand Up @@ -1617,8 +1617,8 @@ _EXPORT_STD _NODISCARD constexpr inline long double lerp(
return _Common_lerp(_ArgA, _ArgB, _ArgT);
}

_EXPORT_STD template <class _Ty1, class _Ty2, class _Ty3,
enable_if_t<is_arithmetic_v<_Ty1> && is_arithmetic_v<_Ty2> && is_arithmetic_v<_Ty3>, int> = 0>
_EXPORT_STD template <class _Ty1, class _Ty2, class _Ty3>
requires is_arithmetic_v<_Ty1> && is_arithmetic_v<_Ty2> && is_arithmetic_v<_Ty3>
_NODISCARD constexpr auto lerp(const _Ty1 _ArgA, const _Ty2 _ArgB, const _Ty3 _ArgT) noexcept {
using _Tgt = conditional_t<_Is_any_of_v<long double, _Ty1, _Ty2, _Ty3>, long double, double>;
return _Common_lerp(static_cast<_Tgt>(_ArgA), static_cast<_Tgt>(_ArgB), static_cast<_Tgt>(_ArgT));
Expand Down
3 changes: 2 additions & 1 deletion stl/inc/compare
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ _STD_BEGIN
void _Literal_zero_is_expected();

struct _Literal_zero {
template <class _Ty, enable_if_t<is_same_v<_Ty, int>, int> = 0>
template <class _Ty>
requires is_same_v<_Ty, int>
consteval _Literal_zero(_Ty _Zero) noexcept {
// Can't use _STL_VERIFY because this is a core header
if (_Zero != 0) {
Expand Down
21 changes: 12 additions & 9 deletions stl/inc/functional
Original file line number Diff line number Diff line change
Expand Up @@ -1866,7 +1866,8 @@ public:

move_only_function(move_only_function&&) noexcept = default;

template <class _Fn, enable_if_t<_Enable_one_arg_constructor<_Fn>, int> = 0>
template <class _Fn>
requires _Enable_one_arg_constructor<_Fn>
move_only_function(_Fn&& _Callable) {
using _Vt = decay_t<_Fn>;
static_assert(is_constructible_v<_Vt, _Fn>, "_Vt should be constructible from _Fn. "
Expand All @@ -1883,7 +1884,8 @@ public:
this->template _Construct_with_fn<_Vt, _VtInvQuals>(_STD forward<_Fn>(_Callable));
}

template <class _Fn, class... _CTypes, enable_if_t<_Enable_in_place_constructor<_Fn, _CTypes...>, int> = 0>
template <class _Fn, class... _CTypes>
requires _Enable_in_place_constructor<_Fn, _CTypes...>
explicit move_only_function(in_place_type_t<_Fn>, _CTypes&&... _Args) {
using _Vt = decay_t<_Fn>;
static_assert(is_same_v<_Vt, _Fn>, "_Vt should be the same type as _Fn. (N4950 [func.wrap.move.ctor]/12)");
Expand All @@ -1892,8 +1894,8 @@ public:
this->template _Construct_with_fn<_Vt, _VtInvQuals>(_STD forward<_CTypes>(_Args)...);
}

template <class _Fn, class _Ux, class... _CTypes,
enable_if_t<_Enable_in_place_list_constructor<_Fn, _Ux, _CTypes...>, int> = 0>
template <class _Fn, class _Ux, class... _CTypes>
requires _Enable_in_place_list_constructor<_Fn, _Ux, _CTypes...>
explicit move_only_function(in_place_type_t<_Fn>, initializer_list<_Ux> _Li, _CTypes&&... _Args) {
using _Vt = decay_t<_Fn>;
static_assert(is_same_v<_Vt, _Fn>, "_Vt should be the same type as _Fn. (N4950 [func.wrap.move.ctor]/18)");
Expand Down Expand Up @@ -1923,7 +1925,8 @@ public:
return *this;
}

template <class _Fn, enable_if_t<is_constructible_v<move_only_function, _Fn>, int> = 0>
template <class _Fn>
requires is_constructible_v<move_only_function, _Fn>
move_only_function& operator=(_Fn&& _Callable) {
this->_Move_assign(move_only_function{_STD forward<_Fn>(_Callable)});
return *this;
Expand Down Expand Up @@ -2243,8 +2246,8 @@ private:
_STL_INTERNAL_STATIC_ASSERT((is_same_v<_Types, decay_t<_Types>> && ...));

public:
template <class _FxInit, class... _TypesInit,
enable_if_t<sizeof...(_TypesInit) != 0 || !is_same_v<remove_cvref_t<_FxInit>, _Front_binder>, int> = 0>
template <class _FxInit, class... _TypesInit>
requires (sizeof...(_TypesInit) != 0 || !is_same_v<remove_cvref_t<_FxInit>, _Front_binder>)
constexpr explicit _Front_binder(_FxInit&& _Func, _TypesInit&&... _Args)
: _Mypair(_One_then_variadic_args_t{}, _STD forward<_FxInit>(_Func), _STD forward<_TypesInit>(_Args)...) {}

Expand Down Expand Up @@ -2336,8 +2339,8 @@ private:
_STL_INTERNAL_STATIC_ASSERT((is_same_v<_Types, decay_t<_Types>> && ...));

public:
template <class _FxInit, class... _TypesInit,
enable_if_t<sizeof...(_TypesInit) != 0 || !is_same_v<remove_cvref_t<_FxInit>, _Back_binder>, int> = 0>
template <class _FxInit, class... _TypesInit>
requires (sizeof...(_TypesInit) != 0 || !is_same_v<remove_cvref_t<_FxInit>, _Back_binder>)
constexpr explicit _Back_binder(_FxInit&& _Func, _TypesInit&&... _Args)
: _Mypair(_One_then_variadic_args_t{}, _STD forward<_FxInit>(_Func), _STD forward<_TypesInit>(_Args)...) {}

Expand Down
Loading