Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
1cb1ddd
Spaceship for regex
cbezault Jul 23, 2020
fcb7824
Merge into test from feature/spaceship
cbezault Jul 31, 2020
949fc53
Remove old test files for merge
cbezault Jul 31, 2020
3264617
Don't rely on comparison re-writes
cbezault Jul 31, 2020
ec851f9
Test all the comparison ops. Add back != because of compiler bug
cbezault Aug 4, 2020
00638f6
clang-format
cbezault Aug 4, 2020
f50220b
Fix compilation error in regex spaceship tests.
cbezault Aug 4, 2020
460440f
Resolve Casey's comments
cbezault Aug 6, 2020
ac1a54c
clang format
cbezault Aug 6, 2020
df0cbc3
Fix redefinition of !=
cbezault Aug 7, 2020
4065715
EDG doesn't have iter_value_t yet
cbezault Aug 7, 2020
11f7fb6
Resolve @CaseyCarter's review suggestions
cbezault Aug 10, 2020
8033dc1
Resolve @StephanTLavavej's PR comments
cbezault Aug 18, 2020
66bf777
Don't use _MSC_VER to check for C1XX
cbezault Aug 18, 2020
665e8ad
Fix copy-pasta error
cbezault Aug 19, 2020
0403d0c
initial diagnostics product code
ahanamuk Jul 21, 2020
92149a4
Add diagnostics tests
cbezault Aug 10, 2020
b82c9dc
clang-format
cbezault Aug 10, 2020
df07d1b
Apply suggestions from code review
cbezault Aug 18, 2020
a119d4b
Fix @StephanTLavavej's comment
cbezault Aug 19, 2020
844f5bf
clang-format
cbezault Aug 19, 2020
469a43b
initial commit
ahanamuk Jul 23, 2020
a00f59d
tuple and pair
ahanamuk Aug 5, 2020
4a9a96b
Finish pair and tuple
cbezault Aug 10, 2020
e7cf24d
Some more tuple cleanup
cbezault Aug 10, 2020
3bc1990
implement optional
cbezault Aug 10, 2020
8d57064
Intermediate push
cbezault Aug 11, 2020
4783064
clang failure
cbezault Aug 13, 2020
8424917
Fixup optional recursive constraint
cbezault Aug 18, 2020
b6793de
Some comment fixups in tuple
cbezault Aug 18, 2020
1a99676
Don't use _MSC_VER to detect C1XX
cbezault Aug 18, 2020
950810a
clang-format
cbezault Aug 18, 2020
d927500
Use ifdef
cbezault Aug 19, 2020
98bb968
Merge branch 'feature/spaceship' of https://github.com/Microsoft/STL …
cbezault Sep 8, 2020
f2ebc96
Merge branch 'feature/spaceship' of https://github.com/Microsoft/STL …
cbezault Feb 7, 2021
e7b8618
fixup
cbezault Feb 7, 2021
47f46d1
Resolve review comments
cbezault Feb 7, 2021
61bbe63
clang-format
cbezault Feb 7, 2021
03fc50f
More fixups
cbezault Feb 7, 2021
44ea87f
Remove workarounds for vso-900973
cbezault Feb 7, 2021
7d6c2f4
Fixup return type
cbezault Feb 8, 2021
702a9e9
clang-format
cbezault Feb 8, 2021
36038f2
fixup
cbezault Feb 8, 2021
f8a0366
fixup
cbezault Feb 8, 2021
7f77cf2
Tuples can have different types and still be compared
cbezault Feb 8, 2021
ef6f5dc
fixup
cbezault Feb 8, 2021
eab8c6d
Fixup test
cbezault Feb 11, 2021
6266413
Apply suggestions from code review
cbezault Feb 12, 2021
ebacf94
resolve PR comments
cbezault Feb 12, 2021
b01e1d1
Resolve merge conflict
cbezault Feb 12, 2021
8b0075a
undo submodule changes
cbezault Feb 12, 2021
91c7950
clang-format
cbezault Feb 12, 2021
b86e223
Merge branch 'feature/spaceship' into gh1206
StephanTLavavej Feb 20, 2021
6a3efd6
Remove workaround - string spaceship is now implemented.
StephanTLavavej Feb 20, 2021
b3bc72b
Restore line wrapping.
StephanTLavavej Feb 20, 2021
0e31d7a
Add preprocessor comment.
StephanTLavavej Feb 20, 2021
43729c0
<tuple> doesn't need to include <new>.
StephanTLavavej Feb 20, 2021
676f5bd
Use a trailing return type.
StephanTLavavej Feb 20, 2021
d56f39a
Note that we haven't submitted an LWG issue for infinite constraint r…
StephanTLavavej Feb 20, 2021
2f00dae
Detect SynthOrdered keys only.
StephanTLavavej Feb 20, 2021
0295795
For dual-mode tests, constexpr functions should have plain asserts.
StephanTLavavej Feb 20, 2021
65c6a1e
Convention: `constexpr ReturnType`
StephanTLavavej Feb 20, 2021
c6501a1
Avoid strange WeaklyOrdered <=> PartiallyOrdered behavior.
StephanTLavavej Feb 20, 2021
2df0c44
Move more tests into tuple_like_test.
StephanTLavavej Feb 20, 2021
401108c
Define variables on separate lines.
StephanTLavavej Feb 20, 2021
d2b17d5
Simplify optional_test() ReturnType.
StephanTLavavej Feb 20, 2021
337410c
Restore compiler bug workaround, reported DevCom-1344701
StephanTLavavej Feb 20, 2021
247d2cf
Merge branch 'feature/spaceship' into gh1206
StephanTLavavej Feb 22, 2021
b9b8504
Merge branch 'feature/spaceship' into gh1206
StephanTLavavej Feb 22, 2021
b2afae5
Cite GitHub issue.
StephanTLavavej Feb 22, 2021
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
29 changes: 29 additions & 0 deletions stl/inc/compare
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,35 @@ struct compare_three_way {
};
// clang-format on

