brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.3 KiB · da0f576 Raw
71 lines · cpp
1// RUN: %clang_cc1 -std=c++2a -verify %s2 3template<typename L, typename R> struct Op { L l; const char *op; R r; };4// FIXME: Remove once we implement P1816R0.5template<typename L, typename R> Op(L, R) -> Op<L, R>;6 7struct A {};8struct B {};9constexpr Op<A, B> operator<=>(A a, B b) { return {a, "<=>", b}; }10 11template<typename T, typename U, typename V> constexpr Op<Op<T, U>, V> operator<  (Op<T, U> a, V b) { return {a, "<",   b}; }12template<typename T, typename U, typename V> constexpr Op<Op<T, U>, V> operator<= (Op<T, U> a, V b) { return {a, "<=",  b}; }13template<typename T, typename U, typename V> constexpr Op<Op<T, U>, V> operator>  (Op<T, U> a, V b) { return {a, ">",   b}; }14template<typename T, typename U, typename V> constexpr Op<Op<T, U>, V> operator>= (Op<T, U> a, V b) { return {a, ">=",  b}; }15template<typename T, typename U, typename V> constexpr Op<Op<T, U>, V> operator<=>(Op<T, U> a, V b) { return {a, "<=>", b}; }16 17template<typename T, typename U, typename V> constexpr Op<T, Op<U, V>> operator<  (T a, Op<U, V> b) { return {a, "<",   b}; }18template<typename T, typename U, typename V> constexpr Op<T, Op<U, V>> operator<= (T a, Op<U, V> b) { return {a, "<=",  b}; }19template<typename T, typename U, typename V> constexpr Op<T, Op<U, V>> operator>  (T a, Op<U, V> b) { return {a, ">",   b}; }20template<typename T, typename U, typename V> constexpr Op<T, Op<U, V>> operator>= (T a, Op<U, V> b) { return {a, ">=",  b}; }21template<typename T, typename U, typename V> constexpr Op<T, Op<U, V>> operator<=>(T a, Op<U, V> b) { return {a, "<=>", b}; }22 23constexpr bool same(A, A) { return true; }24constexpr bool same(B, B) { return true; }25constexpr bool same(int a, int b) { return a == b; }26template<typename T, typename U>27constexpr bool same(Op<T, U> x, Op<T, U> y) {28  return same(x.l, y.l) && __builtin_strcmp(x.op, y.op) == 0 && same(x.r, y.r);29}30 31// x @ y is interpreted as:32void f(A x, B y) {33  //   --  (x <=> y) @ 0 if not reversed34  static_assert(same(x < y, (x <=> y) < 0));35  static_assert(same(x <= y, (x <=> y) <= 0));36  static_assert(same(x > y, (x <=> y) > 0));37  static_assert(same(x >= y, (x <=> y) >= 0));38  static_assert(same(x <=> y, x <=> y)); // (not rewritten)39}40 41void g(B x, A y) {42  //   --  0 @ (y <=> x) if reversed43  static_assert(same(x < y, 0 < (y <=> x)));44  static_assert(same(x <= y, 0 <= (y <=> x)));45  static_assert(same(x > y, 0 > (y <=> x)));46  static_assert(same(x >= y, 0 >= (y <=> x)));47  static_assert(same(x <=> y, 0 <=> (y <=> x)));48}49 50 51// We can rewrite into a call involving a builtin operator.52struct X { int result; };53struct Y {};54constexpr int operator<=>(X x, Y) { return x.result; }55static_assert(X{-1} < Y{});56static_assert(X{0} < Y{}); // expected-error {{failed}}57static_assert(X{0} <= Y{});58static_assert(X{1} <= Y{}); // expected-error {{failed}}59static_assert(X{1} > Y{});60static_assert(X{0} > Y{}); // expected-error {{failed}}61static_assert(X{0} >= Y{});62static_assert(X{-1} >= Y{}); // expected-error {{failed}}63static_assert(Y{} < X{1});64static_assert(Y{} < X{0}); // expected-error {{failed}}65static_assert(Y{} <= X{0});66static_assert(Y{} <= X{-1}); // expected-error {{failed}}67static_assert(Y{} > X{-1});68static_assert(Y{} > X{0}); // expected-error {{failed}}69static_assert(Y{} >= X{0});70static_assert(Y{} >= X{1}); // expected-error {{failed}}71