Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feature/spaceship: Clause 22: Containers #1046

Merged
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
732d748
Container spaceship changes, squashed.
ahanamuk Jul 15, 2020
06dfcd7
incorporated all comments from code review mainly changing ifdef guards
ahanamuk Jul 20, 2020
4ca3624
undid a change to iterator
ahanamuk Jul 20, 2020
17e650d
updated synth_three_way to a regular struct
ahanamuk Jul 21, 2020
c2ec451
Restore braces lost during merging.
StephanTLavavej Jul 23, 2020
3ed745d
Drop <iterator> changes from this PR.
StephanTLavavej Jul 23, 2020
b7e83a4
Adjust comment spacing.
StephanTLavavej Jul 23, 2020
fbc0f89
Update multimap and multiset guards.
StephanTLavavej Jul 23, 2020
3c9a1a0
Fix all spaceship guards; STL's guidance was bogus
StephanTLavavej Jul 23, 2020
f6c5510
vector spaceship needs _Synth_three_way{}.
StephanTLavavej Jul 23, 2020
1dc5c43
Fix queue/stack friendship.
StephanTLavavej Jul 23, 2020
f8ef466
Use unchecked iterators to implement comparisons.
StephanTLavavej Jul 23, 2020
dc3e324
Verify `decltype(smaller <=> larger)`.
StephanTLavavej Jul 24, 2020
b2c5086
Test varying element strengths.
StephanTLavavej Jul 24, 2020
0cfe696
Verify that containers use synth-three-way.
StephanTLavavej Jul 24, 2020
c9699e7
Work around VSO-1161663.
StephanTLavavej Jul 24, 2020
7538c77
Move vector swap/comparison below vector<bool>.
StephanTLavavej Jul 24, 2020
8858a09
Refactor the vector<bool> equality optimization.
StephanTLavavej Jul 24, 2020
1416165
Optimize vector<bool> spaceship and less-than.
StephanTLavavej Jul 24, 2020
015eae3
Minimally upgrade vector<bool> comparison testing.
StephanTLavavej Jul 25, 2020
cd9a610
Implement bit reversal.
StephanTLavavej Jul 25, 2020
9fd5169
Use _Countr_zero() for even more efficiency.
StephanTLavavej Jul 25, 2020
195536b
Further improve `_Vbase_compare_three_way` codegen.
StephanTLavavej Jul 25, 2020
664ac1b
Rename vector_bool_comparisons test.
StephanTLavavej Jul 28, 2020
d6acf3e
Test vector<bool> comparisons.
StephanTLavavej Jul 28, 2020
2059df3
Add forward declaration, move _Vbase/_VBITS, follow synopsis order (n…
StephanTLavavej Jul 28, 2020
0355938
Improve comments.
StephanTLavavej Jul 28, 2020
e372f73
Clarify comment.
StephanTLavavej Jul 28, 2020
f906d04
Rename to P1614R2_spaceship.
StephanTLavavej Jul 28, 2020
3ec3965
Comment and formatting changes.
StephanTLavavej Jul 28, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions stl/inc/array
Original file line number Diff line number Diff line change
Expand Up @@ -778,11 +778,21 @@ _NODISCARD _CONSTEXPR20 bool operator==(const array<_Ty, _Size>& _Left, const ar
return _STD equal(_Left.begin(), _Left.end(), _Right.begin());
}

#if !_HAS_CXX20
template <class _Ty, size_t _Size>
_NODISCARD _CONSTEXPR20 bool operator!=(const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) {
return !(_Left == _Right);
}
#endif // !_HAS_CXX20

#ifdef __cpp_lib_concepts
template <class _Ty, size_t _Size>
_NODISCARD constexpr _Synth_three_way_result<_Ty> operator<=>(
const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) {
return _STD lexicographical_compare_three_way(
_Left.begin(), _Left.end(), _Right.begin(), _Right.end(), _Synth_three_way{});
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved
}
#else // __cpp_lib_concepts
template <class _Ty, size_t _Size>
_NODISCARD _CONSTEXPR20 bool operator<(const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) {
return _STD lexicographical_compare(_Left.begin(), _Left.end(), _Right.begin(), _Right.end());
Expand All @@ -802,6 +812,7 @@ template <class _Ty, size_t _Size>
_NODISCARD _CONSTEXPR20 bool operator>=(const array<_Ty, _Size>& _Left, const array<_Ty, _Size>& _Right) {
return !(_Left < _Right);
}
#endif // __cpp_lib_concepts

#if _HAS_CXX20
// FUNCTION TEMPLATE to_array
Expand Down
10 changes: 10 additions & 0 deletions stl/inc/deque
Original file line number Diff line number Diff line change
Expand Up @@ -1581,11 +1581,20 @@ _NODISCARD bool operator==(const deque<_Ty, _Alloc>& _Left, const deque<_Ty, _Al
&& _STD equal(_Left._Unchecked_begin(), _Left._Unchecked_end(), _Right._Unchecked_begin());
}

#if !_HAS_CXX20
template <class _Ty, class _Alloc>
_NODISCARD bool operator!=(const deque<_Ty, _Alloc>& _Left, const deque<_Ty, _Alloc>& _Right) {
return !(_Left == _Right);
}
#endif // !_HAS_CXX20

#ifdef __cpp_lib_concepts
template <class _Ty, class _Alloc>
_NODISCARD _Synth_three_way_result<_Ty> operator<=>(const deque<_Ty, _Alloc>& _Left, const deque<_Ty, _Alloc>& _Right) {
return _STD lexicographical_compare_three_way(_Left._Unchecked_begin(), _Left._Unchecked_end(),
_Right._Unchecked_begin(), _Right._Unchecked_end(), _Synth_three_way{});
}
#else // __cpp_lib_concepts
template <class _Ty, class _Alloc>
_NODISCARD bool operator<(const deque<_Ty, _Alloc>& _Left, const deque<_Ty, _Alloc>& _Right) {
return _STD lexicographical_compare(
Expand All @@ -1606,6 +1615,7 @@ template <class _Ty, class _Alloc>
_NODISCARD bool operator>=(const deque<_Ty, _Alloc>& _Left, const deque<_Ty, _Alloc>& _Right) {
return !(_Left < _Right);
}
#endif // __cpp_lib_concepts

#if _HAS_CXX20
template <class _Ty, class _Alloc, class _Uty>
Expand Down
11 changes: 11 additions & 0 deletions stl/inc/forward_list
Original file line number Diff line number Diff line change
Expand Up @@ -1521,11 +1521,21 @@ _NODISCARD bool operator==(const forward_list<_Ty, _Alloc>& _Left, const forward
return _STD equal(_Left.begin(), _Left.end(), _Right.begin(), _Right.end());
}

#if !_HAS_CXX20
template <class _Ty, class _Alloc>
_NODISCARD bool operator!=(const forward_list<_Ty, _Alloc>& _Left, const forward_list<_Ty, _Alloc>& _Right) {
return !(_Left == _Right);
}
#endif // !_HAS_CXX20

#ifdef __cpp_lib_concepts
template <class _Ty, class _Alloc>
_NODISCARD _Synth_three_way_result<_Ty> operator<=>(
const forward_list<_Ty, _Alloc>& _Left, const forward_list<_Ty, _Alloc>& _Right) {
return _STD lexicographical_compare_three_way(
_Left.begin(), _Left.end(), _Right.begin(), _Right.end(), _Synth_three_way{});
}
#else // __cpp_lib_concepts
template <class _Ty, class _Alloc>
_NODISCARD bool operator<(const forward_list<_Ty, _Alloc>& _Left, const forward_list<_Ty, _Alloc>& _Right) {
return _STD lexicographical_compare(_Left.begin(), _Left.end(), _Right.begin(), _Right.end());
Expand All @@ -1545,6 +1555,7 @@ template <class _Ty, class _Alloc>
_NODISCARD bool operator>=(const forward_list<_Ty, _Alloc>& _Left, const forward_list<_Ty, _Alloc>& _Right) {
return !(_Left < _Right);
}
#endif // __cpp_lib_concepts

#if _HAS_CXX20
template <class _Ty, class _Alloc, class _Uty>
Expand Down
10 changes: 10 additions & 0 deletions stl/inc/list
Original file line number Diff line number Diff line change
Expand Up @@ -1810,11 +1810,20 @@ _NODISCARD bool operator==(const list<_Ty, _Alloc>& _Left, const list<_Ty, _Allo
return _Left.size() == _Right.size() && _STD equal(_Left.begin(), _Left.end(), _Right.begin());
}

#if !_HAS_CXX20
template <class _Ty, class _Alloc>
_NODISCARD bool operator!=(const list<_Ty, _Alloc>& _Left, const list<_Ty, _Alloc>& _Right) {
return !(_Left == _Right);
}
#endif // !_HAS_CXX20

#ifdef __cpp_lib_concepts
template <class _Ty, class _Alloc>
_NODISCARD _Synth_three_way_result<_Ty> operator<=>(const list<_Ty, _Alloc>& _Left, const list<_Ty, _Alloc>& _Right) {
return _STD lexicographical_compare_three_way(
_Left.begin(), _Left.end(), _Right.begin(), _Right.end(), _Synth_three_way{});
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved
}
#else // __cpp_lib_concepts
template <class _Ty, class _Alloc>
_NODISCARD bool operator<(const list<_Ty, _Alloc>& _Left, const list<_Ty, _Alloc>& _Right) {
return _STD lexicographical_compare(_Left.begin(), _Left.end(), _Right.begin(), _Right.end());
Expand All @@ -1834,6 +1843,7 @@ template <class _Ty, class _Alloc>
_NODISCARD bool operator>=(const list<_Ty, _Alloc>& _Left, const list<_Ty, _Alloc>& _Right) {
return !(_Left < _Right);
}
#endif // __cpp_lib_concepts

#if _HAS_CXX20
template <class _Ty, class _Alloc, class _Uty>
Expand Down
22 changes: 22 additions & 0 deletions stl/inc/map
Original file line number Diff line number Diff line change
Expand Up @@ -369,11 +369,21 @@ _NODISCARD bool operator==(const map<_Kty, _Ty, _Pr, _Alloc>& _Left, const map<_
&& _STD equal(_Left._Unchecked_begin(), _Left._Unchecked_end_iter(), _Right._Unchecked_begin());
}

#if !_HAS_CXX20
template <class _Kty, class _Ty, class _Pr, class _Alloc>
_NODISCARD bool operator!=(const map<_Kty, _Ty, _Pr, _Alloc>& _Left, const map<_Kty, _Ty, _Pr, _Alloc>& _Right) {
return !(_Left == _Right);
}
#endif // !_HAS_CXX20

#ifdef __cpp_lib_concepts
template <class _Kty, class _Ty, class _Pr, class _Alloc>
_NODISCARD _Synth_three_way_result<pair<const _Kty, _Ty>> operator<=>(
const map<_Kty, _Ty, _Pr, _Alloc>& _Left, const map<_Kty, _Ty, _Pr, _Alloc>& _Right) {
return _STD lexicographical_compare_three_way(_Left._Unchecked_begin(), _Left._Unchecked_end_iter(),
_Right._Unchecked_begin(), _Right._Unchecked_end_iter(), _Synth_three_way{});
}
#else // __cpp_lib_concepts
template <class _Kty, class _Ty, class _Pr, class _Alloc>
_NODISCARD bool operator<(const map<_Kty, _Ty, _Pr, _Alloc>& _Left, const map<_Kty, _Ty, _Pr, _Alloc>& _Right) {
return _STD lexicographical_compare(
Expand All @@ -394,6 +404,7 @@ template <class _Kty, class _Ty, class _Pr, class _Alloc>
_NODISCARD bool operator>=(const map<_Kty, _Ty, _Pr, _Alloc>& _Left, const map<_Kty, _Ty, _Pr, _Alloc>& _Right) {
return !(_Left < _Right);
}
#endif // __cpp_lib_concepts

template <class _Kty, class _Ty, class _Pr, class _Alloc>
void swap(map<_Kty, _Ty, _Pr, _Alloc>& _Left, map<_Kty, _Ty, _Pr, _Alloc>& _Right) noexcept(
Expand Down Expand Up @@ -557,12 +568,22 @@ _NODISCARD bool operator==(
&& _STD equal(_Left._Unchecked_begin(), _Left._Unchecked_end_iter(), _Right._Unchecked_begin());
}

#if !_HAS_CXX20
template <class _Kty, class _Ty, class _Pr, class _Alloc>
_NODISCARD bool operator!=(
const multimap<_Kty, _Ty, _Pr, _Alloc>& _Left, const multimap<_Kty, _Ty, _Pr, _Alloc>& _Right) {
return !(_Left == _Right);
}
#endif // !_HAS_CXX20

#ifdef __cpp_lib_concepts
template <class _Kty, class _Ty, class _Pr, class _Alloc>
_NODISCARD _Synth_three_way_result<pair<const _Kty, _Ty>> operator<=>(
const multimap<_Kty, _Ty, _Pr, _Alloc>& _Left, const multimap<_Kty, _Ty, _Pr, _Alloc>& _Right) {
return _STD lexicographical_compare_three_way(_Left._Unchecked_begin(), _Left._Unchecked_end_iter(),
_Right._Unchecked_begin(), _Right._Unchecked_end_iter(), _Synth_three_way{});
}
#else
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved
template <class _Kty, class _Ty, class _Pr, class _Alloc>
_NODISCARD bool operator<(
const multimap<_Kty, _Ty, _Pr, _Alloc>& _Left, const multimap<_Kty, _Ty, _Pr, _Alloc>& _Right) {
Expand All @@ -587,6 +608,7 @@ _NODISCARD bool operator>=(
const multimap<_Kty, _Ty, _Pr, _Alloc>& _Left, const multimap<_Kty, _Ty, _Pr, _Alloc>& _Right) {
return !(_Left < _Right);
}
#endif // __cpp_lib_concepts

template <class _Kty, class _Ty, class _Pr, class _Alloc>
void swap(multimap<_Kty, _Ty, _Pr, _Alloc>& _Left, multimap<_Kty, _Ty, _Pr, _Alloc>& _Right) noexcept(
Expand Down
13 changes: 13 additions & 0 deletions stl/inc/queue
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ _NODISCARD bool operator>=(const queue<_Ty, _Container>& _Left, const queue<_Ty,
return _Left.c >= _Right.c;
}

#ifdef __cpp_lib_concepts
template <class _Ty, three_way_comparable _Container>
_NODISCARD compare_three_way_result_t<_Container> operator<=>(
const queue<_Ty, _Container>& _Left, const queue<_Ty, _Container>& _Right) {
return _Left.c <=> _Right.c;
}
#endif // __cpp_lib_concepts

template <class _Ty, class _Container>
class queue {
public:
Expand Down Expand Up @@ -148,6 +156,11 @@ public:
friend bool operator> <>(const queue&, const queue&);
friend bool operator<= <>(const queue&, const queue&);
friend bool operator>= <>(const queue&, const queue&);
#ifdef __cpp_lib_concepts
template <class _Ty2, three_way_comparable _Container2>
friend compare_three_way_result_t<_Container2> operator<=>(
const queue<_Ty2, _Container2>&, const queue<_Ty2, _Container2>&);
#endif // __cpp_lib_concepts
// clang-format on

protected:
Expand Down
22 changes: 22 additions & 0 deletions stl/inc/set
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,21 @@ _NODISCARD bool operator==(const set<_Kty, _Pr, _Alloc>& _Left, const set<_Kty,
&& _STD equal(_Left._Unchecked_begin(), _Left._Unchecked_end_iter(), _Right._Unchecked_begin());
}

#if !_HAS_CXX20
template <class _Kty, class _Pr, class _Alloc>
_NODISCARD bool operator!=(const set<_Kty, _Pr, _Alloc>& _Left, const set<_Kty, _Pr, _Alloc>& _Right) {
return !(_Left == _Right);
}
#endif // !_HAS_CXX20

#ifdef __cpp_lib_concepts
template <class _Kty, class _Pr, class _Alloc>
_NODISCARD _Synth_three_way_result<_Kty> operator<=>(
const set<_Kty, _Pr, _Alloc>& _Left, const set<_Kty, _Pr, _Alloc>& _Right) {
return _STD lexicographical_compare_three_way(_Left._Unchecked_begin(), _Left._Unchecked_end_iter(),
_Right._Unchecked_begin(), _Right._Unchecked_end_iter(), _Synth_three_way{});
}
#else // __cpp_lib_concepts
template <class _Kty, class _Pr, class _Alloc>
_NODISCARD bool operator<(const set<_Kty, _Pr, _Alloc>& _Left, const set<_Kty, _Pr, _Alloc>& _Right) {
return _STD lexicographical_compare(
Expand All @@ -205,6 +215,7 @@ template <class _Kty, class _Pr, class _Alloc>
_NODISCARD bool operator>=(const set<_Kty, _Pr, _Alloc>& _Left, const set<_Kty, _Pr, _Alloc>& _Right) {
return !(_Left < _Right);
}
#endif // __cpp_lib_concepts

template <class _Kty, class _Pr, class _Alloc>
void swap(set<_Kty, _Pr, _Alloc>& _Left, set<_Kty, _Pr, _Alloc>& _Right) noexcept(noexcept(_Left.swap(_Right))) {
Expand Down Expand Up @@ -352,11 +363,21 @@ _NODISCARD bool operator==(const multiset<_Kty, _Pr, _Alloc>& _Left, const multi
&& _STD equal(_Left._Unchecked_begin(), _Left._Unchecked_end_iter(), _Right._Unchecked_begin());
}

#if !_HAS_CXX20
template <class _Kty, class _Pr, class _Alloc>
_NODISCARD bool operator!=(const multiset<_Kty, _Pr, _Alloc>& _Left, const multiset<_Kty, _Pr, _Alloc>& _Right) {
return !(_Left == _Right);
}
#endif // !_HAS_CXX20

#ifdef __cpp_lib_concepts
template <class _Kty, class _Pr, class _Alloc>
_NODISCARD _Synth_three_way_result<_Kty> operator<=>(
const multiset<_Kty, _Pr, _Alloc>& _Left, const multiset<_Kty, _Pr, _Alloc>& _Right) {
return _STD lexicographical_compare_three_way(_Left._Unchecked_begin(), _Left._Unchecked_end_iter(),
_Right._Unchecked_begin(), _Right._Unchecked_end_iter(), _Synth_three_way{});
}
#else // __cpp_lib_concepts
template <class _Kty, class _Pr, class _Alloc>
_NODISCARD bool operator<(const multiset<_Kty, _Pr, _Alloc>& _Left, const multiset<_Kty, _Pr, _Alloc>& _Right) {
return _STD lexicographical_compare(
Expand All @@ -377,6 +398,7 @@ template <class _Kty, class _Pr, class _Alloc>
_NODISCARD bool operator>=(const multiset<_Kty, _Pr, _Alloc>& _Left, const multiset<_Kty, _Pr, _Alloc>& _Right) {
return !(_Left < _Right);
}
#endif // __cpp_lib_concepts

template <class _Kty, class _Pr, class _Alloc>
void swap(multiset<_Kty, _Pr, _Alloc>& _Left, multiset<_Kty, _Pr, _Alloc>& _Right) noexcept(
Expand Down
13 changes: 13 additions & 0 deletions stl/inc/stack
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ _NODISCARD bool operator>=(const stack<_Ty, _Container>& _Left, const stack<_Ty,
return _Left.c >= _Right.c;
}

#ifdef __cpp_lib_concepts
template <class _Ty, three_way_comparable _Container>
_NODISCARD compare_three_way_result_t<_Container> operator<=>(
const stack<_Ty, _Container>& _Left, const stack<_Ty, _Container>& _Right) {
return _Left.c <=> _Right.c;
}
#endif // __cpp_lib_concepts

template <class _Ty, class _Container>
class stack {
public:
Expand Down Expand Up @@ -138,6 +146,11 @@ public:
friend bool operator> <>(const stack&, const stack&);
friend bool operator<= <>(const stack&, const stack&);
friend bool operator>= <>(const stack&, const stack&);
#ifdef __cpp_lib_concepts
template <class _Ty2, three_way_comparable _Container2>
friend compare_three_way_result_t<_Container2> operator<=>(
const stack<_Ty2, _Container2>&, const stack<_Ty2, _Container2>&);
#endif // __cpp_lib_concepts
// clang-format on

protected:
Expand Down
4 changes: 4 additions & 0 deletions stl/inc/unordered_map
Original file line number Diff line number Diff line change
Expand Up @@ -468,11 +468,13 @@ _NODISCARD bool operator==(const unordered_map<_Kty, _Ty, _Hasher, _Keyeq, _Allo
return _Hash_equal(_Left, _Right);
}

#if !_HAS_CXX20
template <class _Kty, class _Ty, class _Hasher, class _Keyeq, class _Alloc>
_NODISCARD bool operator!=(const unordered_map<_Kty, _Ty, _Hasher, _Keyeq, _Alloc>& _Left,
const unordered_map<_Kty, _Ty, _Hasher, _Keyeq, _Alloc>& _Right) {
return !(_Left == _Right);
}
#endif // !_HAS_CXX20

// CLASS TEMPLATE unordered_multimap
template <class _Kty, class _Ty, class _Hasher = hash<_Kty>, class _Keyeq = equal_to<_Kty>,
Expand Down Expand Up @@ -758,11 +760,13 @@ _NODISCARD bool operator==(const unordered_multimap<_Kty, _Ty, _Hasher, _Keyeq,
return _Hash_equal(_Left, _Right);
}

#if !_HAS_CXX20
template <class _Kty, class _Ty, class _Hasher, class _Keyeq, class _Alloc>
_NODISCARD bool operator!=(const unordered_multimap<_Kty, _Ty, _Hasher, _Keyeq, _Alloc>& _Left,
const unordered_multimap<_Kty, _Ty, _Hasher, _Keyeq, _Alloc>& _Right) {
return !(_Left == _Right);
}
#endif // !_HAS_CXX20

#if _HAS_TR1_NAMESPACE
namespace _DEPRECATE_TR1_NAMESPACE tr1 {
Expand Down
4 changes: 4 additions & 0 deletions stl/inc/unordered_set
Original file line number Diff line number Diff line change
Expand Up @@ -322,11 +322,13 @@ _NODISCARD bool operator==(const unordered_set<_Kty, _Hasher, _Keyeq, _Alloc>& _
return _Hash_equal(_Left, _Right);
}

#if !_HAS_CXX20
template <class _Kty, class _Hasher, class _Keyeq, class _Alloc>
_NODISCARD bool operator!=(const unordered_set<_Kty, _Hasher, _Keyeq, _Alloc>& _Left,
const unordered_set<_Kty, _Hasher, _Keyeq, _Alloc>& _Right) {
return !(_Left == _Right);
}
#endif // !_HAS_CXX20

// CLASS TEMPLATE unordered_multiset
template <class _Kty, class _Hasher = hash<_Kty>, class _Keyeq = equal_to<_Kty>, class _Alloc = allocator<_Kty>>
Expand Down Expand Up @@ -584,11 +586,13 @@ _NODISCARD bool operator==(const unordered_multiset<_Kty, _Hasher, _Keyeq, _Allo
return _Hash_equal(_Left, _Right);
}

#if !_HAS_CXX20
template <class _Kty, class _Hasher, class _Keyeq, class _Alloc>
_NODISCARD bool operator!=(const unordered_multiset<_Kty, _Hasher, _Keyeq, _Alloc>& _Left,
const unordered_multiset<_Kty, _Hasher, _Keyeq, _Alloc>& _Right) {
return !(_Left == _Right);
}
#endif // !_HAS_CXX20

#if _HAS_TR1_NAMESPACE
namespace _DEPRECATE_TR1_NAMESPACE tr1 {
Expand Down
30 changes: 30 additions & 0 deletions stl/inc/utility
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,36 @@ _NODISCARD constexpr bool cmp_greater_equal(const _Ty1 _Left, const _Ty2 _Right)
return !_STD cmp_less(_Left, _Right);
}

#ifdef __cpp_lib_concepts
// STRUCT SYNTH_THREE_WAY
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved
struct _Synth_three_way {
// clang-format off
template <class _Ty1, class _Ty2>
_NODISCARD constexpr auto operator()(const _Ty1& _Left, const _Ty2& _Right) const requires requires {
{ _Left < _Right } -> _Boolean_testable;
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved
{ _Right < _Left } -> _Boolean_testable;
}
// clang-format on
{
if constexpr (three_way_comparable_with<_Ty1, _Ty2>) {
return _Left <=> _Right;
} else {
if (_Left < _Right) {
return weak_ordering::less;
} else if (_Right < _Left) {
return weak_ordering::greater;
} else {
return weak_ordering::equivalent;
}
}
}
};

// ALIAS TEMPLATE _Synth_three_way_result
template <class _Ty1, class _Ty2 = _Ty1>
using _Synth_three_way_result = decltype(_Synth_three_way{}(_STD declval<_Ty1&>(), _STD declval<_Ty2&>()));
#endif // __cpp_lib_concepts

// FUNCTION TEMPLATE in_range
template <class _Ty>
_NODISCARD constexpr _Ty _Min_limit() noexcept { // same as (numeric_limits<_Ty>::min)(), less throughput cost
Expand Down
Loading