1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifndef BASE_TEMPLATE_UTIL_H_ 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define BASE_TEMPLATE_UTIL_H_ 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include <cstddef> // For size_t. 1072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 1121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "build/build_config.h" 1221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace base { 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// template definitions from tr1 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate<class T, T v> 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct integral_constant { 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static const T value = v; 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef T value_type; 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef integral_constant<T, v> type; 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <class T, T v> const T integral_constant<T, v>::value; 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtypedef integral_constant<bool, true> true_type; 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtypedef integral_constant<bool, false> false_type; 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <class T> struct is_pointer : false_type {}; 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <class T> struct is_pointer<T*> : true_type {}; 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate<class> struct is_array : public false_type {}; 3372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate<class T, size_t n> struct is_array<T[n]> : public true_type {}; 3472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate<class T> struct is_array<T[]> : public true_type {}; 3572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 3672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <class T> struct is_non_const_reference : false_type {}; 3772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <class T> struct is_non_const_reference<T&> : true_type {}; 3872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <class T> struct is_non_const_reference<const T&> : false_type {}; 3972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 4021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsennamespace internal { 4121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 4272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Types YesType and NoType are guaranteed such that sizeof(YesType) < 4372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// sizeof(NoType). 4472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentypedef char YesType; 4521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 4672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstruct NoType { 4772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen YesType dummy[2]; 4821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}; 4921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 5021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// This class is an implementation detail for is_convertible, and you 5121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// don't need to know how it works to use is_convertible. For those 5221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// who care: we declare two different functions, one whose argument is 5321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// of type To and one with a variadic argument list. We give them 5421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// return types of different size, so we can use sizeof to trick the 5521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// compiler into telling us which function it would have chosen if we 5621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// had called it with an argument of type From. See Alexandrescu's 5721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// _Modern C++ Design_ for more details on this sort of trick. 5821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 5921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenstruct ConvertHelper { 60dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen template <typename To> 6172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen static YesType Test(To); 62dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 63dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen template <typename To> 6472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen static NoType Test(...); 65dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 66dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen template <typename From> 6721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen static From Create(); 6821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}; 6921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 7072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Used to determine if a type is a struct/union/class. Inspired by Boost's 7172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// is_class type_trait implementation. 7272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstruct IsClassHelper { 7372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen template <typename C> 7472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen static YesType Test(void(C::*)(void)); 7572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 7672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen template <typename C> 7772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen static NoType Test(...); 7872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}; 7972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 8021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} // namespace internal 8121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 8221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Inherits from true_type if From is convertible to To, false_type otherwise. 83dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// 84dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Note that if the type is convertible, this will be a true_type REGARDLESS 85dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// of whether or not the conversion would emit a warning. 8621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsentemplate <typename From, typename To> 8721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenstruct is_convertible 8821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen : integral_constant<bool, 89dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen sizeof(internal::ConvertHelper::Test<To>( 90dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen internal::ConvertHelper::Create<From>())) == 91dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen sizeof(internal::YesType)> { 9221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}; 9321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 9472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsentemplate <typename T> 9572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstruct is_class 9672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen : integral_constant<bool, 9772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen sizeof(internal::IsClassHelper::Test<T>(0)) == 9872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen sizeof(internal::YesType)> { 9972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}; 10072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace base 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#endif // BASE_TEMPLATE_UTIL_H_ 104