Skip to content

Commit

Permalink
Use requires-clauses and concepts for container-like components sin…
Browse files Browse the repository at this point in the history
…ce C++20 (#4718)

Co-authored-by: Stephan T. Lavavej <stl@nuwen.net>
  • Loading branch information
frederick-vs-ja and StephanTLavavej authored Jun 27, 2024
1 parent 756f6d5 commit d6b0352
Show file tree
Hide file tree
Showing 17 changed files with 125 additions and 90 deletions.
3 changes: 1 addition & 2 deletions stl/inc/deque
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
3 changes: 1 addition & 2 deletions stl/inc/forward_list
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
5 changes: 5 additions & 0 deletions stl/inc/hash_map
Original file line number Diff line number Diff line change
Expand Up @@ -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) {}
Expand Down
5 changes: 5 additions & 0 deletions stl/inc/hash_set
Original file line number Diff line number Diff line change
Expand Up @@ -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) {}
Expand Down
3 changes: 1 addition & 2 deletions stl/inc/list
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
12 changes: 6 additions & 6 deletions stl/inc/map
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
20 changes: 9 additions & 11 deletions stl/inc/queue
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {}

Expand Down Expand Up @@ -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) {}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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();
Expand Down
12 changes: 6 additions & 6 deletions stl/inc/set
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
10 changes: 4 additions & 6 deletions stl/inc/sstream
Original file line number Diff line number Diff line change
Expand Up @@ -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};
}
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
}
Expand Down
11 changes: 5 additions & 6 deletions stl/inc/stack
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {}

Expand Down Expand Up @@ -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) {}
Expand Down Expand Up @@ -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

Expand Down
28 changes: 14 additions & 14 deletions stl/inc/unordered_map
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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>;
Expand Down
Loading

0 comments on commit d6b0352

Please sign in to comment.