1 $$ -*- mode: c++; -*- 2 $var n = 10 $$ Maximum number of tuple fields we want to support. 3 $$ This meta comment fixes auto-indentation in Emacs. }} 4 // Copyright 2009 Google Inc. 5 // All Rights Reserved. 6 // 7 // Redistribution and use in source and binary forms, with or without 8 // modification, are permitted provided that the following conditions are 9 // met: 10 // 11 // * Redistributions of source code must retain the above copyright 12 // notice, this list of conditions and the following disclaimer. 13 // * Redistributions in binary form must reproduce the above 14 // copyright notice, this list of conditions and the following disclaimer 15 // in the documentation and/or other materials provided with the 16 // distribution. 17 // * Neither the name of Google Inc. nor the names of its 18 // contributors may be used to endorse or promote products derived from 19 // this software without specific prior written permission. 20 // 21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 // 33 // Author: wan (a] google.com (Zhanyong Wan) 34 35 // Implements a subset of TR1 tuple needed by Google Test and Google Mock. 36 37 #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ 38 #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ 39 40 #include <utility> // For ::std::pair. 41 42 // The compiler used in Symbian has a bug that prevents us from declaring the 43 // tuple template as a friend (it complains that tuple is redefined). This 44 // hack bypasses the bug by declaring the members that should otherwise be 45 // private as public. 46 // Sun Studio versions < 12 also have the above bug. 47 #if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590) 48 # define GTEST_DECLARE_TUPLE_AS_FRIEND_ public: 49 #else 50 # define GTEST_DECLARE_TUPLE_AS_FRIEND_ \ 51 template <GTEST_$(n)_TYPENAMES_(U)> friend class tuple; \ 52 private: 53 #endif 54 55 // Visual Studio 2010, 2012, and 2013 define symbols in std::tr1 that conflict 56 // with our own definitions. Therefore using our own tuple does not work on 57 // those compilers. 58 #if defined(_MSC_VER) && _MSC_VER >= 1600 /* 1600 is Visual Studio 2010 */ 59 # error "gtest's tuple doesn't compile on Visual Studio 2010 or later. \ 60 GTEST_USE_OWN_TR1_TUPLE must be set to 0 on those compilers." 61 #endif 62 63 64 $range i 0..n-1 65 $range j 0..n 66 $range k 1..n 67 // GTEST_n_TUPLE_(T) is the type of an n-tuple. 68 #define GTEST_0_TUPLE_(T) tuple<> 69 70 $for k [[ 71 $range m 0..k-1 72 $range m2 k..n-1 73 #define GTEST_$(k)_TUPLE_(T) tuple<$for m, [[T##$m]]$for m2 [[, void]]> 74 75 ]] 76 77 // GTEST_n_TYPENAMES_(T) declares a list of n typenames. 78 79 $for j [[ 80 $range m 0..j-1 81 #define GTEST_$(j)_TYPENAMES_(T) $for m, [[typename T##$m]] 82 83 84 ]] 85 86 // In theory, defining stuff in the ::std namespace is undefined 87 // behavior. We can do this as we are playing the role of a standard 88 // library vendor. 89 namespace std { 90 namespace tr1 { 91 92 template <$for i, [[typename T$i = void]]> 93 class tuple; 94 95 // Anything in namespace gtest_internal is Google Test's INTERNAL 96 // IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code. 97 namespace gtest_internal { 98 99 // ByRef<T>::type is T if T is a reference; otherwise it's const T&. 100 template <typename T> 101 struct ByRef { typedef const T& type; }; // NOLINT 102 template <typename T> 103 struct ByRef<T&> { typedef T& type; }; // NOLINT 104 105 // A handy wrapper for ByRef. 106 #define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef<T>::type 107 108 // AddRef<T>::type is T if T is a reference; otherwise it's T&. This 109 // is the same as tr1::add_reference<T>::type. 110 template <typename T> 111 struct AddRef { typedef T& type; }; // NOLINT 112 template <typename T> 113 struct AddRef<T&> { typedef T& type; }; // NOLINT 114 115 // A handy wrapper for AddRef. 116 #define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef<T>::type 117 118 // A helper for implementing get<k>(). 119 template <int k> class Get; 120 121 // A helper for implementing tuple_element<k, T>. kIndexValid is true 122 // iff k < the number of fields in tuple type T. 123 template <bool kIndexValid, int kIndex, class Tuple> 124 struct TupleElement; 125 126 127 $for i [[ 128 template <GTEST_$(n)_TYPENAMES_(T)> 129 struct TupleElement<true, $i, GTEST_$(n)_TUPLE_(T) > { 130 typedef T$i type; 131 }; 132 133 134 ]] 135 } // namespace gtest_internal 136 137 template <> 138 class tuple<> { 139 public: 140 tuple() {} 141 tuple(const tuple& /* t */) {} 142 tuple& operator=(const tuple& /* t */) { return *this; } 143 }; 144 145 146 $for k [[ 147 $range m 0..k-1 148 template <GTEST_$(k)_TYPENAMES_(T)> 149 class $if k < n [[GTEST_$(k)_TUPLE_(T)]] $else [[tuple]] { 150 public: 151 template <int k> friend class gtest_internal::Get; 152 153 tuple() : $for m, [[f$(m)_()]] {} 154 155 explicit tuple($for m, [[GTEST_BY_REF_(T$m) f$m]]) : [[]] 156 $for m, [[f$(m)_(f$m)]] {} 157 158 tuple(const tuple& t) : $for m, [[f$(m)_(t.f$(m)_)]] {} 159 160 template <GTEST_$(k)_TYPENAMES_(U)> 161 tuple(const GTEST_$(k)_TUPLE_(U)& t) : $for m, [[f$(m)_(t.f$(m)_)]] {} 162 163 $if k == 2 [[ 164 template <typename U0, typename U1> 165 tuple(const ::std::pair<U0, U1>& p) : f0_(p.first), f1_(p.second) {} 166 167 ]] 168 169 tuple& operator=(const tuple& t) { return CopyFrom(t); } 170 171 template <GTEST_$(k)_TYPENAMES_(U)> 172 tuple& operator=(const GTEST_$(k)_TUPLE_(U)& t) { 173 return CopyFrom(t); 174 } 175 176 $if k == 2 [[ 177 template <typename U0, typename U1> 178 tuple& operator=(const ::std::pair<U0, U1>& p) { 179 f0_ = p.first; 180 f1_ = p.second; 181 return *this; 182 } 183 184 ]] 185 186 GTEST_DECLARE_TUPLE_AS_FRIEND_ 187 188 template <GTEST_$(k)_TYPENAMES_(U)> 189 tuple& CopyFrom(const GTEST_$(k)_TUPLE_(U)& t) { 190 191 $for m [[ 192 f$(m)_ = t.f$(m)_; 193 194 ]] 195 return *this; 196 } 197 198 199 $for m [[ 200 T$m f$(m)_; 201 202 ]] 203 }; 204 205 206 ]] 207 // 6.1.3.2 Tuple creation functions. 208 209 // Known limitations: we don't support passing an 210 // std::tr1::reference_wrapper<T> to make_tuple(). And we don't 211 // implement tie(). 212 213 inline tuple<> make_tuple() { return tuple<>(); } 214 215 $for k [[ 216 $range m 0..k-1 217 218 template <GTEST_$(k)_TYPENAMES_(T)> 219 inline GTEST_$(k)_TUPLE_(T) make_tuple($for m, [[const T$m& f$m]]) { 220 return GTEST_$(k)_TUPLE_(T)($for m, [[f$m]]); 221 } 222 223 ]] 224 225 // 6.1.3.3 Tuple helper classes. 226 227 template <typename Tuple> struct tuple_size; 228 229 230 $for j [[ 231 template <GTEST_$(j)_TYPENAMES_(T)> 232 struct tuple_size<GTEST_$(j)_TUPLE_(T) > { 233 static const int value = $j; 234 }; 235 236 237 ]] 238 template <int k, class Tuple> 239 struct tuple_element { 240 typedef typename gtest_internal::TupleElement< 241 k < (tuple_size<Tuple>::value), k, Tuple>::type type; 242 }; 243 244 #define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element<k, Tuple >::type 245 246 // 6.1.3.4 Element access. 247 248 namespace gtest_internal { 249 250 251 $for i [[ 252 template <> 253 class Get<$i> { 254 public: 255 template <class Tuple> 256 static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple)) 257 Field(Tuple& t) { return t.f$(i)_; } // NOLINT 258 259 template <class Tuple> 260 static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple)) 261 ConstField(const Tuple& t) { return t.f$(i)_; } 262 }; 263 264 265 ]] 266 } // namespace gtest_internal 267 268 template <int k, GTEST_$(n)_TYPENAMES_(T)> 269 GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T))) 270 get(GTEST_$(n)_TUPLE_(T)& t) { 271 return gtest_internal::Get<k>::Field(t); 272 } 273 274 template <int k, GTEST_$(n)_TYPENAMES_(T)> 275 GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T))) 276 get(const GTEST_$(n)_TUPLE_(T)& t) { 277 return gtest_internal::Get<k>::ConstField(t); 278 } 279 280 // 6.1.3.5 Relational operators 281 282 // We only implement == and !=, as we don't have a need for the rest yet. 283 284 namespace gtest_internal { 285 286 // SameSizeTuplePrefixComparator<k, k>::Eq(t1, t2) returns true if the 287 // first k fields of t1 equals the first k fields of t2. 288 // SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if 289 // k1 != k2. 290 template <int kSize1, int kSize2> 291 struct SameSizeTuplePrefixComparator; 292 293 template <> 294 struct SameSizeTuplePrefixComparator<0, 0> { 295 template <class Tuple1, class Tuple2> 296 static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) { 297 return true; 298 } 299 }; 300 301 template <int k> 302 struct SameSizeTuplePrefixComparator<k, k> { 303 template <class Tuple1, class Tuple2> 304 static bool Eq(const Tuple1& t1, const Tuple2& t2) { 305 return SameSizeTuplePrefixComparator<k - 1, k - 1>::Eq(t1, t2) && 306 ::std::tr1::get<k - 1>(t1) == ::std::tr1::get<k - 1>(t2); 307 } 308 }; 309 310 } // namespace gtest_internal 311 312 template <GTEST_$(n)_TYPENAMES_(T), GTEST_$(n)_TYPENAMES_(U)> 313 inline bool operator==(const GTEST_$(n)_TUPLE_(T)& t, 314 const GTEST_$(n)_TUPLE_(U)& u) { 315 return gtest_internal::SameSizeTuplePrefixComparator< 316 tuple_size<GTEST_$(n)_TUPLE_(T) >::value, 317 tuple_size<GTEST_$(n)_TUPLE_(U) >::value>::Eq(t, u); 318 } 319 320 template <GTEST_$(n)_TYPENAMES_(T), GTEST_$(n)_TYPENAMES_(U)> 321 inline bool operator!=(const GTEST_$(n)_TUPLE_(T)& t, 322 const GTEST_$(n)_TUPLE_(U)& u) { return !(t == u); } 323 324 // 6.1.4 Pairs. 325 // Unimplemented. 326 327 } // namespace tr1 328 } // namespace std 329 330 331 $for j [[ 332 #undef GTEST_$(j)_TUPLE_ 333 334 ]] 335 336 337 $for j [[ 338 #undef GTEST_$(j)_TYPENAMES_ 339 340 ]] 341 342 #undef GTEST_DECLARE_TUPLE_AS_FRIEND_ 343 #undef GTEST_BY_REF_ 344 #undef GTEST_ADD_REF_ 345 #undef GTEST_TUPLE_ELEMENT_ 346 347 #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ 348