OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef BASE_TEMPLATE_UTIL_H_ | 5 #ifndef BASE_TEMPLATE_UTIL_H_ |
6 #define BASE_TEMPLATE_UTIL_H_ | 6 #define BASE_TEMPLATE_UTIL_H_ |
7 #pragma once | 7 #pragma once |
8 | 8 |
| 9 #include "build/build_config.h" |
| 10 |
9 namespace base { | 11 namespace base { |
10 | 12 |
11 // template definitions from tr1 | 13 // template definitions from tr1 |
12 | 14 |
13 template<class T, T v> | 15 template<class T, T v> |
14 struct integral_constant { | 16 struct integral_constant { |
15 static const T value = v; | 17 static const T value = v; |
16 typedef T value_type; | 18 typedef T value_type; |
17 typedef integral_constant<T, v> type; | 19 typedef integral_constant<T, v> type; |
18 }; | 20 }; |
19 | 21 |
20 template <class T, T v> const T integral_constant<T, v>::value; | 22 template <class T, T v> const T integral_constant<T, v>::value; |
21 | 23 |
22 typedef integral_constant<bool, true> true_type; | 24 typedef integral_constant<bool, true> true_type; |
23 typedef integral_constant<bool, false> false_type; | 25 typedef integral_constant<bool, false> false_type; |
24 | 26 |
25 template <class T> struct is_pointer : false_type {}; | 27 template <class T> struct is_pointer : false_type {}; |
26 template <class T> struct is_pointer<T*> : true_type {}; | 28 template <class T> struct is_pointer<T*> : true_type {}; |
27 | 29 |
| 30 namespace internal { |
| 31 |
| 32 // Types small_ and big_ are guaranteed such that sizeof(small_) < |
| 33 // sizeof(big_) |
| 34 typedef char small_; |
| 35 |
| 36 struct big_ { |
| 37 small_ dummy[2]; |
| 38 }; |
| 39 |
| 40 #if !defined(OS_WIN) |
| 41 |
| 42 // This class is an implementation detail for is_convertible, and you |
| 43 // don't need to know how it works to use is_convertible. For those |
| 44 // who care: we declare two different functions, one whose argument is |
| 45 // of type To and one with a variadic argument list. We give them |
| 46 // return types of different size, so we can use sizeof to trick the |
| 47 // compiler into telling us which function it would have chosen if we |
| 48 // had called it with an argument of type From. See Alexandrescu's |
| 49 // _Modern C++ Design_ for more details on this sort of trick. |
| 50 |
| 51 template <typename From, typename To> |
| 52 struct ConvertHelper { |
| 53 static small_ Test(To); |
| 54 static big_ Test(...); |
| 55 static From Create(); |
| 56 }; |
| 57 |
| 58 #endif // !defined(OS_WIN) |
| 59 |
| 60 } // namespace internal |
| 61 |
| 62 #if !defined(OS_WIN) |
| 63 |
| 64 // Inherits from true_type if From is convertible to To, false_type otherwise. |
| 65 template <typename From, typename To> |
| 66 struct is_convertible |
| 67 : integral_constant<bool, |
| 68 sizeof(internal::ConvertHelper<From, To>::Test( |
| 69 internal::ConvertHelper<From, To>::Create())) |
| 70 == sizeof(internal::small_)> { |
| 71 }; |
| 72 |
| 73 #endif // !defined(OS_WIN) |
| 74 |
28 } // namespace base | 75 } // namespace base |
29 | 76 |
30 #endif // BASE_TEMPLATE_UTIL_H_ | 77 #endif // BASE_TEMPLATE_UTIL_H_ |
OLD | NEW |