// { dg-do compile { target c++20 } }
// { dg-additional-options "-fconcepts-ts" }

// Basic tests using function concepts.

template<typename T>
concept bool Type() { return true; }

template<typename T>
concept bool False() { return false; }

template<typename T>
concept bool Class() { return __is_class(T); }

template<typename T>
concept bool EmptyClass() { return Class<T>() && __is_empty(T); }

template<typename T, typename U>
concept bool Classes() { return __is_class(T) && __is_class (U); }

struct empty { };

struct nonempty { int n; };

static_assert(Type<int>());
static_assert(False<int>()); // { dg-error "static assertion failed" }

// Basic checks

template<typename T>
  requires (Type<T>())
int fn1(T t) { return 0; }

template<typename T>
  requires (False<T>())
int fn2(T t) { return 0; }

void driver()
{
  fn1(0); // OK
  fn2(0); // { dg-error "" }
}

// Ordering

template<typename T>
concept bool Cf() { return requires (T t) { t.f(); }; }

template<typename T>
concept bool Cfg() { return Cf<T>() && requires (T t) { t.g(); }; }

template<typename T>
concept bool Cf2() { return requires (T t) { t.f(); }; }

template<typename T>
constexpr int algo(T t) { return 0; }

template<typename T> requires (Cf<T>())
constexpr int algo(T t) { return 1; }

template<typename T> requires (Cfg<T>())
constexpr int algo(T t) { return 2; }

template<typename T> requires (Cf<T>())
constexpr int ambig(T t) { return 1; }

template<typename T> requires (Cf2<T>())
constexpr int ambig(T t) { return 1; }

struct T1 {
  void f() { }
};

struct T2 : T1 {
  void g() { }
};

void driver_0()
{
  T1 x;
  T2 y;
  static_assert(algo(0) == 0);
  static_assert(algo(x) == 1);
  static_assert(algo(y) == 2);
  ambig(x); // { dg-error "call of overload | is ambiguous" }
}

template<typename T>
struct S
{
  void f() requires (Class<T>()) { }
  
  template<typename U>
  struct Inner
  {
    void g() requires (Classes<T, U>()) { }
  };

  template<typename U> requires (Classes<T, U>()) void h(U) { }
};

struct X { };

void driver_1()
{
  S<X> s1;
  s1.f(); // OK
  s1.h(s1); // OK
  s1.h(0); // { dg-error "no matching function" }

  S<int> s2;
  s2.f(); // { dg-error "no matching function" }

  S<X>::Inner<X> si1;
  si1.g();
  
  S<X>::Inner<int> si2;
  si2.g(); // { dg-error "no matching function" }
}

// Check constraints on non-dependent arguments, even when in a
// dependent context.

template<typename T> requires (Class<T>()) void f1(T x) { }

// fn1-2.C -- Dependent checks
template<typename T>
void caller_1(T x) 
{ 
  f1(x); // Unchecked dependent arg.
  f1(empty{}); // Checked non-dependent arg, but OK
  f1(0); // { dg-error "" }
}

// fn3.c -- Ordering
template<typename T> 
  requires (Class<T>()) 
constexpr int f2(T x) { return 1; }

template<typename T> 
  requires (EmptyClass<T>())
constexpr int f2(T x) { return 2; }

template<typename T> 
constexpr int f3(T x) requires (Class<T>()) { return 1; }

template<typename T> 
constexpr int f3(T x) requires (EmptyClass<T>()) { return 2; }

void driver_2() 
{
  f2(0); // { dg-error "no matching function" }
  static_assert (f2(empty{}) == 2);
  static_assert (f2(nonempty{}) == 1);
  f3(0); // { dg-error "no matching function" }
  static_assert (f3(empty{}) == 2);
  static_assert (f3(nonempty{}) == 1);
}

// fn8.C -- Address of overloaded functions
template<typename T> requires (Type<T>()) void ok(T) { }
template<typename T> requires (Class<T>()) void err(T) { }

auto p1 = &ok<int>;
auto p2 = &err<int>; // { dg-error "" }
void (*p3)(int) = &ok<int>;
void (*p4)(int) = &err<int>; // { dg-error "no matches" }
void (*p5)(int) = &ok;
void (*p6)(int) = &err; // { dg-error "no matches" }

template<typename T> void g(T x) { }

void driver_3 () 
{
  g(&ok<int>);
  g(&err<int>); // { dg-error "no match" }
}


struct S2 {
  template<typename T> requires (Type<T>()) int ok(T) { return 0; }
  template<typename T> requires (Class<T>()) int err(T) { return 0; }
};

auto p7 = &S2::ok<int>;
auto p8 = &S2::err<int>; // { dg-error "" }
int (S2::*p9)(int) = &S2::ok<int>;
int (S2::*p10)(int) = &S2::err<int>; // { dg-error "no matches" }
int (S2::*p11)(int) = &S2::ok;
int (S2::*p12)(int) = &S2::err; // { dg-error "no matches" }

// fn9.C -- Ordering with function address
template<typename T> 
  requires (Class<T>())
constexpr int fn(T) { return 1; }

template<typename T> 
  requires (EmptyClass<T>())
constexpr int fn(T) { return 2; }

struct S3 
{
  template<typename T> 
    requires (Class<T>())
  constexpr int fn(T) const { return 1; }
  
  template<typename T> 
    requires (EmptyClass<T>())
  constexpr int fn(T) const { return 2; }
};

void driver_5 () {
  struct X { };
  struct Y { X x; };

  constexpr X x;
  constexpr Y y;
  constexpr S3 s;

  constexpr auto p1 = &fn<X>; // Empty f
  static_assert (p1(x) == 2);

  constexpr auto p2 = &fn<Y>; // Class f
  static_assert(p2(y) == 1);

  constexpr auto p3 = &S3::fn<X>; // Empty f
  static_assert((s.*p3)(x) == 2);

  constexpr auto p4 = &S3::fn<Y>; // Empty f
  static_assert((s.*p4)(y) == 1);
}


// Redeclarations

// FIXME: This should be a diagnosable error. The programmer has moved
// the requirements from the template-head to the declarator.
template<typename T> requires (Type<T>()) void f3();
template<typename T> void f3() requires (Type<T>());

void driver_4()
{
  f3<int>(); // { dg-error "call of overload | ambiguous" }
}

template<template<typename T> requires true class X> void f4();
template<template<typename T> class X> void f4(); // OK: different declarations

template<typename T> requires (Type<T>()) void def() { }
template<typename T> requires (Type<T>()) void def() { } // { dg-error "redefinition" }

// fn-concept1.C

template<typename T>
concept bool Tuple() { // { dg-error "multiple statements" }
  static_assert(T::value, "");
  return true;
}

void f(Tuple&);
