brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.6 KiB · c73eb0d Raw
209 lines · cpp
1// This test is for the [class.compare.default]p3 added by P2002R02// Also covers modifications made by P2448R23 4// RUN: %clang_cc1 -std=c++2a -verify=expected,cxx2a %s5// RUN: %clang_cc1 -std=c++23 -verify=expected %s6 7namespace std {8  struct strong_ordering {9    int n;10    constexpr operator int() const { return n; }11    static const strong_ordering less, equal, greater;12  };13  constexpr strong_ordering strong_ordering::less = {-1};14  constexpr strong_ordering strong_ordering::equal = {0};15  constexpr strong_ordering strong_ordering::greater = {1};16}17 18struct A {19  friend bool operator==(const A&, const A&) = default;20  friend bool operator!=(const A&, const A&) = default;21 22  friend std::strong_ordering operator<=>(const A&, const A&) = default;23  friend bool operator<(const A&, const A&) = default;24  friend bool operator<=(const A&, const A&) = default;25  friend bool operator>(const A&, const A&) = default;26  friend bool operator>=(const A&, const A&) = default;27};28struct TestA {29  friend constexpr bool operator==(const A&, const A&) noexcept;30  friend constexpr bool operator!=(const A&, const A&) noexcept;31 32  friend constexpr std::strong_ordering operator<=>(const A&, const A&) noexcept;33  friend constexpr bool operator<(const A&, const A&);34  friend constexpr bool operator<=(const A&, const A&);35  friend constexpr bool operator>(const A&, const A&);36  friend constexpr bool operator>=(const A&, const A&);37};38 39// Declaration order doesn't matter, even though the secondary operators need40// to know whether the primary ones are constexpr.41struct ReversedA {42  friend bool operator>=(const ReversedA&, const ReversedA&) = default;43  friend bool operator>(const ReversedA&, const ReversedA&) = default;44  friend bool operator<=(const ReversedA&, const ReversedA&) = default;45  friend bool operator<(const ReversedA&, const ReversedA&) = default;46  friend std::strong_ordering operator<=>(const ReversedA&, const ReversedA&) = default;47 48  friend bool operator!=(const ReversedA&, const ReversedA&) = default;49  friend bool operator==(const ReversedA&, const ReversedA&) = default;50};51struct TestReversedA {52  friend constexpr bool operator>=(const ReversedA&, const ReversedA&);53  friend constexpr bool operator>(const ReversedA&, const ReversedA&);54  friend constexpr bool operator<=(const ReversedA&, const ReversedA&);55  friend constexpr bool operator<(const ReversedA&, const ReversedA&);56  friend constexpr std::strong_ordering operator<=>(const ReversedA&, const ReversedA&) noexcept;57 58  friend constexpr bool operator!=(const ReversedA&, const ReversedA&) noexcept;59  friend constexpr bool operator==(const ReversedA&, const ReversedA&) noexcept;60};61 62struct B {63  A a;64  friend bool operator==(const B&, const B&) = default;65  friend bool operator!=(const B&, const B&) = default;66 67  friend std::strong_ordering operator<=>(const B&, const B&) = default;68  friend bool operator<(const B&, const B&) = default;69  friend bool operator<=(const B&, const B&) = default;70  friend bool operator>(const B&, const B&) = default;71  friend bool operator>=(const B&, const B&) = default;72};73struct TestB {74  friend constexpr bool operator==(const B&, const B&) noexcept;75  friend constexpr bool operator!=(const B&, const B&) noexcept;76 77  friend constexpr std::strong_ordering operator<=>(const B&, const B&);78  friend constexpr bool operator<(const B&, const B&);79  friend constexpr bool operator<=(const B&, const B&);80  friend constexpr bool operator>(const B&, const B&);81  friend constexpr bool operator>=(const B&, const B&);82};83 84struct C {85  friend bool operator==(const C&, const C&); // expected-note {{previous}} \86                                              // cxx2a-note 2{{declared here}}87  friend bool operator!=(const C&, const C&) = default; // expected-note {{previous}}88 89  friend std::strong_ordering operator<=>(const C&, const C&); // expected-note {{previous}} \90                                                               // cxx2a-note 2{{declared here}}91  friend bool operator<(const C&, const C&) = default; // expected-note {{previous}}92  friend bool operator<=(const C&, const C&) = default; // expected-note {{previous}}93  friend bool operator>(const C&, const C&) = default; // expected-note {{previous}}94  friend bool operator>=(const C&, const C&) = default; // expected-note {{previous}}95};96struct TestC {97  friend constexpr bool operator==(const C&, const C&); // expected-error {{non-constexpr}}98  friend constexpr bool operator!=(const C&, const C&); // expected-error {{non-constexpr}}99 100  friend constexpr std::strong_ordering operator<=>(const C&, const C&); // expected-error {{non-constexpr}}101  friend constexpr bool operator<(const C&, const C&); // expected-error {{non-constexpr}}102  friend constexpr bool operator<=(const C&, const C&); // expected-error {{non-constexpr}}103  friend constexpr bool operator>(const C&, const C&); // expected-error {{non-constexpr}}104  friend constexpr bool operator>=(const C&, const C&); // expected-error {{non-constexpr}}105};106 107struct D {108  A a;109  C c;110  A b;111  friend bool operator==(const D&, const D&) = default; // expected-note {{previous}}112  friend bool operator!=(const D&, const D&) = default; // expected-note {{previous}}113 114  friend std::strong_ordering operator<=>(const D&, const D&) = default; // expected-note {{previous}}115  friend bool operator<(const D&, const D&) = default; // expected-note {{previous}}116  friend bool operator<=(const D&, const D&) = default; // expected-note {{previous}}117  friend bool operator>(const D&, const D&) = default; // expected-note {{previous}}118  friend bool operator>=(const D&, const D&) = default; // expected-note {{previous}}119};120struct TestD {121  friend constexpr bool operator==(const D&, const D&); // expected-error {{non-constexpr}}122  friend constexpr bool operator!=(const D&, const D&); // expected-error {{non-constexpr}}123 124  friend constexpr std::strong_ordering operator<=>(const D&, const D&); // expected-error {{non-constexpr}}125  friend constexpr bool operator<(const D&, const D&); // expected-error {{non-constexpr}}126  friend constexpr bool operator<=(const D&, const D&); // expected-error {{non-constexpr}}127  friend constexpr bool operator>(const D&, const D&); // expected-error {{non-constexpr}}128  friend constexpr bool operator>=(const D&, const D&); // expected-error {{non-constexpr}}129};130 131 132struct E {133  A a;134  C c; // cxx2a-note 2{{non-constexpr comparison function would be used to compare member 'c'}}135  A b;136  friend constexpr bool operator==(const E&, const E&) = default; // cxx2a-error {{cannot be declared constexpr}}137  friend constexpr bool operator!=(const E&, const E&) = default;138 139  friend constexpr std::strong_ordering operator<=>(const E&, const E&) = default; // cxx2a-error {{cannot be declared constexpr}}140  friend constexpr bool operator<(const E&, const E&) = default;141  friend constexpr bool operator<=(const E&, const E&) = default;142  friend constexpr bool operator>(const E&, const E&) = default;143  friend constexpr bool operator>=(const E&, const E&) = default;144};145 146struct E2 : A, C { // cxx2a-note 2{{non-constexpr comparison function would be used to compare base class 'C'}}147  friend constexpr bool operator==(const E2&, const E2&) = default; // cxx2a-error {{cannot be declared constexpr}}148  friend constexpr bool operator!=(const E2&, const E2&) = default;149 150  friend constexpr std::strong_ordering operator<=>(const E2&, const E2&) = default; // cxx2a-error {{cannot be declared constexpr}}151  friend constexpr bool operator<(const E2&, const E2&) = default;152  friend constexpr bool operator<=(const E2&, const E2&) = default;153  friend constexpr bool operator>(const E2&, const E2&) = default;154  friend constexpr bool operator>=(const E2&, const E2&) = default;155};156 157struct F {158  friend bool operator==(const F&, const F&); // cxx2a-note {{declared here}}159  friend constexpr bool operator!=(const F&, const F&) = default; // cxx2a-error {{cannot be declared constexpr}}160 161  friend std::strong_ordering operator<=>(const F&, const F&); // cxx2a-note 4{{non-constexpr comparison function declared here}}162  friend constexpr bool operator<(const F&, const F&) = default; // cxx2a-error {{cannot be declared constexpr}}163  friend constexpr bool operator<=(const F&, const F&) = default; // cxx2a-error {{cannot be declared constexpr}}164  friend constexpr bool operator>(const F&, const F&) = default; // cxx2a-error {{cannot be declared constexpr}}165  friend constexpr bool operator>=(const F&, const F&) = default; // cxx2a-error {{cannot be declared constexpr}}166};167 168// No implicit 'constexpr' if it's not the first declaration.169// FIXME: This rule creates problems for reordering of declarations; is this170// really the right model?171struct G;172bool operator==(const G&, const G&); // expected-note {{previous declaration}}173bool operator!=(const G&, const G&); // expected-note {{previous declaration}}174std::strong_ordering operator<=>(const G&, const G&); // expected-note {{previous declaration}}175bool operator<(const G&, const G&); // expected-note {{previous declaration}}176bool operator<=(const G&, const G&); // expected-note {{previous declaration}}177bool operator>(const G&, const G&); // expected-note {{previous declaration}}178bool operator>=(const G&, const G&); // expected-note {{previous declaration}}179struct G {180  friend bool operator==(const G&, const G&) = default; // expected-error {{because it was already declared outside}}181  friend bool operator!=(const G&, const G&) = default; // expected-error {{because it was already declared outside}}182 183  friend std::strong_ordering operator<=>(const G&, const G&) = default; // expected-error {{because it was already declared outside}}184  friend bool operator<(const G&, const G&) = default; // expected-error {{because it was already declared outside}}185  friend bool operator<=(const G&, const G&) = default; // expected-error {{because it was already declared outside}}186  friend bool operator>(const G&, const G&) = default; // expected-error {{because it was already declared outside}}187  friend bool operator>=(const G&, const G&) = default; // expected-error {{because it was already declared outside}}188};189bool operator==(const G&, const G&);190bool operator!=(const G&, const G&);191 192std::strong_ordering operator<=>(const G&, const G&);193bool operator<(const G&, const G&);194bool operator<=(const G&, const G&);195bool operator>(const G&, const G&);196bool operator>=(const G&, const G&);197 198namespace PR44721 {199  template <typename T> bool operator==(T const &, T const &) { return true; }200  template <typename T, typename U> bool operator!=(T const &, U const &) { return true; }201  template <typename T> int operator<=>(T const &, T const &) { return 0; }202 203  struct S {204    friend bool operator==(const S &, const S &) = default;205    friend bool operator<=>(const S &, const S &) = default;206    int x;207  };208}209