// STRUCT _Synth_three_way
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;
{ _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&>()));

// Note: The following CPOs are passing arguments as lvalues; see GH-1374.

// CUSTOMIZATION POINT OBJECT strong_order
Expand Down
40 changes: 40 additions & 0 deletions stl/inc/optional
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
#if !_HAS_CXX17
#pragma message("The contents of <optional> are available only with C++17 or later.")
#else // ^^^ !_HAS_CXX17 / _HAS_CXX17 vvv
#if _HAS_CXX20
#include <compare>
#endif // _HAS_CXX20
#include <exception>
#include <initializer_list>
#include <type_traits>
Expand Down Expand Up @@ -480,11 +483,30 @@ _NODISCARD constexpr bool operator>=(const optional<_Ty1>& _Left, const optional
return !_Right.has_value() || (_Left.has_value() && *_Left >= *_Right);
}

#ifdef __cpp_lib_concepts
template <class _Ty1, three_way_comparable_with<_Ty1> _Ty2>
_NODISCARD constexpr compare_three_way_result_t<_Ty1, _Ty2> operator<=>(
const optional<_Ty1>& _Left, const optional<_Ty2>& _Right) {
if (_Left && _Right) {
return *_Left <=> *_Right;
}

return _Left.has_value() <=> _Right.has_value();
}
#endif // __cpp_lib_concepts

// COMPARISONS WITH nullopt [optional.nullops]
template <class _Ty>
_NODISCARD constexpr bool operator==(const optional<_Ty>& _Left, nullopt_t) noexcept {
return !_Left.has_value();
}

