1// Copyright 2016 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <fbl/type_support.h>
6
7struct s {};
8union u {};
9
10using fp = void();
11
12// is_void tests:
13static_assert(fbl::is_void<void>::value, "");
14static_assert(fbl::is_void<const void>::value, "");
15static_assert(fbl::is_void<volatile void>::value, "");
16static_assert(fbl::is_void<const volatile void>::value, "");
17
18static_assert(!fbl::is_void<int>::value, "");
19static_assert(!fbl::is_void<void*>::value, "");
20
21// is_null_pointer tests:
22static_assert(fbl::is_null_pointer<decltype(nullptr)>::value, "");
23static_assert(fbl::is_null_pointer<const decltype(nullptr)>::value, "");
24static_assert(fbl::is_null_pointer<volatile decltype(nullptr)>::value, "");
25static_assert(fbl::is_null_pointer<const volatile decltype(nullptr)>::value, "");
26
27static_assert(!fbl::is_null_pointer<int>::value, "");
28static_assert(!fbl::is_null_pointer<int*>::value, "");
29static_assert(!fbl::is_null_pointer<s*>::value, "");
30static_assert(!fbl::is_null_pointer<fp>::value, "");
31
32// is_pointer tests:
33static_assert(fbl::is_pointer<int*>::value, "");
34static_assert(fbl::is_pointer<float*>::value, "");
35static_assert(fbl::is_pointer<s*>::value, "");
36static_assert(fbl::is_pointer<u*>::value, "");
37static_assert(fbl::is_pointer<s*>::value, "");
38static_assert(fbl::is_pointer<fp*>::value, "");
39
40static_assert(fbl::is_pointer<const int*>::value, "");
41static_assert(fbl::is_pointer<const float*>::value, "");
42static_assert(fbl::is_pointer<const s*>::value, "");
43static_assert(fbl::is_pointer<const u*>::value, "");
44static_assert(fbl::is_pointer<const s*>::value, "");
45
46static_assert(fbl::is_pointer<volatile int*>::value, "");
47static_assert(fbl::is_pointer<volatile float*>::value, "");
48static_assert(fbl::is_pointer<volatile s*>::value, "");
49static_assert(fbl::is_pointer<volatile u*>::value, "");
50static_assert(fbl::is_pointer<volatile s*>::value, "");
51
52static_assert(fbl::is_pointer<const volatile int*>::value, "");
53static_assert(fbl::is_pointer<const volatile float*>::value, "");
54static_assert(fbl::is_pointer<const volatile s*>::value, "");
55static_assert(fbl::is_pointer<const volatile u*>::value, "");
56static_assert(fbl::is_pointer<const volatile s*>::value, "");
57
58static_assert(!fbl::is_pointer<int>::value, "");
59static_assert(!fbl::is_pointer<float>::value, "");
60static_assert(!fbl::is_pointer<s>::value, "");
61static_assert(!fbl::is_pointer<u>::value, "");
62static_assert(!fbl::is_pointer<s>::value, "");
63static_assert(!fbl::is_pointer<fp>::value, "");
64
65static_assert(!fbl::is_pointer<const int>::value, "");
66static_assert(!fbl::is_pointer<const float>::value, "");
67static_assert(!fbl::is_pointer<const s>::value, "");
68static_assert(!fbl::is_pointer<const u>::value, "");
69static_assert(!fbl::is_pointer<const s>::value, "");
70
71static_assert(!fbl::is_pointer<volatile int>::value, "");
72static_assert(!fbl::is_pointer<volatile float>::value, "");
73static_assert(!fbl::is_pointer<volatile s>::value, "");
74static_assert(!fbl::is_pointer<volatile u>::value, "");
75static_assert(!fbl::is_pointer<volatile s>::value, "");
76
77static_assert(!fbl::is_pointer<const volatile int>::value, "");
78static_assert(!fbl::is_pointer<const volatile float>::value, "");
79static_assert(!fbl::is_pointer<const volatile s>::value, "");
80static_assert(!fbl::is_pointer<const volatile u>::value, "");
81static_assert(!fbl::is_pointer<const volatile s>::value, "");
82
83// is_reference tests:
84static_assert(fbl::is_reference<int&>::value, "");
85static_assert(fbl::is_reference<int&&>::value, "");
86static_assert(fbl::is_reference<float&>::value, "");
87static_assert(fbl::is_reference<float&&>::value, "");
88static_assert(fbl::is_reference<s&>::value, "");
89static_assert(fbl::is_reference<s&&>::value, "");
90static_assert(fbl::is_reference<u&>::value, "");
91static_assert(fbl::is_reference<u&&>::value, "");
92static_assert(fbl::is_reference<s&>::value, "");
93static_assert(fbl::is_reference<s&&>::value, "");
94static_assert(fbl::is_reference<fp&>::value, "");
95static_assert(fbl::is_reference<fp&&>::value, "");
96
97static_assert(fbl::is_reference<const int&>::value, "");
98static_assert(fbl::is_reference<const int&&>::value, "");
99static_assert(fbl::is_reference<const float&>::value, "");
100static_assert(fbl::is_reference<const float&&>::value, "");
101static_assert(fbl::is_reference<const s&>::value, "");
102static_assert(fbl::is_reference<const s&&>::value, "");
103static_assert(fbl::is_reference<const u&>::value, "");
104static_assert(fbl::is_reference<const u&&>::value, "");
105static_assert(fbl::is_reference<const s&>::value, "");
106static_assert(fbl::is_reference<const s&&>::value, "");
107
108static_assert(fbl::is_reference<volatile int&>::value, "");
109static_assert(fbl::is_reference<volatile int&&>::value, "");
110static_assert(fbl::is_reference<volatile float&>::value, "");
111static_assert(fbl::is_reference<volatile float&&>::value, "");
112static_assert(fbl::is_reference<volatile s&>::value, "");
113static_assert(fbl::is_reference<volatile s&&>::value, "");
114static_assert(fbl::is_reference<volatile u&>::value, "");
115static_assert(fbl::is_reference<volatile u&&>::value, "");
116static_assert(fbl::is_reference<volatile s&>::value, "");
117static_assert(fbl::is_reference<volatile s&&>::value, "");
118
119static_assert(fbl::is_reference<const volatile int&>::value, "");
120static_assert(fbl::is_reference<const volatile int&&>::value, "");
121static_assert(fbl::is_reference<const volatile float&>::value, "");
122static_assert(fbl::is_reference<const volatile float&&>::value, "");
123static_assert(fbl::is_reference<const volatile s&>::value, "");
124static_assert(fbl::is_reference<const volatile s&&>::value, "");
125static_assert(fbl::is_reference<const volatile u&>::value, "");
126static_assert(fbl::is_reference<const volatile u&&>::value, "");
127static_assert(fbl::is_reference<const volatile s&>::value, "");
128static_assert(fbl::is_reference<const volatile s&&>::value, "");
129
130static_assert(!fbl::is_reference<int>::value, "");
131static_assert(!fbl::is_reference<float>::value, "");
132static_assert(!fbl::is_reference<s>::value, "");
133static_assert(!fbl::is_reference<u>::value, "");
134static_assert(!fbl::is_reference<s>::value, "");
135static_assert(!fbl::is_reference<fp>::value, "");
136
137static_assert(!fbl::is_reference<const int>::value, "");
138static_assert(!fbl::is_reference<const float>::value, "");
139static_assert(!fbl::is_reference<const s>::value, "");
140static_assert(!fbl::is_reference<const u>::value, "");
141static_assert(!fbl::is_reference<const s>::value, "");
142
143static_assert(!fbl::is_reference<volatile int>::value, "");
144static_assert(!fbl::is_reference<volatile float>::value, "");
145static_assert(!fbl::is_reference<volatile s>::value, "");
146static_assert(!fbl::is_reference<volatile u>::value, "");
147static_assert(!fbl::is_reference<volatile s>::value, "");
148
149static_assert(!fbl::is_reference<const volatile int>::value, "");
150static_assert(!fbl::is_reference<const volatile float>::value, "");
151static_assert(!fbl::is_reference<const volatile s>::value, "");
152static_assert(!fbl::is_reference<const volatile u>::value, "");
153static_assert(!fbl::is_reference<const volatile s>::value, "");
154
155// is_union tests:
156static_assert(fbl::is_union<u>::value, "");
157
158static_assert(!fbl::is_union<u*>::value, "");
159static_assert(!fbl::is_union<u&>::value, "");
160static_assert(!fbl::is_union<u&&>::value, "");
161
162static_assert(!fbl::is_union<int>::value, "");
163static_assert(!fbl::is_union<float>::value, "");
164static_assert(!fbl::is_union<s>::value, "");
165static_assert(!fbl::is_union<s>::value, "");
166static_assert(!fbl::is_union<fp>::value, "");
167
168// is_const tests:
169static_assert(!fbl::is_const<int>::value, "");
170static_assert(fbl::is_const<const int>::value, "");
171static_assert(!fbl::is_const<s>::value, "");
172static_assert(fbl::is_const<const s>::value, "");
173static_assert(!fbl::is_const<u>::value, "");
174static_assert(fbl::is_const<const u>::value, "");
175
176static_assert(!fbl::is_const<int*>::value, "");
177static_assert(fbl::is_const<int* const>::value, "");
178static_assert(!fbl::is_const<const int*>::value, "");
179static_assert(fbl::is_const<const int* const>::value, "");
180
181// underlying_type:
182
183enum int_enum : int {};
184enum char_enum : char {};
185static_assert(fbl::is_same<fbl::underlying_type<int_enum>::type, int>::value, "expected int");
186static_assert(fbl::is_same<fbl::underlying_type<char_enum>::type, char>::value, "expected char");
187
188// match_cv tests:
189static_assert(fbl::is_same<fbl::match_cv<int, void>::type, void>::value, "wrong type");
190static_assert(fbl::is_same<fbl::match_cv<const int, void>::type, const void>::value,
191              "wrong type");
192static_assert(fbl::is_same<fbl::match_cv<volatile void, char>::type, volatile char>::value,
193              "wrong type");
194static_assert(fbl::is_same<fbl::match_cv<const int, const char>::type, const char>::value,
195              "wrong type");
196static_assert(fbl::is_same<fbl::match_cv<const int, volatile char>::type, const char>::value,
197              "wrong type");
198static_assert(fbl::is_same<fbl::match_cv<char, const volatile void>::type, void>::value,
199              "wrong type");
200
201
202// is_class tests
203namespace is_class_tests {
204static_assert(!fbl::is_class<int>::value, "'int' should not pass the is_class<> test!");
205
206class A { };
207static_assert(fbl::is_class<A>::value, "'class' should pass the is_class<> test!");
208
209struct B { };
210static_assert(fbl::is_class<B>::value, "'struct' should pass the is_class<> test!");
211
212union C { int a; float b; };
213static_assert(!fbl::is_class<C>::value, "'union' should not pass the is_class<> test!");
214
215enum D { D_ENUM_VALUE };
216static_assert(!fbl::is_class<D>::value, "'enum' should not pass the is_class<> test!");
217
218enum class E { VALUE };
219static_assert(!fbl::is_class<E>::value, "'enum class' should not pass the is_class<> test!");
220}  // namespace is_class_tests
221
222// is_base_of tests
223namespace is_base_of_tests {
224
225static_assert(!fbl::is_base_of<int, int>::value,
226              "scalar types should not be bases of scalar types");
227
228class A { };
229static_assert(fbl::is_base_of<A, A>::value, "A should be a base of A!");
230
231class B : public A { };
232static_assert( fbl::is_base_of<B, B>::value, "B should be a base of B!");
233static_assert( fbl::is_base_of<A, B>::value, "A should be a base of B!");
234static_assert(!fbl::is_base_of<B, A>::value, "B should not be a base of A!");
235
236class C : public B { };
237static_assert( fbl::is_base_of<C, C>::value, "C should be a base of C!");
238static_assert( fbl::is_base_of<B, C>::value, "B should be a base of C!");
239static_assert( fbl::is_base_of<A, C>::value, "A should be a base of C!");
240static_assert(!fbl::is_base_of<C, B>::value, "C should not be a base of B!");
241static_assert(!fbl::is_base_of<C, A>::value, "C should not be a base of A!");
242
243class D { };
244class E : public B, public D { };
245static_assert( fbl::is_base_of<D, D>::value, "D should be a base of D!");
246static_assert( fbl::is_base_of<E, E>::value, "E should be a base of E!");
247static_assert( fbl::is_base_of<A, E>::value, "A should be a base of E!");
248static_assert( fbl::is_base_of<B, E>::value, "B should be a base of E!");
249static_assert(!fbl::is_base_of<C, E>::value, "C should not be a base of E!");
250static_assert( fbl::is_base_of<D, E>::value, "D should be a base of E!");
251static_assert(!fbl::is_base_of<E, A>::value, "E should not be a base of A!");
252static_assert(!fbl::is_base_of<E, B>::value, "E should not be a base of B!");
253static_assert(!fbl::is_base_of<E, C>::value, "E should not be a base of C!");
254static_assert(!fbl::is_base_of<E, D>::value, "E should not be a base of D!");
255
256struct sA { };
257static_assert(fbl::is_base_of<sA, sA>::value, "sA should be a base of sA!");
258
259struct sB : public sA { };
260static_assert( fbl::is_base_of<sB, sB>::value, "sB should be a base of sB!");
261static_assert( fbl::is_base_of<sA, sB>::value, "sA should be a base of sB!");
262static_assert(!fbl::is_base_of<sB, sA>::value, "sB should not be a base of sA!");
263
264struct sC : public sB { };
265static_assert( fbl::is_base_of<sC, sC>::value, "sC should be a base of sC!");
266static_assert( fbl::is_base_of<sB, sC>::value, "sB should be a base of sC!");
267static_assert( fbl::is_base_of<sA, sC>::value, "sA should be a base of sC!");
268static_assert(!fbl::is_base_of<sC, sB>::value, "sC should not be a base of sB!");
269static_assert(!fbl::is_base_of<sC, sA>::value, "sC should not be a base of sA!");
270
271struct sD { };
272struct sE : public sB, public sD { };
273static_assert( fbl::is_base_of<sD, sD>::value, "sD should be a base of sD!");
274static_assert( fbl::is_base_of<sE, sE>::value, "sE should be a base of sE!");
275static_assert( fbl::is_base_of<sA, sE>::value, "sA should be a base of sE!");
276static_assert( fbl::is_base_of<sB, sE>::value, "sB should be a base of sE!");
277static_assert(!fbl::is_base_of<sC, sE>::value, "sC should not be a base of sE!");
278static_assert( fbl::is_base_of<sD, sE>::value, "sD should be a base of sE!");
279static_assert(!fbl::is_base_of<sE, sA>::value, "sE should not be a base of sA!");
280static_assert(!fbl::is_base_of<sE, sB>::value, "sE should not be a base of sB!");
281static_assert(!fbl::is_base_of<sE, sC>::value, "sE should not be a base of sC!");
282static_assert(!fbl::is_base_of<sE, sD>::value, "sE should not be a base of sD!");
283
284}  // namespace is_base_of_tests
285
286namespace has_virtual_destructor_tests {
287
288struct A            {         ~A() { } };
289struct B            { virtual ~B() { } };
290struct C : public A {         ~C() { } };
291struct D : public B {         ~D() { } };
292struct E : public A { virtual ~E() { } };
293
294static_assert(!fbl::has_virtual_destructor<A>::value, "A should have no virtual destructor");
295static_assert( fbl::has_virtual_destructor<B>::value, "B should have a virtual destructor");
296static_assert(!fbl::has_virtual_destructor<C>::value, "C should have no virtual destructor");
297static_assert( fbl::has_virtual_destructor<D>::value, "D should have a virtual destructor");
298static_assert( fbl::has_virtual_destructor<E>::value, "E should have a virtual destructor");
299
300}  // namespace has_virtual_destructor_tests
301
302namespace is_floating_point {
303
304static_assert(fbl::is_floating_point<float>::value, "float is floating point");
305static_assert(fbl::is_floating_point<double>::value, "double is floating point");
306static_assert(fbl::is_floating_point<long double>::value, "long double is floating point");
307
308static_assert(!fbl::is_floating_point<int>::value, "int is not floating point");
309static_assert(!fbl::is_floating_point<decltype(nullptr)>::value, "nullptr is not floating point");
310
311struct A {};
312static_assert(!fbl::is_floating_point<A>::value, "A is not floating point");
313static_assert(!fbl::is_floating_point<A*>::value, "A pointer is not floating point");
314
315} // namespace is_floating_point
316
317namespace is_integral_tests {
318
319static_assert(fbl::is_integral<bool>::value, "bool is integral");
320static_assert(fbl::is_integral<char>::value, "char is integral");
321static_assert(fbl::is_integral<char16_t>::value, "char16_t is integral");
322static_assert(fbl::is_integral<char32_t>::value, "char32_t is integral");
323static_assert(fbl::is_integral<wchar_t>::value, "wchar_t is integral");
324static_assert(fbl::is_integral<signed char>::value, "signed char is integral");
325static_assert(fbl::is_integral<unsigned char>::value, "unsigned char is integral");
326static_assert(fbl::is_integral<short int>::value, "short int is integral");
327static_assert(fbl::is_integral<unsigned short int>::value, "unsigned short int is integral");
328static_assert(fbl::is_integral<int>::value, "int is integral");
329static_assert(fbl::is_integral<unsigned int>::value, "unsigned int is integral");
330static_assert(fbl::is_integral<long int>::value, "long int is integral");
331static_assert(fbl::is_integral<unsigned long int>::value, "unsigned long int is integral");
332static_assert(fbl::is_integral<long long int>::value, "long long int is integral");
333static_assert(fbl::is_integral<unsigned long long int>::value, "unsigned long long int is integral");
334
335static_assert(!fbl::is_integral<float>::value, "float is not integral");
336static_assert(!fbl::is_integral<decltype(nullptr)>::value, "nullptr is not integral");
337
338struct A {};
339static_assert(!fbl::is_integral<A>::value, "A is not floating point");
340static_assert(!fbl::is_integral<A*>::value, "A pointer is not integral");
341
342} // namespace is_integral_tests
343
344namespace is_arithmetic_tests {
345
346static_assert(fbl::is_arithmetic<bool>::value, "bool is arithmetic");
347static_assert(fbl::is_arithmetic<char>::value, "char is arithmetic");
348static_assert(fbl::is_arithmetic<char16_t>::value, "char16_t is arithmetic");
349static_assert(fbl::is_arithmetic<char32_t>::value, "char32_t is arithmetic");
350static_assert(fbl::is_arithmetic<wchar_t>::value, "wchar_t is arithmetic");
351static_assert(fbl::is_arithmetic<signed char>::value, "signed char is arithmetic");
352static_assert(fbl::is_arithmetic<unsigned char>::value, "unsigned char is arithmetic");
353static_assert(fbl::is_arithmetic<short int>::value, "short int is arithmetic");
354static_assert(fbl::is_arithmetic<unsigned short int>::value, "unsigned short int is arithmetic");
355static_assert(fbl::is_arithmetic<int>::value, "int is arithmetic");
356static_assert(fbl::is_arithmetic<unsigned int>::value, "unsigned int is arithmetic");
357static_assert(fbl::is_arithmetic<long int>::value, "long int is arithmetic");
358static_assert(fbl::is_arithmetic<unsigned long int>::value, "unsigned long int is arithmetic");
359static_assert(fbl::is_arithmetic<long long int>::value, "long long int is arithmetic");
360static_assert(fbl::is_arithmetic<unsigned long long int>::value, "unsigned long long int is arithmetic");
361
362static_assert(fbl::is_arithmetic<float>::value, "float is arithmetic");
363static_assert(fbl::is_arithmetic<double>::value, "double is arithmetic");
364static_assert(fbl::is_arithmetic<long double>::value, "long double is arithmetic");
365
366static_assert(!fbl::is_arithmetic<decltype(nullptr)>::value, "nullptr is not arithmetic");
367
368struct A {};
369static_assert(!fbl::is_arithmetic<A>::value, "A is not arithmetic");
370static_assert(!fbl::is_arithmetic<A*>::value, "A pointer is not arithmetic");
371
372} // namespace is_arithmetic_tests
373
374namespace is_signed_tests {
375
376static_assert(fbl::is_signed<int>::value, "int is signed");
377static_assert(!fbl::is_signed<unsigned int>::value, "unsigned int is not signed");
378static_assert(fbl::is_signed<float>::value, "float is signed");
379
380static_assert(!fbl::is_signed<decltype(nullptr)>::value, "nullptr is not signed");
381
382struct A {};
383static_assert(!fbl::is_signed<A>::value, "A is not signed");
384static_assert(!fbl::is_signed<A*>::value, "A pointer is not signed");
385
386} // namespace is_signed_tests
387
388namespace is_unsigned_tests {
389
390static_assert(!fbl::is_unsigned<int>::value, "int is not unsigned");
391static_assert(fbl::is_unsigned<unsigned int>::value, "unsigned int is unsigned");
392static_assert(!fbl::is_unsigned<float>::value, "float is not unsigned");
393
394static_assert(!fbl::is_unsigned<decltype(nullptr)>::value, "nullptr is not unsigned");
395
396struct A {};
397static_assert(!fbl::is_unsigned<A>::value, "A is not unsigned");
398static_assert(!fbl::is_unsigned<A*>::value, "A pointer is not unsigned");
399
400} // namespace is_unsigned_tests
401
402namespace is_signed_integer_tests {
403
404static_assert(fbl::is_signed_integer<int>::value, "int is signed integer");
405static_assert(!fbl::is_signed_integer<unsigned int>::value, "unsigned int is not signed integer");
406static_assert(!fbl::is_signed_integer<float>::value, "float is not signed integer");
407
408static_assert(!fbl::is_signed_integer<decltype(nullptr)>::value, "nullptr is not signed integer");
409
410struct A {};
411static_assert(!fbl::is_signed_integer<A>::value, "A is not signed integer");
412static_assert(!fbl::is_signed_integer<A*>::value, "A pointer is not signed integer");
413
414} // namespace is_signed_integer_tests
415
416namespace is_unsigned_integer_tests {
417
418static_assert(!fbl::is_unsigned_integer<int>::value, "int is not unsigned integer");
419static_assert(fbl::is_unsigned_integer<unsigned int>::value, "unsigned int is unsigned integer");
420static_assert(!fbl::is_unsigned_integer<float>::value, "float is not unsigned integer");
421
422static_assert(!fbl::is_unsigned_integer<decltype(nullptr)>::value, "nullptr is not unsigned integer");
423
424struct A {};
425static_assert(!fbl::is_unsigned_integer<A>::value, "A is not unsigned integer");
426static_assert(!fbl::is_unsigned_integer<A*>::value, "A pointer is not unsigned integer");
427
428} // namespace is_unsigned_integer_tests
429
430namespace is_enum_tests {
431
432enum E {};
433struct S {};
434static_assert(fbl::is_enum<E>::value, "enum is an enum");
435static_assert(!fbl::is_enum<S>::value, "struct is not an enum");
436static_assert(!fbl::is_enum<int>::value, "int is not an enum");
437static_assert(!fbl::is_enum<void>::value, "void is not an enum");
438
439} // namespace is_enum_tests
440
441namespace is_pointer_tests {
442
443struct StructType   {
444    void MemberFunction();
445    int member_variable;
446
447    static void StaticMemberFunction();
448    static int static_member_variable;
449};
450
451static void SomeStaticFunc() { }
452void SomeGlobalFunc() {
453    // Force an artifical use of SomeStaticFunc to avoid warnings.
454    SomeStaticFunc();
455}
456
457class  ClassType    { };
458enum   EnumType     { One, Two };
459union  UnionType    { int a; double b; };
460
461static_assert(!fbl::is_pointer<StructType>::value,         "StructType is not a pointer!");
462static_assert( fbl::is_pointer<StructType*>::value,        "StructType* is a pointer!");
463static_assert( fbl::is_pointer<StructType**>::value,       "StructType** is a pointer!");
464static_assert(!fbl::is_pointer<ClassType>::value,          "ClassType is not a pointer!");
465static_assert( fbl::is_pointer<ClassType*>::value,         "ClassType* is a pointer!");
466static_assert( fbl::is_pointer<ClassType**>::value,        "ClassType** is a pointer!");
467static_assert(!fbl::is_pointer<EnumType>::value,           "EnumType is not a pointer!");
468static_assert( fbl::is_pointer<EnumType*>::value,          "EnumType* is a pointer!");
469static_assert( fbl::is_pointer<EnumType**>::value,         "EnumType** is a pointer!");
470static_assert(!fbl::is_pointer<UnionType>::value,          "UnionType is not a pointer!");
471static_assert( fbl::is_pointer<UnionType*>::value,         "UnionType* is a pointer!");
472static_assert( fbl::is_pointer<UnionType**>::value,        "UnionType** is a pointer!");
473static_assert(!fbl::is_pointer<int>::value,                "int is not a pointer!");
474static_assert(!fbl::is_pointer<int[]>::value,              "int[] is not a pointer!");
475static_assert( fbl::is_pointer<int*>::value,               "int* is a pointer!");
476static_assert( fbl::is_pointer<int**>::value,              "int** is a pointer!");
477
478static_assert(!fbl::is_pointer<const int>::value,          "const int is not a pointer!");
479static_assert(!fbl::is_pointer<volatile int>::value,       "volatile int is not a pointer!");
480static_assert(!fbl::is_pointer<const volatile int>::value, "const volatile int is not a pointer!");
481
482static_assert( fbl::is_pointer<const int*>::value,          "const int* is a pointer!");
483static_assert( fbl::is_pointer<volatile int*>::value,       "volatile int* is a pointer!");
484static_assert( fbl::is_pointer<const volatile int*>::value, "const volatile int* is a pointer!");
485
486static_assert( fbl::is_pointer<int* const >::value,          "int* const is a pointer!");
487static_assert( fbl::is_pointer<int* volatile >::value,       "int* volatile is a pointer!");
488static_assert( fbl::is_pointer<int* const volatile >::value, "int* const volatile is a pointer!");
489
490static_assert( fbl::is_pointer<const int* const >::value,    "const int* const is a pointer!");
491static_assert( fbl::is_pointer<const int* volatile >::value, "const int* volatile is a pointer!");
492static_assert( fbl::is_pointer<const int* const volatile>::value,
493        "const int* const volatile is a pointer!");
494
495static_assert( fbl::is_pointer<volatile int* const >::value, "volatile int* const is a pointer!");
496static_assert( fbl::is_pointer<volatile int* volatile >::value,
497        "volatile int* volatile is a pointer!");
498static_assert( fbl::is_pointer<volatile int* const volatile>::value,
499        "volatile int* const volatile is a pointer!");
500
501static_assert( fbl::is_pointer<const volatile int* const >::value,
502        "const volatile int* const is a pointer!");
503static_assert( fbl::is_pointer<const volatile int* volatile >::value,
504        "const volatile int* volatile is a pointer!");
505static_assert( fbl::is_pointer<const volatile int* const volatile>::value,
506        "const volatile int* const volatile is a pointer!");
507
508static_assert(!fbl::is_pointer<decltype(&StructType::MemberFunction)>::value,
509              "pointer to StructType::MemberFunction is not a pointer!");
510static_assert(!fbl::is_pointer<decltype(&StructType::member_variable)>::value,
511              "pointer to StructType::member_variable is not a pointer!");
512
513static_assert( fbl::is_pointer<decltype(&StructType::StaticMemberFunction)>::value,
514              "pointer to StructType::MemberFunction is a pointer!");
515static_assert( fbl::is_pointer<decltype(&StructType::static_member_variable)>::value,
516              "pointer to StructType::static_member_variable is a pointer!");
517
518static_assert( fbl::is_pointer<decltype(&SomeGlobalFunc)>::value,
519              "pointer to SomeGlobalFunc is a pointer!");
520static_assert( fbl::is_pointer<decltype(&SomeStaticFunc)>::value,
521              "pointer to SomeStaticFunc is a pointer!");
522static_assert(!fbl::is_pointer<decltype(nullptr)>::value,
523              "decltype(nullptr) (aka nullptr_t) is not a pointer (because C++)");
524}  // namespace is_pointer_tests;
525
526namespace is_convertible_tests {
527
528class A { };
529class B : public A { };
530class C { };
531
532template <typename From, typename To>
533using icp = fbl::is_convertible_pointer<From, To>;
534
535static_assert( icp<B*, A*>::value, "Should convert B* --> A*");
536static_assert(!icp<A*, B*>::value, "Should not convert A* --> B*");
537static_assert(!icp<A,  B*>::value, "Should not convert A --> B*");
538static_assert(!icp<A*, B>::value,  "Should not convert A* --> B");
539static_assert(!icp<A,  B>::value,  "Should not convert A --> B");
540static_assert(!icp<A*, C*>::value, "Should not convert A* --> C*");
541
542static_assert( icp<int*, void*>::value,         "Should convert int* --> void*");
543static_assert( icp<int*, const int*>::value,    "Should convert int* --> const int*");
544static_assert( icp<int*, volatile int*>::value, "Should convert int* --> volatile int*");
545static_assert(!icp<const int*, int*>::value,    "Should not convert const int* --> int*");
546static_assert(!icp<volatile int*, int*>::value, "Should not convert volatile int* --> int*");
547static_assert(!icp<unsigned int*, int*>::value, "Should not convert unsigned int* --> int*");
548static_assert(!icp<int*, unsigned int*>::value, "Should not convert int* --> unsigned int*");
549static_assert(!icp<float*, double*>::value,     "Should not convert float* --> double*");
550
551}  // namespace is_convertible_tests
552
553namespace conditional_tests {
554
555static_assert(fbl::is_same<fbl::conditional<true, int, bool>::type, int>::value, "wrong type");
556static_assert(fbl::is_same<fbl::conditional<false, int, bool>::type, bool>::value, "wrong type");
557
558}  // namespace conditional_tests
559
560namespace has_member_fn_tests {
561
562struct A {
563  void simple();
564  void overloaded();
565  int overloaded(int);
566  int overloaded(int) const;
567};
568
569struct B {
570  int simple();
571  int overloaded(int) const;
572};
573
574struct C {};
575
576DECLARE_HAS_MEMBER_FN(has_simple, simple);
577DECLARE_HAS_MEMBER_FN(has_overloaded, overloaded);
578DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_simple_void, simple, void (C::*)());
579DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_simple_int, simple, int (C::*)());
580DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_overloaded_void, overloaded, void (C::*)());
581DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_overloaded_int, overloaded, int (C::*)(int));
582DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_overloaded_int_const, overloaded, int (C::*)(int) const);
583
584static_assert(has_simple<A>::value, "");
585static_assert(has_simple<B>::value, "");
586static_assert(!has_simple<C>::value, "");
587static_assert(!has_simple<int>::value, "");
588static_assert(!has_simple<decltype(nullptr)>::value, "");
589
590static_assert(!has_overloaded<A>::value, "fails due to ambiguity");
591static_assert(has_overloaded<B>::value, "unambiguous");
592static_assert(!has_overloaded<C>::value, "");
593static_assert(!has_overloaded<int>::value, "");
594static_assert(!has_overloaded<decltype(nullptr)>::value, "");
595
596static_assert(has_simple_void<A>::value, "");
597static_assert(!has_simple_void<B>::value, "");
598static_assert(!has_simple_void<C>::value, "");
599static_assert(!has_simple_void<int>::value, "");
600static_assert(!has_simple_void<decltype(nullptr)>::value, "");
601
602static_assert(!has_simple_int<A>::value, "");
603static_assert(has_simple_int<B>::value, "");
604static_assert(!has_simple_int<C>::value, "");
605static_assert(!has_simple_int<int>::value, "");
606static_assert(!has_simple_int<decltype(nullptr)>::value, "");
607
608static_assert(has_overloaded_void<A>::value, "");
609static_assert(!has_overloaded_void<B>::value, "");
610static_assert(!has_overloaded_void<C>::value, "");
611static_assert(!has_overloaded_void<int>::value, "");
612static_assert(!has_overloaded_void<decltype(nullptr)>::value, "");
613
614static_assert(has_overloaded_int<A>::value, "");
615static_assert(!has_overloaded_int<B>::value, "");
616static_assert(!has_overloaded_int<C>::value, "");
617static_assert(!has_overloaded_int<int>::value, "");
618static_assert(!has_overloaded_int<decltype(nullptr)>::value, "");
619
620static_assert(has_overloaded_int_const<A>::value, "");
621static_assert(has_overloaded_int_const<B>::value, "");
622static_assert(!has_overloaded_int_const<C>::value, "");
623static_assert(!has_overloaded_int_const<int>::value, "");
624static_assert(!has_overloaded_int_const<decltype(nullptr)>::value, "");
625
626} // namespace has_member_fn_tests
627
628// is_function tests:
629
630namespace is_function_tests {
631
632struct s {};
633union u {};
634
635struct forward_s;
636
637// Lots of things are not functions.
638
639static_assert(!fbl::is_function<int>::value, "");
640static_assert(!fbl::is_function<int[]>::value, "");
641static_assert(!fbl::is_function<int[1]>::value, "");
642static_assert(!fbl::is_function<int*>::value, "");
643static_assert(!fbl::is_function<int&>::value, "");
644static_assert(!fbl::is_function<int&&>::value, "");
645
646static_assert(!fbl::is_function<float>::value, "");
647static_assert(!fbl::is_function<float[]>::value, "");
648static_assert(!fbl::is_function<float[1]>::value, "");
649static_assert(!fbl::is_function<float*>::value, "");
650static_assert(!fbl::is_function<float&>::value, "");
651static_assert(!fbl::is_function<float&&>::value, "");
652
653static_assert(!fbl::is_function<s>::value, "");
654static_assert(!fbl::is_function<s[]>::value, "");
655static_assert(!fbl::is_function<s[1]>::value, "");
656static_assert(!fbl::is_function<s*>::value, "");
657static_assert(!fbl::is_function<s&>::value, "");
658static_assert(!fbl::is_function<s&&>::value, "");
659
660static_assert(!fbl::is_function<u>::value, "");
661static_assert(!fbl::is_function<u[]>::value, "");
662static_assert(!fbl::is_function<u[1]>::value, "");
663static_assert(!fbl::is_function<u*>::value, "");
664static_assert(!fbl::is_function<u&>::value, "");
665static_assert(!fbl::is_function<u&&>::value, "");
666
667static_assert(!fbl::is_function<forward_s>::value, "");
668static_assert(!fbl::is_function<forward_s[]>::value, "");
669static_assert(!fbl::is_function<forward_s[1]>::value, "");
670static_assert(!fbl::is_function<forward_s*>::value, "");
671static_assert(!fbl::is_function<forward_s&>::value, "");
672static_assert(!fbl::is_function<forward_s&&>::value, "");
673
674static_assert(!fbl::is_function<decltype(nullptr)>::value, "");
675static_assert(!fbl::is_function<decltype(nullptr)[]>::value, "");
676static_assert(!fbl::is_function<decltype(nullptr)[1]>::value, "");
677static_assert(!fbl::is_function<decltype(nullptr)*>::value, "");
678static_assert(!fbl::is_function<decltype(nullptr)&>::value, "");
679static_assert(!fbl::is_function<decltype(nullptr)&&>::value, "");
680
681// There are pointers to void, but no references to void or arrays of
682// void.
683static_assert(!fbl::is_function<void>::value, "");
684static_assert(!fbl::is_function<void*>::value, "");
685
686using member_function_pointer = void(s::*)();
687static_assert(!fbl::is_function<member_function_pointer>::value, "");
688static_assert(!fbl::is_function<member_function_pointer[]>::value, "");
689static_assert(!fbl::is_function<member_function_pointer[1]>::value, "");
690static_assert(!fbl::is_function<member_function_pointer*>::value, "");
691static_assert(!fbl::is_function<member_function_pointer&>::value, "");
692static_assert(!fbl::is_function<member_function_pointer&&>::value, "");
693
694// Functions are functions, but pointers or references to them are
695// not.
696
697using void_to_void = void();
698static_assert(fbl::is_function<void_to_void>::value, "");
699static_assert(!fbl::is_function<void_to_void*>::value, "");
700static_assert(!fbl::is_function<void_to_void&>::value, "");
701static_assert(!fbl::is_function<void_to_void&&>::value, "");
702
703using void_to_int = int();
704static_assert(fbl::is_function<void_to_int>::value, "");
705static_assert(!fbl::is_function<void_to_int*>::value, "");
706static_assert(!fbl::is_function<void_to_int&>::value, "");
707static_assert(!fbl::is_function<void_to_int&&>::value, "");
708
709using int_to_void = void(int);
710static_assert(fbl::is_function<int_to_void>::value, "");
711static_assert(!fbl::is_function<int_to_void*>::value, "");
712static_assert(!fbl::is_function<int_to_void&>::value, "");
713static_assert(!fbl::is_function<int_to_void&&>::value, "");
714
715using int_to_int = int(int);
716static_assert(fbl::is_function<int_to_int>::value, "");
717static_assert(!fbl::is_function<int_to_int*>::value, "");
718static_assert(!fbl::is_function<int_to_int&>::value, "");
719static_assert(!fbl::is_function<int_to_int&&>::value, "");
720
721using s_to_void = void(s);
722static_assert(fbl::is_function<s_to_void>::value, "");
723static_assert(!fbl::is_function<s_to_void*>::value, "");
724static_assert(!fbl::is_function<s_to_void&>::value, "");
725static_assert(!fbl::is_function<s_to_void&&>::value, "");
726
727using u_to_void = void(u);
728static_assert(fbl::is_function<u_to_void>::value, "");
729static_assert(!fbl::is_function<u_to_void*>::value, "");
730static_assert(!fbl::is_function<u_to_void&>::value, "");
731static_assert(!fbl::is_function<u_to_void&&>::value, "");
732
733using va_to_void = void(...);
734static_assert(fbl::is_function<va_to_void>::value, "");
735static_assert(!fbl::is_function<va_to_void*>::value, "");
736static_assert(!fbl::is_function<va_to_void&>::value, "");
737static_assert(!fbl::is_function<va_to_void&&>::value, "");
738
739using int_va_to_void = void(int, ...);
740static_assert(fbl::is_function<int_va_to_void>::value, "");
741static_assert(!fbl::is_function<int_va_to_void*>::value, "");
742static_assert(!fbl::is_function<int_va_to_void&>::value, "");
743static_assert(!fbl::is_function<int_va_to_void&&>::value, "");
744
745auto lambda = [](){};
746auto function_pointer_inside_lambda = static_cast<void(*)()>(lambda);
747static_assert(fbl::is_pointer<decltype(function_pointer_inside_lambda)>::value, "");
748using function_type = fbl::remove_pointer<decltype(function_pointer_inside_lambda)>::type;
749static_assert(fbl::is_function<function_type>::value, "");
750
751}; // namespace is_function_tests
752