template_util.h revision 8bcbed890bc3ce4d7a057a8f32cab53fa534672e
13aad3b01afc77993ff051c02e49186294e312980humper@google.com// Copyright (c) 2011 The Chromium Authors. All rights reserved. 23aad3b01afc77993ff051c02e49186294e312980humper@google.com// Use of this source code is governed by a BSD-style license that can be 33aad3b01afc77993ff051c02e49186294e312980humper@google.com// found in the LICENSE file. 43aad3b01afc77993ff051c02e49186294e312980humper@google.com 53aad3b01afc77993ff051c02e49186294e312980humper@google.com#ifndef BASE_TEMPLATE_UTIL_H_ 63aad3b01afc77993ff051c02e49186294e312980humper@google.com#define BASE_TEMPLATE_UTIL_H_ 73aad3b01afc77993ff051c02e49186294e312980humper@google.com 83aad3b01afc77993ff051c02e49186294e312980humper@google.com#include <cstddef> // For size_t. 93aad3b01afc77993ff051c02e49186294e312980humper@google.com 103aad3b01afc77993ff051c02e49186294e312980humper@google.com#include "build/build_config.h" 113aad3b01afc77993ff051c02e49186294e312980humper@google.com 123aad3b01afc77993ff051c02e49186294e312980humper@google.comnamespace base { 133aad3b01afc77993ff051c02e49186294e312980humper@google.com 143aad3b01afc77993ff051c02e49186294e312980humper@google.com// template definitions from tr1 153aad3b01afc77993ff051c02e49186294e312980humper@google.com 163aad3b01afc77993ff051c02e49186294e312980humper@google.comtemplate<class T, T v> 177d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.orgstruct integral_constant { 183aad3b01afc77993ff051c02e49186294e312980humper@google.com static const T value = v; 193aad3b01afc77993ff051c02e49186294e312980humper@google.com typedef T value_type; 203aad3b01afc77993ff051c02e49186294e312980humper@google.com typedef integral_constant<T, v> type; 213aad3b01afc77993ff051c02e49186294e312980humper@google.com}; 223aad3b01afc77993ff051c02e49186294e312980humper@google.com 2377af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.comtemplate <class T, T v> const T integral_constant<T, v>::value; 243aad3b01afc77993ff051c02e49186294e312980humper@google.com 253aad3b01afc77993ff051c02e49186294e312980humper@google.comtypedef integral_constant<bool, true> true_type; 263aad3b01afc77993ff051c02e49186294e312980humper@google.comtypedef integral_constant<bool, false> false_type; 273aad3b01afc77993ff051c02e49186294e312980humper@google.com 287d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.orgtemplate <class T> struct is_pointer : false_type {}; 297d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.orgtemplate <class T> struct is_pointer<T*> : true_type {}; 307d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org 317d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.orgtemplate <class T, class U> struct is_same : public false_type {}; 327d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.orgtemplate <class T> struct is_same<T,T> : true_type {}; 333aad3b01afc77993ff051c02e49186294e312980humper@google.com 343aad3b01afc77993ff051c02e49186294e312980humper@google.comtemplate<class> struct is_array : public false_type {}; 353aad3b01afc77993ff051c02e49186294e312980humper@google.comtemplate<class T, size_t n> struct is_array<T[n]> : public true_type {}; 367d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.orgtemplate<class T> struct is_array<T[]> : public true_type {}; 377d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org 387d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.orgtemplate <class T> struct is_non_const_reference : false_type {}; 393aad3b01afc77993ff051c02e49186294e312980humper@google.comtemplate <class T> struct is_non_const_reference<T&> : true_type {}; 403aad3b01afc77993ff051c02e49186294e312980humper@google.comtemplate <class T> struct is_non_const_reference<const T&> : false_type {}; 413aad3b01afc77993ff051c02e49186294e312980humper@google.com 423aad3b01afc77993ff051c02e49186294e312980humper@google.comtemplate <class T> struct is_const : false_type {}; 4377af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.comtemplate <class T> struct is_const<const T> : true_type {}; 4477af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com 453aad3b01afc77993ff051c02e49186294e312980humper@google.comtemplate <class T> struct is_void : false_type {}; 463aad3b01afc77993ff051c02e49186294e312980humper@google.comtemplate <> struct is_void<void> : true_type {}; 473aad3b01afc77993ff051c02e49186294e312980humper@google.com 487d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.orgnamespace internal { 493aad3b01afc77993ff051c02e49186294e312980humper@google.com 503aad3b01afc77993ff051c02e49186294e312980humper@google.com// Types YesType and NoType are guaranteed such that sizeof(YesType) < 513aad3b01afc77993ff051c02e49186294e312980humper@google.com// sizeof(NoType). 5277af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.comtypedef char YesType; 533aad3b01afc77993ff051c02e49186294e312980humper@google.com 547d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.orgstruct NoType { 55a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org YesType dummy[2]; 5677af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com}; 573aad3b01afc77993ff051c02e49186294e312980humper@google.com 583aad3b01afc77993ff051c02e49186294e312980humper@google.com// This class is an implementation detail for is_convertible, and you 593aad3b01afc77993ff051c02e49186294e312980humper@google.com// don't need to know how it works to use is_convertible. For those 603aad3b01afc77993ff051c02e49186294e312980humper@google.com// who care: we declare two different functions, one whose argument is 613aad3b01afc77993ff051c02e49186294e312980humper@google.com// of type To and one with a variadic argument list. We give them 623aad3b01afc77993ff051c02e49186294e312980humper@google.com// return types of different size, so we can use sizeof to trick the 633aad3b01afc77993ff051c02e49186294e312980humper@google.com// compiler into telling us which function it would have chosen if we 643aad3b01afc77993ff051c02e49186294e312980humper@google.com// had called it with an argument of type From. See Alexandrescu's 653aad3b01afc77993ff051c02e49186294e312980humper@google.com// _Modern C++ Design_ for more details on this sort of trick. 663aad3b01afc77993ff051c02e49186294e312980humper@google.com 673aad3b01afc77993ff051c02e49186294e312980humper@google.comstruct ConvertHelper { 683aad3b01afc77993ff051c02e49186294e312980humper@google.com template <typename To> 693aad3b01afc77993ff051c02e49186294e312980humper@google.com static YesType Test(To); 703aad3b01afc77993ff051c02e49186294e312980humper@google.com 713aad3b01afc77993ff051c02e49186294e312980humper@google.com template <typename To> 723aad3b01afc77993ff051c02e49186294e312980humper@google.com static NoType Test(...); 733aad3b01afc77993ff051c02e49186294e312980humper@google.com 743aad3b01afc77993ff051c02e49186294e312980humper@google.com template <typename From> 753aad3b01afc77993ff051c02e49186294e312980humper@google.com static From& Create(); 763aad3b01afc77993ff051c02e49186294e312980humper@google.com}; 773aad3b01afc77993ff051c02e49186294e312980humper@google.com 783aad3b01afc77993ff051c02e49186294e312980humper@google.com// Used to determine if a type is a struct/union/class. Inspired by Boost's 793aad3b01afc77993ff051c02e49186294e312980humper@google.com// is_class type_trait implementation. 803aad3b01afc77993ff051c02e49186294e312980humper@google.comstruct IsClassHelper { 813aad3b01afc77993ff051c02e49186294e312980humper@google.com template <typename C> 823aad3b01afc77993ff051c02e49186294e312980humper@google.com static YesType Test(void(C::*)(void)); 83dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org 84dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org template <typename C> 85dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org static NoType Test(...); 86dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org}; 87dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org 88dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org} // namespace internal 89dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org 90dec61503d02862760f3c91203a698636a02c882acommit-bot@chromium.org// Inherits from true_type if From is convertible to To, false_type otherwise. 917d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org// 923aad3b01afc77993ff051c02e49186294e312980humper@google.com// Note that if the type is convertible, this will be a true_type REGARDLESS 933aad3b01afc77993ff051c02e49186294e312980humper@google.com// of whether or not the conversion would emit a warning. 943aad3b01afc77993ff051c02e49186294e312980humper@google.comtemplate <typename From, typename To> 953aad3b01afc77993ff051c02e49186294e312980humper@google.comstruct is_convertible 967d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org : integral_constant<bool, 977d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org sizeof(internal::ConvertHelper::Test<To>( 987d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org internal::ConvertHelper::Create<From>())) == 993aad3b01afc77993ff051c02e49186294e312980humper@google.com sizeof(internal::YesType)> { 1007d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org}; 1013aad3b01afc77993ff051c02e49186294e312980humper@google.com 1027d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.orgtemplate <typename T> 1037d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.orgstruct is_class 1047d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org : integral_constant<bool, 1053aad3b01afc77993ff051c02e49186294e312980humper@google.com sizeof(internal::IsClassHelper::Test<T>(0)) == 1063aad3b01afc77993ff051c02e49186294e312980humper@google.com sizeof(internal::YesType)> { 1073aad3b01afc77993ff051c02e49186294e312980humper@google.com}; 1083aad3b01afc77993ff051c02e49186294e312980humper@google.com 1093aad3b01afc77993ff051c02e49186294e312980humper@google.comtemplate<bool B, class T = void> 1107d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.orgstruct enable_if {}; 1113aad3b01afc77993ff051c02e49186294e312980humper@google.com 1123aad3b01afc77993ff051c02e49186294e312980humper@google.comtemplate<class T> 1133aad3b01afc77993ff051c02e49186294e312980humper@google.comstruct enable_if<true, T> { typedef T type; }; 114d3baf20dd1de9940717dd50b5c9ff6061561342ecommit-bot@chromium.org 1153aad3b01afc77993ff051c02e49186294e312980humper@google.com} // namespace base 1167d7f31433b627e62f518e9186d3f2d9bd44662e0commit-bot@chromium.org 1173aad3b01afc77993ff051c02e49186294e312980humper@google.com#endif // BASE_TEMPLATE_UTIL_H_ 1183aad3b01afc77993ff051c02e49186294e312980humper@google.com