(root)/
gcc-13.2.0/
gcc/
testsuite/
g++.dg/
cpp2a/
is-corresponding-member2.C
// P0466R5
// { dg-do run { target c++20 } }

namespace std
{
template <class S1, class S2, class M1, class M2>
constexpr bool
is_corresponding_member (M1 S1::*m1, M2 S2::*m2) noexcept
{
  return __builtin_is_corresponding_member (m1, m2);
}
}

struct A { int a; };
struct B { const int b; };
struct C { int a; unsigned int b; int f; A c; int : 0; int d; double e; };
struct D { const int x; unsigned int y; int g; B z; int u; double w; };
struct E { int a; [[no_unique_address]] int b; };
struct F { int c; const int d; };
struct G { double a; int b; double c; };
struct H { const volatile double d; int e : 16; double f; };
struct I { const double g; int h : 15; const double i; };
struct J : public A {};
struct K {};
struct L : public K, public B {};
union U { int a; };
struct V { void foo () {}; };
struct W { int a; private: int b; public: int c; };
struct Z : public A, public B {};

int
main ()
{
  auto t1 = &A::a;
  auto t2 = &A::a;
  if (!std::is_corresponding_member (t1, t2))
    __builtin_abort ();
  auto t3 = &A::a;
  auto t4 = &B::b;
  if (!std::is_corresponding_member (t3, t4))
    __builtin_abort ();
  auto t5 = &C::a;
  auto t6 = &D::x;
  if (!std::is_corresponding_member (t5, t6))
    __builtin_abort ();
  auto t9 = &C::b;
  auto t10 = &D::y;
  if (!std::is_corresponding_member (t9, t10))
    __builtin_abort ();
  auto t11 = &C::f;
  auto t12 = &D::g;
  if (!std::is_corresponding_member (t11, t12))
    __builtin_abort ();
  auto t13 = &C::c;
  auto t14 = &D::z;
  if (!std::is_corresponding_member (t13, t14))
    __builtin_abort ();
  auto t15 = &C::d;
  auto t16 = &D::u;
  if (std::is_corresponding_member (t15, t16))
    __builtin_abort ();
  auto t17 = &C::e;
  auto t18 = &D::w;
  if (std::is_corresponding_member (t17, t18))
    __builtin_abort ();
  auto t19 = &C::f;
  auto t20 = &D::x;
  if (std::is_corresponding_member (t19, t20))
    __builtin_abort ();
  auto t21 = &C::a;
  auto t22 = &D::g;
  if (std::is_corresponding_member (t21, t22))
    __builtin_abort ();
  auto t23 = &E::a;
  auto t24 = &F::c;
  if (!std::is_corresponding_member (t23, t24))
    __builtin_abort ();
  auto t25 = &E::b;
  auto t26 = &F::d;
  if (std::is_corresponding_member (t25, t26))
    __builtin_abort ();
  auto t27 = &G::a;
  auto t28 = &H::d;
  if (!std::is_corresponding_member (t27, t28))
    __builtin_abort ();
  auto t29 = &G::c;
  auto t30 = &H::f;
  if (std::is_corresponding_member (t29, t30))
    __builtin_abort ();
  auto t31 = &H::d;
  auto t32 = &I::g;
  if (!std::is_corresponding_member (t31, t32))
    __builtin_abort ();
  auto t33 = &H::f;
  auto t34 = &I::i;
  if (std::is_corresponding_member (t33, t34))
    __builtin_abort ();
  auto t35 = &J::a;
  auto t36 = &B::b;
  if (!std::is_corresponding_member (t35, t36))
    __builtin_abort ();
  int J::*t37 = &J::a;
  const int B::*t38 = &B::b;
  if (!std::is_corresponding_member (t37, t38))
    __builtin_abort ();
  auto t39 = &J::a;
  auto t40 = &L::b;
  if (!std::is_corresponding_member (t39, t40))
    __builtin_abort ();
  int J::*t41 = &J::a;
  const int L::*t42 = &L::b;
  if (!std::is_corresponding_member (t41, t42))
    __builtin_abort ();
  auto t43 = &L::b;
  auto t44 = &B::b;
  if (!std::is_corresponding_member (t43, t44))
    __builtin_abort ();
  const int L::*t45 = &L::b;
  const int B::*t46 = &B::b;
  if (!std::is_corresponding_member (t45, t46))
    __builtin_abort ();
  auto t47 = &U::a;
  auto t48 = &U::a;
  if (std::is_corresponding_member (t47, t48))
    __builtin_abort ();
  auto t49 = &A::a;
  auto t50 = (int A::*) nullptr;
  if (std::is_corresponding_member (t49, t50))
    __builtin_abort ();
  auto t51 = (int A::*) nullptr;
  auto t52 = &A::a;
  if (std::is_corresponding_member (t51, t52))
    __builtin_abort ();
  auto t53 = (int A::*) nullptr;
  auto t54 = (int A::*) nullptr;
  if (std::is_corresponding_member (t53, t54))
    __builtin_abort ();
  auto t55 = &V::foo;
  auto t56 = &V::foo;
  if (std::is_corresponding_member (t55, t56))
    __builtin_abort ();
  auto t57 = &W::a;
  auto t58 = &W::a;
  if (std::is_corresponding_member (t57, t58))
    __builtin_abort ();
  auto t59 = &W::c;
  auto t60 = &W::c;
  if (std::is_corresponding_member (t59, t60))
    __builtin_abort ();
  auto t61 = &Z::a;
  auto t62 = &Z::b;
  if (!std::is_corresponding_member (t61, t62))
    __builtin_abort ();
  int Z::*t63 = &Z::a;
  const int Z::*t64 = &Z::b;
  if (std::is_corresponding_member (t63, t64))
    __builtin_abort ();
}