Use `requires`-clauses and concepts for container-like components since C++20 (#4718)

Co-authored-by: Stephan T. Lavavej <stl@nuwen.net>
This commit is contained in:
A. Jiang 2024-06-28 04:15:26 +08:00 коммит произвёл GitHub
Родитель 756f6d5185
Коммит d6b0352715
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
17 изменённых файлов: 125 добавлений и 90 удалений

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

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

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

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

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

@ -58,6 +58,11 @@ namespace stdext {
using _Deduce_key = const _Kty&;
using key_equal = _Tr;
#if _HAS_CXX20 && defined(__EDG__) // TRANSITION, DevCom-10678753
template <class, class>
static constexpr bool _Supports_transparency = false;
#endif // ^^^ workaround ^^^
_Hmap_traits() = default;
_Hmap_traits(const _Tr& _Traits) noexcept(_STD is_nothrow_copy_constructible_v<_Tr>) : _Tr(_Traits) {}

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

@ -53,6 +53,11 @@ namespace stdext {
using _Deduce_key = const _Kty&;
using key_equal = _Tr;
#if _HAS_CXX20 && defined(__EDG__) // TRANSITION, DevCom-10678753
template <class, class>
static constexpr bool _Supports_transparency = false;
#endif // ^^^ workaround ^^^
_Hset_traits() = default;
_Hset_traits(const _Tr& _Traits) noexcept(_STD is_nothrow_copy_constructible_v<_Tr>) : _Tr(_Traits) {}

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

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

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

@ -385,12 +385,12 @@ map(initializer_list<pair<_Kty, _Ty>>, _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<conjunction_v<negation<_Is_allocator<_Pr>>, _Is_allocator<_Alloc>>, int> = 0>
_Allocator_for_container _Alloc = allocator<_Range_to_alloc_type<_Rng>>>
requires (!_Allocator_for_container<_Pr>)
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<pair<_Kty, _Ty>>, _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<conjunction_v<negation<_Is_allocator<_Pr>>, _Is_allocator<_Alloc>>, int> = 0>
_Allocator_for_container _Alloc = allocator<_Range_to_alloc_type<_Rng>>>
requires (!_Allocator_for_container<_Pr>)
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

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

@ -50,7 +50,7 @@ public:
: c(_STD move(_Cont)) {}
#if _HAS_CXX23
template <class _InIt, enable_if_t<_Is_iterator_v<_InIt>, 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)) {}
@ -79,8 +79,8 @@ public:
: c(_STD move(_Right.c), _Al) {}
#if _HAS_CXX23
template <class _InIt, class _Alloc,
enable_if_t<conjunction_v<_Is_iterator<_InIt>, 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) {}
@ -169,12 +169,10 @@ queue(_Container, _Alloc) -> queue<typename _Container::value_type, _Container>;
#endif // _HAS_CXX17
#if _HAS_CXX23
template <class _InIt, class _Alloc = allocator<_Iter_value_t<_InIt>>,
enable_if_t<conjunction_v<_Is_iterator<_InIt>, _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
@ -345,15 +343,15 @@ public:
}
#if _HAS_CXX23
template <_Container_compatible_range<_Ty> _Rng, class _Alloc,
enable_if_t<uses_allocator_v<_Container, _Alloc>, 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<uses_allocator_v<_Container, _Alloc>, 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();

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

@ -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<conjunction_v<negation<_Is_allocator<_Pr>>, _Is_allocator<_Alloc>>, int> = 0>
_Allocator_for_container _Alloc = allocator<_RANGES range_value_t<_Rng>>>
requires (!_Allocator_for_container<_Pr>)
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<conjunction_v<negation<_Is_allocator<_Pr>>, _Is_allocator<_Alloc>>, int> = 0>
_Allocator_for_container _Alloc = allocator<_RANGES range_value_t<_Rng>>>
requires (!_Allocator_for_container<_Pr>)
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

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

@ -230,8 +230,7 @@ public:
}
#if _HAS_CXX20
template <class _Alloc2>
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 <class _Alloc2>
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 <class _Alloc2, enable_if_t<_Is_allocator<_Alloc2>::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 <class _Alloc2, enable_if_t<_Is_allocator<_Alloc2>::value, int> = 0>
template <_Allocator_for_container _Alloc2>
_NODISCARD basic_string<_Elem, _Traits, _Alloc2> str(const _Alloc2& _Al) const {
return _Stringbuffer.str(_Al);
}

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

