diff --git a/stl/inc/deque b/stl/inc/deque index 905eb16213..2756ad3a20 100644 --- a/stl/inc/deque +++ b/stl/inc/deque @@ -1777,8 +1777,7 @@ deque(_Iter, _Iter, _Alloc = _Alloc()) -> deque<_Iter_value_t<_Iter>, _Alloc>; #endif // _HAS_CXX17 #if _HAS_CXX23 -template <_RANGES input_range _Rng, class _Alloc = allocator<_RANGES range_value_t<_Rng>>, - enable_if_t<_Is_allocator<_Alloc>::value, int> = 0> +template <_RANGES input_range _Rng, _Allocator_for_container _Alloc = allocator<_RANGES range_value_t<_Rng>>> deque(from_range_t, _Rng&&, _Alloc = _Alloc()) -> deque<_RANGES range_value_t<_Rng>, _Alloc>; #endif // _HAS_CXX23 diff --git a/stl/inc/forward_list b/stl/inc/forward_list index 433452691e..afcdbf9925 100644 --- a/stl/inc/forward_list +++ b/stl/inc/forward_list @@ -1561,8 +1561,7 @@ forward_list(_Iter, _Iter, _Alloc = _Alloc()) -> forward_list<_Iter_value_t<_Ite #endif // _HAS_CXX17 #if _HAS_CXX23 -template <_RANGES input_range _Rng, class _Alloc = allocator<_RANGES range_value_t<_Rng>>, - enable_if_t<_Is_allocator<_Alloc>::value, int> = 0> +template <_RANGES input_range _Rng, _Allocator_for_container _Alloc = allocator<_RANGES range_value_t<_Rng>>> forward_list(from_range_t, _Rng&&, _Alloc = _Alloc()) -> forward_list<_RANGES range_value_t<_Rng>, _Alloc>; #endif // _HAS_CXX23 diff --git a/stl/inc/list b/stl/inc/list index ccc49ff243..84160362f4 100644 --- a/stl/inc/list +++ b/stl/inc/list @@ -1864,8 +1864,7 @@ list(_Iter, _Iter, _Alloc = _Alloc()) -> list<_Iter_value_t<_Iter>, _Alloc>; #endif // _HAS_CXX17 #if _HAS_CXX23 -template <_RANGES input_range _Rng, class _Alloc = allocator<_RANGES range_value_t<_Rng>>, - enable_if_t<_Is_allocator<_Alloc>::value, int> = 0> +template <_RANGES input_range _Rng, _Allocator_for_container _Alloc = allocator<_RANGES range_value_t<_Rng>>> list(from_range_t, _Rng&&, _Alloc = _Alloc()) -> list<_RANGES range_value_t<_Rng>, _Alloc>; #endif // _HAS_CXX23 diff --git a/stl/inc/map b/stl/inc/map index a8b764723f..ca69f1acf2 100644 --- a/stl/inc/map +++ b/stl/inc/map @@ -385,12 +385,12 @@ map(initializer_list>, _Alloc) -> map<_Kty, _Ty, less<_Kty>, _Al #if _HAS_CXX23 template <_RANGES input_range _Rng, class _Pr = less<_Range_key_type<_Rng>>, - class _Alloc = allocator<_Range_to_alloc_type<_Rng>>, - enable_if_t>, _Is_allocator<_Alloc>>, int> = 0> + class _Alloc = allocator<_Range_to_alloc_type<_Rng>>> + requires (!_Allocator_for_container<_Pr>) && _Allocator_for_container<_Alloc> map(from_range_t, _Rng&&, _Pr = _Pr(), _Alloc = _Alloc()) -> map<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Pr, _Alloc>; -template <_RANGES input_range _Rng, class _Alloc, enable_if_t<_Is_allocator<_Alloc>::value, int> = 0> +template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> map(from_range_t, _Rng&&, _Alloc) -> map<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, less<_Range_key_type<_Rng>>, _Alloc>; #endif // _HAS_CXX23 @@ -616,12 +616,12 @@ multimap(initializer_list>, _Alloc) -> multimap<_Kty, _Ty, less< #if _HAS_CXX23 template <_RANGES input_range _Rng, class _Pr = less<_Range_key_type<_Rng>>, - class _Alloc = allocator<_Range_to_alloc_type<_Rng>>, - enable_if_t>, _Is_allocator<_Alloc>>, int> = 0> + class _Alloc = allocator<_Range_to_alloc_type<_Rng>>> + requires (!_Allocator_for_container<_Pr>) && _Allocator_for_container<_Alloc> multimap(from_range_t, _Rng&&, _Pr = _Pr(), _Alloc = _Alloc()) -> multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Pr, _Alloc>; -template <_RANGES input_range _Rng, class _Alloc, enable_if_t<_Is_allocator<_Alloc>::value, int> = 0> +template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> multimap(from_range_t, _Rng&&, _Alloc) -> multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, less<_Range_key_type<_Rng>>, _Alloc>; #endif // _HAS_CXX23 diff --git a/stl/inc/queue b/stl/inc/queue index 847ddc5e2e..783de1834d 100644 --- a/stl/inc/queue +++ b/stl/inc/queue @@ -44,7 +44,7 @@ public: : c(_STD move(_Cont)) {} #if _HAS_CXX23 - template , int> = 0> + template <_Iterator_for_container _InIt> queue(_InIt _First, _InIt _Last) noexcept(is_nothrow_constructible_v<_Container, _InIt, _InIt>) // strengthened : c(_STD move(_First), _STD move(_Last)) {} @@ -73,8 +73,8 @@ public: : c(_STD move(_Right.c), _Al) {} #if _HAS_CXX23 - template , uses_allocator<_Container, _Alloc>>, int> = 0> + template <_Iterator_for_container _InIt, class _Alloc> + requires uses_allocator_v<_Container, _Alloc> queue(_InIt _First, _InIt _Last, const _Alloc& _Al) noexcept( is_nothrow_constructible_v<_Container, _InIt, _InIt, const _Alloc&>) // strengthened : c(_STD move(_First), _STD move(_Last), _Al) {} @@ -163,12 +163,10 @@ queue(_Container, _Alloc) -> queue; #endif // _HAS_CXX17 #if _HAS_CXX23 -template >, - enable_if_t, _Is_allocator<_Alloc>>, int> = 0> +template <_Iterator_for_container _InIt, _Allocator_for_container _Alloc = allocator<_Iter_value_t<_InIt>>> queue(_InIt, _InIt, _Alloc = _Alloc()) -> queue<_Iter_value_t<_InIt>, deque<_Iter_value_t<_InIt>, _Alloc>>; -template <_RANGES input_range _Rng, class _Alloc = allocator<_RANGES range_value_t<_Rng>>, - enable_if_t<_Is_allocator<_Alloc>::value, int> = 0> +template <_RANGES input_range _Rng, _Allocator_for_container _Alloc = allocator<_RANGES range_value_t<_Rng>>> queue(from_range_t, _Rng&&, _Alloc = _Alloc()) -> queue<_RANGES range_value_t<_Rng>, deque<_RANGES range_value_t<_Rng>, _Alloc>>; #endif // _HAS_CXX23 @@ -339,15 +337,15 @@ public: } #if _HAS_CXX23 - template <_Container_compatible_range<_Ty> _Rng, class _Alloc, - enable_if_t, int> = 0> + template <_Container_compatible_range<_Ty> _Rng, class _Alloc> + requires uses_allocator_v<_Container, _Alloc> priority_queue(from_range_t, _Rng&& _Range, const _Pr& _Pred, const _Alloc& _Al) : c(_RANGES to<_Container>(_STD forward<_Rng>(_Range), _Al)), comp(_Pred) { _Make_heap(); } - template <_Container_compatible_range<_Ty> _Rng, class _Alloc, - enable_if_t, int> = 0> + template <_Container_compatible_range<_Ty> _Rng, class _Alloc> + requires uses_allocator_v<_Container, _Alloc> priority_queue(from_range_t, _Rng&& _Range, const _Alloc& _Al) : c(_RANGES to<_Container>(_STD forward<_Rng>(_Range), _Al)), comp() { _Make_heap(); @@ -460,17 +458,17 @@ priority_queue(_Iter, _Iter, _Compare, _Container, _Alloc) -> priority_queue; #if _HAS_CXX23 -template <_RANGES input_range _Rng, class _Pr = less<_RANGES range_value_t<_Rng>>, - enable_if_t::value, int> = 0> +template <_RANGES input_range _Rng, class _Pr = less<_RANGES range_value_t<_Rng>>> + requires (!_Allocator_for_container<_Pr>) priority_queue(from_range_t, _Rng&&, _Pr = _Pr()) -> priority_queue<_RANGES range_value_t<_Rng>, vector<_RANGES range_value_t<_Rng>>, _Pr>; -template <_RANGES input_range _Rng, class _Pr, class _Alloc, - enable_if_t>, _Is_allocator<_Alloc>>, int> = 0> +template <_RANGES input_range _Rng, class _Pr, class _Alloc> + requires (!_Allocator_for_container<_Pr>) && _Allocator_for_container<_Alloc> priority_queue(from_range_t, _Rng&&, _Pr, _Alloc) -> priority_queue<_RANGES range_value_t<_Rng>, vector<_RANGES range_value_t<_Rng>, _Alloc>, _Pr>; -template <_RANGES input_range _Rng, class _Alloc, enable_if_t<_Is_allocator<_Alloc>::value, int> = 0> +template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> priority_queue(from_range_t, _Rng&&, _Alloc) -> priority_queue<_RANGES range_value_t<_Rng>, vector<_RANGES range_value_t<_Rng>, _Alloc>>; #endif // _HAS_CXX23 diff --git a/stl/inc/set b/stl/inc/set index 08a60f028b..f55d95446c 100644 --- a/stl/inc/set +++ b/stl/inc/set @@ -196,11 +196,11 @@ set(initializer_list<_Kty>, _Alloc) -> set<_Kty, less<_Kty>, _Alloc>; #if _HAS_CXX23 template <_RANGES input_range _Rng, class _Pr = less<_RANGES range_value_t<_Rng>>, - class _Alloc = allocator<_RANGES range_value_t<_Rng>>, - enable_if_t>, _Is_allocator<_Alloc>>, int> = 0> + class _Alloc = allocator<_RANGES range_value_t<_Rng>>> + requires (!_Allocator_for_container<_Pr>) && _Allocator_for_container<_Alloc> set(from_range_t, _Rng&&, _Pr = _Pr(), _Alloc = _Alloc()) -> set<_RANGES range_value_t<_Rng>, _Pr, _Alloc>; -template <_RANGES input_range _Rng, class _Alloc, enable_if_t<_Is_allocator<_Alloc>::value, int> = 0> +template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> set(from_range_t, _Rng&&, _Alloc) -> set<_RANGES range_value_t<_Rng>, less<_RANGES range_value_t<_Rng>>, _Alloc>; #endif // _HAS_CXX23 #endif // _HAS_CXX17 @@ -410,11 +410,11 @@ multiset(initializer_list<_Kty>, _Alloc) -> multiset<_Kty, less<_Kty>, _Alloc>; #if _HAS_CXX23 template <_RANGES input_range _Rng, class _Pr = less<_RANGES range_value_t<_Rng>>, - class _Alloc = allocator<_RANGES range_value_t<_Rng>>, - enable_if_t>, _Is_allocator<_Alloc>>, int> = 0> + class _Alloc = allocator<_RANGES range_value_t<_Rng>>> + requires (!_Allocator_for_container<_Pr>) && _Allocator_for_container<_Alloc> multiset(from_range_t, _Rng&&, _Pr = _Pr(), _Alloc = _Alloc()) -> multiset<_RANGES range_value_t<_Rng>, _Pr, _Alloc>; -template <_RANGES input_range _Rng, class _Alloc, enable_if_t<_Is_allocator<_Alloc>::value, int> = 0> +template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> multiset(from_range_t, _Rng&&, _Alloc) -> multiset<_RANGES range_value_t<_Rng>, less<_RANGES range_value_t<_Rng>>, _Alloc>; #endif // _HAS_CXX23 diff --git a/stl/inc/sstream b/stl/inc/sstream index 4d44166fa3..338f3f41cd 100644 --- a/stl/inc/sstream +++ b/stl/inc/sstream @@ -230,8 +230,7 @@ public: } #if _HAS_CXX20 - template - requires _Is_allocator<_Alloc2>::value + template <_Allocator_for_container _Alloc2> _NODISCARD basic_string<_Elem, _Traits, _Alloc2> str(const _Alloc2& _Al) const { return basic_string<_Elem, _Traits, _Alloc2>{view(), _Al}; } @@ -694,8 +693,7 @@ public: } #if _HAS_CXX20 - template - requires _Is_allocator<_Alloc2>::value + template <_Allocator_for_container _Alloc2> _NODISCARD basic_string<_Elem, _Traits, _Alloc2> str(const _Alloc2& _Al) const { return _Stringbuffer.str(_Al); } @@ -814,7 +812,7 @@ public: } #if _HAS_CXX20 - template ::value, int> = 0> + template <_Allocator_for_container _Alloc2> _NODISCARD basic_string<_Elem, _Traits, _Alloc2> str(const _Alloc2& _Al) const { return _Stringbuffer.str(_Al); } @@ -939,7 +937,7 @@ public: } #if _HAS_CXX20 - template ::value, int> = 0> + template <_Allocator_for_container _Alloc2> _NODISCARD basic_string<_Elem, _Traits, _Alloc2> str(const _Alloc2& _Al) const { return _Stringbuffer.str(_Al); } diff --git a/stl/inc/stack b/stl/inc/stack index 582e2873fe..002e541a0c 100644 --- a/stl/inc/stack +++ b/stl/inc/stack @@ -42,7 +42,7 @@ public: : c(_STD move(_Cont)) {} #if _HAS_CXX23 - template , int> = 0> + template <_Iterator_for_container _InIt> stack(_InIt _First, _InIt _Last) noexcept(is_nothrow_constructible_v<_Container, _InIt, _InIt>) // strengthened : c(_STD move(_First), _STD move(_Last)) {} @@ -71,8 +71,8 @@ public: : c(_STD move(_Right.c), _Al) {} #if _HAS_CXX23 - template , uses_allocator<_Container, _Alloc>>, int> = 0> + template <_Iterator_for_container _InIt, class _Alloc> + requires uses_allocator_v<_Container, _Alloc> stack(_InIt _First, _InIt _Last, const _Alloc& _Al) noexcept( is_nothrow_constructible_v<_Container, _InIt, _InIt, const _Alloc&>) // strengthened : c(_STD move(_First), _STD move(_Last), _Al) {} @@ -153,14 +153,13 @@ stack(_Container, _Alloc) -> stack; #endif // _HAS_CXX17 #if _HAS_CXX23 -template >, - enable_if_t, _Is_allocator<_Alloc>>, int> = 0> +template <_Iterator_for_container _InIt, _Allocator_for_container _Alloc = allocator<_Iter_value_t<_InIt>>> stack(_InIt, _InIt, _Alloc = _Alloc()) -> stack<_Iter_value_t<_InIt>, deque<_Iter_value_t<_InIt>, _Alloc>>; template <_RANGES input_range _Rng> stack(from_range_t, _Rng&&) -> stack<_RANGES range_value_t<_Rng>>; -template <_RANGES input_range _Rng, class _Alloc, enable_if_t<_Is_allocator<_Alloc>::value, int> = 0> +template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> stack(from_range_t, _Rng&&, _Alloc) -> stack<_RANGES range_value_t<_Rng>, deque<_RANGES range_value_t<_Rng>, _Alloc>>; #endif // _HAS_CXX23 diff --git a/stl/inc/unordered_map b/stl/inc/unordered_map index bff9e8d6a2..c2e5bd0454 100644 --- a/stl/inc/unordered_map +++ b/stl/inc/unordered_map @@ -498,21 +498,20 @@ unordered_map(initializer_list>, _Guide_size_type_t<_Alloc>, _Ha #if _HAS_CXX23 template <_RANGES input_range _Rng, class _Hasher = hash<_Range_key_type<_Rng>>, - class _Keyeq = equal_to<_Range_key_type<_Rng>>, class _Alloc = allocator<_Range_to_alloc_type<_Rng>>, - enable_if_t, negation<_Is_allocator<_Keyeq>>, _Is_allocator<_Alloc>>, int> = 0> + class _Keyeq = equal_to<_Range_key_type<_Rng>>, class _Alloc = allocator<_Range_to_alloc_type<_Rng>>> + requires _Hasher_for_container<_Hasher> && (!_Allocator_for_container<_Keyeq>) && _Allocator_for_container<_Alloc> unordered_map(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc> = 0, _Hasher = _Hasher(), _Keyeq = _Keyeq(), _Alloc = _Alloc()) -> unordered_map<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Hasher, _Keyeq, _Alloc>; -template <_RANGES input_range _Rng, class _Alloc, enable_if_t<_Is_allocator<_Alloc>::value, int> = 0> +template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> unordered_map(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, _Alloc) -> unordered_map<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, hash<_Range_key_type<_Rng>>, equal_to<_Range_key_type<_Rng>>, _Alloc>; -template <_RANGES input_range _Rng, class _Alloc, enable_if_t<_Is_allocator<_Alloc>::value, int> = 0> +template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> unordered_map(from_range_t, _Rng&&, _Alloc) -> unordered_map<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, hash<_Range_key_type<_Rng>>, equal_to<_Range_key_type<_Rng>>, _Alloc>; -template <_RANGES input_range _Rng, class _Hasher, class _Alloc, - enable_if_t, _Is_allocator<_Alloc>>, int> = 0> +template <_RANGES input_range _Rng, _Hasher_for_container _Hasher, _Allocator_for_container _Alloc> unordered_map(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, _Hasher, _Alloc) -> unordered_map<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Hasher, equal_to<_Range_key_type<_Rng>>, _Alloc>; #endif // _HAS_CXX23 @@ -868,22 +867,21 @@ unordered_multimap(initializer_list>, _Guide_size_type_t<_Alloc> #if _HAS_CXX23 template <_RANGES input_range _Rng, class _Hasher = hash<_Range_key_type<_Rng>>, - class _Keyeq = equal_to<_Range_key_type<_Rng>>, class _Alloc = allocator<_Range_to_alloc_type<_Rng>>, - enable_if_t, negation<_Is_allocator<_Keyeq>>, _Is_allocator<_Alloc>>, int> = 0> + class _Keyeq = equal_to<_Range_key_type<_Rng>>, class _Alloc = allocator<_Range_to_alloc_type<_Rng>>> + requires _Hasher_for_container<_Hasher> && (!_Allocator_for_container<_Keyeq>) && _Allocator_for_container<_Alloc> unordered_multimap(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc> = 0, _Hasher = _Hasher(), _Keyeq = _Keyeq(), _Alloc = _Alloc()) -> unordered_multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Hasher, _Keyeq, _Alloc>; -template <_RANGES input_range _Rng, class _Alloc, enable_if_t<_Is_allocator<_Alloc>::value, int> = 0> +template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> unordered_multimap(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, _Alloc) -> unordered_multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, hash<_Range_key_type<_Rng>>, equal_to<_Range_key_type<_Rng>>, _Alloc>; -template <_RANGES input_range _Rng, class _Alloc, enable_if_t<_Is_allocator<_Alloc>::value, int> = 0> +template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> unordered_multimap(from_range_t, _Rng&&, _Alloc) -> unordered_multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, hash<_Range_key_type<_Rng>>, equal_to<_Range_key_type<_Rng>>, _Alloc>; -template <_RANGES input_range _Rng, class _Hasher, class _Alloc, - enable_if_t, _Is_allocator<_Alloc>>, int> = 0> +template <_RANGES input_range _Rng, _Hasher_for_container _Hasher, _Allocator_for_container _Alloc> unordered_multimap(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, _Hasher, _Alloc) -> unordered_multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Hasher, equal_to<_Range_key_type<_Rng>>, _Alloc>; diff --git a/stl/inc/unordered_set b/stl/inc/unordered_set index d9a390c256..0a07b874e7 100644 --- a/stl/inc/unordered_set +++ b/stl/inc/unordered_set @@ -354,21 +354,20 @@ unordered_set(initializer_list<_Kty>, _Guide_size_type_t<_Alloc>, _Hasher, _Allo #if _HAS_CXX23 template <_RANGES input_range _Rng, class _Hasher = hash<_RANGES range_value_t<_Rng>>, - class _Keyeq = equal_to<_RANGES range_value_t<_Rng>>, class _Alloc = allocator<_RANGES range_value_t<_Rng>>, - enable_if_t, negation<_Is_allocator<_Keyeq>>, _Is_allocator<_Alloc>>, int> = 0> + class _Keyeq = equal_to<_RANGES range_value_t<_Rng>>, class _Alloc = allocator<_RANGES range_value_t<_Rng>>> + requires _Hasher_for_container<_Hasher> && (!_Allocator_for_container<_Keyeq>) && _Allocator_for_container<_Alloc> unordered_set(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc> = 0, _Hasher = _Hasher(), _Keyeq = _Keyeq(), _Alloc = _Alloc()) -> unordered_set<_RANGES range_value_t<_Rng>, _Hasher, _Keyeq, _Alloc>; -template <_RANGES input_range _Rng, class _Alloc, enable_if_t<_Is_allocator<_Alloc>::value, int> = 0> +template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> unordered_set(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, _Alloc) -> unordered_set<_RANGES range_value_t<_Rng>, hash<_RANGES range_value_t<_Rng>>, equal_to<_RANGES range_value_t<_Rng>>, _Alloc>; -template <_RANGES input_range _Rng, class _Alloc, enable_if_t<_Is_allocator<_Alloc>::value, int> = 0> +template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> unordered_set(from_range_t, _Rng&&, _Alloc) -> unordered_set<_RANGES range_value_t<_Rng>, hash<_RANGES range_value_t<_Rng>>, equal_to<_RANGES range_value_t<_Rng>>, _Alloc>; -template <_RANGES input_range _Rng, class _Hasher, class _Alloc, - enable_if_t, _Is_allocator<_Alloc>>, int> = 0> +template <_RANGES input_range _Rng, _Hasher_for_container _Hasher, _Allocator_for_container _Alloc> unordered_set(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, _Hasher, _Alloc) -> unordered_set<_RANGES range_value_t<_Rng>, _Hasher, equal_to<_RANGES range_value_t<_Rng>>, _Alloc>; #endif // _HAS_CXX23 @@ -697,22 +696,21 @@ unordered_multiset(initializer_list<_Kty>, _Guide_size_type_t<_Alloc>, _Hasher, #if _HAS_CXX23 template <_RANGES input_range _Rng, class _Hasher = hash<_RANGES range_value_t<_Rng>>, - class _Keyeq = equal_to<_RANGES range_value_t<_Rng>>, class _Alloc = allocator<_RANGES range_value_t<_Rng>>, - enable_if_t, negation<_Is_allocator<_Keyeq>>, _Is_allocator<_Alloc>>, int> = 0> + class _Keyeq = equal_to<_RANGES range_value_t<_Rng>>, class _Alloc = allocator<_RANGES range_value_t<_Rng>>> + requires _Hasher_for_container<_Hasher> && (!_Allocator_for_container<_Keyeq>) && _Allocator_for_container<_Alloc> unordered_multiset(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc> = 0, _Hasher = _Hasher(), _Keyeq = _Keyeq(), _Alloc = _Alloc()) -> unordered_multiset<_RANGES range_value_t<_Rng>, _Hasher, _Keyeq, _Alloc>; -template <_RANGES input_range _Rng, class _Alloc, enable_if_t<_Is_allocator<_Alloc>::value, int> = 0> +template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> unordered_multiset(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, _Alloc) -> unordered_multiset<_RANGES range_value_t<_Rng>, hash<_RANGES range_value_t<_Rng>>, equal_to<_RANGES range_value_t<_Rng>>, _Alloc>; -template <_RANGES input_range _Rng, class _Alloc, enable_if_t<_Is_allocator<_Alloc>::value, int> = 0> +template <_RANGES input_range _Rng, _Allocator_for_container _Alloc> unordered_multiset(from_range_t, _Rng&&, _Alloc) -> unordered_multiset<_RANGES range_value_t<_Rng>, hash<_RANGES range_value_t<_Rng>>, equal_to<_RANGES range_value_t<_Rng>>, _Alloc>; -template <_RANGES input_range _Rng, class _Hasher, class _Alloc, - enable_if_t, _Is_allocator<_Alloc>>, int> = 0> +template <_RANGES input_range _Rng, _Hasher_for_container _Hasher, _Allocator_for_container _Alloc> unordered_multiset(from_range_t, _Rng&&, _Guide_size_type_t<_Alloc>, _Hasher, _Alloc) -> unordered_multiset<_RANGES range_value_t<_Rng>, _Hasher, equal_to<_RANGES range_value_t<_Rng>>, _Alloc>; #endif // _HAS_CXX23 diff --git a/stl/inc/vector b/stl/inc/vector index e2d7e0cc60..f6d6cf4302 100644 --- a/stl/inc/vector +++ b/stl/inc/vector @@ -2208,8 +2208,7 @@ vector(_Iter, _Iter, _Alloc = _Alloc()) -> vector<_Iter_value_t<_Iter>, _Alloc>; #endif // _HAS_CXX17 #if _HAS_CXX23 -template <_RANGES input_range _Rng, class _Alloc = allocator<_RANGES range_value_t<_Rng>>, - enable_if_t<_Is_allocator<_Alloc>::value, int> = 0> +template <_RANGES input_range _Rng, _Allocator_for_container _Alloc = allocator<_RANGES range_value_t<_Rng>>> vector(from_range_t, _Rng&&, _Alloc = _Alloc()) -> vector<_RANGES range_value_t<_Rng>, _Alloc>; #endif // _HAS_CXX23 diff --git a/stl/inc/xhash b/stl/inc/xhash index 20f884eefa..810fb00540 100644 --- a/stl/inc/xhash +++ b/stl/inc/xhash @@ -93,7 +93,7 @@ _STD_END #endif // _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS _STD_BEGIN -template +template struct _Uhash_choose_transparency { // transparency selector for non-transparent hashed containers template @@ -102,8 +102,8 @@ struct _Uhash_choose_transparency { #if _HAS_CXX20 template -struct _Uhash_choose_transparency<_Kty, _Hasher, _Keyeq, - enable_if_t, _Is_transparent<_Keyeq>>>> { + requires _Is_transparent_v<_Hasher> && _Is_transparent_v<_Keyeq> +struct _Uhash_choose_transparency<_Kty, _Hasher, _Keyeq> { // transparency selector for transparent hashed containers template using _Deduce_key = const _Keyty&; @@ -1137,8 +1137,8 @@ public: } #if _HAS_CXX23 - template , int> = 0> + template + requires (_Traits::template _Supports_transparency<_Hash, _Kx>) size_type erase(_Kx&& _Keyval) noexcept(noexcept(_Erase(_Keyval))) /* strengthened */ { return _Erase(_Keyval); } @@ -1347,8 +1347,8 @@ public: } #if _HAS_CXX23 - template , int> = 0> + template + requires (_Traits::template _Supports_transparency<_Hash, _Kx>) node_type extract(_Kx&& _Keyval) { const auto _Ptr = _Extract(_Keyval); if (!_Ptr) { @@ -1967,9 +1967,17 @@ protected: }; #if _HAS_CXX17 -// For constraining deduction guides (N4950 [unord.req.general]/243.3) +// For constraining deduction guides (N4981 [unord.req.general]/248.3) +#if _HAS_CXX23 +template +concept _Hasher_for_container = !integral<_Hasher> && !_Allocator_for_container<_Hasher>; + +template +using _Is_hasher = bool_constant<_Hasher_for_container<_Hasher>>; +#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv template using _Is_hasher = negation, _Is_allocator<_Hasher>>>; +#endif // ^^^ !_HAS_CXX20 ^^^ #endif // _HAS_CXX17 template diff --git a/stl/inc/xstring b/stl/inc/xstring index b048c1f2f4..ed4026cff2 100644 --- a/stl/inc/xstring +++ b/stl/inc/xstring @@ -3106,8 +3106,7 @@ basic_string(basic_string_view<_Elem, _Traits>, _Guide_size_type_t<_Alloc>, _Gui const _Alloc& = _Alloc()) -> basic_string<_Elem, _Traits, _Alloc>; #if _HAS_CXX23 -template <_RANGES input_range _Rng, class _Alloc = allocator<_RANGES range_value_t<_Rng>>, - enable_if_t<_Is_allocator<_Alloc>::value, int> = 0> +template <_RANGES input_range _Rng, _Allocator_for_container _Alloc = allocator<_RANGES range_value_t<_Rng>>> basic_string(from_range_t, _Rng&&, _Alloc = _Alloc()) -> basic_string<_RANGES range_value_t<_Rng>, char_traits<_RANGES range_value_t<_Rng>>, _Alloc>; #endif // _HAS_CXX23 diff --git a/stl/inc/xtree b/stl/inc/xtree index 5d970ede45..5b7c60bdbe 100644 --- a/stl/inc/xtree +++ b/stl/inc/xtree @@ -1335,10 +1335,9 @@ public: } #if _HAS_CXX23 - template , - negation, is_convertible<_Kx, iterator>>>>, - int> = 0> + template + requires _Is_transparent_v + && (!is_convertible_v<_Kx, const_iterator>) && (!is_convertible_v<_Kx, iterator>) size_type erase(_Kx&& _Keyval) noexcept(noexcept(_Eqrange(_Keyval))) /* strengthened */ { return _Erase(_Eqrange(_Keyval)); } @@ -1390,7 +1389,8 @@ public: return _Lower_bound_duplicate(_Find_lower_bound(_Keyval)._Bound, _Keyval); } - template , int> = 0> + template + requires _Is_transparent_v _NODISCARD bool contains(const _Other& _Keyval) const { return _Lower_bound_duplicate(_Find_lower_bound(_Keyval)._Bound, _Keyval); } @@ -1743,10 +1743,9 @@ public: } #if _HAS_CXX23 - template , - negation, is_convertible<_Kx, iterator>>>>, - int> = 0> + template + requires _Is_transparent_v + && (!is_convertible_v<_Kx, const_iterator>) && (!is_convertible_v<_Kx, iterator>) node_type extract(_Kx&& _Keyval) { const const_iterator _Where = find(_Keyval); if (_Where == end()) { diff --git a/stl/inc/xutility b/stl/inc/xutility index 72b733a834..e9197c5cf1 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -1205,6 +1205,16 @@ using _Common_diff_t = common_type_t<_Iter_diff_t<_Iters>...>; template using _Iter_cat_t = typename iterator_traits<_Iter>::iterator_category; +#if _HAS_CXX20 +template +concept _Iterator_for_container = requires { typename _Iter_cat_t<_Ty>; }; + +template +constexpr bool _Is_iterator_v = _Iterator_for_container<_Ty>; + +template +struct _Is_iterator : bool_constant<_Iterator_for_container<_Ty>> {}; +#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv template constexpr bool _Is_iterator_v = false; @@ -1213,6 +1223,7 @@ constexpr bool _Is_iterator_v<_Ty, void_t<_Iter_cat_t<_Ty>>> = true; template struct _Is_iterator : bool_constant<_Is_iterator_v<_Ty>> {}; +#endif // ^^^ !_HAS_CXX20 ^^^ template constexpr bool _Is_cpp17_input_iter_v = is_convertible_v<_Iter_cat_t<_Iter>, input_iterator_tag>; @@ -1423,6 +1434,17 @@ constexpr void _Seek_wrapped(_Iter& _It, _UIter&& _UIt) { } #if _HAS_CXX17 +#if _HAS_CXX20 +// detects whether _Ty resembles an allocator, N4981 [container.reqmts]/69 +template +concept _Allocator_for_container = requires(_Ty& _Alloc) { + typename _Ty::value_type; + _Alloc.deallocate(_Alloc.allocate(size_t{1}), size_t{1}); +}; + +template +struct _Is_allocator : bool_constant<_Allocator_for_container<_Ty>> {}; +#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv template struct _Is_allocator : false_type {}; // selected when _Ty can't possibly be an allocator @@ -1430,6 +1452,7 @@ template struct _Is_allocator<_Ty, void_t().deallocate( _STD declval<_Ty&>().allocate(size_t{1}), size_t{1}))>> : true_type {}; // selected when _Ty resembles an allocator, N4950 [container.reqmts]/69 +#endif // ^^^ !_HAS_CXX20 ^^^ // deduction guide utilities (N4950 [associative.general]/2) template