1 // RUN: clang-cc -fsyntax-only -verify %s 2 template<typename T> 3 struct is_pointer { 4 static const bool value = false; 5 }; 6 7 template<typename T> 8 struct is_pointer<T*> { 9 static const bool value = true; 10 }; 11 12 template<typename T> 13 struct is_pointer<const T*> { 14 static const bool value = true; 15 }; 16 17 int array0[is_pointer<int>::value? -1 : 1]; 18 int array1[is_pointer<int*>::value? 1 : -1]; 19 int array2[is_pointer<const int*>::value? 1 : -1]; // expected-error{{partial ordering}} \ 20 // expected-error{{negative}} 21 22 template<typename T> 23 struct is_lvalue_reference { 24 static const bool value = false; 25 }; 26 27 template<typename T> 28 struct is_lvalue_reference<T&> { 29 static const bool value = true; 30 }; 31 32 int lvalue_ref0[is_lvalue_reference<int>::value? -1 : 1]; 33 int lvalue_ref1[is_lvalue_reference<const int&>::value? 1 : -1]; 34 35 template<typename T> 36 struct is_const { 37 static const bool value = false; 38 }; 39 40 template<typename T> 41 struct is_const<const T> { 42 static const bool value = true; 43 }; 44 45 int is_const0[is_const<int>::value? -1 : 1]; 46 int is_const1[is_const<const int>::value? 1 : -1]; 47 int is_const2[is_const<const volatile int>::value? 1 : -1]; 48 49 template<typename T> 50 struct is_volatile { 51 static const bool value = false; 52 }; 53 54 template<typename T> 55 struct is_volatile<volatile T> { 56 static const bool value = true; 57 }; 58 59 int is_volatile0[is_volatile<int>::value? -1 : 1]; 60 int is_volatile1[is_volatile<volatile int>::value? 1 : -1]; 61 int is_volatile2[is_volatile<const volatile int>::value? 1 : -1]; 62 int is_volatile3[is_volatile<volatile char[3]>::value? 1 : -1]; 63 64 template<typename T, typename U> 65 struct is_same { 66 static const bool value = false; 67 }; 68 69 template<typename T> 70 struct is_same<T, T> { 71 static const bool value = true; 72 }; 73 74 typedef int INT; 75 typedef INT* int_ptr; 76 77 int is_same0[is_same<int, int>::value? 1 : -1]; 78 int is_same1[is_same<int, INT>::value? 1 : -1]; 79 int is_same2[is_same<const int, int>::value? -1 : 1]; 80 int is_same3[is_same<int_ptr, int>::value? -1 : 1]; 81 82 template<typename T> 83 struct remove_reference { 84 typedef T type; 85 }; 86 87 template<typename T> 88 struct remove_reference<T&> { 89 typedef T type; 90 }; 91 92 int remove_ref0[is_same<remove_reference<int>::type, int>::value? 1 : -1]; 93 int remove_ref1[is_same<remove_reference<int&>::type, int>::value? 1 : -1]; 94 95 template<typename T> 96 struct is_incomplete_array { 97 static const bool value = false; 98 }; 99 100 template<typename T> 101 struct is_incomplete_array<T[]> { 102 static const bool value = true; 103 }; 104 105 int incomplete_array0[is_incomplete_array<int>::value ? -1 : 1]; 106 int incomplete_array1[is_incomplete_array<int[1]>::value ? -1 : 1]; 107 int incomplete_array2[is_incomplete_array<bool[]>::value ? 1 : -1]; 108 int incomplete_array3[is_incomplete_array<int[]>::value ? 1 : -1]; 109 110 template<typename T> 111 struct is_array_with_4_elements { 112 static const bool value = false; 113 }; 114 115 template<typename T> 116 struct is_array_with_4_elements<T[4]> { 117 static const bool value = true; 118 }; 119 120 int array_with_4_elements0[is_array_with_4_elements<int[]>::value ? -1 : 1]; 121 int array_with_4_elements1[is_array_with_4_elements<int[1]>::value ? -1 : 1]; 122 int array_with_4_elements2[is_array_with_4_elements<int[4]>::value ? 1 : -1]; 123 int array_with_4_elements3[is_array_with_4_elements<int[4][2]>::value ? 1 : -1]; 124 125 template<typename T> 126 struct get_array_size; 127 128 template<typename T, unsigned N> 129 struct get_array_size<T[N]> { 130 static const unsigned value = N; 131 }; 132 133 int array_size0[get_array_size<int[12]>::value == 12? 1 : -1]; 134 135 template<typename T> 136 struct is_unary_function { 137 static const bool value = false; 138 }; 139 140 template<typename T, typename U> 141 struct is_unary_function<T (*)(U)> { 142 static const bool value = true; 143 }; 144 145 int is_unary_function0[is_unary_function<int>::value ? -1 : 1]; 146 int is_unary_function1[is_unary_function<int (*)()>::value ? -1 : 1]; 147 int is_unary_function2[is_unary_function<int (*)(int, bool)>::value ? -1 : 1]; 148 int is_unary_function3[is_unary_function<int (*)(bool)>::value ? 1 : -1]; 149 int is_unary_function4[is_unary_function<int (*)(int)>::value ? 1 : -1]; 150 151 template<typename T> 152 struct is_unary_function_with_same_return_type_as_argument_type { 153 static const bool value = false; 154 }; 155 156 template<typename T> 157 struct is_unary_function_with_same_return_type_as_argument_type<T (*)(T)> { 158 static const bool value = true; 159 }; 160 161 int is_unary_function5[is_unary_function_with_same_return_type_as_argument_type<int>::value ? -1 : 1]; 162 int is_unary_function6[is_unary_function_with_same_return_type_as_argument_type<int (*)()>::value ? -1 : 1]; 163 int is_unary_function7[is_unary_function_with_same_return_type_as_argument_type<int (*)(int, bool)>::value ? -1 : 1]; 164 int is_unary_function8[is_unary_function_with_same_return_type_as_argument_type<int (*)(bool)>::value ? -1 : 1]; 165 int is_unary_function9[is_unary_function_with_same_return_type_as_argument_type<int (*)(int)>::value ? 1 : -1]; 166 int is_unary_function10[is_unary_function_with_same_return_type_as_argument_type<int (*)(int, ...)>::value ? -1 : 1]; 167 int is_unary_function11[is_unary_function_with_same_return_type_as_argument_type<int (* const)(int)>::value ? -1 : 1]; 168 169 template<typename T> 170 struct is_binary_function { 171 static const bool value = false; 172 }; 173 174 template<typename R, typename T1, typename T2> 175 struct is_binary_function<R(T1, T2)> { 176 static const bool value = true; 177 }; 178 179 int is_binary_function0[is_binary_function<int(float, double)>::value? 1 : -1]; 180 181 template<typename T> 182 struct is_member_pointer { 183 static const bool value = false; 184 }; 185 186 template<typename T, typename Class> 187 struct is_member_pointer<T Class::*> { 188 static const bool value = true; 189 }; 190 191 struct X { }; 192 193 int is_member_pointer0[is_member_pointer<int X::*>::value? 1 : -1]; 194 int is_member_pointer1[is_member_pointer<const int X::*>::value? 1 : -1]; 195 int is_member_pointer2[is_member_pointer<int (X::*)()>::value? 1 : -1]; 196 int is_member_pointer3[is_member_pointer<int (X::*)(int) const>::value? 1 : -1]; 197 int is_member_pointer4[is_member_pointer<int (X::**)(int) const>::value? -1 : 1]; 198 int is_member_pointer5[is_member_pointer<int>::value? -1 : 1]; 199 200 template<typename T> 201 struct is_member_function_pointer { 202 static const bool value = false; 203 }; 204 205 template<typename T, typename Class> 206 struct is_member_function_pointer<T (Class::*)()> { 207 static const bool value = true; 208 }; 209 210 template<typename T, typename Class> 211 struct is_member_function_pointer<T (Class::*)() const> { 212 static const bool value = true; 213 }; 214 215 template<typename T, typename Class> 216 struct is_member_function_pointer<T (Class::*)() volatile> { 217 static const bool value = true; 218 }; 219 220 template<typename T, typename Class> 221 struct is_member_function_pointer<T (Class::*)() const volatile> { 222 static const bool value = true; 223 }; 224 225 template<typename T, typename Class, typename A1> 226 struct is_member_function_pointer<T (Class::*)(A1)> { 227 static const bool value = true; 228 }; 229 230 template<typename T, typename Class, typename A1> 231 struct is_member_function_pointer<T (Class::*)(A1) const> { 232 static const bool value = true; 233 }; 234 235 template<typename T, typename Class, typename A1> 236 struct is_member_function_pointer<T (Class::*)(A1) volatile> { 237 static const bool value = true; 238 }; 239 240 template<typename T, typename Class, typename A1> 241 struct is_member_function_pointer<T (Class::*)(A1) const volatile> { 242 static const bool value = true; 243 }; 244 245 int is_member_function_pointer0[ 246 is_member_function_pointer<int X::*>::value? -1 : 1]; 247 int is_member_function_pointer1[ 248 is_member_function_pointer<int (X::*)()>::value? 1 : -1]; 249 int is_member_function_pointer2[ 250 is_member_function_pointer<X (X::*)(X&)>::value? 1 : -1]; 251 int is_member_function_pointer3[ 252 is_member_function_pointer<int (X::*)() const>::value? 1 : -1]; 253 int is_member_function_pointer4[ 254 is_member_function_pointer<int (X::*)(float) const>::value? 1 : -1]; 255 256 // Test substitution of non-dependent arguments back into the template 257 // argument list of the class template partial specialization. 258 template<typename T, typename ValueType = T> 259 struct is_nested_value_type_identity { 260 static const bool value = false; 261 }; 262 263 template<typename T> 264 struct is_nested_value_type_identity<T, typename T::value_type> { 265 static const bool value = true; 266 }; 267 268 template<typename T> 269 struct HasValueType { 270 typedef T value_type; 271 }; 272 273 struct HasIdentityValueType { 274 typedef HasIdentityValueType value_type; 275 }; 276 277 struct NoValueType { }; 278 279 int is_nested_value_type_identity0[ 280 is_nested_value_type_identity<HasValueType<int> >::value? -1 : 1]; 281 int is_nested_value_type_identity1[ 282 is_nested_value_type_identity<HasIdentityValueType>::value? 1 : -1]; 283 int is_nested_value_type_identity2[ 284 is_nested_value_type_identity<NoValueType>::value? -1 : 1]; 285 286 287 // C++ [temp.class.spec]p4: 288 template<class T1, class T2, int I> class A { }; //#1 289 template<class T, int I> class A<T, T*, I> { }; //#2 290 template<class T1, class T2, int I> class A<T1*, T2, I> { }; //#3 291 template<class T> class A<int, T*, 5> { }; //#4 292 template<class T1, class T2, int I> class A<T1, T2*, I> { }; //#5 293