template_util.h revision 21d179b334e59e9a3bfcaed4c4430bef1bc5759d
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 3// found in the LICENSE file. 4 5#ifndef BASE_TEMPLATE_UTIL_H_ 6#define BASE_TEMPLATE_UTIL_H_ 7#pragma once 8 9#include "build/build_config.h" 10 11namespace base { 12 13// template definitions from tr1 14 15template<class T, T v> 16struct integral_constant { 17 static const T value = v; 18 typedef T value_type; 19 typedef integral_constant<T, v> type; 20}; 21 22template <class T, T v> const T integral_constant<T, v>::value; 23 24typedef integral_constant<bool, true> true_type; 25typedef integral_constant<bool, false> false_type; 26 27template <class T> struct is_pointer : false_type {}; 28template <class T> struct is_pointer<T*> : true_type {}; 29 30namespace internal { 31 32// Types small_ and big_ are guaranteed such that sizeof(small_) < 33// sizeof(big_) 34typedef char small_; 35 36struct 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 51template <typename From, typename To> 52struct 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. 65template <typename From, typename To> 66struct 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 75} // namespace base 76 77#endif // BASE_TEMPLATE_UTIL_H_ 78