namespace std {
class strong_ordering {
int n;
constexpr strong_ordering(int n) : n(n) {}
public:
static const strong_ordering less, equal, greater;
bool operator!=(int) { return n != 0; }
};
constexpr strong_ordering strong_ordering::less{-1},
strong_ordering::equal{0}, strong_ordering::greater{1};
class weak_ordering {
int n;
constexpr weak_ordering(int n) : n(n) {}
public:
constexpr weak_ordering(strong_ordering o);
static const weak_ordering less, equivalent, greater;
bool operator!=(int) { return n != 0; }
};
constexpr weak_ordering weak_ordering::less{-1},
weak_ordering::equivalent{0}, weak_ordering::greater{1};
class partial_ordering {
int n;
constexpr partial_ordering(int n) : n(n) {}
public:
constexpr partial_ordering(strong_ordering o);
constexpr partial_ordering(weak_ordering o);
static const partial_ordering less, equivalent, greater, unordered;
bool operator!=(int) { return n != 0; }
};
constexpr partial_ordering partial_ordering::less{-1},
partial_ordering::equivalent{0}, partial_ordering::greater{1},
partial_ordering::unordered{2};
}
namespace DeducedNotCat {
struct A {
A operator<=>(const A&) const; };
struct B {
A a; auto operator<=>(const B&) const = default; };
}
namespace DeducedVsSynthesized {
struct A {
bool operator==(const A&) const;
bool operator<(const A&) const;
};
struct B {
A a; auto operator<=>(const B&) const = default; };
}
namespace Deduction {
template<typename T> struct wrap {
T t;
friend auto operator<=>(const wrap&, const wrap&) = default;
};
using strong = wrap<int>;
using strong2 = wrap<int*>;
struct weak {
friend std::weak_ordering operator<=>(weak, weak);
};
using partial = wrap<float>;
template<typename ...T> struct A : T... {
friend auto operator<=>(const A&, const A&) = default;
};
template<typename Expected, typename ...Ts> void f() {
using T = Expected; using T = decltype(A<Ts...>() <=> A<Ts...>()); void(A<Ts...>() <=> A<Ts...>()); }
template void f<std::strong_ordering>();
template void f<std::strong_ordering, strong>();
template void f<std::strong_ordering, strong, strong2>();
template void f<std::weak_ordering, weak>();
template void f<std::weak_ordering, weak, strong>();
template void f<std::weak_ordering, strong, weak>();
template void f<std::partial_ordering, partial>();
template void f<std::partial_ordering, weak, partial>();
template void f<std::partial_ordering, strong, partial>();
template void f<std::partial_ordering, partial, weak>();
template void f<std::partial_ordering, partial, strong>();
template void f<std::partial_ordering, weak, partial, strong>();
template void f<std::strong_ordering, weak>();
std::strong_ordering x = A<strong>() <=> A<strong>();
}
namespace PR44723 {
template<int> struct a {
friend constexpr auto operator<=>(a const &lhs, a const &rhs) {
return std::strong_ordering::equal;
}
};
struct b {
friend constexpr auto operator<=>(b const &, b const &) = default;
a<0> m_value;
};
std::strong_ordering cmp_b = b() <=> b();
struct c {
auto operator<=>(const c&) const&; };
struct d : c { friend auto operator<=>(const d&, const d&) = default; };
auto c::operator<=>(const c&) const& { return std::strong_ordering::equal;
}
std::strong_ordering cmp_d = d() <=> d();
}
namespace BadDeducedType {
struct A {
friend auto &operator<=>(const A&, const A&) = default;
};
struct B {
friend const auto operator<=>(const B&, const B&) = default;
};
template<typename T> struct X {}; struct C {
friend X operator<=>(const C&, const C&) = default;
};
template<typename T> concept CmpCat = true;
struct D {
friend CmpCat auto operator<=>(const D&, const D&) = default;
};
}
namespace PR48856 {
struct A {
auto operator<=>(const A &) const = default; void (*x)(); };
struct B {
auto operator<=>(const B &) const = default; void (B::*x)(); };
struct C {
auto operator<=>(const C &) const = default; int C::*x; };
}
namespace PR50591 {
struct a1 {
operator int() const;
};
struct b1 {
auto operator<=>(b1 const &) const = default;
a1 f;
};
std::strong_ordering cmp_b1 = b1() <=> b1();
struct a2 {
operator float() const;
};
struct b2 {
auto operator<=>(b2 const &) const = default;
a2 f;
};
std::partial_ordering cmp_b2 = b2() <=> b2();
using fp = void (*)();
struct a3 {
operator fp() const;
};
struct b3 {
auto operator<=>(b3 const &) const = default; a3 f; };
struct a4 { operator int() const;
operator fp() const;
};
struct b4 {
auto operator<=>(b4 const &) const = default;
a4 f;
};
std::strong_ordering cmp_b4 = b4() <=> b4();
}