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