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 34 // Implements a subset of TR1 tuple needed by Google Test and Google Mock. 35 36 // GOOGLETEST_CM0001 DO NOT DELETE 37 38 #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ 39 #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ 40 41 #include <utility> // For ::std::pair. 42 43 // The compiler used in Symbian has a bug that prevents us from declaring the 44 // tuple template as a friend (it complains that tuple is redefined). This 45 // bypasses the bug by declaring the members that should otherwise be 46 // private as public. 47 // Sun Studio versions < 12 also have the above bug. 48 #if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590) 49 # define GTEST_DECLARE_TUPLE_AS_FRIEND_ public: 50 #else 51 # define GTEST_DECLARE_TUPLE_AS_FRIEND_ \ 52 template <GTEST_$(n)_TYPENAMES_(U)> friend class tuple; \ 53 private: 54 #endif 55 56 // Visual Studio 2010, 2012, and 2013 define symbols in std::tr1 that conflict 57 // with our own definitions. Therefore using our own tuple does not work on 58 // those compilers. 59 #if defined(_MSC_VER) && _MSC_VER >= 1600 /* 1600 is Visual Studio 2010 */ 60 # error "gtest's tuple doesn't compile on Visual Studio 2010 or later. \ 61 GTEST_USE_OWN_TR1_TUPLE must be set to 0 on those compilers." 62 #endif 63 64 65 $range i 0..n-1 66 $range j 0..n 67 $range k 1..n 68 // GTEST_n_TUPLE_(T) is the type of an n-tuple. 69 #define GTEST_0_TUPLE_(T) tuple<> 70 71 $for k [[ 72 $range m 0..k-1 73 $range m2 k..n-1 74 #define GTEST_$(k)_TUPLE_(T) tuple<$for m, [[T##$m]]$for m2 [[, void]]> 75 76 ]] 77 78 // GTEST_n_TYPENAMES_(T) declares a list of n typenames. 79 80 $for j [[ 81 $range m 0..j-1 82 #define GTEST_$(j)_TYPENAMES_(T) $for m, [[typename T##$m]] 83 84 85 ]] 86 87 // In theory, defining stuff in the ::std namespace is undefined 88 // behavior. We can do this as we are playing the role of a standard 89 // library vendor. 90 namespace std { 91 namespace tr1 { 92 93 template <$for i, [[typename T$i = void]]> 94 class tuple; 95 96 // Anything in namespace gtest_internal is Google Test's INTERNAL 97 // IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code. 98 namespace gtest_internal { 99 100 // ByRef<T>::type is T if T is a reference; otherwise it's const T&. 101 template <typename T> 102 struct ByRef { typedef const T& type; }; // NOLINT 103 template <typename T> 104 struct ByRef<T&> { typedef T& type; }; // NOLINT 105 106 // A handy wrapper for ByRef. 107 #define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef<T>::type 108 109 // AddRef<T>::type is T if T is a reference; otherwise it's T&. This 110 // is the same as tr1::add_reference<T>::type. 111 template <typename T> 112 struct AddRef { typedef T& type; }; // NOLINT 113 template <typename T> 114 struct AddRef<T&> { typedef T& type; }; // NOLINT 115 116 // A handy wrapper for AddRef. 117 #define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef<T>::type 118 119 // A helper for implementing get<k>(). 120 template <int k> class Get; 121 122 // A helper for implementing tuple_element<k, T>. kIndexValid is true 123 // iff k < the number of fields in tuple type T. 124 template <bool kIndexValid, int kIndex, class Tuple> 125 struct TupleElement; 126 127 128 $for i [[ 129 template <GTEST_$(n)_TYPENAMES_(T)> 130 struct TupleElement<true, $i, GTEST_$(n)_TUPLE_(T) > { 131 typedef T$i type; 132 }; 133 134 135 ]] 136 } // namespace gtest_internal 137 138 template <> 139 class tuple<> { 140 public: 141 tuple() {} 142 tuple(const tuple& /* t */) {} 143 tuple& operator=(const tuple& /* t */) { return *this; } 144 }; 145 146 147 $for k [[ 148 $range m 0..k-1 149 template <GTEST_$(k)_TYPENAMES_(T)> 150 class $if k < n [[GTEST_$(k)_TUPLE_(T)]] $else [[tuple]] { 151 public: 152 template <int k> friend class gtest_internal::Get; 153 154 tuple() : $for m, [[f$(m)_()]] {} 155 156 explicit tuple($for m, [[GTEST_BY_REF_(T$m) f$m]]) : [[]] 157 $for m, [[f$(m)_(f$m)]] {} 158 159 tuple(const tuple& t) : $for m, [[f$(m)_(t.f$(m)_)]] {} 160 161 template <GTEST_$(k)_TYPENAMES_(U)> 162 tuple(const GTEST_$(k)_TUPLE_(U)& t) : $for m, [[f$(m)_(t.f$(m)_)]] {} 163 164 $if k == 2 [[ 165 template <typename U0, typename U1> 166 tuple(const ::std::pair<U0, U1>& p) : f0_(p.first), f1_(p.second) {} 167 168 ]] 169 170 tuple& operator=(const tuple& t) { return CopyFrom(t); } 171 172 template <GTEST_$(k)_TYPENAMES_(U)> 173 tuple& operator=(const GTEST_$(k)_TUPLE_(U)& t) { 174 return CopyFrom(t); 175 } 176 177 $if k == 2 [[ 178 template <typename U0, typename U1> 179 tuple& operator=(const ::std::pair<U0, U1>& p) { 180 f0_ = p.first; 181 f1_ = p.second; 182 return *this; 183 } 184 185 ]] 186 187 GTEST_DECLARE_TUPLE_AS_FRIEND_ 188 189 template <GTEST_$(k)_TYPENAMES_(U)> 190 tuple& CopyFrom(const GTEST_$(k)_TUPLE_(U)& t) { 191 192 $for m [[ 193 f$(m)_ = t.f$(m)_; 194 195 ]] 196 return *this; 197 } 198 199 200 $for m [[ 201 T$m f$(m)_; 202 203 ]] 204 }; 205 206 207 ]] 208 // 6.1.3.2 Tuple creation functions. 209 210 // Known limitations: we don't support passing an 211 // std::tr1::reference_wrapper<T> to make_tuple(). And we don't 212 // implement tie(). 213 214 inline tuple<> make_tuple() { return tuple<>(); } 215 216 $for k [[ 217 $range m 0..k-1 218 219 template <GTEST_$(k)_TYPENAMES_(T)> 220 inline GTEST_$(k)_TUPLE_(T) make_tuple($for m, [[const T$m& f$m]]) { 221 return GTEST_$(k)_TUPLE_(T)($for m, [[f$m]]); 222 } 223 224 ]] 225 226 // 6.1.3.3 Tuple helper classes. 227 228 template <typename Tuple> struct tuple_size; 229 230 231 $for j [[ 232 template <GTEST_$(j)_TYPENAMES_(T)> 233 struct tuple_size<GTEST_$(j)_TUPLE_(T) > { 234 static const int value = $j; 235 }; 236 237 238 ]] 239 template <int k, class Tuple> 240 struct tuple_element { 241 typedef typename gtest_internal::TupleElement< 242 k < (tuple_size<Tuple>::value), k, Tuple>::type type; 243 }; 244 245 #define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element<k, Tuple >::type 246 247 // 6.1.3.4 Element access. 248 249 namespace gtest_internal { 250 251 252 $for i [[ 253 template <> 254 class Get<$i> { 255 public: 256 template <class Tuple> 257 static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple)) 258 Field(Tuple& t) { return t.f$(i)_; } // NOLINT 259 260 template <class Tuple> 261 static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple)) 262 ConstField(const Tuple& t) { return t.f$(i)_; } 263 }; 264 265 266 ]] 267 } // namespace gtest_internal 268 269 template <int k, GTEST_$(n)_TYPENAMES_(T)> 270 GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T))) 271 get(GTEST_$(n)_TUPLE_(T)& t) { 272 return gtest_internal::Get<k>::Field(t); 273 } 274 275 template <int k, GTEST_$(n)_TYPENAMES_(T)> 276 GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T))) 277 get(const GTEST_$(n)_TUPLE_(T)& t) { 278 return gtest_internal::Get<k>::ConstField(t); 279 } 280 281 // 6.1.3.5 Relational operators 282 283 // We only implement == and !=, as we don't have a need for the rest yet. 284 285 namespace gtest_internal { 286 287 // SameSizeTuplePrefixComparator<k, k>::Eq(t1, t2) returns true if the 288 // first k fields of t1 equals the first k fields of t2. 289 // SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if 290 // k1 != k2. 291 template <int kSize1, int kSize2> 292 struct SameSizeTuplePrefixComparator; 293 294 template <> 295 struct SameSizeTuplePrefixComparator<0, 0> { 296 template <class Tuple1, class Tuple2> 297 static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) { 298 return true; 299 } 300 }; 301 302 template <int k> 303 struct SameSizeTuplePrefixComparator<k, k> { 304 template <class Tuple1, class Tuple2> 305 static bool Eq(const Tuple1& t1, const Tuple2& t2) { 306 return SameSizeTuplePrefixComparator<k - 1, k - 1>::Eq(t1, t2) && 307 ::std::tr1::get<k - 1>(t1) == ::std::tr1::get<k - 1>(t2); 308 } 309 }; 310 311 } // namespace gtest_internal 312 313 template <GTEST_$(n)_TYPENAMES_(T), GTEST_$(n)_TYPENAMES_(U)> 314 inline bool operator==(const GTEST_$(n)_TUPLE_(T)& t, 315 const GTEST_$(n)_TUPLE_(U)& u) { 316 return gtest_internal::SameSizeTuplePrefixComparator< 317 tuple_size<GTEST_$(n)_TUPLE_(T) >::value, 318 tuple_size<GTEST_$(n)_TUPLE_(U) >::value>::Eq(t, u); 319 } 320 321 template <GTEST_$(n)_TYPENAMES_(T), GTEST_$(n)_TYPENAMES_(U)> 322 inline bool operator!=(const GTEST_$(n)_TUPLE_(T)& t, 323 const GTEST_$(n)_TUPLE_(U)& u) { return !(t == u); } 324 325 // 6.1.4 Pairs. 326 // Unimplemented. 327 328 } // namespace tr1 329 } // namespace std 330 331 332 $for j [[ 333 #undef GTEST_$(j)_TUPLE_ 334 335 ]] 336 337 338 $for j [[ 339 #undef GTEST_$(j)_TYPENAMES_ 340 341 ]] 342 343 #undef GTEST_DECLARE_TUPLE_AS_FRIEND_ 344 #undef GTEST_BY_REF_ 345 #undef GTEST_ADD_REF_ 346 #undef GTEST_TUPLE_ELEMENT_ 347 348 #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_