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

This commit is contained in:
A. Jiang 2024-05-21 06:50:10 +08:00 коммит произвёл GitHub
Родитель 697653d506
Коммит 23344e2643
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
15 изменённых файлов: 227 добавлений и 205 удалений

Просмотреть файл

@ -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
@ -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

Просмотреть файл

@ -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);
}
@ -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;
@ -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};
@ -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;
@ -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>;
@ -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>;
@ -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))
@ -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);
}

Просмотреть файл

@ -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>,
@ -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>,
@ -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>,
@ -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>,
@ -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 {
@ -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>;

Просмотреть файл

@ -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));

Просмотреть файл

@ -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) {

Просмотреть файл

@ -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. "
@ -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)");
@ -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)");
@ -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;
@ -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)...) {}
@ -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)...) {}

Просмотреть файл

@ -1542,6 +1542,20 @@ struct _Temporary_owner_del {
}
};
#if _HAS_CXX20
template <class _Ty>
concept _Not_builtin_array = !is_array_v<_Ty>;
template <class _Ty>
concept _Bounded_builtin_array = is_bounded_array_v<_Ty>;
template <class _Ty>
concept _Unbounded_builtin_array = is_unbounded_array_v<_Ty>;
template <class _Ty>
concept _Not_unbounded_builtin_array = !is_unbounded_array_v<_Ty>;
#endif // _HAS_CXX20
_EXPORT_STD template <class _Ty>
class shared_ptr : public _Ptr_base<_Ty> { // class for reference counted resource management
private:
@ -1794,31 +1808,29 @@ private:
}
#if _HAS_CXX20
template <class _Ty0, class... _Types>
friend enable_if_t<!is_array_v<_Ty0>, shared_ptr<_Ty0>> make_shared(_Types&&... _Args);
template <_Not_builtin_array _Ty0, class... _Types>
friend shared_ptr<_Ty0> make_shared(_Types&&... _Args);
template <class _Ty0, class _Alloc, class... _Types>
friend enable_if_t<!is_array_v<_Ty0>, shared_ptr<_Ty0>> allocate_shared(const _Alloc& _Al_arg, _Types&&... _Args);
template <_Not_builtin_array _Ty0, class _Alloc, class... _Types>
friend shared_ptr<_Ty0> allocate_shared(const _Alloc& _Al_arg, _Types&&... _Args);
template <class _Ty0>
friend enable_if_t<is_bounded_array_v<_Ty0>, shared_ptr<_Ty0>> make_shared();
template <_Bounded_builtin_array _Ty0>
friend shared_ptr<_Ty0> make_shared();
template <class _Ty0, class _Alloc>
friend enable_if_t<is_bounded_array_v<_Ty0>, shared_ptr<_Ty0>> allocate_shared(const _Alloc& _Al_arg);
template <_Bounded_builtin_array _Ty0, class _Alloc>
friend shared_ptr<_Ty0> allocate_shared(const _Alloc& _Al_arg);
template <class _Ty0>
friend enable_if_t<is_bounded_array_v<_Ty0>, shared_ptr<_Ty0>> make_shared(const remove_extent_t<_Ty0>& _Val);
template <_Bounded_builtin_array _Ty0>
friend shared_ptr<_Ty0> make_shared(const remove_extent_t<_Ty0>& _Val);
template <class _Ty0, class _Alloc>
friend enable_if_t<is_bounded_array_v<_Ty0>, shared_ptr<_Ty0>> allocate_shared(
const _Alloc& _Al_arg, const remove_extent_t<_Ty0>& _Val);
template <_Bounded_builtin_array _Ty0, class _Alloc>
friend shared_ptr<_Ty0> allocate_shared(const _Alloc& _Al_arg, const remove_extent_t<_Ty0>& _Val);
template <class _Ty0>
friend enable_if_t<!is_unbounded_array_v<_Ty0>, shared_ptr<_Ty0>> make_shared_for_overwrite();
template <_Not_unbounded_builtin_array _Ty0>
friend shared_ptr<_Ty0> make_shared_for_overwrite();
template <class _Ty0, class _Alloc>
friend enable_if_t<!is_unbounded_array_v<_Ty0>, shared_ptr<_Ty0>> allocate_shared_for_overwrite(
const _Alloc& _Al_arg);
template <_Not_unbounded_builtin_array _Ty0, class _Alloc>
friend shared_ptr<_Ty0> allocate_shared_for_overwrite(const _Alloc& _Al_arg);
template <class _Ty0, class... _ArgTypes>
friend shared_ptr<_Ty0> _Make_shared_unbounded_array(size_t _Count, const _ArgTypes&... _Args);
@ -2885,14 +2897,12 @@ private:
};
#endif // _HAS_CXX20
_EXPORT_STD template <class _Ty, class... _Types>
_NODISCARD_SMART_PTR_ALLOC
#if _HAS_CXX20
enable_if_t<!is_array_v<_Ty>, shared_ptr<_Ty>>
#else
shared_ptr<_Ty>
#endif
make_shared(_Types&&... _Args) { // make a shared_ptr to non-array object
_EXPORT_STD template <_Not_builtin_array _Ty, class... _Types>
#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv
template <class _Ty, class... _Types>
#endif // ^^^ !_HAS_CXX20 ^^^
_NODISCARD_SMART_PTR_ALLOC shared_ptr<_Ty> make_shared(_Types&&... _Args) { // make a shared_ptr to non-array object
const auto _Rx = new _Ref_count_obj2<_Ty>(_STD forward<_Types>(_Args)...);
shared_ptr<_Ty> _Ret;
_Ret._Set_ptr_rep_and_enable_shared(_STD addressof(_Rx->_Storage._Value), _Rx);
@ -2928,19 +2938,18 @@ _NODISCARD shared_ptr<_Ty> _Make_shared_unbounded_array(const size_t _Count, con
return _Ret;
}
_EXPORT_STD template <class _Ty>
_NODISCARD_SMART_PTR_ALLOC enable_if_t<is_unbounded_array_v<_Ty>, shared_ptr<_Ty>> make_shared(const size_t _Count) {
_EXPORT_STD template <_Unbounded_builtin_array _Ty>
_NODISCARD_SMART_PTR_ALLOC shared_ptr<_Ty> make_shared(const size_t _Count) {
return _STD _Make_shared_unbounded_array<_Ty>(_Count);
}
_EXPORT_STD template <class _Ty>
_NODISCARD_SMART_PTR_ALLOC enable_if_t<is_unbounded_array_v<_Ty>, shared_ptr<_Ty>> make_shared(
const size_t _Count, const remove_extent_t<_Ty>& _Val) {
_EXPORT_STD template <_Unbounded_builtin_array _Ty>
_NODISCARD_SMART_PTR_ALLOC shared_ptr<_Ty> make_shared(const size_t _Count, const remove_extent_t<_Ty>& _Val) {
return _STD _Make_shared_unbounded_array<_Ty>(_Count, _Val);
}
_EXPORT_STD template <class _Ty>
_NODISCARD_SMART_PTR_ALLOC enable_if_t<is_bounded_array_v<_Ty>, shared_ptr<_Ty>> make_shared() {
_EXPORT_STD template <_Bounded_builtin_array _Ty>
_NODISCARD_SMART_PTR_ALLOC shared_ptr<_Ty> make_shared() {
// make a shared_ptr to a bounded array
const auto _Rx = new _Ref_count_bounded_array<_Ty>();
shared_ptr<_Ty> _Ret;
@ -2948,9 +2957,8 @@ _NODISCARD_SMART_PTR_ALLOC enable_if_t<is_bounded_array_v<_Ty>, shared_ptr<_Ty>>
return _Ret;
}
_EXPORT_STD template <class _Ty>
_NODISCARD_SMART_PTR_ALLOC enable_if_t<is_bounded_array_v<_Ty>, shared_ptr<_Ty>> make_shared(
const remove_extent_t<_Ty>& _Val) {
_EXPORT_STD template <_Bounded_builtin_array _Ty>
_NODISCARD_SMART_PTR_ALLOC shared_ptr<_Ty> make_shared(const remove_extent_t<_Ty>& _Val) {
// make a shared_ptr to a bounded array
const auto _Rx = new _Ref_count_bounded_array<_Ty>(_Val);
shared_ptr<_Ty> _Ret;
@ -2958,8 +2966,8 @@ _NODISCARD_SMART_PTR_ALLOC enable_if_t<is_bounded_array_v<_Ty>, shared_ptr<_Ty>>
return _Ret;
}
_EXPORT_STD template <class _Ty>
_NODISCARD_SMART_PTR_ALLOC enable_if_t<!is_unbounded_array_v<_Ty>, shared_ptr<_Ty>> make_shared_for_overwrite() {
_EXPORT_STD template <_Not_unbounded_builtin_array _Ty>
_NODISCARD_SMART_PTR_ALLOC shared_ptr<_Ty> make_shared_for_overwrite() {
shared_ptr<_Ty> _Ret;
if constexpr (is_array_v<_Ty>) {
// make a shared_ptr to a bounded array
@ -2973,21 +2981,19 @@ _NODISCARD_SMART_PTR_ALLOC enable_if_t<!is_unbounded_array_v<_Ty>, shared_ptr<_T
return _Ret;
}
_EXPORT_STD template <class _Ty>
_NODISCARD_SMART_PTR_ALLOC enable_if_t<is_unbounded_array_v<_Ty>, shared_ptr<_Ty>> make_shared_for_overwrite(
const size_t _Count) {
_EXPORT_STD template <_Unbounded_builtin_array _Ty>
_NODISCARD_SMART_PTR_ALLOC shared_ptr<_Ty> make_shared_for_overwrite(const size_t _Count) {
return _STD _Make_shared_unbounded_array<_Ty>(_Count, _For_overwrite_tag{});
}
#endif // _HAS_CXX20
_EXPORT_STD template <class _Ty, class _Alloc, class... _Types>
_NODISCARD_SMART_PTR_ALLOC
#if _HAS_CXX20
enable_if_t<!is_array_v<_Ty>, shared_ptr<_Ty>>
#else
shared_ptr<_Ty>
#endif
allocate_shared(const _Alloc& _Al, _Types&&... _Args) { // make a shared_ptr to non-array object
_EXPORT_STD template <_Not_builtin_array _Ty, class _Alloc, class... _Types>
#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv
template <class _Ty, class _Alloc, class... _Types>
#endif // ^^^ !_HAS_CXX20 ^^^
_NODISCARD_SMART_PTR_ALLOC shared_ptr<_Ty> allocate_shared(const _Alloc& _Al, _Types&&... _Args) {
// make a shared_ptr to non-array object
// Note: As of 2019-05-28, this implements the proposed resolution of LWG-3210 (which controls whether
// allocator::construct sees T or const T when _Ty is const qualified)
using _Refoa = _Ref_count_obj_alloc3<remove_cv_t<_Ty>, _Alloc>;
@ -3044,20 +3050,19 @@ _NODISCARD shared_ptr<_Ty> _Allocate_shared_unbounded_array(
return _Ret;
}
_EXPORT_STD template <class _Ty, class _Alloc>
_NODISCARD_SMART_PTR_ALLOC enable_if_t<is_unbounded_array_v<_Ty>, shared_ptr<_Ty>> allocate_shared(
const _Alloc& _Al, const size_t _Count) {
_EXPORT_STD template <_Unbounded_builtin_array _Ty, class _Alloc>
_NODISCARD_SMART_PTR_ALLOC shared_ptr<_Ty> allocate_shared(const _Alloc& _Al, const size_t _Count) {
return _STD _Allocate_shared_unbounded_array<false, _Ty>(_Al, _Count);
}
_EXPORT_STD template <class _Ty, class _Alloc>
_NODISCARD_SMART_PTR_ALLOC enable_if_t<is_unbounded_array_v<_Ty>, shared_ptr<_Ty>> allocate_shared(
_EXPORT_STD template <_Unbounded_builtin_array _Ty, class _Alloc>
_NODISCARD_SMART_PTR_ALLOC shared_ptr<_Ty> allocate_shared(
const _Alloc& _Al, const size_t _Count, const remove_extent_t<_Ty>& _Val) {
return _STD _Allocate_shared_unbounded_array<false, _Ty>(_Al, _Count, _Val);
}
_EXPORT_STD template <class _Ty, class _Alloc>
_NODISCARD_SMART_PTR_ALLOC enable_if_t<is_bounded_array_v<_Ty>, shared_ptr<_Ty>> allocate_shared(const _Alloc& _Al) {
_EXPORT_STD template <_Bounded_builtin_array _Ty, class _Alloc>
_NODISCARD_SMART_PTR_ALLOC shared_ptr<_Ty> allocate_shared(const _Alloc& _Al) {
// make a shared_ptr to a bounded array
using _Refc = _Ref_count_bounded_array_alloc<remove_cv_t<_Ty>, _Alloc>;
using _Alblock = _Rebind_alloc_t<_Alloc, _Refc>;
@ -3071,9 +3076,8 @@ _NODISCARD_SMART_PTR_ALLOC enable_if_t<is_bounded_array_v<_Ty>, shared_ptr<_Ty>>
return _Ret;
}
_EXPORT_STD template <class _Ty, class _Alloc>
_NODISCARD_SMART_PTR_ALLOC enable_if_t<is_bounded_array_v<_Ty>, shared_ptr<_Ty>> allocate_shared(
const _Alloc& _Al, const remove_extent_t<_Ty>& _Val) {
_EXPORT_STD template <_Bounded_builtin_array _Ty, class _Alloc>
_NODISCARD_SMART_PTR_ALLOC shared_ptr<_Ty> allocate_shared(const _Alloc& _Al, const remove_extent_t<_Ty>& _Val) {
// make a shared_ptr to a bounded array
using _Refc = _Ref_count_bounded_array_alloc<remove_cv_t<_Ty>, _Alloc>;
using _Alblock = _Rebind_alloc_t<_Alloc, _Refc>;
@ -3087,9 +3091,8 @@ _NODISCARD_SMART_PTR_ALLOC enable_if_t<is_bounded_array_v<_Ty>, shared_ptr<_Ty>>
return _Ret;
}
_EXPORT_STD template <class _Ty, class _Alloc>
_NODISCARD_SMART_PTR_ALLOC enable_if_t<!is_unbounded_array_v<_Ty>, shared_ptr<_Ty>> allocate_shared_for_overwrite(
const _Alloc& _Al) {
_EXPORT_STD template <_Not_unbounded_builtin_array _Ty, class _Alloc>
_NODISCARD_SMART_PTR_ALLOC shared_ptr<_Ty> allocate_shared_for_overwrite(const _Alloc& _Al) {
shared_ptr<_Ty> _Ret;
if constexpr (is_array_v<_Ty>) {
// make a shared_ptr to a bounded array
@ -3116,9 +3119,8 @@ _NODISCARD_SMART_PTR_ALLOC enable_if_t<!is_unbounded_array_v<_Ty>, shared_ptr<_T
return _Ret;
}
_EXPORT_STD template <class _Ty, class _Alloc>
_NODISCARD_SMART_PTR_ALLOC enable_if_t<is_unbounded_array_v<_Ty>, shared_ptr<_Ty>> allocate_shared_for_overwrite(
const _Alloc& _Al, const size_t _Count) {
_EXPORT_STD template <_Unbounded_builtin_array _Ty, class _Alloc>
_NODISCARD_SMART_PTR_ALLOC shared_ptr<_Ty> allocate_shared_for_overwrite(const _Alloc& _Al, const size_t _Count) {
return _STD _Allocate_shared_unbounded_array<true, _Ty>(_Al, _Count);
}
#endif // _HAS_CXX20
@ -3605,20 +3607,20 @@ _EXPORT_STD template <class _Ty, class... _Types, enable_if_t<extent_v<_Ty> != 0
void make_unique(_Types&&...) = delete;
#if _HAS_CXX20
_EXPORT_STD template <class _Ty, enable_if_t<!is_array_v<_Ty>, int> = 0>
_EXPORT_STD template <_Not_builtin_array _Ty>
_NODISCARD_SMART_PTR_ALLOC _CONSTEXPR23 unique_ptr<_Ty> make_unique_for_overwrite() {
// make a unique_ptr with default initialization
return unique_ptr<_Ty>(new _Ty);
}
_EXPORT_STD template <class _Ty, enable_if_t<is_unbounded_array_v<_Ty>, int> = 0>
_EXPORT_STD template <_Unbounded_builtin_array _Ty>
_NODISCARD_SMART_PTR_ALLOC _CONSTEXPR23 unique_ptr<_Ty> make_unique_for_overwrite(const size_t _Size) {
// make a unique_ptr with default initialization
using _Elem = remove_extent_t<_Ty>;
return unique_ptr<_Ty>(new _Elem[_Size]);
}
_EXPORT_STD template <class _Ty, class... _Types, enable_if_t<is_bounded_array_v<_Ty>, int> = 0>
_EXPORT_STD template <_Bounded_builtin_array _Ty, class... _Types>
void make_unique_for_overwrite(_Types&&...) = delete;
#endif // _HAS_CXX20

Просмотреть файл

@ -657,7 +657,8 @@ _NODISCARD constexpr common_type_t<_Mt, _Nt> lcm(const _Mt _Mx, const _Nt _Nx) n
#endif // _HAS_CXX17
#if _HAS_CXX20
_EXPORT_STD template <class _Ty, enable_if_t<is_arithmetic_v<_Ty> && !is_same_v<remove_cv_t<_Ty>, bool>, int> = 0>
_EXPORT_STD template <class _Ty>
requires is_arithmetic_v<_Ty> && (!is_same_v<remove_cv_t<_Ty>, bool>)
_NODISCARD constexpr _Ty midpoint(const _Ty _Val1, const _Ty _Val2) noexcept {
if constexpr (is_floating_point_v<_Ty>) {
if (_STD is_constant_evaluated()) {
@ -722,7 +723,8 @@ _NODISCARD constexpr _Ty midpoint(const _Ty _Val1, const _Ty _Val2) noexcept {
}
}
_EXPORT_STD template <class _Ty, enable_if_t<is_object_v<_Ty>, int> = 0>
_EXPORT_STD template <class _Ty>
requires is_object_v<_Ty>
_NODISCARD constexpr _Ty* midpoint(_Ty* const _Val1, _Ty* const _Val2) noexcept /* strengthened */ {
if (_Val1 > _Val2) {
return _Val1 - ((_Val1 - _Val2) >> 1); // shift for codegen

Просмотреть файл

@ -549,7 +549,8 @@ _NODISCARD auto as_bytes(span<_Ty, _Extent> _Sp) noexcept {
return _ReturnType{reinterpret_cast<const byte*>(_Sp.data()), _Sp.size_bytes()};
}
_EXPORT_STD template <class _Ty, size_t _Extent, enable_if_t<!is_const_v<_Ty>, int> = 0>
_EXPORT_STD template <class _Ty, size_t _Extent>
requires (!is_const_v<_Ty>)
_NODISCARD auto as_writable_bytes(span<_Ty, _Extent> _Sp) noexcept {
using _ReturnType = span<byte, _Extent == dynamic_extent ? dynamic_extent : sizeof(_Ty) * _Extent>;
return _ReturnType{reinterpret_cast<byte*>(_Sp.data()), _Sp.size_bytes()};

Просмотреть файл

@ -61,7 +61,8 @@ public:
basic_stringbuf(const basic_string<_Elem, _Traits, _Alloc2>& _Str, const _Alloc& _Al_)
: basic_stringbuf(_Str, ios_base::in | ios_base::out, _Al_) {}
template <class _Alloc2, enable_if_t<!is_same_v<_Alloc2, _Alloc>, int> = 0>
template <class _Alloc2>
requires (!is_same_v<_Alloc2, _Alloc>)
explicit basic_stringbuf(
const basic_string<_Elem, _Traits, _Alloc2>& _Str, ios_base::openmode _Mode = ios_base::in | ios_base::out)
: basic_stringbuf(_Str, _Mode, _Alloc{}) {}
@ -229,7 +230,8 @@ public:
}
#if _HAS_CXX20
template <class _Alloc2, enable_if_t<_Is_allocator<_Alloc2>::value, int> = 0>
template <class _Alloc2>
requires _Is_allocator<_Alloc2>::value
_NODISCARD basic_string<_Elem, _Traits, _Alloc2> str(const _Alloc2& _Al) const {
return basic_string<_Elem, _Traits, _Alloc2>{view(), _Al};
}
@ -260,7 +262,8 @@ public:
return _Mystr_view{_View._Ptr, _View._Size};
}
template <class _Alloc2, enable_if_t<!is_same_v<_Alloc2, _Alloc>, int> = 0>
template <class _Alloc2>
requires (!is_same_v<_Alloc2, _Alloc>)
void str(const basic_string<_Elem, _Traits, _Alloc2>& _Newstr) {
_Tidy();
_Init(_Newstr.c_str(), _Newstr.size(), _Mystate);
@ -641,7 +644,8 @@ public:
basic_istringstream(const basic_string<_Elem, _Traits, _Alloc2>& _Str, ios_base::openmode _Mode, const _Alloc& _Al)
: _Mybase(_STD addressof(_Stringbuffer)), _Stringbuffer(_Str, _Mode | ios_base::in, _Al) {}
template <class _Alloc2, enable_if_t<!is_same_v<_Alloc2, _Alloc>, int> = 0>
template <class _Alloc2>
requires (!is_same_v<_Alloc2, _Alloc>)
explicit basic_istringstream(
const basic_string<_Elem, _Traits, _Alloc2>& _Str, ios_base::openmode _Mode = ios_base::in)
: _Mybase(_STD addressof(_Stringbuffer)), _Stringbuffer(_Str, _Mode | ios_base::in) {}
@ -690,7 +694,8 @@ public:
}
#if _HAS_CXX20
template <class _Alloc2, enable_if_t<_Is_allocator<_Alloc2>::value, int> = 0>
template <class _Alloc2>
requires _Is_allocator<_Alloc2>::value
_NODISCARD basic_string<_Elem, _Traits, _Alloc2> str(const _Alloc2& _Al) const {
return _Stringbuffer.str(_Al);
}
@ -703,7 +708,8 @@ public:
return _Stringbuffer.view();
}
template <class _Alloc2, enable_if_t<!is_same_v<_Alloc2, _Alloc>, int> = 0>
template <class _Alloc2>
requires (!is_same_v<_Alloc2, _Alloc>)
void str(const basic_string<_Elem, _Traits, _Alloc2>& _Newstr) {
_Stringbuffer.str(_Newstr);
}
@ -758,7 +764,8 @@ public:
basic_ostringstream(const basic_string<_Elem, _Traits, _Alloc2>& _Str, ios_base::openmode _Mode, const _Alloc& _Al)
: _Mybase(_STD addressof(_Stringbuffer)), _Stringbuffer(_Str, _Mode | ios_base::out, _Al) {}
template <class _Alloc2, enable_if_t<!is_same_v<_Alloc2, _Alloc>, int> = 0>
template <class _Alloc2>
requires (!is_same_v<_Alloc2, _Alloc>)
explicit basic_ostringstream(
const basic_string<_Elem, _Traits, _Alloc2>& _Str, ios_base::openmode _Mode = ios_base::out)
: _Mybase(_STD addressof(_Stringbuffer)), _Stringbuffer(_Str, _Mode | ios_base::out) {}
@ -820,7 +827,8 @@ public:
return _Stringbuffer.view();
}
template <class _Alloc2, enable_if_t<!is_same_v<_Alloc2, _Alloc>, int> = 0>
template <class _Alloc2>
requires (!is_same_v<_Alloc2, _Alloc>)
void str(const basic_string<_Elem, _Traits, _Alloc2>& _Newstr) {
_Stringbuffer.str(_Newstr);
}
@ -881,7 +889,8 @@ public:
basic_stringstream(const basic_string<_Elem, _Traits, _Alloc2>& _Str, ios_base::openmode _Mode, const _Alloc& _Al)
: _Mybase(_STD addressof(_Stringbuffer)), _Stringbuffer(_Str, _Mode, _Al) {}
template <class _Alloc2, enable_if_t<!is_same_v<_Alloc2, _Alloc>, int> = 0>
template <class _Alloc2>
requires (!is_same_v<_Alloc2, _Alloc>)
explicit basic_stringstream(
const basic_string<_Elem, _Traits, _Alloc2>& _Str, ios_base::openmode _Mode = ios_base::in | ios_base::out)
: _Mybase(_STD addressof(_Stringbuffer)), _Stringbuffer(_Str, _Mode) {}
@ -943,7 +952,8 @@ public:
return _Stringbuffer.view();
}
template <class _Alloc2, enable_if_t<!is_same_v<_Alloc2, _Alloc>, int> = 0>
template <class _Alloc2>
requires (!is_same_v<_Alloc2, _Alloc>)
void str(const basic_string<_Elem, _Traits, _Alloc2>& _Newstr) {
_Stringbuffer.str(_Newstr);
}

Просмотреть файл

@ -357,14 +357,16 @@ class stop_callback : public _Stop_callback_base {
public:
using callback_type = _Callback;
template <class _CbInitTy, enable_if_t<is_constructible_v<_Callback, _CbInitTy>, int> = 0>
template <class _CbInitTy>
requires is_constructible_v<_Callback, _CbInitTy>
explicit stop_callback(const stop_token& _Token, _CbInitTy&& _Cb_) noexcept(
is_nothrow_constructible_v<_Callback, _CbInitTy>)
: _Stop_callback_base{_Invoke_by_stop}, _Cb(_STD forward<_CbInitTy>(_Cb_)) {
_Attach(_Token);
}
template <class _CbInitTy, enable_if_t<is_constructible_v<_Callback, _CbInitTy>, int> = 0>
template <class _CbInitTy>
requires is_constructible_v<_Callback, _CbInitTy>
explicit stop_callback(stop_token&& _Token, _CbInitTy&& _Cb_) noexcept(
is_nothrow_constructible_v<_Callback, _CbInitTy>)
: _Stop_callback_base{_Invoke_by_stop}, _Cb(_STD forward<_CbInitTy>(_Cb_)) {

Просмотреть файл

@ -350,7 +350,8 @@ public:
jthread() noexcept : _Impl{}, _Ssource{nostopstate} {}
template <class _Fn, class... _Args, enable_if_t<!is_same_v<remove_cvref_t<_Fn>, jthread>, int> = 0>
template <class _Fn, class... _Args>
requires (!is_same_v<remove_cvref_t<_Fn>, jthread>)
_NODISCARD_CTOR_JTHREAD explicit jthread(_Fn&& _Fx, _Args&&... _Ax) {
if constexpr (is_invocable_v<decay_t<_Fn>, stop_token, decay_t<_Args>...>) {
_Impl._Start(_STD forward<_Fn>(_Fx), _Ssource.get_token(), _STD forward<_Args>(_Ax)...);

Просмотреть файл

@ -1295,13 +1295,23 @@ template <class _Ty1, class _Ty2>
using _Conditional_type = decltype(false ? _STD declval<_Ty1>() : _STD declval<_Ty2>());
#if _HAS_CXX20
#if defined(__clang__) || defined(__EDG__) // TRANSITION, DevCom-10648215
template <class _Ty1, class _Ty2>
#else // ^^^ no workaround / workaround vvv
template <class _Ty1, class _Ty2, class = void>
struct _Const_lvalue_cond_oper {};
#endif // ^^^ workaround ^^^
struct _Const_lvalue_cond_oper {
};
// N4950 [meta.trans.other]/3.3.4 (per the proposed resolution of LWG-3205): "Otherwise, if remove_cvref_t</**/> denotes
// a type..."
template <class _Ty1, class _Ty2>
#if defined(__clang__) || defined(__EDG__) // TRANSITION, DevCom-10648215
requires requires { typename _Conditional_type<const _Ty1&, const _Ty2&>; }
struct _Const_lvalue_cond_oper<_Ty1, _Ty2> {
#else // ^^^ no workaround / workaround vvv
struct _Const_lvalue_cond_oper<_Ty1, _Ty2, void_t<_Conditional_type<const _Ty1&, const _Ty2&>>> {
#endif // ^^^ workaround ^^^
using type = remove_cvref_t<_Conditional_type<const _Ty1&, const _Ty2&>>;
};
@ -1419,12 +1429,13 @@ struct common_reference<_Ty> {
// N4950 [meta.trans.other]/5.3.4: "if common_type_t<T1, T2> is well-formed..."
// N4950 [meta.trans.other]/5.3.5: "Otherwise, there shall be no member type."
template <class _Ty1, class _Ty2, class = void>
template <class _Ty1, class _Ty2>
struct _Common_reference2C : common_type<_Ty1, _Ty2> {};
// N4950 [meta.trans.other]/5.3.3: "if COND_RES(T1, T2) is well-formed..."
template <class _Ty1, class _Ty2>
struct _Common_reference2C<_Ty1, _Ty2, void_t<_Cond_res<_Ty1, _Ty2>>> {
requires requires { typename _Cond_res<_Ty1, _Ty2>; }
struct _Common_reference2C<_Ty1, _Ty2> {
using type = _Cond_res<_Ty1, _Ty2>;
};
@ -1433,39 +1444,43 @@ template <class _Ty1, class _Ty2>
using _Basic_specialization = basic_common_reference<remove_cvref_t<_Ty1>, remove_cvref_t<_Ty2>,
_Add_qualifiers<_Ty1>::template _Apply, _Add_qualifiers<_Ty2>::template _Apply>::type;
template <class _Ty1, class _Ty2, class = void>
template <class _Ty1, class _Ty2>
struct _Common_reference2B : _Common_reference2C<_Ty1, _Ty2> {};
template <class _Ty1, class _Ty2>
struct _Common_reference2B<_Ty1, _Ty2, void_t<_Basic_specialization<_Ty1, _Ty2>>> {
requires requires { typename _Basic_specialization<_Ty1, _Ty2>; }
struct _Common_reference2B<_Ty1, _Ty2> {
using type = _Basic_specialization<_Ty1, _Ty2>;
};
// N4950 [meta.trans.other]/5.3.1: "Let R be COMMON-REF(T1, T2). If T1 and T2 are reference types, R is well-formed, and
// is_convertible_v<add_pointer_t<T1>, add_pointer_t<R>> && is_convertible_v<add_pointer_t<T2>, add_pointer_t<R>> is
// true, then the member typedef type denotes R."
template <class _Ty1, class _Ty2, class = void>
template <class _Ty1, class _Ty2>
struct _Common_reference2A : _Common_reference2B<_Ty1, _Ty2> {};
template <class _Ty1, class _Ty2, class _Result = _Cond_res<_Copy_cv<_Ty1, _Ty2>&, _Copy_cv<_Ty2, _Ty1>&>,
enable_if_t<is_lvalue_reference_v<_Result>, int> = 0>
using _LL_common_ref = _Result;
template <class _Ty1, class _Ty2>
requires is_lvalue_reference_v<_Cond_res<_Copy_cv<_Ty1, _Ty2>&, _Copy_cv<_Ty2, _Ty1>&>>
using _LL_common_ref = _Cond_res<_Copy_cv<_Ty1, _Ty2>&, _Copy_cv<_Ty2, _Ty1>&>;
template <class _Ty1, class _Ty2, class = void>
template <class _Ty1, class _Ty2>
struct _Common_reference2AX {};
template <class _Ty1, class _Ty2>
struct _Common_reference2AX<_Ty1&, _Ty2&, void_t<_LL_common_ref<_Ty1, _Ty2>>> {
requires requires { typename _LL_common_ref<_Ty1, _Ty2>; }
struct _Common_reference2AX<_Ty1&, _Ty2&> {
using type = _LL_common_ref<_Ty1, _Ty2>; // "both lvalues" case from N4950 [meta.trans.other]/2.5
};
template <class _Ty1, class _Ty2>
struct _Common_reference2AX<_Ty1&&, _Ty2&, enable_if_t<is_convertible_v<_Ty1&&, _LL_common_ref<const _Ty1, _Ty2>>>> {
requires is_convertible_v<_Ty1&&, _LL_common_ref<const _Ty1, _Ty2>>
struct _Common_reference2AX<_Ty1&&, _Ty2&> {
using type = _LL_common_ref<const _Ty1, _Ty2>; // "rvalue and lvalue" case from N4950 [meta.trans.other]/2.7
};
template <class _Ty1, class _Ty2>
struct _Common_reference2AX<_Ty1&, _Ty2&&, enable_if_t<is_convertible_v<_Ty2&&, _LL_common_ref<const _Ty2, _Ty1>>>> {
requires is_convertible_v<_Ty2&&, _LL_common_ref<const _Ty2, _Ty1>>
struct _Common_reference2AX<_Ty1&, _Ty2&&> {
using type = _LL_common_ref<const _Ty2, _Ty1>; // "lvalue and rvalue" case from N4950 [meta.trans.other]/2.8
};
@ -1473,9 +1488,9 @@ template <class _Ty1, class _Ty2>
using _RR_common_ref = remove_reference_t<_LL_common_ref<_Ty1, _Ty2>>&&;
template <class _Ty1, class _Ty2>
struct _Common_reference2AX<_Ty1&&, _Ty2&&,
enable_if_t<is_convertible_v<_Ty1&&, _RR_common_ref<_Ty1, _Ty2>>
&& is_convertible_v<_Ty2&&, _RR_common_ref<_Ty1, _Ty2>>>> {
requires is_convertible_v<_Ty1&&, _RR_common_ref<_Ty1, _Ty2>>
&& is_convertible_v<_Ty2&&, _RR_common_ref<_Ty1, _Ty2>>
struct _Common_reference2AX<_Ty1&&, _Ty2&&> {
using type = _RR_common_ref<_Ty1, _Ty2>; // "both rvalues" case from N4950 [meta.trans.other]/2.6
};
@ -1483,9 +1498,9 @@ template <class _Ty1, class _Ty2>
using _Common_ref_2AX_t = _Common_reference2AX<_Ty1, _Ty2>::type;
template <class _Ty1, class _Ty2>
struct _Common_reference2A<_Ty1, _Ty2,
enable_if_t<is_convertible_v<add_pointer_t<_Ty1>, add_pointer_t<_Common_ref_2AX_t<_Ty1, _Ty2>>>
&& is_convertible_v<add_pointer_t<_Ty2>, add_pointer_t<_Common_ref_2AX_t<_Ty1, _Ty2>>>>> {
requires is_convertible_v<add_pointer_t<_Ty1>, add_pointer_t<_Common_ref_2AX_t<_Ty1, _Ty2>>>
&& is_convertible_v<add_pointer_t<_Ty2>, add_pointer_t<_Common_ref_2AX_t<_Ty1, _Ty2>>>
struct _Common_reference2A<_Ty1, _Ty2> {
using type = _Common_ref_2AX_t<_Ty1, _Ty2>;
};
@ -1493,14 +1508,12 @@ template <class _Ty1, class _Ty2>
struct common_reference<_Ty1, _Ty2> : _Common_reference2A<_Ty1, _Ty2> {};
// N4950 [meta.trans.other]/5.4: "if sizeof...(T) is greater than two..."
template <class _Void, class _Ty1, class _Ty2, class... _Types>
struct _Fold_common_reference {};
template <class _Ty1, class _Ty2, class... _Types>
struct _Fold_common_reference<void_t<common_reference_t<_Ty1, _Ty2>>, _Ty1, _Ty2, _Types...>
: common_reference<common_reference_t<_Ty1, _Ty2>, _Types...> {};
template <class _Ty1, class _Ty2, class _Ty3, class... _Rest>
struct common_reference<_Ty1, _Ty2, _Ty3, _Rest...> : _Fold_common_reference<void, _Ty1, _Ty2, _Ty3, _Rest...> {};
struct common_reference<_Ty1, _Ty2, _Ty3, _Rest...> {};
template <class _Ty1, class _Ty2, class _Ty3, class... _Rest>
requires requires { typename common_reference_t<_Ty1, _Ty2>; }
struct common_reference<_Ty1, _Ty2, _Ty3, _Rest...> : common_reference<common_reference_t<_Ty1, _Ty2>, _Ty3, _Rest...> {
};
_EXPORT_STD template <class _Ty>
struct type_identity {

Просмотреть файл

@ -2156,10 +2156,8 @@ _NODISCARD constexpr bool _Allocators_equal(const _Alloc& _Lhs, const _Alloc& _R
}
#if _HAS_CXX23
template <class _Ty, class = void>
constexpr bool _Has_member_from_primary = false;
template <class _Ty>
constexpr bool _Has_member_from_primary<_Ty, void_t<typename _Ty::_From_primary>> = true;
constexpr bool _Has_member_from_primary = requires { typename _Ty::_From_primary; };
// Avoid using allocate_at_least when the allocator publicly derives from std::allocator:
// "old" allocators might hide allocate and deallocate but fail to hide allocate_at_least.
@ -2293,7 +2291,18 @@ template <class _Ty, class _Uty>
constexpr bool _Is_normally_bindable<_Ty, _Uty, void_t<_Normally_bound_ref<_Ty, _Uty>>> = true;
#if _HAS_CXX20
_EXPORT_STD template <class _Ty, class _Alloc, class... _Types, enable_if_t<!_Is_cv_pair<_Ty>, int> = 0>
template <class _Ty>
concept _Cv_std_pair = _Is_cv_pair<_Ty>;
template <class _Ty>
concept _Usable_for_pair_like_overload =
#if _HAS_CXX23
_Pair_like<_Ty> ||
#endif // _HAS_CXX23
!_Is_deducible_as_pair<_Ty&>;
_EXPORT_STD template <class _Ty, class _Alloc, class... _Types>
requires (!_Is_cv_pair<_Ty>)
_NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, _Types&&... _Args) noexcept {
if constexpr (!uses_allocator_v<remove_cv_t<_Ty>, _Alloc>) {
static_assert(is_constructible_v<_Ty, _Types...>,
@ -2313,39 +2322,33 @@ _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, _T
}
}
_EXPORT_STD template <class _Ty, class _Alloc, enable_if_t<_Is_cv_pair<_Ty>, int> = 0>
_EXPORT_STD template <_Cv_std_pair _Ty, class _Alloc>
_NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al) noexcept;
_EXPORT_STD template <class _Ty, class _Alloc, class _Uty1, class _Uty2, enable_if_t<_Is_cv_pair<_Ty>, int> = 0>
_EXPORT_STD template <_Cv_std_pair _Ty, class _Alloc, class _Uty1, class _Uty2>
_NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, _Uty1&& _Val1, _Uty2&& _Val2) noexcept;
#if _HAS_CXX23
_EXPORT_STD template <class _Ty, class _Alloc, class _Uty1, class _Uty2, enable_if_t<_Is_cv_pair<_Ty>, int> = 0>
_EXPORT_STD template <_Cv_std_pair _Ty, class _Alloc, class _Uty1, class _Uty2>
_NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, pair<_Uty1, _Uty2>& _Pair) noexcept;
#endif // _HAS_CXX23
_EXPORT_STD template <class _Ty, class _Alloc, class _Uty1, class _Uty2, enable_if_t<_Is_cv_pair<_Ty>, int> = 0>
_EXPORT_STD template <_Cv_std_pair _Ty, class _Alloc, class _Uty1, class _Uty2>
_NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, const pair<_Uty1, _Uty2>& _Pair) noexcept;
_EXPORT_STD template <class _Ty, class _Alloc, class _Uty1, class _Uty2, enable_if_t<_Is_cv_pair<_Ty>, int> = 0>
_EXPORT_STD template <_Cv_std_pair _Ty, class _Alloc, class _Uty1, class _Uty2>
_NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, pair<_Uty1, _Uty2>&& _Pair) noexcept;
#if _HAS_CXX23
_EXPORT_STD template <class _Ty, class _Alloc, class _Uty1, class _Uty2, enable_if_t<_Is_cv_pair<_Ty>, int> = 0>
_EXPORT_STD template <_Cv_std_pair _Ty, class _Alloc, class _Uty1, class _Uty2>
_NODISCARD constexpr auto uses_allocator_construction_args(
const _Alloc& _Al, const pair<_Uty1, _Uty2>&& _Pair) noexcept;
#endif // _HAS_CXX23
#if _HAS_CXX23
_EXPORT_STD template <class _Ty, class _Alloc, class _Uty>
requires _Is_cv_pair<_Ty> && (_Pair_like<_Uty> || !_Is_deducible_as_pair<_Uty&>)
#else // ^^^ _HAS_CXX23 / !_HAS_CXX23 vvv
_EXPORT_STD template <class _Ty, class _Alloc, class _Uty,
enable_if_t<_Is_cv_pair<_Ty> && !_Is_deducible_as_pair<_Uty&>, int> = 0>
#endif // ^^^ !_HAS_CXX23 ^^^
_EXPORT_STD template <_Cv_std_pair _Ty, class _Alloc, _Usable_for_pair_like_overload _Uty>
_NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, _Uty&& _Ux) noexcept;
_EXPORT_STD template <class _Ty, class _Alloc, class _Tuple1, class _Tuple2, enable_if_t<_Is_cv_pair<_Ty>, int> = 0>
_EXPORT_STD template <_Cv_std_pair _Ty, class _Alloc, class _Tuple1, class _Tuple2>
_NODISCARD constexpr auto uses_allocator_construction_args(
const _Alloc& _Al, piecewise_construct_t, _Tuple1&& _Tup1, _Tuple2&& _Tup2) noexcept {
return _STD make_tuple(piecewise_construct,
@ -2363,7 +2366,7 @@ _NODISCARD constexpr auto uses_allocator_construction_args(
_STD forward<_Tuple2>(_Tup2)));
}
_EXPORT_STD template <class _Ty, class _Alloc, enable_if_t<_Is_cv_pair<_Ty>, int> /* = 0 */>
_EXPORT_STD template <_Cv_std_pair _Ty, class _Alloc>
_NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al) noexcept {
// equivalent to
// return _STD uses_allocator_construction_args<_Ty>(_Al, piecewise_construct, tuple<>{}, tuple<>{});
@ -2371,7 +2374,7 @@ _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al) no
_STD uses_allocator_construction_args<typename _Ty::second_type>(_Al));
}
_EXPORT_STD template <class _Ty, class _Alloc, class _Uty1, class _Uty2, enable_if_t<_Is_cv_pair<_Ty>, int> /* = 0 */>
_EXPORT_STD template <_Cv_std_pair _Ty, class _Alloc, class _Uty1, class _Uty2>
_NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, _Uty1&& _Val1, _Uty2&& _Val2) noexcept {
// equivalent to
// return _STD uses_allocator_construction_args<_Ty>(_Al, piecewise_construct,
@ -2382,7 +2385,7 @@ _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, _U
}
#if _HAS_CXX23
_EXPORT_STD template <class _Ty, class _Alloc, class _Uty1, class _Uty2, enable_if_t<_Is_cv_pair<_Ty>, int> /* = 0 */>
_EXPORT_STD template <_Cv_std_pair _Ty, class _Alloc, class _Uty1, class _Uty2>
_NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, pair<_Uty1, _Uty2>& _Pair) noexcept {
// equivalent to
// return _STD uses_allocator_construction_args<_Ty>(_Al, piecewise_construct,
@ -2393,7 +2396,7 @@ _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, pa
}
#endif // _HAS_CXX23
_EXPORT_STD template <class _Ty, class _Alloc, class _Uty1, class _Uty2, enable_if_t<_Is_cv_pair<_Ty>, int> /* = 0 */>
_EXPORT_STD template <_Cv_std_pair _Ty, class _Alloc, class _Uty1, class _Uty2>
_NODISCARD constexpr auto uses_allocator_construction_args(
const _Alloc& _Al, const pair<_Uty1, _Uty2>& _Pair) noexcept {
// equivalent to
@ -2404,7 +2407,7 @@ _NODISCARD constexpr auto uses_allocator_construction_args(
_STD uses_allocator_construction_args<typename _Ty::second_type>(_Al, _Pair.second));
}
_EXPORT_STD template <class _Ty, class _Alloc, class _Uty1, class _Uty2, enable_if_t<_Is_cv_pair<_Ty>, int> /* = 0 */>
_EXPORT_STD template <_Cv_std_pair _Ty, class _Alloc, class _Uty1, class _Uty2>
_NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, pair<_Uty1, _Uty2>&& _Pair) noexcept {
// equivalent to
// return _STD uses_allocator_construction_args<_Ty>(_Al, piecewise_construct,
@ -2415,7 +2418,7 @@ _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, pa
}
#if _HAS_CXX23
_EXPORT_STD template <class _Ty, class _Alloc, class _Uty1, class _Uty2, enable_if_t<_Is_cv_pair<_Ty>, int> /* = 0 */>
_EXPORT_STD template <_Cv_std_pair _Ty, class _Alloc, class _Uty1, class _Uty2>
_NODISCARD constexpr auto uses_allocator_construction_args(
const _Alloc& _Al, const pair<_Uty1, _Uty2>&& _Pair) noexcept {
// equivalent to
@ -2427,13 +2430,7 @@ _NODISCARD constexpr auto uses_allocator_construction_args(
}
#endif // _HAS_CXX23
#if _HAS_CXX23
_EXPORT_STD template <class _Ty, class _Alloc, class _Uty>
requires _Is_cv_pair<_Ty> && (_Pair_like<_Uty> || !_Is_deducible_as_pair<_Uty&>)
#else // ^^^ _HAS_CXX23 / !_HAS_CXX23 vvv
_EXPORT_STD template <class _Ty, class _Alloc, class _Uty,
enable_if_t<_Is_cv_pair<_Ty> && !_Is_deducible_as_pair<_Uty&>, int> /* = 0 */>
#endif // ^^^ !_HAS_CXX23 ^^^
_EXPORT_STD template <_Cv_std_pair _Ty, class _Alloc, _Usable_for_pair_like_overload _Uty>
_NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, _Uty&& _Ux) noexcept {
#if _HAS_CXX23
if constexpr (_Pair_like<_Uty> && !_Is_subrange_v<remove_cvref_t<_Uty>>) {

Просмотреть файл

@ -381,15 +381,10 @@ struct _Get_rebind_alias<_Ty, _Other, void_t<typename _Ty::template rebind<_Othe
};
#if _HAS_CXX20
#if defined(__clang__) || defined(__EDG__) // TRANSITION, DevCom-1691516
// per LWG-3888
_EXPORT_STD template <class _Ty, class... _Types,
class = void_t<decltype(::new(static_cast<void*>(_STD declval<_Ty*>())) _Ty(_STD declval<_Types>()...))>>
#else // ^^^ no workaround / workaround vvv
// per LWG-3888
_EXPORT_STD template <class _Ty, class... _Types,
void_t<decltype(::new(static_cast<void*>(_STD declval<_Ty*>())) _Ty(_STD declval<_Types>()...))>* = nullptr>
#endif // ^^^ workaround ^^^
_EXPORT_STD template <class _Ty, class... _Types>
requires requires(_Ty* _Location, _Types&&... _Args) {
::new (static_cast<void*>(_Location)) _Ty(_STD forward<_Types>(_Args)...); // per LWG-3888
}
constexpr _Ty* construct_at(_Ty* const _Location, _Types&&... _Args) noexcept(
noexcept(::new(static_cast<void*>(_Location)) _Ty(_STD forward<_Types>(_Args)...))) /* strengthened */ {
_MSVC_CONSTEXPR return ::new (static_cast<void*>(_Location)) _Ty(_STD forward<_Types>(_Args)...);
@ -711,8 +706,8 @@ _NODISCARD constexpr auto _Pass_fn(_Fn& _Func) noexcept {
}
#if _HAS_CXX23
_EXPORT_STD template <class _Result_type, class _Callable, class... _Types,
enable_if_t<is_invocable_r_v<_Result_type, _Callable, _Types...>, int> = 0>
_EXPORT_STD template <class _Result_type, class _Callable, class... _Types>
requires is_invocable_r_v<_Result_type, _Callable, _Types...>
_NODISCARD constexpr _Result_type invoke_r(_Callable&& _Obj, _Types&&... _Args) noexcept(
is_nothrow_invocable_r_v<_Result_type, _Callable, _Types...>) {
if constexpr (is_void_v<_Result_type>) {
@ -4330,7 +4325,8 @@ public:
_Verify_range(_First._Current, _Last._Get_current());
}
#if _HAS_CXX20
template <sentinel_for<_Iter> _Sent, enable_if_t<_Range_verifiable_v<_Iter, _Sent>, int> = 0>
template <sentinel_for<_Iter> _Sent>
requires _Range_verifiable_v<_Iter, _Sent>
friend constexpr void _Verify_range(const move_iterator& _First, const move_sentinel<_Sent>& _Last) noexcept {
_Verify_range(_First._Current, _Last._Get_last());
}