@ -43,7 +43,7 @@ public:
: c(_STD move(_Cont)) {}
#if _HAS_CXX23
template <class _InIt, enable_if_t<_Is_iterator_v<_InIt>, 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)) {}
@ -72,8 +72,8 @@ public:
: c(_STD move(_Right.c), _Al) {}
#if _HAS_CXX23
template <class _InIt, class _Alloc,
enable_if_t<conjunction_v<_Is_iterator<_InIt>, 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) {}
@ -154,14 +154,13 @@ stack(_Container, _Alloc) -> stack<typename _Container::value_type, _Container>;
#endif // _HAS_CXX17
#if _HAS_CXX23
template <class _InIt, class _Alloc = allocator<_Iter_value_t<_InIt>>,
enable_if_t<conjunction_v<_Is_iterator<_InIt>, _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

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

@ -497,22 +497,22 @@ unordered_map(initializer_list<pair<_Kty, _Ty>>, _Guide_size_type_t<_Alloc>, _Ha
-> unordered_map<_Kty, _Ty, _Hasher, equal_to<_Kty>, _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<conjunction_v<_Is_hasher<_Hasher>, negation<_Is_allocator<_Keyeq>>, _Is_allocator<_Alloc>>, int> = 0>
template <_RANGES input_range _Rng, _Hasher_for_container _Hasher = hash<_Range_key_type<_Rng>>,
class _Keyeq = equal_to<_Range_key_type<_Rng>>,
_Allocator_for_container _Alloc = allocator<_Range_to_alloc_type<_Rng>>>
requires (!_Allocator_for_container<_Keyeq>)
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<conjunction_v<_Is_hasher<_Hasher>, _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
@ -867,23 +867,23 @@ unordered_multimap(initializer_list<pair<_Kty, _Ty>>, _Guide_size_type_t<_Alloc>
-> unordered_multimap<_Kty, _Ty, _Hasher, equal_to<_Kty>, _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<conjunction_v<_Is_hasher<_Hasher>, negation<_Is_allocator<_Keyeq>>, _Is_allocator<_Alloc>>, int> = 0>
template <_RANGES input_range _Rng, _Hasher_for_container _Hasher = hash<_Range_key_type<_Rng>>,
class _Keyeq = equal_to<_Range_key_type<_Rng>>,
_Allocator_for_container _Alloc = allocator<_Range_to_alloc_type<_Rng>>>
requires (!_Allocator_for_container<_Keyeq>)
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<conjunction_v<_Is_hasher<_Hasher>, _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>;

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

@ -353,22 +353,22 @@ unordered_set(initializer_list<_Kty>, _Guide_size_type_t<_Alloc>, _Hasher, _Allo
-> unordered_set<_Kty, _Hasher, equal_to<_Kty>, _Alloc>;
#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<conjunction_v<_Is_hasher<_Hasher>, negation<_Is_allocator<_Keyeq>>, _Is_allocator<_Alloc>>, int> = 0>
template <_RANGES input_range _Rng, _Hasher_for_container _Hasher = hash<_RANGES range_value_t<_Rng>>,
class _Keyeq = equal_to<_RANGES range_value_t<_Rng>>,
_Allocator_for_container _Alloc = allocator<_RANGES range_value_t<_Rng>>>
requires (!_Allocator_for_container<_Keyeq>)
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<conjunction_v<_Is_hasher<_Hasher>, _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
@ -696,23 +696,23 @@ unordered_multiset(initializer_list<_Kty>, _Guide_size_type_t<_Alloc>, _Hasher,
-> unordered_multiset<_Kty, _Hasher, equal_to<_Kty>, _Alloc>;
#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<conjunction_v<_Is_hasher<_Hasher>, negation<_Is_allocator<_Keyeq>>, _Is_allocator<_Alloc>>, int> = 0>
template <_RANGES input_range _Rng, _Hasher_for_container _Hasher = hash<_RANGES range_value_t<_Rng>>,
class _Keyeq = equal_to<_RANGES range_value_t<_Rng>>,
_Allocator_for_container _Alloc = allocator<_RANGES range_value_t<_Rng>>>
requires (!_Allocator_for_container<_Keyeq>)
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<conjunction_v<_Is_hasher<_Hasher>, _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

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

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

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

@ -93,17 +93,22 @@ _STD_END
#endif // _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS
_STD_BEGIN
template <class _Kty, class _Hasher, class _Keyeq, class = void>
template <class _Kty, class _Hasher, class _Keyeq>
struct _Uhash_choose_transparency {
// transparency selector for non-transparent hashed containers
template <class>
using _Deduce_key = const _Kty&;
#if _HAS_CXX20 && defined(__EDG__) // TRANSITION, DevCom-10678753
template <class, class>
static constexpr bool _Supports_transparency = false;
#endif // ^^^ workaround ^^^
};
#if _HAS_CXX20
template <class _Kty, class _Hasher, class _Keyeq>
struct _Uhash_choose_transparency<_Kty, _Hasher, _Keyeq,
enable_if_t<conjunction_v<_Is_transparent<_Hasher>, _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 <class _Keyty>
using _Deduce_key = const _Keyty&;
@ -1137,8 +1142,8 @@ public:
}
#if _HAS_CXX23
template <class _Kx, class _Mytraits = _Traits,
enable_if_t<_Mytraits::template _Supports_transparency<_Hash, _Kx>, int> = 0>
template <class _Kx>
requires (_Traits::template _Supports_transparency<_Hash, _Kx>)
size_type erase(_Kx&& _Keyval) noexcept(noexcept(_Erase(_Keyval))) /* strengthened */ {
return _Erase(_Keyval);
}
@ -1347,8 +1352,8 @@ public:
}
#if _HAS_CXX23
template <class _Kx, class _Mytraits = _Traits,
enable_if_t<_Mytraits::template _Supports_transparency<_Hash, _Kx>, int> = 0>
template <class _Kx>
requires (_Traits::template _Supports_transparency<_Hash, _Kx>)
node_type extract(_Kx&& _Keyval) {
const auto _Ptr = _Extract(_Keyval);
if (!_Ptr) {
@ -1967,9 +1972,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 <class _Hasher>
concept _Hasher_for_container = !integral<_Hasher> && !_Allocator_for_container<_Hasher>;
template <class _Hasher>
using _Is_hasher = bool_constant<_Hasher_for_container<_Hasher>>;
#else // ^^^ _HAS_CXX23 / !_HAS_CXX23 vvv
template <class _Hasher>
using _Is_hasher = negation<disjunction<is_integral<_Hasher>, _Is_allocator<_Hasher>>>;
#endif // ^^^ !_HAS_CXX23 ^^^
#endif // _HAS_CXX17
template <class _Traits>

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

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

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

@ -1335,10 +1335,9 @@ public:
}
#if _HAS_CXX23
template <class _Kx, class _Mycomp = key_compare,
enable_if_t<conjunction_v<_Is_transparent<_Mycomp>,
negation<disjunction<is_convertible<_Kx, const_iterator>, is_convertible<_Kx, iterator>>>>,
int> = 0>
template <class _Kx>
requires _Is_transparent_v<key_compare>
&& (!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 <class _Other, class _Mycomp = key_compare, enable_if_t<_Is_transparent_v<_Mycomp>, int> = 0>
template <class _Other>
requires _Is_transparent_v<key_compare>
_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 <class _Kx, class _Mycomp = key_compare,
enable_if_t<conjunction_v<_Is_transparent<_Mycomp>,
negation<disjunction<is_convertible<_Kx, const_iterator>, is_convertible<_Kx, iterator>>>>,
int> = 0>
template <class _Kx>
requires _Is_transparent_v<key_compare>
&& (!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()) {

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

@ -1205,6 +1205,16 @@ using _Common_diff_t = common_type_t<_Iter_diff_t<_Iters>...>;
template <class _Iter>
using _Iter_cat_t = typename iterator_traits<_Iter>::iterator_category;
#if _HAS_CXX20
template <class _Ty>
concept _Iterator_for_container = requires { typename _Iter_cat_t<_Ty>; };
template <class _Ty>
constexpr bool _Is_iterator_v = _Iterator_for_container<_Ty>;
template <class _Ty>
struct _Is_iterator : bool_constant<_Iterator_for_container<_Ty>> {};
#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv
template <class _Ty, class = void>
constexpr bool _Is_iterator_v = false;
@ -1213,6 +1223,7 @@ constexpr bool _Is_iterator_v<_Ty, void_t<_Iter_cat_t<_Ty>>> = true;
template <class _Ty>
struct _Is_iterator : bool_constant<_Is_iterator_v<_Ty>> {};
#endif // ^^^ !_HAS_CXX20 ^^^
template <class _Iter>
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 <class _Ty>
concept _Allocator_for_container = requires(_Ty& _Alloc) {
typename _Ty::value_type;
_Alloc.deallocate(_Alloc.allocate(size_t{1}), size_t{1});
};
template <class _Ty>
struct _Is_allocator : bool_constant<_Allocator_for_container<_Ty>> {};
#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv
template <class _Ty, class = void>
struct _Is_allocator : false_type {}; // selected when _Ty can't possibly be an allocator
@ -1430,6 +1452,7 @@ template <class _Ty>
struct _Is_allocator<_Ty, void_t<typename _Ty::value_type, decltype(_STD declval<_Ty&>().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 <class _Iter>