111
|
1 // DR 339
|
|
2 //
|
|
3 // Test of the use of the new and new[] operators with SFINAE
|
|
4
|
|
5 // Boilerplate helpers
|
|
6 typedef char yes_type;
|
|
7 struct no_type { char data[2]; };
|
|
8
|
|
9 template<typename T> T create_a();
|
|
10 template<typename T> struct type { };
|
|
11
|
|
12 template<bool, typename T = void> struct enable_if { typedef T type; };
|
|
13 template<typename T> struct enable_if<false, T> { };
|
|
14
|
|
15 #define JOIN( X, Y ) DO_JOIN( X, Y )
|
|
16 #define DO_JOIN( X, Y ) DO_JOIN2(X,Y)
|
|
17 #define DO_JOIN2( X, Y ) X##Y
|
|
18
|
|
19 template<typename T>
|
|
20 typename enable_if<(sizeof(new T, 0) > 0), yes_type>::type
|
|
21 check_new(int);
|
|
22
|
|
23 template<typename T> no_type check_new(...);
|
|
24
|
|
25 template<typename T>
|
|
26 struct has_new
|
|
27 {
|
|
28 static const bool value =
|
|
29 (sizeof(check_new<T>(0)) == sizeof(yes_type));
|
|
30 };
|
|
31
|
|
32 template<typename T, typename U>
|
|
33 typename enable_if<(sizeof((new T(create_a<U>())), 0) > 0),
|
|
34 yes_type>::type
|
|
35 check_new_one_arg(int);
|
|
36
|
|
37 template<typename T, typename U> no_type check_new_one_arg(...);
|
|
38
|
|
39 template<typename T, typename U>
|
|
40 struct has_new_one_arg
|
|
41 {
|
|
42 static const bool value =
|
|
43 (sizeof(check_new_one_arg<T, U>(0)) == sizeof(yes_type));
|
|
44 };
|
|
45
|
|
46 template<typename T, typename U, U N>
|
|
47 typename enable_if<(sizeof(new T[N], 0) > 0), yes_type>::type
|
|
48 check_array_new(int);
|
|
49
|
|
50 template<typename T, typename U, U N> no_type check_array_new(...);
|
|
51
|
|
52 template<typename T, typename U, U N>
|
|
53 struct has_array_new
|
|
54 {
|
|
55 static const bool value =
|
|
56 (sizeof(check_array_new<T, U, N>(0)) == sizeof(yes_type));
|
|
57 };
|
|
58
|
|
59 #ifdef __GXX_EXPERIMENTAL_CXX0X__
|
|
60 # define STATIC_ASSERT(Expr) static_assert(Expr, #Expr)
|
|
61 #else
|
|
62 # define STATIC_ASSERT(Expr) int JOIN(a,__LINE__)[Expr? 1 : -1]
|
|
63 #endif
|
|
64
|
|
65 struct X {
|
|
66 X(int);
|
|
67 };
|
|
68
|
|
69 struct Y { int foo; };
|
|
70
|
|
71 STATIC_ASSERT((has_new<Y>::value));
|
|
72 STATIC_ASSERT(!(has_new<X>::value));
|
|
73 STATIC_ASSERT((has_new_one_arg<Y, Y>::value));
|
|
74 STATIC_ASSERT((has_new_one_arg<X, float>::value));
|
|
75 STATIC_ASSERT(!(has_new_one_arg<X, int X::*>::value));
|
|
76
|
|
77 STATIC_ASSERT((has_array_new<Y, int, 5>::value));
|
|
78 STATIC_ASSERT(!(has_array_new<X, int Y::*, &Y::foo>::value));
|
|
79 STATIC_ASSERT((has_array_new<X, int, 5>::value));
|