struct B {};
template<typename T = void>
bool operator<(const B&, const B&) = default;
struct A {
friend bool operator==(const A&, const A&) = default;
friend bool operator!=(const A&, const B&) = default; friend bool operator!=(const B&, const B&) = default; friend bool operator<(const A&, const A&);
friend bool operator<(const B&, const B&) = default; friend bool operator>(A, A) = default;
bool operator<(const A&) const;
bool operator<=(const A&) const = default;
bool operator==(const A&) const volatile && = default; bool operator<=>(const A&) = default; bool operator>=(const B&) const = default; static bool operator>(const B&) = default; friend bool operator>(A, const A&) = default;
template<typename T = void>
friend bool operator==(const A&, const A&) = default; template<typename T = void>
bool operator==(const A&) const = default; };
template<typename T> struct Dependent {
using U = typename T::type;
bool operator==(U) const = default; friend bool operator==(U, U) = default; };
struct Good { using type = const Dependent<Good>&; };
template struct Dependent<Good>;
struct Bad { using type = Dependent<Bad>&; };
template struct Dependent<Bad>;
namespace std {
struct strong_ordering {
int n;
constexpr operator int() const { return n; }
static const strong_ordering equal, greater, less;
};
constexpr strong_ordering strong_ordering::equal = {0};
constexpr strong_ordering strong_ordering::greater = {1};
constexpr strong_ordering strong_ordering::less = {-1};
}
namespace LookupContext {
struct A {};
namespace N {
template <typename T> auto f() {
bool operator==(const T &, const T &);
bool operator<(const T &, const T &);
struct B {
T a;
std::strong_ordering operator<=>(const B &) const = default;
};
return B();
}
auto g() {
struct Cmp { Cmp(std::strong_ordering); };
Cmp operator<=>(const A&, const A&);
bool operator!=(const Cmp&, int);
struct B {
A a;
Cmp operator<=>(const B &) const = default;
};
return B();
}
auto h() {
struct B;
bool operator==(const B&, const B&);
bool operator!=(const B&, const B&); std::strong_ordering operator<=>(const B&, const B&);
bool operator<(const B&, const B&); bool operator<=(const B&, const B&); bool operator>(const B&, const B&); bool operator>=(const B&, const B&);
struct B {
bool operator!=(const B&) const = default; bool operator<(const B&) const = default; bool operator<=(const B&) const = default; bool operator>(const B&) const = default; bool operator>=(const B&) const = default; };
return B();
}
}
namespace M {
bool operator==(const A &, const A &) = delete;
bool operator<(const A &, const A &) = delete;
bool cmp = N::f<A>() < N::f<A>();
void operator<=>(const A &, const A &) = delete;
auto cmp2 = N::g() <=> N::g();
void use_h() {
N::h() != N::h(); N::h() < N::h(); N::h() <= N::h(); N::h() > N::h(); N::h() >= N::h(); }
}
}
namespace evil1 {
template <class T> struct Bad {
bool operator==(T const &) const = default;
Bad(int = 0);
};
template <class T> struct Weird {
bool operator==(typename T::Weird_ const &) const = default;
Weird(int = 0);
};
struct evil {
using Weird_ = Weird<evil>;
};
template struct Bad<float>; template struct Weird<float>; template struct Weird<evil>;
}
namespace P1946 {
struct A {
friend bool operator==(A &, A &); };
struct B {
A a; friend bool operator==(B, B) = default; friend bool operator==(const B&, const B&) = default; };
}
namespace p2085 {
struct S1 {
bool operator==(S1 const &) const;
};
bool S1::operator==(S1 const &) const = default;
bool F1(S1 &s) {
return s != s;
}
struct S2 {
friend bool operator==(S2 const &, S2 const &);
};
bool operator==(S2 const &, S2 const &) = default;
bool F2(S2 &s) {
return s != s;
}
struct S3 {}; bool operator==(S3 const &, S3 const &) = default;
struct S4; bool operator==(S4 const &, S4 const &) = default;
struct S5; bool operator==(S5, S5) = default;
enum e {};
bool operator==(e, int) = default;
bool operator==(e *, int *) = default; }
namespace p2085_2 {
template <class T> struct S6 {
bool operator==(T const &) const;
};
template <class T> bool S6<T>::operator==(T const &) const = default;
template struct S6<int>;
void f1() {
S6<float> a;
(void)(a == 0); }
template <class T> struct S7 {
bool operator==(typename T::S7_ const &) const;
S7(int = 0);
};
template <class T> bool S7<T>::operator==(typename T::S7_ const &) const = default;
struct evil {
using S7_ = S7<evil>;
};
template struct S7<float>;
void f2() {
S7<int> a; S7<evil> b;
(void)(a == 0); (void)(b == 0);
}
}