Index: base/template_util.h |
diff --git a/base/template_util.h b/base/template_util.h |
index 2cfe04cdebcee18cec79de4eccc8efe0af49f844..27bdb7348890571b1e7628ba1c908dfab330afa9 100644 |
--- a/base/template_util.h |
+++ b/base/template_util.h |
@@ -6,6 +6,8 @@ |
#define BASE_TEMPLATE_UTIL_H_ |
#pragma once |
+#include "build/build_config.h" |
+ |
namespace base { |
// template definitions from tr1 |
@@ -25,6 +27,51 @@ typedef integral_constant<bool, false> false_type; |
template <class T> struct is_pointer : false_type {}; |
template <class T> struct is_pointer<T*> : true_type {}; |
+namespace internal { |
+ |
+// Types small_ and big_ are guaranteed such that sizeof(small_) < |
+// sizeof(big_) |
+typedef char small_; |
+ |
+struct big_ { |
+ small_ dummy[2]; |
+}; |
+ |
+#if !defined(OS_WIN) |
+ |
+// This class is an implementation detail for is_convertible, and you |
+// don't need to know how it works to use is_convertible. For those |
+// who care: we declare two different functions, one whose argument is |
+// of type To and one with a variadic argument list. We give them |
+// return types of different size, so we can use sizeof to trick the |
+// compiler into telling us which function it would have chosen if we |
+// had called it with an argument of type From. See Alexandrescu's |
+// _Modern C++ Design_ for more details on this sort of trick. |
+ |
+template <typename From, typename To> |
+struct ConvertHelper { |
+ static small_ Test(To); |
+ static big_ Test(...); |
+ static From Create(); |
+}; |
+ |
+#endif // !defined(OS_WIN) |
+ |
+} // namespace internal |
+ |
+#if !defined(OS_WIN) |
+ |
+// Inherits from true_type if From is convertible to To, false_type otherwise. |
+template <typename From, typename To> |
+struct is_convertible |
+ : integral_constant<bool, |
+ sizeof(internal::ConvertHelper<From, To>::Test( |
+ internal::ConvertHelper<From, To>::Create())) |
+ == sizeof(internal::small_)> { |
+}; |
+ |
+#endif // !defined(OS_WIN) |
+ |
} // namespace base |
#endif // BASE_TEMPLATE_UTIL_H_ |