|
1 // Copyright (c) 2011 The Chromium 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 #ifndef BASE_TEMPLATE_UTIL_H_ |
|
6 #define BASE_TEMPLATE_UTIL_H_ |
|
7 |
|
8 #include <cstddef> // For size_t. |
|
9 |
|
10 #include "build/build_config.h" |
|
11 |
|
12 namespace base { |
|
13 |
|
14 // template definitions from tr1 |
|
15 |
|
16 template<class T, T v> |
|
17 struct integral_constant { |
|
18 static const T value = v; |
|
19 typedef T value_type; |
|
20 typedef integral_constant<T, v> type; |
|
21 }; |
|
22 |
|
23 template <class T, T v> const T integral_constant<T, v>::value; |
|
24 |
|
25 typedef integral_constant<bool, true> true_type; |
|
26 typedef integral_constant<bool, false> false_type; |
|
27 |
|
28 template <class T> struct is_pointer : false_type {}; |
|
29 template <class T> struct is_pointer<T*> : true_type {}; |
|
30 |
|
31 template <class T, class U> struct is_same : public false_type {}; |
|
32 template <class T> struct is_same<T,T> : true_type {}; |
|
33 |
|
34 template<class> struct is_array : public false_type {}; |
|
35 template<class T, size_t n> struct is_array<T[n]> : public true_type {}; |
|
36 template<class T> struct is_array<T[]> : public true_type {}; |
|
37 |
|
38 template <class T> struct is_non_const_reference : false_type {}; |
|
39 template <class T> struct is_non_const_reference<T&> : true_type {}; |
|
40 template <class T> struct is_non_const_reference<const T&> : false_type {}; |
|
41 |
|
42 template <class T> struct is_void : false_type {}; |
|
43 template <> struct is_void<void> : true_type {}; |
|
44 |
|
45 namespace internal { |
|
46 |
|
47 // Types YesType and NoType are guaranteed such that sizeof(YesType) < |
|
48 // sizeof(NoType). |
|
49 typedef char YesType; |
|
50 |
|
51 struct NoType { |
|
52 YesType dummy[2]; |
|
53 }; |
|
54 |
|
55 // This class is an implementation detail for is_convertible, and you |
|
56 // don't need to know how it works to use is_convertible. For those |
|
57 // who care: we declare two different functions, one whose argument is |
|
58 // of type To and one with a variadic argument list. We give them |
|
59 // return types of different size, so we can use sizeof to trick the |
|
60 // compiler into telling us which function it would have chosen if we |
|
61 // had called it with an argument of type From. See Alexandrescu's |
|
62 // _Modern C++ Design_ for more details on this sort of trick. |
|
63 |
|
64 struct ConvertHelper { |
|
65 template <typename To> |
|
66 static YesType Test(To); |
|
67 |
|
68 template <typename To> |
|
69 static NoType Test(...); |
|
70 |
|
71 template <typename From> |
|
72 static From& Create(); |
|
73 }; |
|
74 |
|
75 // Used to determine if a type is a struct/union/class. Inspired by Boost's |
|
76 // is_class type_trait implementation. |
|
77 struct IsClassHelper { |
|
78 template <typename C> |
|
79 static YesType Test(void(C::*)(void)); |
|
80 |
|
81 template <typename C> |
|
82 static NoType Test(...); |
|
83 }; |
|
84 |
|
85 } // namespace internal |
|
86 |
|
87 // Inherits from true_type if From is convertible to To, false_type otherwise. |
|
88 // |
|
89 // Note that if the type is convertible, this will be a true_type REGARDLESS |
|
90 // of whether or not the conversion would emit a warning. |
|
91 template <typename From, typename To> |
|
92 struct is_convertible |
|
93 : integral_constant<bool, |
|
94 sizeof(internal::ConvertHelper::Test<To>( |
|
95 internal::ConvertHelper::Create<From>())) == |
|
96 sizeof(internal::YesType)> { |
|
97 }; |
|
98 |
|
99 template <typename T> |
|
100 struct is_class |
|
101 : integral_constant<bool, |
|
102 sizeof(internal::IsClassHelper::Test<T>(0)) == |
|
103 sizeof(internal::YesType)> { |
|
104 }; |
|
105 |
|
106 } // namespace base |
|
107 |
|
108 #endif // BASE_TEMPLATE_UTIL_H_ |