1// DR 339
2//
3// Test of the use of free functions with SFINAE
4void foo(int) { }
5template<typename T> void foo(T*) { }
6
7typedef char yes_type;
8struct no_type { char data[2]; };
9
10template<typename T> T create_a();
11
12template<bool, typename T = void> struct enable_if { typedef T type; };
13template<typename T> struct enable_if<false, T> { };
14
15template<typename T>
16  typename enable_if<(sizeof(foo(create_a<T const&>()), 1) > 0),
17		     yes_type>::type
18  check_has_foo(const volatile T&);
19
20no_type check_has_foo(...);
21
22template<typename T>
23struct has_foo
24{
25  static const bool value =
26    (sizeof(check_has_foo(create_a<T const&>())) == sizeof(yes_type));
27};
28
29struct X { };
30
31int a1[has_foo<int>::value? 1 : -1];
32int a2[has_foo<long>::value? 1 : -1];
33int a3[has_foo<int*>::value? 1 : -1];
34int a4[has_foo<X>::value? -1 : 1];
35int a5[has_foo<int X::*>::value? -1 : 1];
36