1ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Copyright (c) 2006, Google Inc. 2ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// All rights reserved. 3ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// 4ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Redistribution and use in source and binary forms, with or without 5ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// modification, are permitted provided that the following conditions are 6ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// met: 7ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// 8ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// * Redistributions of source code must retain the above copyright 9ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// notice, this list of conditions and the following disclaimer. 10ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// * Redistributions in binary form must reproduce the above 11ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// copyright notice, this list of conditions and the following disclaimer 12ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// in the documentation and/or other materials provided with the 13ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// distribution. 14ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// * Neither the name of Google Inc. nor the names of its 15ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// contributors may be used to endorse or promote products derived from 16ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// this software without specific prior written permission. 17ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// 18ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 30ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// ---- 31ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Author: Matt Austern 32ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// 33ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// This code is compiled directly on many platforms, including client 34ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// platforms like Windows, Mac, and embedded systems. Before making 35ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// any changes here, make sure that you're not breaking any platforms. 36ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// 37ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Define a small subset of tr1 type traits. The traits we define are: 38ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// is_integral 39ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// is_floating_point 40ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// is_pointer 41ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// is_enum 42ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// is_reference 43ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// is_pod 44ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// has_trivial_constructor 45ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// has_trivial_copy 46ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// has_trivial_assign 47ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// has_trivial_destructor 48ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// remove_const 49ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// remove_volatile 50ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// remove_cv 51ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// remove_reference 52ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// add_reference 53ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// remove_pointer 54ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// is_same 55ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// is_convertible 56ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// We can add more type traits as required. 57ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 58ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#ifndef GOOGLE_PROTOBUF_TYPE_TRAITS_H_ 59ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#define GOOGLE_PROTOBUF_TYPE_TRAITS_H_ 60ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 61ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include <utility> // For pair 62ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 63ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include <google/protobuf/stubs/template_util.h> // For true_type and false_type 64ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 65ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochnamespace google { 66ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochnamespace protobuf { 67ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochnamespace internal { 68ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 69ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct is_integral; 70ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct is_floating_point; 71ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct is_pointer; 72ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// MSVC can't compile this correctly, and neither can gcc 3.3.5 (at least) 73ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) 74ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// is_enum uses is_convertible, which is not available on MSVC. 75ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct is_enum; 76ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#endif 77ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct is_reference; 78ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct is_pod; 79ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct has_trivial_constructor; 80ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct has_trivial_copy; 81ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct has_trivial_assign; 82ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct has_trivial_destructor; 83ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct remove_const; 84ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct remove_volatile; 85ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct remove_cv; 86ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct remove_reference; 87ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct add_reference; 88ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct remove_pointer; 89ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T, class U> struct is_same; 90ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) 91ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class From, class To> struct is_convertible; 92ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#endif 93ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 94ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// is_integral is false except for the built-in integer types. A 95ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// cv-qualified type is integral if and only if the underlying type is. 96ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct is_integral : false_type { }; 97ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<> struct is_integral<bool> : true_type { }; 98ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<> struct is_integral<char> : true_type { }; 99ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<> struct is_integral<unsigned char> : true_type { }; 100ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<> struct is_integral<signed char> : true_type { }; 101ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#if defined(_MSC_VER) 102ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// wchar_t is not by default a distinct type from unsigned short in 103ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Microsoft C. 104ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// See http://msdn2.microsoft.com/en-us/library/dh8che7s(VS.80).aspx 105ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<> struct is_integral<__wchar_t> : true_type { }; 106ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#else 107ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<> struct is_integral<wchar_t> : true_type { }; 108ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#endif 109ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<> struct is_integral<short> : true_type { }; 110ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<> struct is_integral<unsigned short> : true_type { }; 111ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<> struct is_integral<int> : true_type { }; 112ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<> struct is_integral<unsigned int> : true_type { }; 113ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<> struct is_integral<long> : true_type { }; 114ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<> struct is_integral<unsigned long> : true_type { }; 115ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#ifdef HAVE_LONG_LONG 116ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<> struct is_integral<long long> : true_type { }; 117ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<> struct is_integral<unsigned long long> : true_type { }; 118ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#endif 119ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct is_integral<const T> : is_integral<T> { }; 120ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct is_integral<volatile T> : is_integral<T> { }; 121ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct is_integral<const volatile T> : is_integral<T> { }; 122ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 123ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// is_floating_point is false except for the built-in floating-point types. 124ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// A cv-qualified type is integral if and only if the underlying type is. 125ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct is_floating_point : false_type { }; 126ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<> struct is_floating_point<float> : true_type { }; 127ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<> struct is_floating_point<double> : true_type { }; 128ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<> struct is_floating_point<long double> : true_type { }; 129ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct is_floating_point<const T> 130ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : is_floating_point<T> { }; 131ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct is_floating_point<volatile T> 132ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : is_floating_point<T> { }; 133ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct is_floating_point<const volatile T> 134ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : is_floating_point<T> { }; 135ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 136ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// is_pointer is false except for pointer types. A cv-qualified type (e.g. 137ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// "int* const", as opposed to "int const*") is cv-qualified if and only if 138ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// the underlying type is. 139ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct is_pointer : false_type { }; 140ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct is_pointer<T*> : true_type { }; 141ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct is_pointer<const T> : is_pointer<T> { }; 142ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct is_pointer<volatile T> : is_pointer<T> { }; 143ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct is_pointer<const volatile T> : is_pointer<T> { }; 144ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 145ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) 146ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 147ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochnamespace internal { 148ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 149ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct is_class_or_union { 150ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch template <class U> static small_ tester(void (U::*)()); 151ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch template <class U> static big_ tester(...); 152ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch static const bool value = sizeof(tester<T>(0)) == sizeof(small_); 153ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}; 154ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 155ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// is_convertible chokes if the first argument is an array. That's why 156ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// we use add_reference here. 157ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <bool NotUnum, class T> struct is_enum_impl 158ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : is_convertible<typename add_reference<T>::type, int> { }; 159ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 160ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct is_enum_impl<true, T> : false_type { }; 161ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 162ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} // namespace internal 163ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 164ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Specified by TR1 [4.5.1] primary type categories. 165ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 166ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Implementation note: 167ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// 168ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Each type is either void, integral, floating point, array, pointer, 169ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// reference, member object pointer, member function pointer, enum, 170ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// union or class. Out of these, only integral, floating point, reference, 171ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// class and enum types are potentially convertible to int. Therefore, 172ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// if a type is not a reference, integral, floating point or class and 173ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// is convertible to int, it's a enum. Adding cv-qualification to a type 174ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// does not change whether it's an enum. 175ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// 176ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Is-convertible-to-int check is done only if all other checks pass, 177ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// because it can't be used with some types (e.g. void or classes with 178ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// inaccessible conversion operators). 179ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct is_enum 180ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : internal::is_enum_impl< 181ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch is_same<T, void>::value || 182ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch is_integral<T>::value || 183ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch is_floating_point<T>::value || 184ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch is_reference<T>::value || 185ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch internal::is_class_or_union<T>::value, 186ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch T> { }; 187ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 188ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct is_enum<const T> : is_enum<T> { }; 189ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct is_enum<volatile T> : is_enum<T> { }; 190ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct is_enum<const volatile T> : is_enum<T> { }; 191ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 192ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#endif 193ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 194ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// is_reference is false except for reference types. 195ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<typename T> struct is_reference : false_type {}; 196ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<typename T> struct is_reference<T&> : true_type {}; 197ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 198ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 199ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// We can't get is_pod right without compiler help, so fail conservatively. 200ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// We will assume it's false except for arithmetic types, enumerations, 201ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// pointers and cv-qualified versions thereof. Note that std::pair<T,U> 202ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// is not a POD even if T and U are PODs. 203ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct is_pod 204ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : integral_constant<bool, (is_integral<T>::value || 205ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch is_floating_point<T>::value || 206ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) 207ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // is_enum is not available on MSVC. 208ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch is_enum<T>::value || 209ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#endif 210ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch is_pointer<T>::value)> { }; 211ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct is_pod<const T> : is_pod<T> { }; 212ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct is_pod<volatile T> : is_pod<T> { }; 213ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct is_pod<const volatile T> : is_pod<T> { }; 214ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 215ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 216ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// We can't get has_trivial_constructor right without compiler help, so 217ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// fail conservatively. We will assume it's false except for: (1) types 218ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// for which is_pod is true. (2) std::pair of types with trivial 219ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// constructors. (3) array of a type with a trivial constructor. 220ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// (4) const versions thereof. 221ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct has_trivial_constructor : is_pod<T> { }; 222ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T, class U> struct has_trivial_constructor<std::pair<T, U> > 223ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : integral_constant<bool, 224ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch (has_trivial_constructor<T>::value && 225ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch has_trivial_constructor<U>::value)> { }; 226ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class A, int N> struct has_trivial_constructor<A[N]> 227ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : has_trivial_constructor<A> { }; 228ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct has_trivial_constructor<const T> 229ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : has_trivial_constructor<T> { }; 230ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 231ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// We can't get has_trivial_copy right without compiler help, so fail 232ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// conservatively. We will assume it's false except for: (1) types 233ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// for which is_pod is true. (2) std::pair of types with trivial copy 234ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// constructors. (3) array of a type with a trivial copy constructor. 235ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// (4) const versions thereof. 236ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct has_trivial_copy : is_pod<T> { }; 237ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T, class U> struct has_trivial_copy<std::pair<T, U> > 238ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : integral_constant<bool, 239ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch (has_trivial_copy<T>::value && 240ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch has_trivial_copy<U>::value)> { }; 241ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class A, int N> struct has_trivial_copy<A[N]> 242ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : has_trivial_copy<A> { }; 243ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct has_trivial_copy<const T> : has_trivial_copy<T> { }; 244ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 245ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// We can't get has_trivial_assign right without compiler help, so fail 246ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// conservatively. We will assume it's false except for: (1) types 247ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// for which is_pod is true. (2) std::pair of types with trivial copy 248ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// constructors. (3) array of a type with a trivial assign constructor. 249ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct has_trivial_assign : is_pod<T> { }; 250ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T, class U> struct has_trivial_assign<std::pair<T, U> > 251ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : integral_constant<bool, 252ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch (has_trivial_assign<T>::value && 253ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch has_trivial_assign<U>::value)> { }; 254ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class A, int N> struct has_trivial_assign<A[N]> 255ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : has_trivial_assign<A> { }; 256ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 257ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// We can't get has_trivial_destructor right without compiler help, so 258ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// fail conservatively. We will assume it's false except for: (1) types 259ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// for which is_pod is true. (2) std::pair of types with trivial 260ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// destructors. (3) array of a type with a trivial destructor. 261ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// (4) const versions thereof. 262ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct has_trivial_destructor : is_pod<T> { }; 263ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T, class U> struct has_trivial_destructor<std::pair<T, U> > 264ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : integral_constant<bool, 265ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch (has_trivial_destructor<T>::value && 266ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch has_trivial_destructor<U>::value)> { }; 267ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class A, int N> struct has_trivial_destructor<A[N]> 268ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : has_trivial_destructor<A> { }; 269ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T> struct has_trivial_destructor<const T> 270ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : has_trivial_destructor<T> { }; 271ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 272ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Specified by TR1 [4.7.1] 273ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<typename T> struct remove_const { typedef T type; }; 274ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<typename T> struct remove_const<T const> { typedef T type; }; 275ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<typename T> struct remove_volatile { typedef T type; }; 276ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<typename T> struct remove_volatile<T volatile> { typedef T type; }; 277ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<typename T> struct remove_cv { 278ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch typedef typename remove_const<typename remove_volatile<T>::type>::type type; 279ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}; 280ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 281ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 282ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Specified by TR1 [4.7.2] Reference modifications. 283ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<typename T> struct remove_reference { typedef T type; }; 284ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<typename T> struct remove_reference<T&> { typedef T type; }; 285ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 286ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <typename T> struct add_reference { typedef T& type; }; 287ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <typename T> struct add_reference<T&> { typedef T& type; }; 288ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 289ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Specified by TR1 [4.7.4] Pointer modifications. 290ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<typename T> struct remove_pointer { typedef T type; }; 291ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<typename T> struct remove_pointer<T*> { typedef T type; }; 292ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<typename T> struct remove_pointer<T* const> { typedef T type; }; 293ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<typename T> struct remove_pointer<T* volatile> { typedef T type; }; 294ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<typename T> struct remove_pointer<T* const volatile> { 295ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch typedef T type; }; 296ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 297ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Specified by TR1 [4.6] Relationships between types 298ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<typename T, typename U> struct is_same : public false_type { }; 299ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate<typename T> struct is_same<T, T> : public true_type { }; 300ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 301ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Specified by TR1 [4.6] Relationships between types 302ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) 303ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochnamespace internal { 304ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 305ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// This class is an implementation detail for is_convertible, and you 306ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// don't need to know how it works to use is_convertible. For those 307ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// who care: we declare two different functions, one whose argument is 308ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// of type To and one with a variadic argument list. We give them 309ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// return types of different size, so we can use sizeof to trick the 310ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// compiler into telling us which function it would have chosen if we 311ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// had called it with an argument of type From. See Alexandrescu's 312ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// _Modern C++ Design_ for more details on this sort of trick. 313ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 314ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <typename From, typename To> 315ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochstruct ConvertHelper { 316ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch static small_ Test(To); 317ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch static big_ Test(...); 318ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch static From Create(); 319ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}; 320ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} // namespace internal 321ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 322ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Inherits from true_type if From is convertible to To, false_type otherwise. 323ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <typename From, typename To> 324ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochstruct is_convertible 325ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : integral_constant<bool, 326ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch sizeof(internal::ConvertHelper<From, To>::Test( 327ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch internal::ConvertHelper<From, To>::Create())) 328ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch == sizeof(small_)> { 329ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}; 330ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#endif 331ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 332ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} // namespace internal 333ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} // namespace protobuf 334ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} // namespace google 335ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 336ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#endif // GOOGLE_PROTOBUF_TYPE_TRAITS_H_ 337