15a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// Copyright (c) 2006, Google Inc. 25a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// All rights reserved. 35a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// 45a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// Redistribution and use in source and binary forms, with or without 55a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// modification, are permitted provided that the following conditions are 65a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// met: 75a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// 85a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// * Redistributions of source code must retain the above copyright 95a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// notice, this list of conditions and the following disclaimer. 105a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// * Redistributions in binary form must reproduce the above 115a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// copyright notice, this list of conditions and the following disclaimer 125a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// in the documentation and/or other materials provided with the 135a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// distribution. 145a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// * Neither the name of Google Inc. nor the names of its 155a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// contributors may be used to endorse or promote products derived from 165a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// this software without specific prior written permission. 175a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// 185a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 195a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 205a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 215a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 225a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 235a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 245a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 255a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 265a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 275a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 285a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 295a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 305a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// ---- 315a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// Author: Matt Austern 325a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// 335a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// This code is compiled directly on many platforms, including client 345a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// platforms like Windows, Mac, and embedded systems. Before making 355a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// any changes here, make sure that you're not breaking any platforms. 365a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// 375a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// Define a small subset of tr1 type traits. The traits we define are: 385a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// enable_if 395a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// is_integral 405a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// is_floating_point 415a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// is_pointer 425a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// is_enum 435a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// is_reference 445a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// is_pod 455a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// has_trivial_constructor 465a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// has_trivial_copy 475a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// has_trivial_assign 485a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// has_trivial_destructor 495a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// remove_const 505a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// remove_volatile 515a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// remove_cv 525a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// remove_reference 535a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// add_reference 545a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// remove_pointer 555a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// is_same 565a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// is_convertible 575a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// We can add more type traits as required. 585a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 595a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot#ifndef GOOGLE_PROTOBUF_TYPE_TRAITS_H_ 605a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot#define GOOGLE_PROTOBUF_TYPE_TRAITS_H_ 615a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 625a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot#include <cstddef> // for NULL 635a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot#include <utility> // For pair 645a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 655a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot#include <google/protobuf/stubs/template_util.h> // For true_type and false_type 665a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 675a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robotnamespace google { 685a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robotnamespace protobuf { 695a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robotnamespace internal { 705a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 715a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<typename B, typename D> 725a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robotstruct is_base_of { 735a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot typedef char (&yes)[1]; 745a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot typedef char (&no)[2]; 755a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 765a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot // BEGIN GOOGLE LOCAL MODIFICATION -- check is a #define on Mac. 775a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot #undef check 785a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot // END GOOGLE LOCAL MODIFICATION 795a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 805a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot static yes check(const B*); 815a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot static no check(const void*); 825a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 835a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot enum { 845a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot value = sizeof(check(static_cast<const D*>(NULL))) == sizeof(yes), 855a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot }; 865a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot}; 875a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 885a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <bool cond, class T = void> struct enable_if; 895a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct is_integral; 905a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct is_floating_point; 915a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct is_pointer; 925a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// MSVC can't compile this correctly, and neither can gcc 3.3.5 (at least) 935a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) 945a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// is_enum uses is_convertible, which is not available on MSVC. 955a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct is_enum; 965a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot#endif 975a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct is_reference; 985a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct is_pod; 995a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct has_trivial_constructor; 1005a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct has_trivial_copy; 1015a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct has_trivial_assign; 1025a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct has_trivial_destructor; 1035a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct remove_const; 1045a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct remove_volatile; 1055a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct remove_cv; 1065a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct remove_reference; 1075a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct add_reference; 1085a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct remove_pointer; 1095a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T, class U> struct is_same; 1105a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot#if !(defined(__GNUC__) && __GNUC__ <= 3) 1115a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class From, class To> struct is_convertible; 1125a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot#endif 1135a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 1145a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// enable_if, equivalent semantics to c++11 std::enable_if, specifically: 1155a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// "If B is true, the member typedef type shall equal T; otherwise, there 1165a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// shall be no member typedef type." 1175a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// Specified by 20.9.7.6 [Other transformations] 1185a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 1195a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<bool cond, class T> struct enable_if { typedef T type; }; 1205a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<class T> struct enable_if<false, T> {}; 1215a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// is_integral is false except for the built-in integer types. A 1225a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// cv-qualified type is integral if and only if the underlying type is. 1235a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct is_integral : false_type { }; 1245a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<> struct is_integral<bool> : true_type { }; 1255a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<> struct is_integral<char> : true_type { }; 1265a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<> struct is_integral<unsigned char> : true_type { }; 1275a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<> struct is_integral<signed char> : true_type { }; 1285a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot#if defined(_MSC_VER) 1295a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// wchar_t is not by default a distinct type from unsigned short in 1305a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// Microsoft C. 1315a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// See http://msdn2.microsoft.com/en-us/library/dh8che7s(VS.80).aspx 1325a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<> struct is_integral<__wchar_t> : true_type { }; 1335a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot#else 1345a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<> struct is_integral<wchar_t> : true_type { }; 1355a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot#endif 1365a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<> struct is_integral<short> : true_type { }; 1375a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<> struct is_integral<unsigned short> : true_type { }; 1385a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<> struct is_integral<int> : true_type { }; 1395a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<> struct is_integral<unsigned int> : true_type { }; 1405a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<> struct is_integral<long> : true_type { }; 1415a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<> struct is_integral<unsigned long> : true_type { }; 1425a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot#ifdef HAVE_LONG_LONG 1435a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<> struct is_integral<long long> : true_type { }; 1445a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<> struct is_integral<unsigned long long> : true_type { }; 1455a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot#endif 1465a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct is_integral<const T> : is_integral<T> { }; 1475a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct is_integral<volatile T> : is_integral<T> { }; 1485a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct is_integral<const volatile T> : is_integral<T> { }; 1495a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 1505a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// is_floating_point is false except for the built-in floating-point types. 1515a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// A cv-qualified type is integral if and only if the underlying type is. 1525a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct is_floating_point : false_type { }; 1535a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<> struct is_floating_point<float> : true_type { }; 1545a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<> struct is_floating_point<double> : true_type { }; 1555a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<> struct is_floating_point<long double> : true_type { }; 1565a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct is_floating_point<const T> 1575a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot : is_floating_point<T> { }; 1585a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct is_floating_point<volatile T> 1595a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot : is_floating_point<T> { }; 1605a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct is_floating_point<const volatile T> 1615a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot : is_floating_point<T> { }; 1625a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 1635a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// is_pointer is false except for pointer types. A cv-qualified type (e.g. 1645a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// "int* const", as opposed to "int const*") is cv-qualified if and only if 1655a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// the underlying type is. 1665a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct is_pointer : false_type { }; 1675a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct is_pointer<T*> : true_type { }; 1685a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct is_pointer<const T> : is_pointer<T> { }; 1695a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct is_pointer<volatile T> : is_pointer<T> { }; 1705a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct is_pointer<const volatile T> : is_pointer<T> { }; 1715a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 1725a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) 1735a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 1745a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robotnamespace type_traits_internal { 1755a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 1765a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct is_class_or_union { 1775a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot template <class U> static small_ tester(void (U::*)()); 1785a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot template <class U> static big_ tester(...); 1795a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot static const bool value = sizeof(tester<T>(0)) == sizeof(small_); 1805a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot}; 1815a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 1825a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// is_convertible chokes if the first argument is an array. That's why 1835a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// we use add_reference here. 1845a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <bool NotUnum, class T> struct is_enum_impl 1855a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot : is_convertible<typename add_reference<T>::type, int> { }; 1865a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 1875a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct is_enum_impl<true, T> : false_type { }; 1885a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 1895a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot} // namespace type_traits_internal 1905a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 1915a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// Specified by TR1 [4.5.1] primary type categories. 1925a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 1935a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// Implementation note: 1945a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// 1955a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// Each type is either void, integral, floating point, array, pointer, 1965a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// reference, member object pointer, member function pointer, enum, 1975a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// union or class. Out of these, only integral, floating point, reference, 1985a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// class and enum types are potentially convertible to int. Therefore, 1995a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// if a type is not a reference, integral, floating point or class and 2005a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// is convertible to int, it's a enum. Adding cv-qualification to a type 2015a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// does not change whether it's an enum. 2025a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// 2035a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// Is-convertible-to-int check is done only if all other checks pass, 2045a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// because it can't be used with some types (e.g. void or classes with 2055a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// inaccessible conversion operators). 2065a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct is_enum 2075a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot : type_traits_internal::is_enum_impl< 2085a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot is_same<T, void>::value || 2095a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot is_integral<T>::value || 2105a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot is_floating_point<T>::value || 2115a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot is_reference<T>::value || 2125a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot type_traits_internal::is_class_or_union<T>::value, 2135a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot T> { }; 2145a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 2155a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct is_enum<const T> : is_enum<T> { }; 2165a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct is_enum<volatile T> : is_enum<T> { }; 2175a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct is_enum<const volatile T> : is_enum<T> { }; 2185a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 2195a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot#endif 2205a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 2215a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// is_reference is false except for reference types. 2225a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<typename T> struct is_reference : false_type {}; 2235a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<typename T> struct is_reference<T&> : true_type {}; 2245a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 2255a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 2265a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// We can't get is_pod right without compiler help, so fail conservatively. 2275a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// We will assume it's false except for arithmetic types, enumerations, 2285a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// pointers and cv-qualified versions thereof. Note that std::pair<T,U> 2295a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// is not a POD even if T and U are PODs. 2305a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct is_pod 2315a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot : integral_constant<bool, (is_integral<T>::value || 2325a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot is_floating_point<T>::value || 2335a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) 2345a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot // is_enum is not available on MSVC. 2355a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot is_enum<T>::value || 2365a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot#endif 2375a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot is_pointer<T>::value)> { }; 2385a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct is_pod<const T> : is_pod<T> { }; 2395a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct is_pod<volatile T> : is_pod<T> { }; 2405a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct is_pod<const volatile T> : is_pod<T> { }; 2415a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 2425a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 2435a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// We can't get has_trivial_constructor right without compiler help, so 2445a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// fail conservatively. We will assume it's false except for: (1) types 2455a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// for which is_pod is true. (2) std::pair of types with trivial 2465a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// constructors. (3) array of a type with a trivial constructor. 2475a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// (4) const versions thereof. 2485a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct has_trivial_constructor : is_pod<T> { }; 2495a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T, class U> struct has_trivial_constructor<std::pair<T, U> > 2505a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot : integral_constant<bool, 2515a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot (has_trivial_constructor<T>::value && 2525a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot has_trivial_constructor<U>::value)> { }; 2535a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class A, int N> struct has_trivial_constructor<A[N]> 2545a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot : has_trivial_constructor<A> { }; 2555a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct has_trivial_constructor<const T> 2565a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot : has_trivial_constructor<T> { }; 2575a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 2585a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// We can't get has_trivial_copy right without compiler help, so fail 2595a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// conservatively. We will assume it's false except for: (1) types 2605a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// for which is_pod is true. (2) std::pair of types with trivial copy 2615a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// constructors. (3) array of a type with a trivial copy constructor. 2625a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// (4) const versions thereof. 2635a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct has_trivial_copy : is_pod<T> { }; 2645a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T, class U> struct has_trivial_copy<std::pair<T, U> > 2655a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot : integral_constant<bool, 2665a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot (has_trivial_copy<T>::value && 2675a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot has_trivial_copy<U>::value)> { }; 2685a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class A, int N> struct has_trivial_copy<A[N]> 2695a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot : has_trivial_copy<A> { }; 2705a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct has_trivial_copy<const T> : has_trivial_copy<T> { }; 2715a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 2725a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// We can't get has_trivial_assign right without compiler help, so fail 2735a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// conservatively. We will assume it's false except for: (1) types 2745a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// for which is_pod is true. (2) std::pair of types with trivial copy 2755a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// constructors. (3) array of a type with a trivial assign constructor. 2765a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct has_trivial_assign : is_pod<T> { }; 2775a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T, class U> struct has_trivial_assign<std::pair<T, U> > 2785a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot : integral_constant<bool, 2795a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot (has_trivial_assign<T>::value && 2805a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot has_trivial_assign<U>::value)> { }; 2815a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class A, int N> struct has_trivial_assign<A[N]> 2825a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot : has_trivial_assign<A> { }; 2835a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 2845a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// We can't get has_trivial_destructor right without compiler help, so 2855a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// fail conservatively. We will assume it's false except for: (1) types 2865a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// for which is_pod is true. (2) std::pair of types with trivial 2875a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// destructors. (3) array of a type with a trivial destructor. 2885a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// (4) const versions thereof. 2895a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct has_trivial_destructor : is_pod<T> { }; 2905a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T, class U> struct has_trivial_destructor<std::pair<T, U> > 2915a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot : integral_constant<bool, 2925a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot (has_trivial_destructor<T>::value && 2935a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot has_trivial_destructor<U>::value)> { }; 2945a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class A, int N> struct has_trivial_destructor<A[N]> 2955a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot : has_trivial_destructor<A> { }; 2965a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <class T> struct has_trivial_destructor<const T> 2975a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot : has_trivial_destructor<T> { }; 2985a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 2995a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// Specified by TR1 [4.7.1] 3005a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<typename T> struct remove_const { typedef T type; }; 3015a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<typename T> struct remove_const<T const> { typedef T type; }; 3025a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<typename T> struct remove_volatile { typedef T type; }; 3035a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<typename T> struct remove_volatile<T volatile> { typedef T type; }; 3045a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<typename T> struct remove_cv { 3055a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot typedef typename remove_const<typename remove_volatile<T>::type>::type type; 3065a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot}; 3075a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 3085a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 3095a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// Specified by TR1 [4.7.2] Reference modifications. 3105a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<typename T> struct remove_reference { typedef T type; }; 3115a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<typename T> struct remove_reference<T&> { typedef T type; }; 3125a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 3135a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <typename T> struct add_reference { typedef T& type; }; 3145a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <typename T> struct add_reference<T&> { typedef T& type; }; 3155a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 3165a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// Specified by TR1 [4.7.4] Pointer modifications. 3175a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<typename T> struct remove_pointer { typedef T type; }; 3185a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<typename T> struct remove_pointer<T*> { typedef T type; }; 3195a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<typename T> struct remove_pointer<T* const> { typedef T type; }; 3205a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<typename T> struct remove_pointer<T* volatile> { typedef T type; }; 3215a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<typename T> struct remove_pointer<T* const volatile> { 3225a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot typedef T type; }; 3235a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 3245a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// Specified by TR1 [4.6] Relationships between types 3255a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<typename T, typename U> struct is_same : public false_type { }; 3265a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate<typename T> struct is_same<T, T> : public true_type { }; 3275a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 3285a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// Specified by TR1 [4.6] Relationships between types 3295a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot#if !(defined(__GNUC__) && __GNUC__ <= 3) 3305a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robotnamespace type_traits_internal { 3315a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 3325a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// This class is an implementation detail for is_convertible, and you 3335a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// don't need to know how it works to use is_convertible. For those 3345a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// who care: we declare two different functions, one whose argument is 3355a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// of type To and one with a variadic argument list. We give them 3365a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// return types of different size, so we can use sizeof to trick the 3375a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// compiler into telling us which function it would have chosen if we 3385a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// had called it with an argument of type From. See Alexandrescu's 3395a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// _Modern C++ Design_ for more details on this sort of trick. 3405a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 3415a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <typename From, typename To> 3425a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robotstruct ConvertHelper { 3435a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot static small_ Test(To); 3445a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot static big_ Test(...); 3455a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot static From Create(); 3465a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot enum { 3475a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot value = sizeof(Test(Create())) == sizeof(small_) 3485a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot }; 3495a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot}; 3505a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot} // namespace type_traits_internal 3515a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 3525a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot// Inherits from true_type if From is convertible to To, false_type otherwise. 3535a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robottemplate <typename From, typename To> 3545a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robotstruct is_convertible 3555a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot : integral_constant<bool, 3565a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot type_traits_internal::ConvertHelper<From, To>::value> { 3575a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot}; 3585a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot#endif 3595a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 3605a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot} // namespace internal 3615a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot} // namespace protobuf 3625a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot} // namespace google 3635a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot 3645a6e989368cab2b72ab8db50330d02e459b47d4android-build-team Robot#endif // GOOGLE_PROTOBUF_TYPE_TRAITS_H_ 365