reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only  -emit-llvm-only %s
// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only  -fdelayed-template-parsing %s 
// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only  -fms-extensions %s 
// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only  -fdelayed-template-parsing -fms-extensions %s 

template<class T, class U> struct is_same { enum { value = false }; };
template<class T> struct is_same<T, T> { enum { value = true }; };

namespace test_sfinae_and_delete {

namespace ns1 {
template<class T> double f(T) = delete; //expected-note{{candidate}}
char f(...); //expected-note{{candidate}}

static_assert(is_same<decltype(f(3)),char>::value, ""); //expected-error{{call to deleted function}} expected-error{{static_assert failed}}

template<class T> decltype(f(T{})) g(T); // this one sfinae's out.
template<class T> int *g(T);
void foo() {
  int *ip = g(3);
}
} //end ns1

namespace ns2 {
template<class T> double* f(T);
template<> double* f(double) = delete;

template<class T> decltype(f(T{})) g(T); // expected-note{{candidate}}
template<class T> int *g(T); //expected-note{{candidate}}
void foo() {
  double *dp = g(3); //expected-error{{ambiguous}}
  int *ip = g(3.14); // this is OK - because the explicit specialization is deleted and sfinae's out one of the template candidates
}

} // end ns2

namespace ns3 {
template<class T> double* f(T) = delete;
template<> double* f(double);

template<class T> decltype(f(T{})) g(T); // expected-note{{candidate}}
template<class T> int *g(T); //expected-note{{candidate}}

void foo() {
  int *dp = g(3); // this is OK - because the non-double specializations are deleted and sfinae's out one of the template candidates
  double *ip = g(3.14); //expected-error{{ambiguous}}
}

} // end ns3
} // end ns test_sfinae_and_delete

namespace test_explicit_specialization_of_member {
namespace ns1 {
template<class T> struct X {
  int* f(T) = delete;
}; 
template<> int* X<int>::f(int) { }

template<class T> decltype(X<T>{}.f(T{})) g(T); // expected-note{{candidate}}
template<class T> int *g(T); //expected-note{{candidate}}

void foo() {
  int *ip2 = g(3.14); // this is OK - because the non-int specializations are deleted and sfinae's out one of the template candidates
  int *ip = g(3); //expected-error{{ambiguous}}
}

} // end ns1

namespace ns2 {
struct X {
template<class T> double* f(T) = delete;
}; 
template<> double* X::f(int);

template<class T> decltype(X{}.f(T{})) g(T); // expected-note{{candidate}}
template<class T> int *g(T); //expected-note{{candidate}}

void foo() {
  int *ip2 = g(3.14); // this is OK - because the non-int specializations are deleted and sfinae's out one of the template candidates
  int *ip = g(3); //expected-error{{ambiguous}}
}

} // end ns2

namespace ns3 {
template<class T> struct X {
  template<class U> double *f1(U, T) = delete;
  template<class U> double *f2(U, T) = delete;
};
template<> template<> double* X<int>::f1(int, int);
template<> template<class U> double* X<int>::f2(U, int);

template<class T, class U> decltype(X<T>{}.f1(U{}, T{})) g1(U, T); // expected-note{{candidate}}
template<class T, class U> int *g1(U, T); //expected-note{{candidate}}

template<class T, class U> decltype(X<T>{}.f2(U{}, T{})) g2(U, T); // expected-note2{{candidate}}
template<class T, class U> int *g2(U, T); //expected-note2{{candidate}}


void foo() {
  int *ip2 = g1(3.14, 3); // this is OK - because the non-int specializations are deleted and sfinae's out one of the template candidates
  int *ip = g1(3, 3); //expected-error{{ambiguous}}
  {
   int *ip3 = g2(3.14, 3); //expected-error{{ambiguous}}
   int *ip4 = g2(3, 3); //expected-error{{ambiguous}}
  }
  {
   int *ip3 = g2(3.14, 3.14); 
   int *ip4 = g2(3, 3.14); 
  }
}


} // end ns3

namespace ns4 {
template < typename T> T* foo (T);
template <> int* foo(int) = delete;
template <> int* foo(int); //expected-note{{candidate}}

int *IP = foo(2); //expected-error{{deleted}}
double *DP = foo(3.14);
} //end ns4

namespace ns5 {
template < typename T> T* foo (T);
template <> int* foo(int); //expected-note{{previous}}
template <> int* foo(int) = delete; //expected-error{{deleted definition must be first declaration}}

} //end ns5


} // end test_explicit_specializations_and_delete