Skip to content

Commit 27a5dd1

Browse files
committed
Eq and Ord require noexcept
1 parent d1875e4 commit 27a5dd1

File tree

12 files changed

+75
-64
lines changed

12 files changed

+75
-64
lines changed

subspace/choice/__private/nothing.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,13 @@
1818

1919
namespace sus::choice_type::__private {
2020

21-
struct Nothing {};
22-
constexpr auto nothing = Nothing();
23-
24-
constexpr bool operator==(const Nothing&, const Nothing&) { return true; }
25-
constexpr auto operator<=>(const Nothing&, const Nothing&) {
26-
return std::strong_ordering::equivalent;
27-
}
21+
struct Nothing {
22+
friend constexpr bool operator==(const Nothing&, const Nothing&) noexcept {
23+
return true;
24+
}
25+
friend constexpr auto operator<=>(const Nothing&, const Nothing&) noexcept {
26+
return std::strong_ordering::equivalent;
27+
}
28+
};
2829

2930
} // namespace sus::choice_type::__private

subspace/choice/__private/ops_concepts.h

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -20,99 +20,99 @@
2020

2121
namespace sus::choice_type::__private {
2222

23-
template <class ValueType1, class Types1, class ValueType2, class Types2>
23+
template <class TagType1, class Types1, class TagType2, class Types2>
2424
struct ChoiceIsEqHelper;
2525

26-
template <class ValueType1, class... Types1, class ValueType2, class... Types2>
27-
struct ChoiceIsEqHelper<ValueType1, TypeList<Types1...>, ValueType2,
26+
template <class TagType1, class... Types1, class TagType2, class... Types2>
27+
struct ChoiceIsEqHelper<TagType1, TypeList<Types1...>, TagType2,
2828
TypeList<Types2...>> {
29-
static constexpr bool value = (::sus::ops::Eq<ValueType1, ValueType2> &&
30-
... && ::sus::ops::Eq<Types1, Types2>);
29+
static constexpr bool value = (::sus::ops::Eq<TagType1, TagType2> && ... &&
30+
::sus::ops::Eq<Types1, Types2>);
3131
};
3232

3333
// Out of line from the requires clause, and in a struct, to work around
3434
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108067.
35-
template <class ValueType1, class Types1, class ValueType2, class Types2>
35+
template <class TagType1, class Types1, class TagType2, class Types2>
3636
concept ChoiceIsEq =
37-
ChoiceIsEqHelper<ValueType1, Types1, ValueType2, Types2>::value;
37+
ChoiceIsEqHelper<TagType1, Types1, TagType2, Types2>::value;
3838

39-
template <class ValueType1, class Types1, class ValueType2, class Types2>
39+
template <class TagType1, class Types1, class TagType2, class Types2>
4040
struct ChoiceIsOrdHelper;
4141

42-
template <class ValueType1, class... Types1, class ValueType2, class... Types2>
43-
struct ChoiceIsOrdHelper<ValueType1, TypeList<Types1...>, ValueType2,
42+
template <class TagType1, class... Types1, class TagType2, class... Types2>
43+
struct ChoiceIsOrdHelper<TagType1, TypeList<Types1...>, TagType2,
4444
TypeList<Types2...>> {
45-
static constexpr bool value = (::sus::ops::Ord<ValueType1, ValueType2> &&
46-
... && ::sus::ops::Ord<Types1, Types2>);
45+
static constexpr bool value = (::sus::ops::Ord<TagType1, TagType2> && ... &&
46+
::sus::ops::Ord<Types1, Types2>);
4747
};
4848

4949
// Out of line from the requires clause, and in a struct, to work around
5050
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108067.
51-
template <class ValueType1, class Types1, class ValueType2, class Types2>
51+
template <class TagType1, class Types1, class TagType2, class Types2>
5252
concept ChoiceIsOrd =
53-
ChoiceIsOrdHelper<ValueType1, Types1, ValueType2, Types2>::value;
53+
ChoiceIsOrdHelper<TagType1, Types1, TagType2, Types2>::value;
5454

55-
template <class ValueType1, class Types1, class ValueType2, class Types2>
55+
template <class TagType1, class Types1, class TagType2, class Types2>
5656
struct ChoiceIsWeakOrdHelper;
5757

58-
template <class ValueType1, class... Types1, class ValueType2, class... Types2>
59-
struct ChoiceIsWeakOrdHelper<ValueType1, TypeList<Types1...>, ValueType2,
58+
template <class TagType1, class... Types1, class TagType2, class... Types2>
59+
struct ChoiceIsWeakOrdHelper<TagType1, TypeList<Types1...>, TagType2,
6060
TypeList<Types2...>> {
6161
// clang-format off
6262
static constexpr bool value =
63-
((!::sus::ops::Ord<ValueType1, ValueType2> || ... ||
63+
((!::sus::ops::Ord<TagType1, TagType2> || ... ||
6464
!::sus::ops::Ord<Types1, Types2>)
6565
&&
66-
(::sus::ops::WeakOrd<ValueType1, ValueType2> && ... &&
66+
(::sus::ops::WeakOrd<TagType1, TagType2> && ... &&
6767
::sus::ops::WeakOrd<Types1, Types2>));
6868
// clang-format on
6969
};
7070

7171
// Out of line from the requires clause, in a struct, to work around
7272
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108067.
73-
template <class ValueType1, class Types1, class ValueType2, class Types2>
73+
template <class TagType1, class Types1, class TagType2, class Types2>
7474
concept ChoiceIsWeakOrd =
75-
ChoiceIsWeakOrdHelper<ValueType1, Types1, ValueType2, Types2>::value;
75+
ChoiceIsWeakOrdHelper<TagType1, Types1, TagType2, Types2>::value;
7676

77-
template <class ValueType1, class Types1, class ValueType2, class Types2>
77+
template <class TagType1, class Types1, class TagType2, class Types2>
7878
struct ChoiceIsPartialOrdHelper;
7979

80-
template <class ValueType1, class... Types1, class ValueType2, class... Types2>
81-
struct ChoiceIsPartialOrdHelper<ValueType1, TypeList<Types1...>, ValueType2,
80+
template <class TagType1, class... Types1, class TagType2, class... Types2>
81+
struct ChoiceIsPartialOrdHelper<TagType1, TypeList<Types1...>, TagType2,
8282
TypeList<Types2...>> {
8383
// clang-format off
8484
static constexpr bool value =
85-
(!::sus::ops::WeakOrd<ValueType1, ValueType2> || ... ||
85+
(!::sus::ops::WeakOrd<TagType1, TagType2> || ... ||
8686
!::sus::ops::WeakOrd<Types1, Types2>)
8787
&&
88-
(::sus::ops::PartialOrd<ValueType1, ValueType2> && ... &&
88+
(::sus::ops::PartialOrd<TagType1, TagType2> && ... &&
8989
::sus::ops::PartialOrd<Types1, Types2>);
9090
// clang-format on
9191
};
9292

9393
// Out of line from the requires clause, in a struct, to work around
9494
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108067.
95-
template <class ValueType1, class Types1, class ValueType2, class Types2>
95+
template <class TagType1, class Types1, class TagType2, class Types2>
9696
concept ChoiceIsPartialOrd =
97-
ChoiceIsPartialOrdHelper<ValueType1, Types1, ValueType2, Types2>::value;
97+
ChoiceIsPartialOrdHelper<TagType1, Types1, TagType2, Types2>::value;
9898

99-
template <class ValueType1, class Types1, class ValueType2, class Types2>
99+
template <class TagType1, class Types1, class TagType2, class Types2>
100100
struct ChoiceIsAnyOrdHelper;
101101

102-
template <class ValueType1, class... Types1, class ValueType2, class... Types2>
103-
struct ChoiceIsAnyOrdHelper<ValueType1, TypeList<Types1...>, ValueType2,
102+
template <class TagType1, class... Types1, class TagType2, class... Types2>
103+
struct ChoiceIsAnyOrdHelper<TagType1, TypeList<Types1...>, TagType2,
104104
TypeList<Types2...>> {
105105
// clang-format off
106106
static constexpr bool value =
107-
(::sus::ops::PartialOrd<ValueType1, ValueType2> && ... &&
107+
(::sus::ops::PartialOrd<TagType1, TagType2> && ... &&
108108
::sus::ops::PartialOrd<Types1, Types2>);
109109
// clang-format on
110110
};
111111

112112
// Out of line from the requires clause, in a struct, to work around
113113
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108067.
114-
template <class ValueType1, class Types1, class ValueType2, class Types2>
114+
template <class TagType1, class Types1, class TagType2, class Types2>
115115
concept ChoiceIsAnyOrd =
116-
ChoiceIsAnyOrdHelper<ValueType1, Types1, ValueType2, Types2>::value;
116+
ChoiceIsAnyOrdHelper<TagType1, Types1, TagType2, Types2>::value;
117117

118118
} // namespace sus::choice_type::__private

subspace/choice/__private/storage.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -476,19 +476,19 @@ union Storage<I, ::sus::Tuple<Ts...>> {
476476
::sus::check(index == I);
477477
tuple_.~Type();
478478
}
479-
inline constexpr bool eq(size_t index, const Storage& other) const& {
479+
inline constexpr bool eq(size_t index, const Storage& other) const& noexcept {
480480
::sus::check(index == I);
481481
return tuple_ == other.tuple_;
482482
}
483-
inline constexpr auto ord(size_t index, const Storage& other) const& {
483+
inline constexpr auto ord(size_t index, const Storage& other) const& noexcept {
484484
::sus::check(index == I);
485485
return std::strong_order(tuple_, other.tuple_);
486486
}
487-
inline constexpr auto weak_ord(size_t index, const Storage& other) const& {
487+
inline constexpr auto weak_ord(size_t index, const Storage& other) const& noexcept {
488488
::sus::check(index == I);
489489
return std::weak_order(tuple_, other.tuple_);
490490
}
491-
inline constexpr auto partial_ord(size_t index, const Storage& other) const& {
491+
inline constexpr auto partial_ord(size_t index, const Storage& other) const& noexcept {
492492
::sus::check(index == I);
493493
return std::partial_order(tuple_, other.tuple_);
494494
}

subspace/choice/choice_unittest.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -622,10 +622,10 @@ TEST(Choice, StrongOrder) {
622622
struct Weak {
623623
sus_clang_bug_54040(constexpr inline Weak(i32 a, i32 b) : a(a), b(b){});
624624

625-
constexpr auto operator==(const Weak& o) const& {
625+
constexpr auto operator==(const Weak& o) const& noexcept {
626626
return a == o.a && b == o.b;
627627
}
628-
constexpr auto operator<=>(const Weak& o) const& {
628+
constexpr auto operator<=>(const Weak& o) const& noexcept {
629629
if (a == o.a) return std::weak_ordering::equivalent;
630630
if (a < o.a) return std::weak_ordering::less;
631631
return std::weak_ordering::greater;

subspace/containers/array_unittest.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -356,8 +356,8 @@ TEST(Array, StrongOrder) {
356356
}
357357

358358
struct Weak final {
359-
auto operator==(const Weak& o) const& { return a == o.a && b == o.b; }
360-
auto operator<=>(const Weak& o) const& {
359+
auto operator==(const Weak& o) const& noexcept { return a == o.a && b == o.b; }
360+
auto operator<=>(const Weak& o) const& noexcept {
361361
if (a == o.a) return std::weak_ordering::equivalent;
362362
if (a < o.a) return std::weak_ordering::less;
363363
return std::weak_ordering::greater;

subspace/ops/eq.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ namespace sus::ops {
3737
/// TODO: How do we do PartialEq? Can we even? Should we require Ord to be Eq?
3838
template <class T, class U = T>
3939
concept Eq = requires(const T& lhs, const U& rhs) {
40-
{ lhs == rhs } -> std::same_as<bool>;
41-
{ lhs != rhs } -> std::same_as<bool>;
42-
};
40+
{ lhs == rhs } noexcept -> std::same_as<bool>;
41+
{ lhs != rhs } noexcept -> std::same_as<bool>;
42+
};
4343

4444
} // namespace sus::ops

subspace/ops/eq_unittest.cc

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,14 @@ using sus::ops::Eq;
2222

2323
struct CComp {};
2424
struct C {
25-
friend bool operator==(const C&, const C&) { return true; }
26-
friend bool operator==(const C&, const CComp&) { return true; }
25+
friend bool operator==(const C&, const C&) noexcept { return true; }
26+
friend bool operator==(const C&, const CComp&) noexcept { return true; }
27+
};
28+
29+
struct E {
30+
// Not noexcept.
31+
friend bool operator==(const E&, const E&) { return true; }
32+
friend bool operator==(const E&, const CComp&) { return true; }
2733
};
2834

2935
// These types are comparable.
@@ -33,6 +39,10 @@ static_assert(Eq<C>);
3339
static_assert(Eq<C, C>);
3440
static_assert(Eq<C, CComp>);
3541

42+
// Not noexcept.
43+
static_assert(!Eq<E>);
44+
static_assert(!Eq<E, CComp>);
45+
3646
struct S {}; // No operator==.
3747

3848
// These types are not comparable.

subspace/ops/ord.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ concept Ordering = (std::same_as<T, std::strong_ordering> ||
3838
/// Concept for types that form a total order (aka `std::strong_ordering`).
3939
template <class T, class U = T>
4040
concept Ord = requires(const T& lhs, const U& rhs) {
41-
{ lhs <=> rhs } -> std::same_as<std::strong_ordering>;
41+
{ lhs <=> rhs } noexcept -> std::same_as<std::strong_ordering>;
4242
};
4343

4444
/// Concept for types that form a weak ordering (aka `std::weak_ordering`).
@@ -48,7 +48,7 @@ concept Ord = requires(const T& lhs, const U& rhs) {
4848
/// strongest type of ordering between the types, use `ExclusiveWeakOrd`.
4949
template <class T, class U = T>
5050
concept WeakOrd = Ord<T, U> || requires(const T& lhs, const U& rhs) {
51-
{ lhs <=> rhs } -> std::same_as<std::weak_ordering>;
51+
{ lhs <=> rhs } noexcept -> std::same_as<std::weak_ordering>;
5252
};
5353

5454
/// Concept for types that form a partial ordering (aka
@@ -60,7 +60,7 @@ concept WeakOrd = Ord<T, U> || requires(const T& lhs, const U& rhs) {
6060
template <class T, class U = T>
6161
concept PartialOrd =
6262
WeakOrd<T, U> || Ord<T, U> || requires(const T& lhs, const U& rhs) {
63-
{ lhs <=> rhs } -> std::same_as<std::partial_ordering>;
63+
{ lhs <=> rhs } noexcept -> std::same_as<std::partial_ordering>;
6464
};
6565

6666
/// Concept for types that have a total ordering (aka `std::strong_ordering`).

subspace/ops/ord_unittest.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ struct Strong {
3535
i32 i;
3636
i32 id;
3737

38-
friend std::strong_ordering operator<=>(const Strong& a, const Strong& b) {
38+
friend std::strong_ordering operator<=>(const Strong& a, const Strong& b) noexcept {
3939
return a.i <=> b.i;
4040
}
4141
};

subspace/option/option_unittest.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1637,8 +1637,8 @@ TEST(Option, StrongOrder) {
16371637
}
16381638

16391639
struct Weak {
1640-
auto operator==(const Weak& o) const& { return a == o.a && b == o.b; }
1641-
auto operator<=>(const Weak& o) const& {
1640+
auto operator==(const Weak& o) const& noexcept { return a == o.a && b == o.b; }
1641+
auto operator<=>(const Weak& o) const& noexcept {
16421642
if (a == o.a) return std::weak_ordering::equivalent;
16431643
if (a < o.a) return std::weak_ordering::less;
16441644
return std::weak_ordering::greater;

0 commit comments

Comments
 (0)