#if _HAS_CXX20
template <class _Ty>
_NODISCARD constexpr strong_ordering operator<=>(const optional<_Ty>& _Left, nullopt_t) noexcept {
return _Left.has_value() <=> false;
}
#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv
template <class _Ty>
_NODISCARD constexpr bool operator==(nullopt_t, const optional<_Ty>& _Right) noexcept {
return !_Right.has_value();
Expand Down Expand Up @@ -534,6 +556,7 @@ template <class _Ty>
_NODISCARD constexpr bool operator>=(nullopt_t, const optional<_Ty>& _Right) noexcept {
return !_Right.has_value();
}
#endif // !_HAS_CXX20

// COMPARISONS WITH T [optional.comp_with_t]
template <class _Ty>
Expand Down Expand Up @@ -567,6 +590,7 @@ template <class _Ty1, class _Ty2, _Enable_if_comparable_with_equal<_Ty1, _Ty2> =
_NODISCARD constexpr bool operator==(const optional<_Ty1>& _Left, const _Ty2& _Right) {
return _Left ? *_Left == _Right : false;
}

template <class _Ty1, class _Ty2, _Enable_if_comparable_with_equal<_Ty1, _Ty2> = 0>
_NODISCARD constexpr bool operator==(const _Ty1& _Left, const optional<_Ty2>& _Right) {
return _Right ? _Left == *_Right : false;
Expand Down Expand Up @@ -617,6 +641,22 @@ _NODISCARD constexpr bool operator>=(const _Ty1& _Left, const optional<_Ty2>& _R
return _Right ? _Left >= *_Right : true;
}

#ifdef __cpp_lib_concepts
// clang-format off
template <class _Ty1, class _Ty2>
requires (!_Is_specialization_v<_Ty2, optional>) // TRANSITION, GH-1674
&& three_way_comparable_with<_Ty1, _Ty2>
_NODISCARD constexpr compare_three_way_result_t<_Ty1, _Ty2>
operator<=>(const optional<_Ty1>& _Left, const _Ty2& _Right) {
// clang-format on
if (_Left) {
return *_Left <=> _Right;
}

return strong_ordering::less;
}
#endif // __cpp_lib_concepts

// FUNCTION TEMPLATE swap [optional.specalg]
template <class _Ty, enable_if_t<is_move_constructible_v<_Ty> && is_swappable_v<_Ty>, int> = 0>
void swap(optional<_Ty>& _Left, optional<_Ty>& _Right) noexcept(noexcept(_Left.swap(_Right))) {
Expand Down
233 changes: 0 additions & 233 deletions stl/inc/regex
Original file line number Diff line number Diff line change
Expand Up @@ -730,35 +730,6 @@ template <class _BidIt>
_NODISCARD auto operator<=>(const sub_match<_BidIt>& _Left, const sub_match<_BidIt>& _Right) {
return static_cast<typename sub_match<_BidIt>::_Comparison_category>(_Left.compare(_Right) <=> 0);
}

#if !defined(__clang__) && !defined(__EDG__) // TRANSITION, VSO-900973
// The compiler incorrectly performs overload resolution by preferring implicit conversions over rewrites.
// In C++20 mode the only required comparison operators should be == and <=>.
template <class _BidIt>
_NODISCARD bool operator!=(const sub_match<_BidIt>& _Left, const sub_match<_BidIt>& _Right) {
return !(_Left == _Right);
}

template <class _BidIt>
_NODISCARD bool operator<(const sub_match<_BidIt>& _Left, const sub_match<_BidIt>& _Right) {
return (_Left <=> _Right) < 0;
}

template <class _BidIt>
_NODISCARD bool operator>(const sub_match<_BidIt>& _Left, const sub_match<_BidIt>& _Right) {
return (_Left <=> _Right) > 0;
}

template <class _BidIt>
_NODISCARD bool operator<=(const sub_match<_BidIt>& _Left, const sub_match<_BidIt>& _Right) {
return (_Left <=> _Right) <= 0;
}

template <class _BidIt>
_NODISCARD bool operator>=(const sub_match<_BidIt>& _Left, const sub_match<_BidIt>& _Right) {
return (_Left <=> _Right) >= 0;
}
#endif // TRANSITION, VSO-900973
#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv
template <class _BidIt>
_NODISCARD bool operator!=(const sub_match<_BidIt>& _Left, const sub_match<_BidIt>& _Right) {
Expand Down Expand Up @@ -797,70 +768,6 @@ template <class _BidIt>
_NODISCARD auto operator<=>(const sub_match<_BidIt>& _Left, const _Iter_value_t<_BidIt>* _Right) {
return static_cast<typename sub_match<_BidIt>::_Comparison_category>(_Left.compare(_Right) <=> 0);
}

#if !defined(__clang__) && !defined(__EDG__) // TRANSITION, VSO-900973
// The compiler incorrectly performs overload resolution by preferring implicit conversions over rewrites.
// In C++20 mode the only required comparison operators should be == and <=>.
template <class _BidIt>
_NODISCARD auto operator<=>(const _Iter_value_t<_BidIt>* _Left, const sub_match<_BidIt>& _Right) {
return static_cast<typename sub_match<_BidIt>::_Comparison_category>(0 <=> (_Right <=> _Left));
}

template <class _BidIt>
_NODISCARD bool operator==(const _Iter_value_t<_BidIt>* _Left, const sub_match<_BidIt>& _Right) {
return _Right._Match_equal(_Left);
}

template <class _BidIt>
_NODISCARD bool operator!=(const _Iter_value_t<_BidIt>* _Left, const sub_match<_BidIt>& _Right) {
return !(_Left == _Right);
}

template <class _BidIt>
_NODISCARD bool operator<(const _Iter_value_t<_BidIt>* _Left, const sub_match<_BidIt>& _Right) {
return (_Left <=> _Right) < 0;
}

template <class _BidIt>
_NODISCARD bool operator>(const _Iter_value_t<_BidIt>* _Left, const sub_match<_BidIt>& _Right) {
return (_Left <=> _Right) > 0;
}

template <class _BidIt>
_NODISCARD bool operator<=(const _Iter_value_t<_BidIt>* _Left, const sub_match<_BidIt>& _Right) {
return (_Left <=> _Right) <= 0;
}

template <class _BidIt>
_NODISCARD bool operator>=(const _Iter_value_t<_BidIt>* _Left, const sub_match<_BidIt>& _Right) {
return (_Left <=> _Right) >= 0;
}

template <class _BidIt>
_NODISCARD bool operator!=(const sub_match<_BidIt>& _Left, const _Iter_value_t<_BidIt>* _Right) {
return !(_Left == _Right);
}

template <class _BidIt>
_NODISCARD bool operator<(const sub_match<_BidIt>& _Left, const _Iter_value_t<_BidIt>* _Right) {
return (_Left <=> _Right) < 0;
}

template <class _BidIt>
_NODISCARD bool operator>(const sub_match<_BidIt>& _Left, const _Iter_value_t<_BidIt>* _Right) {
return (_Left <=> _Right) > 0;
}

template <class _BidIt>
_NODISCARD bool operator<=(const sub_match<_BidIt>& _Left, const _Iter_value_t<_BidIt>* _Right) {
return (_Left <=> _Right) <= 0;
}

template <class _BidIt>
_NODISCARD bool operator>=(const sub_match<_BidIt>& _Left, const _Iter_value_t<_BidIt>* _Right) {
return (_Left <=> _Right) >= 0;
}
#endif // TRANSTITION, VSO-900973
#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv
template <class _BidIt>
_NODISCARD bool operator==(const _Iter_value_t<_BidIt>* _Left, const sub_match<_BidIt>& _Right) {
Expand Down Expand Up @@ -930,70 +837,6 @@ _NODISCARD auto operator<=>(const sub_match<_BidIt>& _Left, const _Iter_value_t<
return static_cast<typename sub_match<_BidIt>::_Comparison_category>(
_Left._Compare(_STD addressof(_Right), 1) <=> 0);
}

#if !defined(__clang__) && !defined(__EDG__) // TRANSITION, VSO-900973
// The compiler incorrectly performs overload resolution by preferring implicit conversions over rewrites.
// In C++20 mode the only required comparison operators should be == and <=>.
template <class _BidIt>
_NODISCARD auto operator<=>(const _Iter_value_t<_BidIt>& _Left, const sub_match<_BidIt>& _Right) {
return static_cast<typename sub_match<_BidIt>::_Comparison_category>(0 <=> (_Right <=> _Left));
}

template <class _BidIt>
_NODISCARD bool operator==(const _Iter_value_t<_BidIt>& _Left, const sub_match<_BidIt>& _Right) {
return _Right._Match_equal(_STD addressof(_Left), 1);
}

template <class _BidIt>
_NODISCARD bool operator!=(const _Iter_value_t<_BidIt>& _Left, const sub_match<_BidIt>& _Right) {
return !(_Left == _Right);
}

template <class _BidIt>
_NODISCARD bool operator<(const _Iter_value_t<_BidIt>& _Left, const sub_match<_BidIt>& _Right) {
return (_Left <=> _Right) < 0;
}

template <class _BidIt>
_NODISCARD bool operator>(const _Iter_value_t<_BidIt>& _Left, const sub_match<_BidIt>& _Right) {
return (_Left <=> _Right) > 0;
}

template <class _BidIt>
_NODISCARD bool operator<=(const _Iter_value_t<_BidIt>& _Left, const sub_match<_BidIt>& _Right) {
return (_Left <=> _Right) <= 0;
}

template <class _BidIt>
_NODISCARD bool operator>=(const _Iter_value_t<_BidIt>& _Left, const sub_match<_BidIt>& _Right) {
return (_Left <=> _Right) >= 0;
}

template <class _BidIt>
_NODISCARD bool operator!=(const sub_match<_BidIt>& _Left, const _Iter_value_t<_BidIt>& _Right) {
return !(_Left == _Right);
}

template <class _BidIt>
_NODISCARD bool operator<(const sub_match<_BidIt>& _Left, const _Iter_value_t<_BidIt>& _Right) {
return (_Left <=> _Right) < 0;
}

template <class _BidIt>
_NODISCARD bool operator>(const sub_match<_BidIt>& _Left, const _Iter_value_t<_BidIt>& _Right) {
return (_Left <=> _Right) > 0;
}

template <class _BidIt>
_NODISCARD bool operator<=(const sub_match<_BidIt>& _Left, const _Iter_value_t<_BidIt>& _Right) {
return (_Left <=> _Right) <= 0;
}

template <class _BidIt>
_NODISCARD bool operator>=(const sub_match<_BidIt>& _Left, const _Iter_value_t<_BidIt>& _Right) {
return (_Left <=> _Right) >= 0;
}
#endif // TRANSITION, VSO-900973
#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv
template <class _BidIt>
_NODISCARD bool operator==(const _Iter_value_t<_BidIt>& _Left, const sub_match<_BidIt>& _Right) {
Expand Down Expand Up @@ -1064,82 +907,6 @@ _NODISCARD auto operator<=>(
const sub_match<_BidIt>& _Left, const basic_string<_Iter_value_t<_BidIt>, _Traits, _Alloc>& _Right) {
return static_cast<typename sub_match<_BidIt>::_Comparison_category>(_Left.compare(_Right) <=> 0);
}

#if !defined(__clang__) && !defined(__EDG__) // TRANSITION, VSO-900973
// The compiler incorrectly performs overload resolution by preferring implicit conversions over rewrites.
// In C++20 mode the only required comparison operators should be == and <=>.
template <class _BidIt, class _Traits, class _Alloc>
_NODISCARD auto operator<=>(
const basic_string<_Iter_value_t<_BidIt>, _Traits, _Alloc>& _Left, const sub_match<_BidIt>& _Right) {
return static_cast<typename sub_match<_BidIt>::_Comparison_category>(0 <=> (_Right <=> _Left));
}

template <class _BidIt, class _Traits, class _Alloc>
_NODISCARD bool operator==(
const basic_string<_Iter_value_t<_BidIt>, _Traits, _Alloc>& _Left, const sub_match<_BidIt>& _Right) {
return _Right._Match_equal(_Left.data(), _Left.size());
}

template <class _BidIt, class _Traits, class _Alloc>
_NODISCARD bool operator!=(
const basic_string<_Iter_value_t<_BidIt>, _Traits, _Alloc>& _Left, const sub_match<_BidIt>& _Right) {
return !(_Left == _Right);
}

template <class _BidIt, class _Traits, class _Alloc>
_NODISCARD bool operator<(
const basic_string<_Iter_value_t<_BidIt>, _Traits, _Alloc>& _Left, const sub_match<_BidIt>& _Right) {
return (_Left <=> _Right) < 0;
}

template <class _BidIt, class _Traits, class _Alloc>
_NODISCARD bool operator>(
const basic_string<_Iter_value_t<_BidIt>, _Traits, _Alloc>& _Left, const sub_match<_BidIt>& _Right) {
return (_Left <=> _Right) > 0;
}

template <class _BidIt, class _Traits, class _Alloc>
_NODISCARD bool operator<=(
const basic_string<_Iter_value_t<_BidIt>, _Traits, _Alloc>& _Left, const sub_match<_BidIt>& _Right) {
return (_Left <=> _Right) <= 0;
}

template <class _BidIt, class _Traits, class _Alloc>
_NODISCARD bool operator>=(
const basic_string<_Iter_value_t<_BidIt>, _Traits, _Alloc>& _Left, const sub_match<_BidIt>& _Right) {
return (_Left <=> _Right) >= 0;
}

template <class _BidIt, class _Traits, class _Alloc>
_NODISCARD bool operator!=(
const sub_match<_BidIt>& _Left, const basic_string<_Iter_value_t<_BidIt>, _Traits, _Alloc>& _Right) {
return !(_Left == _Right);
}

template <class _BidIt, class _Traits, class _Alloc>
_NODISCARD bool operator<(
const sub_match<_BidIt>& _Left, const basic_string<_Iter_value_t<_BidIt>, _Traits, _Alloc>& _Right) {
return (_Left <=> _Right) < 0;
}

template <class _BidIt, class _Traits, class _Alloc>
_NODISCARD bool operator>(
const sub_match<_BidIt>& _Left, const basic_string<_Iter_value_t<_BidIt>, _Traits, _Alloc>& _Right) {
return (_Left <=> _Right) > 0;
}

template <class _BidIt, class _Traits, class _Alloc>
_NODISCARD bool operator<=(
const sub_match<_BidIt>& _Left, const basic_string<_Iter_value_t<_BidIt>, _Traits, _Alloc>& _Right) {
return (_Left <=> _Right) <= 0;
}

template <class _BidIt, class _Traits, class _Alloc>
_NODISCARD bool operator>=(
const sub_match<_BidIt>& _Left, const basic_string<_Iter_value_t<_BidIt>, _Traits, _Alloc>& _Right) {
return (_Left <=> _Right) >= 0;
}
#endif // TRANSITION, VSO-900973
#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv
template <class _BidIt, class _Traits, class _Alloc>
_NODISCARD bool operator==(
Expand Down
Loading