// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // This code is compiled directly on many platforms, including client // platforms like Windows, Mac, and embedded systems. Before making // any changes here, make sure that you're not breaking any platforms. // // // Define a small subset of tr1 type traits. The traits we define are: // is_integral // is_floating_point // is_pointer // is_reference // is_pod // has_trivial_constructor // has_trivial_copy // has_trivial_assign // has_trivial_destructor // remove_const // remove_volatile // remove_cv // remove_reference // remove_pointer // is_convertible // We can add more type traits as required. #ifndef BASE_TYPE_TRAITS_H_ #define BASE_TYPE_TRAITS_H_ #include "base/template_util.h" // For true_type and false_type #include // For pair namespace base { // is_integral is false except for the built-in integer types. template struct is_integral : false_type { }; template<> struct is_integral : true_type { }; template<> struct is_integral : true_type { }; template<> struct is_integral : true_type { }; template<> struct is_integral : true_type { }; #if defined(_MSC_VER) // wchar_t is not by default a distinct type from unsigned short in // Microsoft C. // See http://msdn2.microsoft.com/en-us/library/dh8che7s(VS.80).aspx template<> struct is_integral<__wchar_t> : true_type { }; #else template<> struct is_integral : true_type { }; #endif template<> struct is_integral : true_type { }; template<> struct is_integral : true_type { }; template<> struct is_integral : true_type { }; template<> struct is_integral : true_type { }; template<> struct is_integral : true_type { }; template<> struct is_integral : true_type { }; template<> struct is_integral : true_type { }; template<> struct is_integral : true_type { }; // is_floating_point is false except for the built-in floating-point types. template struct is_floating_point : false_type { }; template<> struct is_floating_point : true_type { }; template<> struct is_floating_point : true_type { }; template<> struct is_floating_point : true_type { }; // is_pointer is false except for pointer types. template struct is_pointer : false_type { }; template struct is_pointer : true_type { }; // is_reference is false except for reference types. template struct is_reference : false_type {}; template struct is_reference : true_type {}; // We can't get is_pod right without compiler help, so fail conservatively. // We will assume it's false except for arithmetic types and pointers, // and const versions thereof. Note that std::pair is not a POD. template struct is_pod : integral_constant::value || is_floating_point::value || is_pointer::value)> { }; template struct is_pod : is_pod { }; // We can't get has_trivial_constructor right without compiler help, so // fail conservatively. We will assume it's false except for: (1) types // for which is_pod is true. (2) std::pair of types with trivial // constructors. (3) array of a type with a trivial constructor. // (4) const versions thereof. template struct has_trivial_constructor : is_pod { }; template struct has_trivial_constructor > : integral_constant::value && has_trivial_constructor::value)> { }; template struct has_trivial_constructor : has_trivial_constructor { }; template struct has_trivial_constructor : has_trivial_constructor { }; // We can't get has_trivial_copy right without compiler help, so fail // conservatively. We will assume it's false except for: (1) types // for which is_pod is true. (2) std::pair of types with trivial copy // constructors. (3) array of a type with a trivial copy constructor. // (4) const versions thereof. template struct has_trivial_copy : is_pod { }; template struct has_trivial_copy > : integral_constant::value && has_trivial_copy::value)> { }; template struct has_trivial_copy : has_trivial_copy { }; template struct has_trivial_copy : has_trivial_copy { }; // We can't get has_trivial_assign right without compiler help, so fail // conservatively. We will assume it's false except for: (1) types // for which is_pod is true. (2) std::pair of types with trivial copy // constructors. (3) array of a type with a trivial assign constructor. template struct has_trivial_assign : is_pod { }; template struct has_trivial_assign > : integral_constant::value && has_trivial_assign::value)> { }; template struct has_trivial_assign : has_trivial_assign { }; // We can't get has_trivial_destructor right without compiler help, so // fail conservatively. We will assume it's false except for: (1) types // for which is_pod is true. (2) std::pair of types with trivial // destructors. (3) array of a type with a trivial destructor. // (4) const versions thereof. template struct has_trivial_destructor : is_pod { }; template struct has_trivial_destructor > : integral_constant::value && has_trivial_destructor::value)> { }; template struct has_trivial_destructor : has_trivial_destructor { }; template struct has_trivial_destructor : has_trivial_destructor { }; // Specified by TR1 [4.7.1] template struct remove_const { typedef T type; }; template struct remove_const { typedef T type; }; template struct remove_volatile { typedef T type; }; template struct remove_volatile { typedef T type; }; template struct remove_cv { typedef typename remove_const::type>::type type; }; // Specified by TR1 [4.7.2] template struct remove_reference { typedef T type; }; template struct remove_reference { typedef T type; }; // Specified by TR1 [4.7.4] Pointer modifications. template struct remove_pointer { typedef T type; }; template struct remove_pointer { typedef T type; }; template struct remove_pointer { typedef T type; }; template struct remove_pointer { typedef T type; }; template struct remove_pointer { typedef T type; }; // Specified by TR1 [4.6] Relationships between types #ifndef _MSC_VER namespace internal { // 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 struct ConvertHelper { static small_ Test(To); static big_ Test(...); static From Create(); }; } // namespace internal // Inherits from true_type if From is convertible to To, false_type otherwise. template struct is_convertible : integral_constant::Test( internal::ConvertHelper::Create())) == sizeof(small_)> { }; #endif } // Close namespace base #endif // BASE_TYPE_TRAITS_H_