1// This file was GENERATED by a script.  DO NOT EDIT BY HAND!!!
2
3// Copyright 2009 Google Inc.
4// All Rights Reserved.
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met:
9//
10//     * Redistributions of source code must retain the above copyright
11// notice, this list of conditions and the following disclaimer.
12//     * Redistributions in binary form must reproduce the above
13// copyright notice, this list of conditions and the following disclaimer
14// in the documentation and/or other materials provided with the
15// distribution.
16//     * Neither the name of Google Inc. nor the names of its
17// contributors may be used to endorse or promote products derived from
18// this software without specific prior written permission.
19//
20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31//
32// Author: wan@google.com (Zhanyong Wan)
33
34// Implements a subset of TR1 tuple needed by Google Test and Google Mock.
35
36#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
37#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
38
39#include <utility>  // For ::std::pair.
40
41// The compiler used in Symbian has a bug that prevents us from declaring the
42// tuple template as a friend (it complains that tuple is redefined).  This
43// hack bypasses the bug by declaring the members that should otherwise be
44// private as public.
45// Sun Studio versions < 12 also have the above bug.
46#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590)
47# define GTEST_DECLARE_TUPLE_AS_FRIEND_ public:
48#else
49# define GTEST_DECLARE_TUPLE_AS_FRIEND_ \
50    template <GTEST_10_TYPENAMES_(U)> friend class tuple; \
51   private:
52#endif
53
54// GTEST_n_TUPLE_(T) is the type of an n-tuple.
55#define GTEST_0_TUPLE_(T) tuple<>
56#define GTEST_1_TUPLE_(T) tuple<T##0, void, void, void, void, void, void, \
57    void, void, void>
58#define GTEST_2_TUPLE_(T) tuple<T##0, T##1, void, void, void, void, void, \
59    void, void, void>
60#define GTEST_3_TUPLE_(T) tuple<T##0, T##1, T##2, void, void, void, void, \
61    void, void, void>
62#define GTEST_4_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, void, void, void, \
63    void, void, void>
64#define GTEST_5_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, void, void, \
65    void, void, void>
66#define GTEST_6_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, void, \
67    void, void, void>
68#define GTEST_7_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
69    void, void, void>
70#define GTEST_8_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
71    T##7, void, void>
72#define GTEST_9_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
73    T##7, T##8, void>
74#define GTEST_10_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
75    T##7, T##8, T##9>
76
77// GTEST_n_TYPENAMES_(T) declares a list of n typenames.
78#define GTEST_0_TYPENAMES_(T)
79#define GTEST_1_TYPENAMES_(T) typename T##0
80#define GTEST_2_TYPENAMES_(T) typename T##0, typename T##1
81#define GTEST_3_TYPENAMES_(T) typename T##0, typename T##1, typename T##2
82#define GTEST_4_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
83    typename T##3
84#define GTEST_5_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
85    typename T##3, typename T##4
86#define GTEST_6_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
87    typename T##3, typename T##4, typename T##5
88#define GTEST_7_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
89    typename T##3, typename T##4, typename T##5, typename T##6
90#define GTEST_8_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
91    typename T##3, typename T##4, typename T##5, typename T##6, typename T##7
92#define GTEST_9_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
93    typename T##3, typename T##4, typename T##5, typename T##6, \
94    typename T##7, typename T##8
95#define GTEST_10_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
96    typename T##3, typename T##4, typename T##5, typename T##6, \
97    typename T##7, typename T##8, typename T##9
98
99// In theory, defining stuff in the ::std namespace is undefined
100// behavior.  We can do this as we are playing the role of a standard
101// library vendor.
102namespace std {
103namespace tr1 {
104
105template <typename T0 = void, typename T1 = void, typename T2 = void,
106    typename T3 = void, typename T4 = void, typename T5 = void,
107    typename T6 = void, typename T7 = void, typename T8 = void,
108    typename T9 = void>
109class tuple;
110
111// Anything in namespace gtest_internal is Google Test's INTERNAL
112// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code.
113namespace gtest_internal {
114
115// ByRef<T>::type is T if T is a reference; otherwise it's const T&.
116template <typename T>
117struct ByRef { typedef const T& type; };  // NOLINT
118template <typename T>
119struct ByRef<T&> { typedef T& type; };  // NOLINT
120
121// A handy wrapper for ByRef.
122#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef<T>::type
123
124// AddRef<T>::type is T if T is a reference; otherwise it's T&.  This
125// is the same as tr1::add_reference<T>::type.
126template <typename T>
127struct AddRef { typedef T& type; };  // NOLINT
128template <typename T>
129struct AddRef<T&> { typedef T& type; };  // NOLINT
130
131// A handy wrapper for AddRef.
132#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef<T>::type
133
134// A helper for implementing get<k>().
135template <int k> class Get;
136
137// A helper for implementing tuple_element<k, T>.  kIndexValid is true
138// iff k < the number of fields in tuple type T.
139template <bool kIndexValid, int kIndex, class Tuple>
140struct TupleElement;
141
142template <GTEST_10_TYPENAMES_(T)>
143struct TupleElement<true, 0, GTEST_10_TUPLE_(T)> { typedef T0 type; };
144
145template <GTEST_10_TYPENAMES_(T)>
146struct TupleElement<true, 1, GTEST_10_TUPLE_(T)> { typedef T1 type; };
147
148template <GTEST_10_TYPENAMES_(T)>
149struct TupleElement<true, 2, GTEST_10_TUPLE_(T)> { typedef T2 type; };
150
151template <GTEST_10_TYPENAMES_(T)>
152struct TupleElement<true, 3, GTEST_10_TUPLE_(T)> { typedef T3 type; };
153
154template <GTEST_10_TYPENAMES_(T)>
155struct TupleElement<true, 4, GTEST_10_TUPLE_(T)> { typedef T4 type; };
156
157template <GTEST_10_TYPENAMES_(T)>
158struct TupleElement<true, 5, GTEST_10_TUPLE_(T)> { typedef T5 type; };
159
160template <GTEST_10_TYPENAMES_(T)>
161struct TupleElement<true, 6, GTEST_10_TUPLE_(T)> { typedef T6 type; };
162
163template <GTEST_10_TYPENAMES_(T)>
164struct TupleElement<true, 7, GTEST_10_TUPLE_(T)> { typedef T7 type; };
165
166template <GTEST_10_TYPENAMES_(T)>
167struct TupleElement<true, 8, GTEST_10_TUPLE_(T)> { typedef T8 type; };
168
169template <GTEST_10_TYPENAMES_(T)>
170struct TupleElement<true, 9, GTEST_10_TUPLE_(T)> { typedef T9 type; };
171
172}  // namespace gtest_internal
173
174template <>
175class tuple<> {
176 public:
177  tuple() {}
178  tuple(const tuple& /* t */)  {}
179  tuple& operator=(const tuple& /* t */) { return *this; }
180};
181
182template <GTEST_1_TYPENAMES_(T)>
183class GTEST_1_TUPLE_(T) {
184 public:
185  template <int k> friend class gtest_internal::Get;
186
187  tuple() : f0_() {}
188
189  explicit tuple(GTEST_BY_REF_(T0) f0) : f0_(f0) {}
190
191  tuple(const tuple& t) : f0_(t.f0_) {}
192
193  template <GTEST_1_TYPENAMES_(U)>
194  tuple(const GTEST_1_TUPLE_(U)& t) : f0_(t.f0_) {}
195
196  tuple& operator=(const tuple& t) { return CopyFrom(t); }
197
198  template <GTEST_1_TYPENAMES_(U)>
199  tuple& operator=(const GTEST_1_TUPLE_(U)& t) {
200    return CopyFrom(t);
201  }
202
203  GTEST_DECLARE_TUPLE_AS_FRIEND_
204
205  template <GTEST_1_TYPENAMES_(U)>
206  tuple& CopyFrom(const GTEST_1_TUPLE_(U)& t) {
207    f0_ = t.f0_;
208    return *this;
209  }
210
211  T0 f0_;
212};
213
214template <GTEST_2_TYPENAMES_(T)>
215class GTEST_2_TUPLE_(T) {
216 public:
217  template <int k> friend class gtest_internal::Get;
218
219  tuple() : f0_(), f1_() {}
220
221  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1) : f0_(f0),
222      f1_(f1) {}
223
224  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_) {}
225
226  template <GTEST_2_TYPENAMES_(U)>
227  tuple(const GTEST_2_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_) {}
228  template <typename U0, typename U1>
229  tuple(const ::std::pair<U0, U1>& p) : f0_(p.first), f1_(p.second) {}
230
231  tuple& operator=(const tuple& t) { return CopyFrom(t); }
232
233  template <GTEST_2_TYPENAMES_(U)>
234  tuple& operator=(const GTEST_2_TUPLE_(U)& t) {
235    return CopyFrom(t);
236  }
237  template <typename U0, typename U1>
238  tuple& operator=(const ::std::pair<U0, U1>& p) {
239    f0_ = p.first;
240    f1_ = p.second;
241    return *this;
242  }
243
244  GTEST_DECLARE_TUPLE_AS_FRIEND_
245
246  template <GTEST_2_TYPENAMES_(U)>
247  tuple& CopyFrom(const GTEST_2_TUPLE_(U)& t) {
248    f0_ = t.f0_;
249    f1_ = t.f1_;
250    return *this;
251  }
252
253  T0 f0_;
254  T1 f1_;
255};
256
257template <GTEST_3_TYPENAMES_(T)>
258class GTEST_3_TUPLE_(T) {
259 public:
260  template <int k> friend class gtest_internal::Get;
261
262  tuple() : f0_(), f1_(), f2_() {}
263
264  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
265      GTEST_BY_REF_(T2) f2) : f0_(f0), f1_(f1), f2_(f2) {}
266
267  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {}
268
269  template <GTEST_3_TYPENAMES_(U)>
270  tuple(const GTEST_3_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {}
271
272  tuple& operator=(const tuple& t) { return CopyFrom(t); }
273
274  template <GTEST_3_TYPENAMES_(U)>
275  tuple& operator=(const GTEST_3_TUPLE_(U)& t) {
276    return CopyFrom(t);
277  }
278
279  GTEST_DECLARE_TUPLE_AS_FRIEND_
280
281  template <GTEST_3_TYPENAMES_(U)>
282  tuple& CopyFrom(const GTEST_3_TUPLE_(U)& t) {
283    f0_ = t.f0_;
284    f1_ = t.f1_;
285    f2_ = t.f2_;
286    return *this;
287  }
288
289  T0 f0_;
290  T1 f1_;
291  T2 f2_;
292};
293
294template <GTEST_4_TYPENAMES_(T)>
295class GTEST_4_TUPLE_(T) {
296 public:
297  template <int k> friend class gtest_internal::Get;
298
299  tuple() : f0_(), f1_(), f2_(), f3_() {}
300
301  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
302      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3) : f0_(f0), f1_(f1), f2_(f2),
303      f3_(f3) {}
304
305  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) {}
306
307  template <GTEST_4_TYPENAMES_(U)>
308  tuple(const GTEST_4_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
309      f3_(t.f3_) {}
310
311  tuple& operator=(const tuple& t) { return CopyFrom(t); }
312
313  template <GTEST_4_TYPENAMES_(U)>
314  tuple& operator=(const GTEST_4_TUPLE_(U)& t) {
315    return CopyFrom(t);
316  }
317
318  GTEST_DECLARE_TUPLE_AS_FRIEND_
319
320  template <GTEST_4_TYPENAMES_(U)>
321  tuple& CopyFrom(const GTEST_4_TUPLE_(U)& t) {
322    f0_ = t.f0_;
323    f1_ = t.f1_;
324    f2_ = t.f2_;
325    f3_ = t.f3_;
326    return *this;
327  }
328
329  T0 f0_;
330  T1 f1_;
331  T2 f2_;
332  T3 f3_;
333};
334
335template <GTEST_5_TYPENAMES_(T)>
336class GTEST_5_TUPLE_(T) {
337 public:
338  template <int k> friend class gtest_internal::Get;
339
340  tuple() : f0_(), f1_(), f2_(), f3_(), f4_() {}
341
342  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
343      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3,
344      GTEST_BY_REF_(T4) f4) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4) {}
345
346  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
347      f4_(t.f4_) {}
348
349  template <GTEST_5_TYPENAMES_(U)>
350  tuple(const GTEST_5_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
351      f3_(t.f3_), f4_(t.f4_) {}
352
353  tuple& operator=(const tuple& t) { return CopyFrom(t); }
354
355  template <GTEST_5_TYPENAMES_(U)>
356  tuple& operator=(const GTEST_5_TUPLE_(U)& t) {
357    return CopyFrom(t);
358  }
359
360  GTEST_DECLARE_TUPLE_AS_FRIEND_
361
362  template <GTEST_5_TYPENAMES_(U)>
363  tuple& CopyFrom(const GTEST_5_TUPLE_(U)& t) {
364    f0_ = t.f0_;
365    f1_ = t.f1_;
366    f2_ = t.f2_;
367    f3_ = t.f3_;
368    f4_ = t.f4_;
369    return *this;
370  }
371
372  T0 f0_;
373  T1 f1_;
374  T2 f2_;
375  T3 f3_;
376  T4 f4_;
377};
378
379template <GTEST_6_TYPENAMES_(T)>
380class GTEST_6_TUPLE_(T) {
381 public:
382  template <int k> friend class gtest_internal::Get;
383
384  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_() {}
385
386  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
387      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
388      GTEST_BY_REF_(T5) f5) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),
389      f5_(f5) {}
390
391  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
392      f4_(t.f4_), f5_(t.f5_) {}
393
394  template <GTEST_6_TYPENAMES_(U)>
395  tuple(const GTEST_6_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
396      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) {}
397
398  tuple& operator=(const tuple& t) { return CopyFrom(t); }
399
400  template <GTEST_6_TYPENAMES_(U)>
401  tuple& operator=(const GTEST_6_TUPLE_(U)& t) {
402    return CopyFrom(t);
403  }
404
405  GTEST_DECLARE_TUPLE_AS_FRIEND_
406
407  template <GTEST_6_TYPENAMES_(U)>
408  tuple& CopyFrom(const GTEST_6_TUPLE_(U)& t) {
409    f0_ = t.f0_;
410    f1_ = t.f1_;
411    f2_ = t.f2_;
412    f3_ = t.f3_;
413    f4_ = t.f4_;
414    f5_ = t.f5_;
415    return *this;
416  }
417
418  T0 f0_;
419  T1 f1_;
420  T2 f2_;
421  T3 f3_;
422  T4 f4_;
423  T5 f5_;
424};
425
426template <GTEST_7_TYPENAMES_(T)>
427class GTEST_7_TUPLE_(T) {
428 public:
429  template <int k> friend class gtest_internal::Get;
430
431  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_() {}
432
433  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
434      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
435      GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6) : f0_(f0), f1_(f1), f2_(f2),
436      f3_(f3), f4_(f4), f5_(f5), f6_(f6) {}
437
438  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
439      f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {}
440
441  template <GTEST_7_TYPENAMES_(U)>
442  tuple(const GTEST_7_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
443      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {}
444
445  tuple& operator=(const tuple& t) { return CopyFrom(t); }
446
447  template <GTEST_7_TYPENAMES_(U)>
448  tuple& operator=(const GTEST_7_TUPLE_(U)& t) {
449    return CopyFrom(t);
450  }
451
452  GTEST_DECLARE_TUPLE_AS_FRIEND_
453
454  template <GTEST_7_TYPENAMES_(U)>
455  tuple& CopyFrom(const GTEST_7_TUPLE_(U)& t) {
456    f0_ = t.f0_;
457    f1_ = t.f1_;
458    f2_ = t.f2_;
459    f3_ = t.f3_;
460    f4_ = t.f4_;
461    f5_ = t.f5_;
462    f6_ = t.f6_;
463    return *this;
464  }
465
466  T0 f0_;
467  T1 f1_;
468  T2 f2_;
469  T3 f3_;
470  T4 f4_;
471  T5 f5_;
472  T6 f6_;
473};
474
475template <GTEST_8_TYPENAMES_(T)>
476class GTEST_8_TUPLE_(T) {
477 public:
478  template <int k> friend class gtest_internal::Get;
479
480  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_() {}
481
482  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
483      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
484      GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6,
485      GTEST_BY_REF_(T7) f7) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),
486      f5_(f5), f6_(f6), f7_(f7) {}
487
488  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
489      f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {}
490
491  template <GTEST_8_TYPENAMES_(U)>
492  tuple(const GTEST_8_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
493      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {}
494
495  tuple& operator=(const tuple& t) { return CopyFrom(t); }
496
497  template <GTEST_8_TYPENAMES_(U)>
498  tuple& operator=(const GTEST_8_TUPLE_(U)& t) {
499    return CopyFrom(t);
500  }
501
502  GTEST_DECLARE_TUPLE_AS_FRIEND_
503
504  template <GTEST_8_TYPENAMES_(U)>
505  tuple& CopyFrom(const GTEST_8_TUPLE_(U)& t) {
506    f0_ = t.f0_;
507    f1_ = t.f1_;
508    f2_ = t.f2_;
509    f3_ = t.f3_;
510    f4_ = t.f4_;
511    f5_ = t.f5_;
512    f6_ = t.f6_;
513    f7_ = t.f7_;
514    return *this;
515  }
516
517  T0 f0_;
518  T1 f1_;
519  T2 f2_;
520  T3 f3_;
521  T4 f4_;
522  T5 f5_;
523  T6 f6_;
524  T7 f7_;
525};
526
527template <GTEST_9_TYPENAMES_(T)>
528class GTEST_9_TUPLE_(T) {
529 public:
530  template <int k> friend class gtest_internal::Get;
531
532  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_() {}
533
534  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
535      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
536      GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7,
537      GTEST_BY_REF_(T8) f8) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),
538      f5_(f5), f6_(f6), f7_(f7), f8_(f8) {}
539
540  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
541      f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {}
542
543  template <GTEST_9_TYPENAMES_(U)>
544  tuple(const GTEST_9_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
545      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {}
546
547  tuple& operator=(const tuple& t) { return CopyFrom(t); }
548
549  template <GTEST_9_TYPENAMES_(U)>
550  tuple& operator=(const GTEST_9_TUPLE_(U)& t) {
551    return CopyFrom(t);
552  }
553
554  GTEST_DECLARE_TUPLE_AS_FRIEND_
555
556  template <GTEST_9_TYPENAMES_(U)>
557  tuple& CopyFrom(const GTEST_9_TUPLE_(U)& t) {
558    f0_ = t.f0_;
559    f1_ = t.f1_;
560    f2_ = t.f2_;
561    f3_ = t.f3_;
562    f4_ = t.f4_;
563    f5_ = t.f5_;
564    f6_ = t.f6_;
565    f7_ = t.f7_;
566    f8_ = t.f8_;
567    return *this;
568  }
569
570  T0 f0_;
571  T1 f1_;
572  T2 f2_;
573  T3 f3_;
574  T4 f4_;
575  T5 f5_;
576  T6 f6_;
577  T7 f7_;
578  T8 f8_;
579};
580
581template <GTEST_10_TYPENAMES_(T)>
582class tuple {
583 public:
584  template <int k> friend class gtest_internal::Get;
585
586  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_(),
587      f9_() {}
588
589  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
590      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
591      GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7,
592      GTEST_BY_REF_(T8) f8, GTEST_BY_REF_(T9) f9) : f0_(f0), f1_(f1), f2_(f2),
593      f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8), f9_(f9) {}
594
595  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
596      f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) {}
597
598  template <GTEST_10_TYPENAMES_(U)>
599  tuple(const GTEST_10_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
600      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_),
601      f9_(t.f9_) {}
602
603  tuple& operator=(const tuple& t) { return CopyFrom(t); }
604
605  template <GTEST_10_TYPENAMES_(U)>
606  tuple& operator=(const GTEST_10_TUPLE_(U)& t) {
607    return CopyFrom(t);
608  }
609
610  GTEST_DECLARE_TUPLE_AS_FRIEND_
611
612  template <GTEST_10_TYPENAMES_(U)>
613  tuple& CopyFrom(const GTEST_10_TUPLE_(U)& t) {
614    f0_ = t.f0_;
615    f1_ = t.f1_;
616    f2_ = t.f2_;
617    f3_ = t.f3_;
618    f4_ = t.f4_;
619    f5_ = t.f5_;
620    f6_ = t.f6_;
621    f7_ = t.f7_;
622    f8_ = t.f8_;
623    f9_ = t.f9_;
624    return *this;
625  }
626
627  T0 f0_;
628  T1 f1_;
629  T2 f2_;
630  T3 f3_;
631  T4 f4_;
632  T5 f5_;
633  T6 f6_;
634  T7 f7_;
635  T8 f8_;
636  T9 f9_;
637};
638
639// 6.1.3.2 Tuple creation functions.
640
641// Known limitations: we don't support passing an
642// std::tr1::reference_wrapper<T> to make_tuple().  And we don't
643// implement tie().
644
645inline tuple<> make_tuple() { return tuple<>(); }
646
647template <GTEST_1_TYPENAMES_(T)>
648inline GTEST_1_TUPLE_(T) make_tuple(const T0& f0) {
649  return GTEST_1_TUPLE_(T)(f0);
650}
651
652template <GTEST_2_TYPENAMES_(T)>
653inline GTEST_2_TUPLE_(T) make_tuple(const T0& f0, const T1& f1) {
654  return GTEST_2_TUPLE_(T)(f0, f1);
655}
656
657template <GTEST_3_TYPENAMES_(T)>
658inline GTEST_3_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2) {
659  return GTEST_3_TUPLE_(T)(f0, f1, f2);
660}
661
662template <GTEST_4_TYPENAMES_(T)>
663inline GTEST_4_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
664    const T3& f3) {
665  return GTEST_4_TUPLE_(T)(f0, f1, f2, f3);
666}
667
668template <GTEST_5_TYPENAMES_(T)>
669inline GTEST_5_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
670    const T3& f3, const T4& f4) {
671  return GTEST_5_TUPLE_(T)(f0, f1, f2, f3, f4);
672}
673
674template <GTEST_6_TYPENAMES_(T)>
675inline GTEST_6_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
676    const T3& f3, const T4& f4, const T5& f5) {
677  return GTEST_6_TUPLE_(T)(f0, f1, f2, f3, f4, f5);
678}
679
680template <GTEST_7_TYPENAMES_(T)>
681inline GTEST_7_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
682    const T3& f3, const T4& f4, const T5& f5, const T6& f6) {
683  return GTEST_7_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6);
684}
685
686template <GTEST_8_TYPENAMES_(T)>
687inline GTEST_8_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
688    const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7) {
689  return GTEST_8_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7);
690}
691
692template <GTEST_9_TYPENAMES_(T)>
693inline GTEST_9_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
694    const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7,
695    const T8& f8) {
696  return GTEST_9_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8);
697}
698
699template <GTEST_10_TYPENAMES_(T)>
700inline GTEST_10_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
701    const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7,
702    const T8& f8, const T9& f9) {
703  return GTEST_10_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9);
704}
705
706// 6.1.3.3 Tuple helper classes.
707
708template <typename Tuple> struct tuple_size;
709
710template <GTEST_0_TYPENAMES_(T)>
711struct tuple_size<GTEST_0_TUPLE_(T)> { static const int value = 0; };
712
713template <GTEST_1_TYPENAMES_(T)>
714struct tuple_size<GTEST_1_TUPLE_(T)> { static const int value = 1; };
715
716template <GTEST_2_TYPENAMES_(T)>
717struct tuple_size<GTEST_2_TUPLE_(T)> { static const int value = 2; };
718
719template <GTEST_3_TYPENAMES_(T)>
720struct tuple_size<GTEST_3_TUPLE_(T)> { static const int value = 3; };
721
722template <GTEST_4_TYPENAMES_(T)>
723struct tuple_size<GTEST_4_TUPLE_(T)> { static const int value = 4; };
724
725template <GTEST_5_TYPENAMES_(T)>
726struct tuple_size<GTEST_5_TUPLE_(T)> { static const int value = 5; };
727
728template <GTEST_6_TYPENAMES_(T)>
729struct tuple_size<GTEST_6_TUPLE_(T)> { static const int value = 6; };
730
731template <GTEST_7_TYPENAMES_(T)>
732struct tuple_size<GTEST_7_TUPLE_(T)> { static const int value = 7; };
733
734template <GTEST_8_TYPENAMES_(T)>
735struct tuple_size<GTEST_8_TUPLE_(T)> { static const int value = 8; };
736
737template <GTEST_9_TYPENAMES_(T)>
738struct tuple_size<GTEST_9_TUPLE_(T)> { static const int value = 9; };
739
740template <GTEST_10_TYPENAMES_(T)>
741struct tuple_size<GTEST_10_TUPLE_(T)> { static const int value = 10; };
742
743template <int k, class Tuple>
744struct tuple_element {
745  typedef typename gtest_internal::TupleElement<
746      k < (tuple_size<Tuple>::value), k, Tuple>::type type;
747};
748
749#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element<k, Tuple >::type
750
751// 6.1.3.4 Element access.
752
753namespace gtest_internal {
754
755template <>
756class Get<0> {
757 public:
758  template <class Tuple>
759  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple))
760  Field(Tuple& t) { return t.f0_; }  // NOLINT
761
762  template <class Tuple>
763  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple))
764  ConstField(const Tuple& t) { return t.f0_; }
765};
766
767template <>
768class Get<1> {
769 public:
770  template <class Tuple>
771  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple))
772  Field(Tuple& t) { return t.f1_; }  // NOLINT
773
774  template <class Tuple>
775  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple))
776  ConstField(const Tuple& t) { return t.f1_; }
777};
778
779template <>
780class Get<2> {
781 public:
782  template <class Tuple>
783  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple))
784  Field(Tuple& t) { return t.f2_; }  // NOLINT
785
786  template <class Tuple>
787  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple))
788  ConstField(const Tuple& t) { return t.f2_; }
789};
790
791template <>
792class Get<3> {
793 public:
794  template <class Tuple>
795  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple))
796  Field(Tuple& t) { return t.f3_; }  // NOLINT
797
798  template <class Tuple>
799  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple))
800  ConstField(const Tuple& t) { return t.f3_; }
801};
802
803template <>
804class Get<4> {
805 public:
806  template <class Tuple>
807  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple))
808  Field(Tuple& t) { return t.f4_; }  // NOLINT
809
810  template <class Tuple>
811  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple))
812  ConstField(const Tuple& t) { return t.f4_; }
813};
814
815template <>
816class Get<5> {
817 public:
818  template <class Tuple>
819  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple))
820  Field(Tuple& t) { return t.f5_; }  // NOLINT
821
822  template <class Tuple>
823  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple))
824  ConstField(const Tuple& t) { return t.f5_; }
825};
826
827template <>
828class Get<6> {
829 public:
830  template <class Tuple>
831  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple))
832  Field(Tuple& t) { return t.f6_; }  // NOLINT
833
834  template <class Tuple>
835  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple))
836  ConstField(const Tuple& t) { return t.f6_; }
837};
838
839template <>
840class Get<7> {
841 public:
842  template <class Tuple>
843  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple))
844  Field(Tuple& t) { return t.f7_; }  // NOLINT
845
846  template <class Tuple>
847  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple))
848  ConstField(const Tuple& t) { return t.f7_; }
849};
850
851template <>
852class Get<8> {
853 public:
854  template <class Tuple>
855  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple))
856  Field(Tuple& t) { return t.f8_; }  // NOLINT
857
858  template <class Tuple>
859  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple))
860  ConstField(const Tuple& t) { return t.f8_; }
861};
862
863template <>
864class Get<9> {
865 public:
866  template <class Tuple>
867  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple))
868  Field(Tuple& t) { return t.f9_; }  // NOLINT
869
870  template <class Tuple>
871  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple))
872  ConstField(const Tuple& t) { return t.f9_; }
873};
874
875}  // namespace gtest_internal
876
877template <int k, GTEST_10_TYPENAMES_(T)>
878GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T)))
879get(GTEST_10_TUPLE_(T)& t) {
880  return gtest_internal::Get<k>::Field(t);
881}
882
883template <int k, GTEST_10_TYPENAMES_(T)>
884GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k,  GTEST_10_TUPLE_(T)))
885get(const GTEST_10_TUPLE_(T)& t) {
886  return gtest_internal::Get<k>::ConstField(t);
887}
888
889// 6.1.3.5 Relational operators
890
891// We only implement == and !=, as we don't have a need for the rest yet.
892
893namespace gtest_internal {
894
895// SameSizeTuplePrefixComparator<k, k>::Eq(t1, t2) returns true if the
896// first k fields of t1 equals the first k fields of t2.
897// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if
898// k1 != k2.
899template <int kSize1, int kSize2>
900struct SameSizeTuplePrefixComparator;
901
902template <>
903struct SameSizeTuplePrefixComparator<0, 0> {
904  template <class Tuple1, class Tuple2>
905  static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) {
906    return true;
907  }
908};
909
910template <int k>
911struct SameSizeTuplePrefixComparator<k, k> {
912  template <class Tuple1, class Tuple2>
913  static bool Eq(const Tuple1& t1, const Tuple2& t2) {
914    return SameSizeTuplePrefixComparator<k - 1, k - 1>::Eq(t1, t2) &&
915        ::std::tr1::get<k - 1>(t1) == ::std::tr1::get<k - 1>(t2);
916  }
917};
918
919}  // namespace gtest_internal
920
921template <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)>
922inline bool operator==(const GTEST_10_TUPLE_(T)& t,
923                       const GTEST_10_TUPLE_(U)& u) {
924  return gtest_internal::SameSizeTuplePrefixComparator<
925      tuple_size<GTEST_10_TUPLE_(T)>::value,
926      tuple_size<GTEST_10_TUPLE_(U)>::value>::Eq(t, u);
927}
928
929template <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)>
930inline bool operator!=(const GTEST_10_TUPLE_(T)& t,
931                       const GTEST_10_TUPLE_(U)& u) { return !(t == u); }
932
933// 6.1.4 Pairs.
934// Unimplemented.
935
936}  // namespace tr1
937}  // namespace std
938
939#undef GTEST_0_TUPLE_
940#undef GTEST_1_TUPLE_
941#undef GTEST_2_TUPLE_
942#undef GTEST_3_TUPLE_
943#undef GTEST_4_TUPLE_
944#undef GTEST_5_TUPLE_
945#undef GTEST_6_TUPLE_
946#undef GTEST_7_TUPLE_
947#undef GTEST_8_TUPLE_
948#undef GTEST_9_TUPLE_
949#undef GTEST_10_TUPLE_
950
951#undef GTEST_0_TYPENAMES_
952#undef GTEST_1_TYPENAMES_
953#undef GTEST_2_TYPENAMES_
954#undef GTEST_3_TYPENAMES_
955#undef GTEST_4_TYPENAMES_
956#undef GTEST_5_TYPENAMES_
957#undef GTEST_6_TYPENAMES_
958#undef GTEST_7_TYPENAMES_
959#undef GTEST_8_TYPENAMES_
960#undef GTEST_9_TYPENAMES_
961#undef GTEST_10_TYPENAMES_
962
963#undef GTEST_DECLARE_TUPLE_AS_FRIEND_
964#undef GTEST_BY_REF_
965#undef GTEST_ADD_REF_
966#undef GTEST_TUPLE_ELEMENT_
967
968#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
969