1 // Copyright 2005 Google Inc. 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above 11 // copyright notice, this list of conditions and the following disclaimer 12 // in the documentation and/or other materials provided with the 13 // distribution. 14 // * Neither the name of Google Inc. nor the names of its 15 // contributors may be used to endorse or promote products derived from 16 // this software without specific prior written permission. 17 // 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30 // ---- 31 // Author: lar (at) google.com (Laramie Leavitt) 32 // 33 // Template metaprogramming utility functions. 34 // 35 // This code is compiled directly on many platforms, including client 36 // platforms like Windows, Mac, and embedded systems. Before making 37 // any changes here, make sure that you're not breaking any platforms. 38 // 39 // 40 // The names choosen here reflect those used in tr1 and the boost::mpl 41 // library, there are similar operations used in the Loki library as 42 // well. I prefer the boost names for 2 reasons: 43 // 1. I think that portions of the Boost libraries are more likely to 44 // be included in the c++ standard. 45 // 2. It is not impossible that some of the boost libraries will be 46 // included in our own build in the future. 47 // Both of these outcomes means that we may be able to directly replace 48 // some of these with boost equivalents. 49 // 50 #ifndef GOOGLE_PROTOBUF_TEMPLATE_UTIL_H_ 51 #define GOOGLE_PROTOBUF_TEMPLATE_UTIL_H_ 52 53 namespace google { 54 namespace protobuf { 55 namespace internal { 56 57 // Types small_ and big_ are guaranteed such that sizeof(small_) < 58 // sizeof(big_) 59 typedef char small_; 60 61 struct big_ { 62 char dummy[2]; 63 }; 64 65 // Identity metafunction. 66 template <class T> 67 struct identity_ { 68 typedef T type; 69 }; 70 71 // integral_constant, defined in tr1, is a wrapper for an integer 72 // value. We don't really need this generality; we could get away 73 // with hardcoding the integer type to bool. We use the fully 74 // general integer_constant for compatibility with tr1. 75 76 template<class T, T v> 77 struct integral_constant { 78 static const T value = v; 79 typedef T value_type; 80 typedef integral_constant<T, v> type; 81 }; 82 83 template <class T, T v> const T integral_constant<T, v>::value; 84 85 86 // Abbreviations: true_type and false_type are structs that represent boolean 87 // true and false values. Also define the boost::mpl versions of those names, 88 // true_ and false_. 89 typedef integral_constant<bool, true> true_type; 90 typedef integral_constant<bool, false> false_type; 91 typedef true_type true_; 92 typedef false_type false_; 93 94 // if_ is a templatized conditional statement. 95 // if_<cond, A, B> is a compile time evaluation of cond. 96 // if_<>::type contains A if cond is true, B otherwise. 97 template<bool cond, typename A, typename B> 98 struct if_{ 99 typedef A type; 100 }; 101 102 template<typename A, typename B> 103 struct if_<false, A, B> { 104 typedef B type; 105 }; 106 107 108 // type_equals_ is a template type comparator, similar to Loki IsSameType. 109 // type_equals_<A, B>::value is true iff "A" is the same type as "B". 110 // 111 // New code should prefer base::is_same, defined in base/type_traits.h. 112 // It is functionally identical, but is_same is the standard spelling. 113 template<typename A, typename B> 114 struct type_equals_ : public false_ { 115 }; 116 117 template<typename A> 118 struct type_equals_<A, A> : public true_ { 119 }; 120 121 // and_ is a template && operator. 122 // and_<A, B>::value evaluates "A::value && B::value". 123 template<typename A, typename B> 124 struct and_ : public integral_constant<bool, (A::value && B::value)> { 125 }; 126 127 // or_ is a template || operator. 128 // or_<A, B>::value evaluates "A::value || B::value". 129 template<typename A, typename B> 130 struct or_ : public integral_constant<bool, (A::value || B::value)> { 131 }; 132 133 134 } // namespace internal 135 } // namespace protobuf 136 } // namespace google 137 138 #endif // GOOGLE_PROTOBUF_TEMPLATE_UTIL_H_ 139