1// This file was GENERATED by a script.  DO NOT EDIT BY HAND!!!
2
3// Copyright 2008 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: vladl@google.com (Vlad Losev)
33
34// Type and function utilities for implementing parameterized tests.
35// This file is generated by a SCRIPT.  DO NOT EDIT BY HAND!
36//
37// Currently Google Test supports at most 50 arguments in Values,
38// and at most 10 arguments in Combine. Please contact
39// googletestframework@googlegroups.com if you need more.
40// Please note that the number of arguments to Combine is limited
41// by the maximum arity of the implementation of tr1::tuple which is
42// currently set at 10.
43
44#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
45#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
46
47// scripts/fuse_gtest.py depends on gtest's own header being #included
48// *unconditionally*.  Therefore these #includes cannot be moved
49// inside #if GTEST_HAS_PARAM_TEST.
50#include <gtest/internal/gtest-param-util.h>
51#include <gtest/internal/gtest-port.h>
52
53#if GTEST_HAS_PARAM_TEST
54
55namespace testing {
56
57// Forward declarations of ValuesIn(), which is implemented in
58// include/gtest/gtest-param-test.h.
59template <typename ForwardIterator>
60internal::ParamGenerator<
61    typename ::std::iterator_traits<ForwardIterator>::value_type> ValuesIn(
62        ForwardIterator begin, ForwardIterator end);
63
64template <typename T, size_t N>
65internal::ParamGenerator<T> ValuesIn(const T (&array)[N]);
66
67template <class Container>
68internal::ParamGenerator<typename Container::value_type> ValuesIn(
69    const Container& container);
70
71namespace internal {
72
73// Used in the Values() function to provide polymorphic capabilities.
74template <typename T1>
75class ValueArray1 {
76 public:
77  explicit ValueArray1(T1 v1) : v1_(v1) {}
78
79  template <typename T>
80  operator ParamGenerator<T>() const { return ValuesIn(&v1_, &v1_ + 1); }
81
82 private:
83  // No implementation - assignment is unsupported.
84  void operator=(const ValueArray1& other);
85
86  const T1 v1_;
87};
88
89template <typename T1, typename T2>
90class ValueArray2 {
91 public:
92  ValueArray2(T1 v1, T2 v2) : v1_(v1), v2_(v2) {}
93
94  template <typename T>
95  operator ParamGenerator<T>() const {
96    const T array[] = {v1_, v2_};
97    return ValuesIn(array);
98  }
99
100 private:
101  // No implementation - assignment is unsupported.
102  void operator=(const ValueArray2& other);
103
104  const T1 v1_;
105  const T2 v2_;
106};
107
108template <typename T1, typename T2, typename T3>
109class ValueArray3 {
110 public:
111  ValueArray3(T1 v1, T2 v2, T3 v3) : v1_(v1), v2_(v2), v3_(v3) {}
112
113  template <typename T>
114  operator ParamGenerator<T>() const {
115    const T array[] = {v1_, v2_, v3_};
116    return ValuesIn(array);
117  }
118
119 private:
120  // No implementation - assignment is unsupported.
121  void operator=(const ValueArray3& other);
122
123  const T1 v1_;
124  const T2 v2_;
125  const T3 v3_;
126};
127
128template <typename T1, typename T2, typename T3, typename T4>
129class ValueArray4 {
130 public:
131  ValueArray4(T1 v1, T2 v2, T3 v3, T4 v4) : v1_(v1), v2_(v2), v3_(v3),
132      v4_(v4) {}
133
134  template <typename T>
135  operator ParamGenerator<T>() const {
136    const T array[] = {v1_, v2_, v3_, v4_};
137    return ValuesIn(array);
138  }
139
140 private:
141  // No implementation - assignment is unsupported.
142  void operator=(const ValueArray4& other);
143
144  const T1 v1_;
145  const T2 v2_;
146  const T3 v3_;
147  const T4 v4_;
148};
149
150template <typename T1, typename T2, typename T3, typename T4, typename T5>
151class ValueArray5 {
152 public:
153  ValueArray5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) : v1_(v1), v2_(v2), v3_(v3),
154      v4_(v4), v5_(v5) {}
155
156  template <typename T>
157  operator ParamGenerator<T>() const {
158    const T array[] = {v1_, v2_, v3_, v4_, v5_};
159    return ValuesIn(array);
160  }
161
162 private:
163  // No implementation - assignment is unsupported.
164  void operator=(const ValueArray5& other);
165
166  const T1 v1_;
167  const T2 v2_;
168  const T3 v3_;
169  const T4 v4_;
170  const T5 v5_;
171};
172
173template <typename T1, typename T2, typename T3, typename T4, typename T5,
174    typename T6>
175class ValueArray6 {
176 public:
177  ValueArray6(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) : v1_(v1), v2_(v2),
178      v3_(v3), v4_(v4), v5_(v5), v6_(v6) {}
179
180  template <typename T>
181  operator ParamGenerator<T>() const {
182    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_};
183    return ValuesIn(array);
184  }
185
186 private:
187  // No implementation - assignment is unsupported.
188  void operator=(const ValueArray6& other);
189
190  const T1 v1_;
191  const T2 v2_;
192  const T3 v3_;
193  const T4 v4_;
194  const T5 v5_;
195  const T6 v6_;
196};
197
198template <typename T1, typename T2, typename T3, typename T4, typename T5,
199    typename T6, typename T7>
200class ValueArray7 {
201 public:
202  ValueArray7(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) : v1_(v1),
203      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7) {}
204
205  template <typename T>
206  operator ParamGenerator<T>() const {
207    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_};
208    return ValuesIn(array);
209  }
210
211 private:
212  // No implementation - assignment is unsupported.
213  void operator=(const ValueArray7& other);
214
215  const T1 v1_;
216  const T2 v2_;
217  const T3 v3_;
218  const T4 v4_;
219  const T5 v5_;
220  const T6 v6_;
221  const T7 v7_;
222};
223
224template <typename T1, typename T2, typename T3, typename T4, typename T5,
225    typename T6, typename T7, typename T8>
226class ValueArray8 {
227 public:
228  ValueArray8(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
229      T8 v8) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
230      v8_(v8) {}
231
232  template <typename T>
233  operator ParamGenerator<T>() const {
234    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_};
235    return ValuesIn(array);
236  }
237
238 private:
239  // No implementation - assignment is unsupported.
240  void operator=(const ValueArray8& other);
241
242  const T1 v1_;
243  const T2 v2_;
244  const T3 v3_;
245  const T4 v4_;
246  const T5 v5_;
247  const T6 v6_;
248  const T7 v7_;
249  const T8 v8_;
250};
251
252template <typename T1, typename T2, typename T3, typename T4, typename T5,
253    typename T6, typename T7, typename T8, typename T9>
254class ValueArray9 {
255 public:
256  ValueArray9(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
257      T9 v9) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
258      v8_(v8), v9_(v9) {}
259
260  template <typename T>
261  operator ParamGenerator<T>() const {
262    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_};
263    return ValuesIn(array);
264  }
265
266 private:
267  // No implementation - assignment is unsupported.
268  void operator=(const ValueArray9& other);
269
270  const T1 v1_;
271  const T2 v2_;
272  const T3 v3_;
273  const T4 v4_;
274  const T5 v5_;
275  const T6 v6_;
276  const T7 v7_;
277  const T8 v8_;
278  const T9 v9_;
279};
280
281template <typename T1, typename T2, typename T3, typename T4, typename T5,
282    typename T6, typename T7, typename T8, typename T9, typename T10>
283class ValueArray10 {
284 public:
285  ValueArray10(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
286      T10 v10) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
287      v8_(v8), v9_(v9), v10_(v10) {}
288
289  template <typename T>
290  operator ParamGenerator<T>() const {
291    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_};
292    return ValuesIn(array);
293  }
294
295 private:
296  // No implementation - assignment is unsupported.
297  void operator=(const ValueArray10& other);
298
299  const T1 v1_;
300  const T2 v2_;
301  const T3 v3_;
302  const T4 v4_;
303  const T5 v5_;
304  const T6 v6_;
305  const T7 v7_;
306  const T8 v8_;
307  const T9 v9_;
308  const T10 v10_;
309};
310
311template <typename T1, typename T2, typename T3, typename T4, typename T5,
312    typename T6, typename T7, typename T8, typename T9, typename T10,
313    typename T11>
314class ValueArray11 {
315 public:
316  ValueArray11(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
317      T10 v10, T11 v11) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
318      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11) {}
319
320  template <typename T>
321  operator ParamGenerator<T>() const {
322    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_};
323    return ValuesIn(array);
324  }
325
326 private:
327  // No implementation - assignment is unsupported.
328  void operator=(const ValueArray11& other);
329
330  const T1 v1_;
331  const T2 v2_;
332  const T3 v3_;
333  const T4 v4_;
334  const T5 v5_;
335  const T6 v6_;
336  const T7 v7_;
337  const T8 v8_;
338  const T9 v9_;
339  const T10 v10_;
340  const T11 v11_;
341};
342
343template <typename T1, typename T2, typename T3, typename T4, typename T5,
344    typename T6, typename T7, typename T8, typename T9, typename T10,
345    typename T11, typename T12>
346class ValueArray12 {
347 public:
348  ValueArray12(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
349      T10 v10, T11 v11, T12 v12) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
350      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12) {}
351
352  template <typename T>
353  operator ParamGenerator<T>() const {
354    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
355        v12_};
356    return ValuesIn(array);
357  }
358
359 private:
360  // No implementation - assignment is unsupported.
361  void operator=(const ValueArray12& other);
362
363  const T1 v1_;
364  const T2 v2_;
365  const T3 v3_;
366  const T4 v4_;
367  const T5 v5_;
368  const T6 v6_;
369  const T7 v7_;
370  const T8 v8_;
371  const T9 v9_;
372  const T10 v10_;
373  const T11 v11_;
374  const T12 v12_;
375};
376
377template <typename T1, typename T2, typename T3, typename T4, typename T5,
378    typename T6, typename T7, typename T8, typename T9, typename T10,
379    typename T11, typename T12, typename T13>
380class ValueArray13 {
381 public:
382  ValueArray13(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
383      T10 v10, T11 v11, T12 v12, T13 v13) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
384      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
385      v12_(v12), v13_(v13) {}
386
387  template <typename T>
388  operator ParamGenerator<T>() const {
389    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
390        v12_, v13_};
391    return ValuesIn(array);
392  }
393
394 private:
395  // No implementation - assignment is unsupported.
396  void operator=(const ValueArray13& other);
397
398  const T1 v1_;
399  const T2 v2_;
400  const T3 v3_;
401  const T4 v4_;
402  const T5 v5_;
403  const T6 v6_;
404  const T7 v7_;
405  const T8 v8_;
406  const T9 v9_;
407  const T10 v10_;
408  const T11 v11_;
409  const T12 v12_;
410  const T13 v13_;
411};
412
413template <typename T1, typename T2, typename T3, typename T4, typename T5,
414    typename T6, typename T7, typename T8, typename T9, typename T10,
415    typename T11, typename T12, typename T13, typename T14>
416class ValueArray14 {
417 public:
418  ValueArray14(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
419      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) : v1_(v1), v2_(v2), v3_(v3),
420      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
421      v11_(v11), v12_(v12), v13_(v13), v14_(v14) {}
422
423  template <typename T>
424  operator ParamGenerator<T>() const {
425    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
426        v12_, v13_, v14_};
427    return ValuesIn(array);
428  }
429
430 private:
431  // No implementation - assignment is unsupported.
432  void operator=(const ValueArray14& other);
433
434  const T1 v1_;
435  const T2 v2_;
436  const T3 v3_;
437  const T4 v4_;
438  const T5 v5_;
439  const T6 v6_;
440  const T7 v7_;
441  const T8 v8_;
442  const T9 v9_;
443  const T10 v10_;
444  const T11 v11_;
445  const T12 v12_;
446  const T13 v13_;
447  const T14 v14_;
448};
449
450template <typename T1, typename T2, typename T3, typename T4, typename T5,
451    typename T6, typename T7, typename T8, typename T9, typename T10,
452    typename T11, typename T12, typename T13, typename T14, typename T15>
453class ValueArray15 {
454 public:
455  ValueArray15(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
456      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) : v1_(v1), v2_(v2),
457      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
458      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15) {}
459
460  template <typename T>
461  operator ParamGenerator<T>() const {
462    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
463        v12_, v13_, v14_, v15_};
464    return ValuesIn(array);
465  }
466
467 private:
468  // No implementation - assignment is unsupported.
469  void operator=(const ValueArray15& other);
470
471  const T1 v1_;
472  const T2 v2_;
473  const T3 v3_;
474  const T4 v4_;
475  const T5 v5_;
476  const T6 v6_;
477  const T7 v7_;
478  const T8 v8_;
479  const T9 v9_;
480  const T10 v10_;
481  const T11 v11_;
482  const T12 v12_;
483  const T13 v13_;
484  const T14 v14_;
485  const T15 v15_;
486};
487
488template <typename T1, typename T2, typename T3, typename T4, typename T5,
489    typename T6, typename T7, typename T8, typename T9, typename T10,
490    typename T11, typename T12, typename T13, typename T14, typename T15,
491    typename T16>
492class ValueArray16 {
493 public:
494  ValueArray16(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
495      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) : v1_(v1),
496      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
497      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
498      v16_(v16) {}
499
500  template <typename T>
501  operator ParamGenerator<T>() const {
502    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
503        v12_, v13_, v14_, v15_, v16_};
504    return ValuesIn(array);
505  }
506
507 private:
508  // No implementation - assignment is unsupported.
509  void operator=(const ValueArray16& other);
510
511  const T1 v1_;
512  const T2 v2_;
513  const T3 v3_;
514  const T4 v4_;
515  const T5 v5_;
516  const T6 v6_;
517  const T7 v7_;
518  const T8 v8_;
519  const T9 v9_;
520  const T10 v10_;
521  const T11 v11_;
522  const T12 v12_;
523  const T13 v13_;
524  const T14 v14_;
525  const T15 v15_;
526  const T16 v16_;
527};
528
529template <typename T1, typename T2, typename T3, typename T4, typename T5,
530    typename T6, typename T7, typename T8, typename T9, typename T10,
531    typename T11, typename T12, typename T13, typename T14, typename T15,
532    typename T16, typename T17>
533class ValueArray17 {
534 public:
535  ValueArray17(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
536      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16,
537      T17 v17) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
538      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
539      v15_(v15), v16_(v16), v17_(v17) {}
540
541  template <typename T>
542  operator ParamGenerator<T>() const {
543    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
544        v12_, v13_, v14_, v15_, v16_, v17_};
545    return ValuesIn(array);
546  }
547
548 private:
549  // No implementation - assignment is unsupported.
550  void operator=(const ValueArray17& other);
551
552  const T1 v1_;
553  const T2 v2_;
554  const T3 v3_;
555  const T4 v4_;
556  const T5 v5_;
557  const T6 v6_;
558  const T7 v7_;
559  const T8 v8_;
560  const T9 v9_;
561  const T10 v10_;
562  const T11 v11_;
563  const T12 v12_;
564  const T13 v13_;
565  const T14 v14_;
566  const T15 v15_;
567  const T16 v16_;
568  const T17 v17_;
569};
570
571template <typename T1, typename T2, typename T3, typename T4, typename T5,
572    typename T6, typename T7, typename T8, typename T9, typename T10,
573    typename T11, typename T12, typename T13, typename T14, typename T15,
574    typename T16, typename T17, typename T18>
575class ValueArray18 {
576 public:
577  ValueArray18(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
578      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
579      T18 v18) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
580      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
581      v15_(v15), v16_(v16), v17_(v17), v18_(v18) {}
582
583  template <typename T>
584  operator ParamGenerator<T>() const {
585    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
586        v12_, v13_, v14_, v15_, v16_, v17_, v18_};
587    return ValuesIn(array);
588  }
589
590 private:
591  // No implementation - assignment is unsupported.
592  void operator=(const ValueArray18& other);
593
594  const T1 v1_;
595  const T2 v2_;
596  const T3 v3_;
597  const T4 v4_;
598  const T5 v5_;
599  const T6 v6_;
600  const T7 v7_;
601  const T8 v8_;
602  const T9 v9_;
603  const T10 v10_;
604  const T11 v11_;
605  const T12 v12_;
606  const T13 v13_;
607  const T14 v14_;
608  const T15 v15_;
609  const T16 v16_;
610  const T17 v17_;
611  const T18 v18_;
612};
613
614template <typename T1, typename T2, typename T3, typename T4, typename T5,
615    typename T6, typename T7, typename T8, typename T9, typename T10,
616    typename T11, typename T12, typename T13, typename T14, typename T15,
617    typename T16, typename T17, typename T18, typename T19>
618class ValueArray19 {
619 public:
620  ValueArray19(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
621      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
622      T18 v18, T19 v19) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
623      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
624      v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19) {}
625
626  template <typename T>
627  operator ParamGenerator<T>() const {
628    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
629        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_};
630    return ValuesIn(array);
631  }
632
633 private:
634  // No implementation - assignment is unsupported.
635  void operator=(const ValueArray19& other);
636
637  const T1 v1_;
638  const T2 v2_;
639  const T3 v3_;
640  const T4 v4_;
641  const T5 v5_;
642  const T6 v6_;
643  const T7 v7_;
644  const T8 v8_;
645  const T9 v9_;
646  const T10 v10_;
647  const T11 v11_;
648  const T12 v12_;
649  const T13 v13_;
650  const T14 v14_;
651  const T15 v15_;
652  const T16 v16_;
653  const T17 v17_;
654  const T18 v18_;
655  const T19 v19_;
656};
657
658template <typename T1, typename T2, typename T3, typename T4, typename T5,
659    typename T6, typename T7, typename T8, typename T9, typename T10,
660    typename T11, typename T12, typename T13, typename T14, typename T15,
661    typename T16, typename T17, typename T18, typename T19, typename T20>
662class ValueArray20 {
663 public:
664  ValueArray20(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
665      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
666      T18 v18, T19 v19, T20 v20) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
667      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
668      v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
669      v19_(v19), v20_(v20) {}
670
671  template <typename T>
672  operator ParamGenerator<T>() const {
673    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
674        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_};
675    return ValuesIn(array);
676  }
677
678 private:
679  // No implementation - assignment is unsupported.
680  void operator=(const ValueArray20& other);
681
682  const T1 v1_;
683  const T2 v2_;
684  const T3 v3_;
685  const T4 v4_;
686  const T5 v5_;
687  const T6 v6_;
688  const T7 v7_;
689  const T8 v8_;
690  const T9 v9_;
691  const T10 v10_;
692  const T11 v11_;
693  const T12 v12_;
694  const T13 v13_;
695  const T14 v14_;
696  const T15 v15_;
697  const T16 v16_;
698  const T17 v17_;
699  const T18 v18_;
700  const T19 v19_;
701  const T20 v20_;
702};
703
704template <typename T1, typename T2, typename T3, typename T4, typename T5,
705    typename T6, typename T7, typename T8, typename T9, typename T10,
706    typename T11, typename T12, typename T13, typename T14, typename T15,
707    typename T16, typename T17, typename T18, typename T19, typename T20,
708    typename T21>
709class ValueArray21 {
710 public:
711  ValueArray21(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
712      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
713      T18 v18, T19 v19, T20 v20, T21 v21) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
714      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
715      v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
716      v18_(v18), v19_(v19), v20_(v20), v21_(v21) {}
717
718  template <typename T>
719  operator ParamGenerator<T>() const {
720    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
721        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_};
722    return ValuesIn(array);
723  }
724
725 private:
726  // No implementation - assignment is unsupported.
727  void operator=(const ValueArray21& other);
728
729  const T1 v1_;
730  const T2 v2_;
731  const T3 v3_;
732  const T4 v4_;
733  const T5 v5_;
734  const T6 v6_;
735  const T7 v7_;
736  const T8 v8_;
737  const T9 v9_;
738  const T10 v10_;
739  const T11 v11_;
740  const T12 v12_;
741  const T13 v13_;
742  const T14 v14_;
743  const T15 v15_;
744  const T16 v16_;
745  const T17 v17_;
746  const T18 v18_;
747  const T19 v19_;
748  const T20 v20_;
749  const T21 v21_;
750};
751
752template <typename T1, typename T2, typename T3, typename T4, typename T5,
753    typename T6, typename T7, typename T8, typename T9, typename T10,
754    typename T11, typename T12, typename T13, typename T14, typename T15,
755    typename T16, typename T17, typename T18, typename T19, typename T20,
756    typename T21, typename T22>
757class ValueArray22 {
758 public:
759  ValueArray22(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
760      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
761      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22) : v1_(v1), v2_(v2), v3_(v3),
762      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
763      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
764      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22) {}
765
766  template <typename T>
767  operator ParamGenerator<T>() const {
768    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
769        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_};
770    return ValuesIn(array);
771  }
772
773 private:
774  // No implementation - assignment is unsupported.
775  void operator=(const ValueArray22& other);
776
777  const T1 v1_;
778  const T2 v2_;
779  const T3 v3_;
780  const T4 v4_;
781  const T5 v5_;
782  const T6 v6_;
783  const T7 v7_;
784  const T8 v8_;
785  const T9 v9_;
786  const T10 v10_;
787  const T11 v11_;
788  const T12 v12_;
789  const T13 v13_;
790  const T14 v14_;
791  const T15 v15_;
792  const T16 v16_;
793  const T17 v17_;
794  const T18 v18_;
795  const T19 v19_;
796  const T20 v20_;
797  const T21 v21_;
798  const T22 v22_;
799};
800
801template <typename T1, typename T2, typename T3, typename T4, typename T5,
802    typename T6, typename T7, typename T8, typename T9, typename T10,
803    typename T11, typename T12, typename T13, typename T14, typename T15,
804    typename T16, typename T17, typename T18, typename T19, typename T20,
805    typename T21, typename T22, typename T23>
806class ValueArray23 {
807 public:
808  ValueArray23(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
809      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
810      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23) : v1_(v1), v2_(v2),
811      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
812      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
813      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
814      v23_(v23) {}
815
816  template <typename T>
817  operator ParamGenerator<T>() const {
818    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
819        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_,
820        v23_};
821    return ValuesIn(array);
822  }
823
824 private:
825  // No implementation - assignment is unsupported.
826  void operator=(const ValueArray23& other);
827
828  const T1 v1_;
829  const T2 v2_;
830  const T3 v3_;
831  const T4 v4_;
832  const T5 v5_;
833  const T6 v6_;
834  const T7 v7_;
835  const T8 v8_;
836  const T9 v9_;
837  const T10 v10_;
838  const T11 v11_;
839  const T12 v12_;
840  const T13 v13_;
841  const T14 v14_;
842  const T15 v15_;
843  const T16 v16_;
844  const T17 v17_;
845  const T18 v18_;
846  const T19 v19_;
847  const T20 v20_;
848  const T21 v21_;
849  const T22 v22_;
850  const T23 v23_;
851};
852
853template <typename T1, typename T2, typename T3, typename T4, typename T5,
854    typename T6, typename T7, typename T8, typename T9, typename T10,
855    typename T11, typename T12, typename T13, typename T14, typename T15,
856    typename T16, typename T17, typename T18, typename T19, typename T20,
857    typename T21, typename T22, typename T23, typename T24>
858class ValueArray24 {
859 public:
860  ValueArray24(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
861      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
862      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24) : v1_(v1),
863      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
864      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
865      v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
866      v22_(v22), v23_(v23), v24_(v24) {}
867
868  template <typename T>
869  operator ParamGenerator<T>() const {
870    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
871        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
872        v24_};
873    return ValuesIn(array);
874  }
875
876 private:
877  // No implementation - assignment is unsupported.
878  void operator=(const ValueArray24& other);
879
880  const T1 v1_;
881  const T2 v2_;
882  const T3 v3_;
883  const T4 v4_;
884  const T5 v5_;
885  const T6 v6_;
886  const T7 v7_;
887  const T8 v8_;
888  const T9 v9_;
889  const T10 v10_;
890  const T11 v11_;
891  const T12 v12_;
892  const T13 v13_;
893  const T14 v14_;
894  const T15 v15_;
895  const T16 v16_;
896  const T17 v17_;
897  const T18 v18_;
898  const T19 v19_;
899  const T20 v20_;
900  const T21 v21_;
901  const T22 v22_;
902  const T23 v23_;
903  const T24 v24_;
904};
905
906template <typename T1, typename T2, typename T3, typename T4, typename T5,
907    typename T6, typename T7, typename T8, typename T9, typename T10,
908    typename T11, typename T12, typename T13, typename T14, typename T15,
909    typename T16, typename T17, typename T18, typename T19, typename T20,
910    typename T21, typename T22, typename T23, typename T24, typename T25>
911class ValueArray25 {
912 public:
913  ValueArray25(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
914      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
915      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24,
916      T25 v25) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
917      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
918      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
919      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25) {}
920
921  template <typename T>
922  operator ParamGenerator<T>() const {
923    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
924        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
925        v24_, v25_};
926    return ValuesIn(array);
927  }
928
929 private:
930  // No implementation - assignment is unsupported.
931  void operator=(const ValueArray25& other);
932
933  const T1 v1_;
934  const T2 v2_;
935  const T3 v3_;
936  const T4 v4_;
937  const T5 v5_;
938  const T6 v6_;
939  const T7 v7_;
940  const T8 v8_;
941  const T9 v9_;
942  const T10 v10_;
943  const T11 v11_;
944  const T12 v12_;
945  const T13 v13_;
946  const T14 v14_;
947  const T15 v15_;
948  const T16 v16_;
949  const T17 v17_;
950  const T18 v18_;
951  const T19 v19_;
952  const T20 v20_;
953  const T21 v21_;
954  const T22 v22_;
955  const T23 v23_;
956  const T24 v24_;
957  const T25 v25_;
958};
959
960template <typename T1, typename T2, typename T3, typename T4, typename T5,
961    typename T6, typename T7, typename T8, typename T9, typename T10,
962    typename T11, typename T12, typename T13, typename T14, typename T15,
963    typename T16, typename T17, typename T18, typename T19, typename T20,
964    typename T21, typename T22, typename T23, typename T24, typename T25,
965    typename T26>
966class ValueArray26 {
967 public:
968  ValueArray26(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
969      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
970      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
971      T26 v26) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
972      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
973      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
974      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26) {}
975
976  template <typename T>
977  operator ParamGenerator<T>() const {
978    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
979        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
980        v24_, v25_, v26_};
981    return ValuesIn(array);
982  }
983
984 private:
985  // No implementation - assignment is unsupported.
986  void operator=(const ValueArray26& other);
987
988  const T1 v1_;
989  const T2 v2_;
990  const T3 v3_;
991  const T4 v4_;
992  const T5 v5_;
993  const T6 v6_;
994  const T7 v7_;
995  const T8 v8_;
996  const T9 v9_;
997  const T10 v10_;
998  const T11 v11_;
999  const T12 v12_;
1000  const T13 v13_;
1001  const T14 v14_;
1002  const T15 v15_;
1003  const T16 v16_;
1004  const T17 v17_;
1005  const T18 v18_;
1006  const T19 v19_;
1007  const T20 v20_;
1008  const T21 v21_;
1009  const T22 v22_;
1010  const T23 v23_;
1011  const T24 v24_;
1012  const T25 v25_;
1013  const T26 v26_;
1014};
1015
1016template <typename T1, typename T2, typename T3, typename T4, typename T5,
1017    typename T6, typename T7, typename T8, typename T9, typename T10,
1018    typename T11, typename T12, typename T13, typename T14, typename T15,
1019    typename T16, typename T17, typename T18, typename T19, typename T20,
1020    typename T21, typename T22, typename T23, typename T24, typename T25,
1021    typename T26, typename T27>
1022class ValueArray27 {
1023 public:
1024  ValueArray27(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
1025      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
1026      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
1027      T26 v26, T27 v27) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
1028      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
1029      v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),
1030      v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),
1031      v26_(v26), v27_(v27) {}
1032
1033  template <typename T>
1034  operator ParamGenerator<T>() const {
1035    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
1036        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
1037        v24_, v25_, v26_, v27_};
1038    return ValuesIn(array);
1039  }
1040
1041 private:
1042  // No implementation - assignment is unsupported.
1043  void operator=(const ValueArray27& other);
1044
1045  const T1 v1_;
1046  const T2 v2_;
1047  const T3 v3_;
1048  const T4 v4_;
1049  const T5 v5_;
1050  const T6 v6_;
1051  const T7 v7_;
1052  const T8 v8_;
1053  const T9 v9_;
1054  const T10 v10_;
1055  const T11 v11_;
1056  const T12 v12_;
1057  const T13 v13_;
1058  const T14 v14_;
1059  const T15 v15_;
1060  const T16 v16_;
1061  const T17 v17_;
1062  const T18 v18_;
1063  const T19 v19_;
1064  const T20 v20_;
1065  const T21 v21_;
1066  const T22 v22_;
1067  const T23 v23_;
1068  const T24 v24_;
1069  const T25 v25_;
1070  const T26 v26_;
1071  const T27 v27_;
1072};
1073
1074template <typename T1, typename T2, typename T3, typename T4, typename T5,
1075    typename T6, typename T7, typename T8, typename T9, typename T10,
1076    typename T11, typename T12, typename T13, typename T14, typename T15,
1077    typename T16, typename T17, typename T18, typename T19, typename T20,
1078    typename T21, typename T22, typename T23, typename T24, typename T25,
1079    typename T26, typename T27, typename T28>
1080class ValueArray28 {
1081 public:
1082  ValueArray28(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
1083      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
1084      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
1085      T26 v26, T27 v27, T28 v28) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
1086      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
1087      v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
1088      v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),
1089      v25_(v25), v26_(v26), v27_(v27), v28_(v28) {}
1090
1091  template <typename T>
1092  operator ParamGenerator<T>() const {
1093    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
1094        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
1095        v24_, v25_, v26_, v27_, v28_};
1096    return ValuesIn(array);
1097  }
1098
1099 private:
1100  // No implementation - assignment is unsupported.
1101  void operator=(const ValueArray28& other);
1102
1103  const T1 v1_;
1104  const T2 v2_;
1105  const T3 v3_;
1106  const T4 v4_;
1107  const T5 v5_;
1108  const T6 v6_;
1109  const T7 v7_;
1110  const T8 v8_;
1111  const T9 v9_;
1112  const T10 v10_;
1113  const T11 v11_;
1114  const T12 v12_;
1115  const T13 v13_;
1116  const T14 v14_;
1117  const T15 v15_;
1118  const T16 v16_;
1119  const T17 v17_;
1120  const T18 v18_;
1121  const T19 v19_;
1122  const T20 v20_;
1123  const T21 v21_;
1124  const T22 v22_;
1125  const T23 v23_;
1126  const T24 v24_;
1127  const T25 v25_;
1128  const T26 v26_;
1129  const T27 v27_;
1130  const T28 v28_;
1131};
1132
1133template <typename T1, typename T2, typename T3, typename T4, typename T5,
1134    typename T6, typename T7, typename T8, typename T9, typename T10,
1135    typename T11, typename T12, typename T13, typename T14, typename T15,
1136    typename T16, typename T17, typename T18, typename T19, typename T20,
1137    typename T21, typename T22, typename T23, typename T24, typename T25,
1138    typename T26, typename T27, typename T28, typename T29>
1139class ValueArray29 {
1140 public:
1141  ValueArray29(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
1142      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
1143      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
1144      T26 v26, T27 v27, T28 v28, T29 v29) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
1145      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
1146      v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
1147      v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),
1148      v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29) {}
1149
1150  template <typename T>
1151  operator ParamGenerator<T>() const {
1152    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
1153        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
1154        v24_, v25_, v26_, v27_, v28_, v29_};
1155    return ValuesIn(array);
1156  }
1157
1158 private:
1159  // No implementation - assignment is unsupported.
1160  void operator=(const ValueArray29& other);
1161
1162  const T1 v1_;
1163  const T2 v2_;
1164  const T3 v3_;
1165  const T4 v4_;
1166  const T5 v5_;
1167  const T6 v6_;
1168  const T7 v7_;
1169  const T8 v8_;
1170  const T9 v9_;
1171  const T10 v10_;
1172  const T11 v11_;
1173  const T12 v12_;
1174  const T13 v13_;
1175  const T14 v14_;
1176  const T15 v15_;
1177  const T16 v16_;
1178  const T17 v17_;
1179  const T18 v18_;
1180  const T19 v19_;
1181  const T20 v20_;
1182  const T21 v21_;
1183  const T22 v22_;
1184  const T23 v23_;
1185  const T24 v24_;
1186  const T25 v25_;
1187  const T26 v26_;
1188  const T27 v27_;
1189  const T28 v28_;
1190  const T29 v29_;
1191};
1192
1193template <typename T1, typename T2, typename T3, typename T4, typename T5,
1194    typename T6, typename T7, typename T8, typename T9, typename T10,
1195    typename T11, typename T12, typename T13, typename T14, typename T15,
1196    typename T16, typename T17, typename T18, typename T19, typename T20,
1197    typename T21, typename T22, typename T23, typename T24, typename T25,
1198    typename T26, typename T27, typename T28, typename T29, typename T30>
1199class ValueArray30 {
1200 public:
1201  ValueArray30(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
1202      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
1203      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
1204      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) : v1_(v1), v2_(v2), v3_(v3),
1205      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
1206      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
1207      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
1208      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
1209      v29_(v29), v30_(v30) {}
1210
1211  template <typename T>
1212  operator ParamGenerator<T>() const {
1213    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
1214        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
1215        v24_, v25_, v26_, v27_, v28_, v29_, v30_};
1216    return ValuesIn(array);
1217  }
1218
1219 private:
1220  // No implementation - assignment is unsupported.
1221  void operator=(const ValueArray30& other);
1222
1223  const T1 v1_;
1224  const T2 v2_;
1225  const T3 v3_;
1226  const T4 v4_;
1227  const T5 v5_;
1228  const T6 v6_;
1229  const T7 v7_;
1230  const T8 v8_;
1231  const T9 v9_;
1232  const T10 v10_;
1233  const T11 v11_;
1234  const T12 v12_;
1235  const T13 v13_;
1236  const T14 v14_;
1237  const T15 v15_;
1238  const T16 v16_;
1239  const T17 v17_;
1240  const T18 v18_;
1241  const T19 v19_;
1242  const T20 v20_;
1243  const T21 v21_;
1244  const T22 v22_;
1245  const T23 v23_;
1246  const T24 v24_;
1247  const T25 v25_;
1248  const T26 v26_;
1249  const T27 v27_;
1250  const T28 v28_;
1251  const T29 v29_;
1252  const T30 v30_;
1253};
1254
1255template <typename T1, typename T2, typename T3, typename T4, typename T5,
1256    typename T6, typename T7, typename T8, typename T9, typename T10,
1257    typename T11, typename T12, typename T13, typename T14, typename T15,
1258    typename T16, typename T17, typename T18, typename T19, typename T20,
1259    typename T21, typename T22, typename T23, typename T24, typename T25,
1260    typename T26, typename T27, typename T28, typename T29, typename T30,
1261    typename T31>
1262class ValueArray31 {
1263 public:
1264  ValueArray31(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
1265      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
1266      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
1267      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) : v1_(v1), v2_(v2),
1268      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
1269      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
1270      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
1271      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
1272      v29_(v29), v30_(v30), v31_(v31) {}
1273
1274  template <typename T>
1275  operator ParamGenerator<T>() const {
1276    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
1277        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
1278        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_};
1279    return ValuesIn(array);
1280  }
1281
1282 private:
1283  // No implementation - assignment is unsupported.
1284  void operator=(const ValueArray31& other);
1285
1286  const T1 v1_;
1287  const T2 v2_;
1288  const T3 v3_;
1289  const T4 v4_;
1290  const T5 v5_;
1291  const T6 v6_;
1292  const T7 v7_;
1293  const T8 v8_;
1294  const T9 v9_;
1295  const T10 v10_;
1296  const T11 v11_;
1297  const T12 v12_;
1298  const T13 v13_;
1299  const T14 v14_;
1300  const T15 v15_;
1301  const T16 v16_;
1302  const T17 v17_;
1303  const T18 v18_;
1304  const T19 v19_;
1305  const T20 v20_;
1306  const T21 v21_;
1307  const T22 v22_;
1308  const T23 v23_;
1309  const T24 v24_;
1310  const T25 v25_;
1311  const T26 v26_;
1312  const T27 v27_;
1313  const T28 v28_;
1314  const T29 v29_;
1315  const T30 v30_;
1316  const T31 v31_;
1317};
1318
1319template <typename T1, typename T2, typename T3, typename T4, typename T5,
1320    typename T6, typename T7, typename T8, typename T9, typename T10,
1321    typename T11, typename T12, typename T13, typename T14, typename T15,
1322    typename T16, typename T17, typename T18, typename T19, typename T20,
1323    typename T21, typename T22, typename T23, typename T24, typename T25,
1324    typename T26, typename T27, typename T28, typename T29, typename T30,
1325    typename T31, typename T32>
1326class ValueArray32 {
1327 public:
1328  ValueArray32(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
1329      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
1330      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
1331      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32) : v1_(v1),
1332      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
1333      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
1334      v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
1335      v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),
1336      v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32) {}
1337
1338  template <typename T>
1339  operator ParamGenerator<T>() const {
1340    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
1341        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
1342        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_};
1343    return ValuesIn(array);
1344  }
1345
1346 private:
1347  // No implementation - assignment is unsupported.
1348  void operator=(const ValueArray32& other);
1349
1350  const T1 v1_;
1351  const T2 v2_;
1352  const T3 v3_;
1353  const T4 v4_;
1354  const T5 v5_;
1355  const T6 v6_;
1356  const T7 v7_;
1357  const T8 v8_;
1358  const T9 v9_;
1359  const T10 v10_;
1360  const T11 v11_;
1361  const T12 v12_;
1362  const T13 v13_;
1363  const T14 v14_;
1364  const T15 v15_;
1365  const T16 v16_;
1366  const T17 v17_;
1367  const T18 v18_;
1368  const T19 v19_;
1369  const T20 v20_;
1370  const T21 v21_;
1371  const T22 v22_;
1372  const T23 v23_;
1373  const T24 v24_;
1374  const T25 v25_;
1375  const T26 v26_;
1376  const T27 v27_;
1377  const T28 v28_;
1378  const T29 v29_;
1379  const T30 v30_;
1380  const T31 v31_;
1381  const T32 v32_;
1382};
1383
1384template <typename T1, typename T2, typename T3, typename T4, typename T5,
1385    typename T6, typename T7, typename T8, typename T9, typename T10,
1386    typename T11, typename T12, typename T13, typename T14, typename T15,
1387    typename T16, typename T17, typename T18, typename T19, typename T20,
1388    typename T21, typename T22, typename T23, typename T24, typename T25,
1389    typename T26, typename T27, typename T28, typename T29, typename T30,
1390    typename T31, typename T32, typename T33>
1391class ValueArray33 {
1392 public:
1393  ValueArray33(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
1394      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
1395      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
1396      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32,
1397      T33 v33) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
1398      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
1399      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
1400      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
1401      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
1402      v33_(v33) {}
1403
1404  template <typename T>
1405  operator ParamGenerator<T>() const {
1406    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
1407        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
1408        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_};
1409    return ValuesIn(array);
1410  }
1411
1412 private:
1413  // No implementation - assignment is unsupported.
1414  void operator=(const ValueArray33& other);
1415
1416  const T1 v1_;
1417  const T2 v2_;
1418  const T3 v3_;
1419  const T4 v4_;
1420  const T5 v5_;
1421  const T6 v6_;
1422  const T7 v7_;
1423  const T8 v8_;
1424  const T9 v9_;
1425  const T10 v10_;
1426  const T11 v11_;
1427  const T12 v12_;
1428  const T13 v13_;
1429  const T14 v14_;
1430  const T15 v15_;
1431  const T16 v16_;
1432  const T17 v17_;
1433  const T18 v18_;
1434  const T19 v19_;
1435  const T20 v20_;
1436  const T21 v21_;
1437  const T22 v22_;
1438  const T23 v23_;
1439  const T24 v24_;
1440  const T25 v25_;
1441  const T26 v26_;
1442  const T27 v27_;
1443  const T28 v28_;
1444  const T29 v29_;
1445  const T30 v30_;
1446  const T31 v31_;
1447  const T32 v32_;
1448  const T33 v33_;
1449};
1450
1451template <typename T1, typename T2, typename T3, typename T4, typename T5,
1452    typename T6, typename T7, typename T8, typename T9, typename T10,
1453    typename T11, typename T12, typename T13, typename T14, typename T15,
1454    typename T16, typename T17, typename T18, typename T19, typename T20,
1455    typename T21, typename T22, typename T23, typename T24, typename T25,
1456    typename T26, typename T27, typename T28, typename T29, typename T30,
1457    typename T31, typename T32, typename T33, typename T34>
1458class ValueArray34 {
1459 public:
1460  ValueArray34(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
1461      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
1462      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
1463      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
1464      T34 v34) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
1465      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
1466      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
1467      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
1468      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
1469      v33_(v33), v34_(v34) {}
1470
1471  template <typename T>
1472  operator ParamGenerator<T>() const {
1473    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
1474        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
1475        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_};
1476    return ValuesIn(array);
1477  }
1478
1479 private:
1480  // No implementation - assignment is unsupported.
1481  void operator=(const ValueArray34& other);
1482
1483  const T1 v1_;
1484  const T2 v2_;
1485  const T3 v3_;
1486  const T4 v4_;
1487  const T5 v5_;
1488  const T6 v6_;
1489  const T7 v7_;
1490  const T8 v8_;
1491  const T9 v9_;
1492  const T10 v10_;
1493  const T11 v11_;
1494  const T12 v12_;
1495  const T13 v13_;
1496  const T14 v14_;
1497  const T15 v15_;
1498  const T16 v16_;
1499  const T17 v17_;
1500  const T18 v18_;
1501  const T19 v19_;
1502  const T20 v20_;
1503  const T21 v21_;
1504  const T22 v22_;
1505  const T23 v23_;
1506  const T24 v24_;
1507  const T25 v25_;
1508  const T26 v26_;
1509  const T27 v27_;
1510  const T28 v28_;
1511  const T29 v29_;
1512  const T30 v30_;
1513  const T31 v31_;
1514  const T32 v32_;
1515  const T33 v33_;
1516  const T34 v34_;
1517};
1518
1519template <typename T1, typename T2, typename T3, typename T4, typename T5,
1520    typename T6, typename T7, typename T8, typename T9, typename T10,
1521    typename T11, typename T12, typename T13, typename T14, typename T15,
1522    typename T16, typename T17, typename T18, typename T19, typename T20,
1523    typename T21, typename T22, typename T23, typename T24, typename T25,
1524    typename T26, typename T27, typename T28, typename T29, typename T30,
1525    typename T31, typename T32, typename T33, typename T34, typename T35>
1526class ValueArray35 {
1527 public:
1528  ValueArray35(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
1529      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
1530      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
1531      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
1532      T34 v34, T35 v35) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
1533      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
1534      v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),
1535      v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),
1536      v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31),
1537      v32_(v32), v33_(v33), v34_(v34), v35_(v35) {}
1538
1539  template <typename T>
1540  operator ParamGenerator<T>() const {
1541    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
1542        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
1543        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_,
1544        v35_};
1545    return ValuesIn(array);
1546  }
1547
1548 private:
1549  // No implementation - assignment is unsupported.
1550  void operator=(const ValueArray35& other);
1551
1552  const T1 v1_;
1553  const T2 v2_;
1554  const T3 v3_;
1555  const T4 v4_;
1556  const T5 v5_;
1557  const T6 v6_;
1558  const T7 v7_;
1559  const T8 v8_;
1560  const T9 v9_;
1561  const T10 v10_;
1562  const T11 v11_;
1563  const T12 v12_;
1564  const T13 v13_;
1565  const T14 v14_;
1566  const T15 v15_;
1567  const T16 v16_;
1568  const T17 v17_;
1569  const T18 v18_;
1570  const T19 v19_;
1571  const T20 v20_;
1572  const T21 v21_;
1573  const T22 v22_;
1574  const T23 v23_;
1575  const T24 v24_;
1576  const T25 v25_;
1577  const T26 v26_;
1578  const T27 v27_;
1579  const T28 v28_;
1580  const T29 v29_;
1581  const T30 v30_;
1582  const T31 v31_;
1583  const T32 v32_;
1584  const T33 v33_;
1585  const T34 v34_;
1586  const T35 v35_;
1587};
1588
1589template <typename T1, typename T2, typename T3, typename T4, typename T5,
1590    typename T6, typename T7, typename T8, typename T9, typename T10,
1591    typename T11, typename T12, typename T13, typename T14, typename T15,
1592    typename T16, typename T17, typename T18, typename T19, typename T20,
1593    typename T21, typename T22, typename T23, typename T24, typename T25,
1594    typename T26, typename T27, typename T28, typename T29, typename T30,
1595    typename T31, typename T32, typename T33, typename T34, typename T35,
1596    typename T36>
1597class ValueArray36 {
1598 public:
1599  ValueArray36(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
1600      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
1601      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
1602      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
1603      T34 v34, T35 v35, T36 v36) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
1604      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
1605      v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
1606      v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),
1607      v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30),
1608      v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36) {}
1609
1610  template <typename T>
1611  operator ParamGenerator<T>() const {
1612    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
1613        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
1614        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
1615        v36_};
1616    return ValuesIn(array);
1617  }
1618
1619 private:
1620  // No implementation - assignment is unsupported.
1621  void operator=(const ValueArray36& other);
1622
1623  const T1 v1_;
1624  const T2 v2_;
1625  const T3 v3_;
1626  const T4 v4_;
1627  const T5 v5_;
1628  const T6 v6_;
1629  const T7 v7_;
1630  const T8 v8_;
1631  const T9 v9_;
1632  const T10 v10_;
1633  const T11 v11_;
1634  const T12 v12_;
1635  const T13 v13_;
1636  const T14 v14_;
1637  const T15 v15_;
1638  const T16 v16_;
1639  const T17 v17_;
1640  const T18 v18_;
1641  const T19 v19_;
1642  const T20 v20_;
1643  const T21 v21_;
1644  const T22 v22_;
1645  const T23 v23_;
1646  const T24 v24_;
1647  const T25 v25_;
1648  const T26 v26_;
1649  const T27 v27_;
1650  const T28 v28_;
1651  const T29 v29_;
1652  const T30 v30_;
1653  const T31 v31_;
1654  const T32 v32_;
1655  const T33 v33_;
1656  const T34 v34_;
1657  const T35 v35_;
1658  const T36 v36_;
1659};
1660
1661template <typename T1, typename T2, typename T3, typename T4, typename T5,
1662    typename T6, typename T7, typename T8, typename T9, typename T10,
1663    typename T11, typename T12, typename T13, typename T14, typename T15,
1664    typename T16, typename T17, typename T18, typename T19, typename T20,
1665    typename T21, typename T22, typename T23, typename T24, typename T25,
1666    typename T26, typename T27, typename T28, typename T29, typename T30,
1667    typename T31, typename T32, typename T33, typename T34, typename T35,
1668    typename T36, typename T37>
1669class ValueArray37 {
1670 public:
1671  ValueArray37(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
1672      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
1673      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
1674      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
1675      T34 v34, T35 v35, T36 v36, T37 v37) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
1676      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
1677      v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
1678      v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),
1679      v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29),
1680      v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35),
1681      v36_(v36), v37_(v37) {}
1682
1683  template <typename T>
1684  operator ParamGenerator<T>() const {
1685    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
1686        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
1687        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
1688        v36_, v37_};
1689    return ValuesIn(array);
1690  }
1691
1692 private:
1693  // No implementation - assignment is unsupported.
1694  void operator=(const ValueArray37& other);
1695
1696  const T1 v1_;
1697  const T2 v2_;
1698  const T3 v3_;
1699  const T4 v4_;
1700  const T5 v5_;
1701  const T6 v6_;
1702  const T7 v7_;
1703  const T8 v8_;
1704  const T9 v9_;
1705  const T10 v10_;
1706  const T11 v11_;
1707  const T12 v12_;
1708  const T13 v13_;
1709  const T14 v14_;
1710  const T15 v15_;
1711  const T16 v16_;
1712  const T17 v17_;
1713  const T18 v18_;
1714  const T19 v19_;
1715  const T20 v20_;
1716  const T21 v21_;
1717  const T22 v22_;
1718  const T23 v23_;
1719  const T24 v24_;
1720  const T25 v25_;
1721  const T26 v26_;
1722  const T27 v27_;
1723  const T28 v28_;
1724  const T29 v29_;
1725  const T30 v30_;
1726  const T31 v31_;
1727  const T32 v32_;
1728  const T33 v33_;
1729  const T34 v34_;
1730  const T35 v35_;
1731  const T36 v36_;
1732  const T37 v37_;
1733};
1734
1735template <typename T1, typename T2, typename T3, typename T4, typename T5,
1736    typename T6, typename T7, typename T8, typename T9, typename T10,
1737    typename T11, typename T12, typename T13, typename T14, typename T15,
1738    typename T16, typename T17, typename T18, typename T19, typename T20,
1739    typename T21, typename T22, typename T23, typename T24, typename T25,
1740    typename T26, typename T27, typename T28, typename T29, typename T30,
1741    typename T31, typename T32, typename T33, typename T34, typename T35,
1742    typename T36, typename T37, typename T38>
1743class ValueArray38 {
1744 public:
1745  ValueArray38(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
1746      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
1747      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
1748      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
1749      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38) : v1_(v1), v2_(v2), v3_(v3),
1750      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
1751      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
1752      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
1753      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
1754      v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
1755      v35_(v35), v36_(v36), v37_(v37), v38_(v38) {}
1756
1757  template <typename T>
1758  operator ParamGenerator<T>() const {
1759    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
1760        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
1761        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
1762        v36_, v37_, v38_};
1763    return ValuesIn(array);
1764  }
1765
1766 private:
1767  // No implementation - assignment is unsupported.
1768  void operator=(const ValueArray38& other);
1769
1770  const T1 v1_;
1771  const T2 v2_;
1772  const T3 v3_;
1773  const T4 v4_;
1774  const T5 v5_;
1775  const T6 v6_;
1776  const T7 v7_;
1777  const T8 v8_;
1778  const T9 v9_;
1779  const T10 v10_;
1780  const T11 v11_;
1781  const T12 v12_;
1782  const T13 v13_;
1783  const T14 v14_;
1784  const T15 v15_;
1785  const T16 v16_;
1786  const T17 v17_;
1787  const T18 v18_;
1788  const T19 v19_;
1789  const T20 v20_;
1790  const T21 v21_;
1791  const T22 v22_;
1792  const T23 v23_;
1793  const T24 v24_;
1794  const T25 v25_;
1795  const T26 v26_;
1796  const T27 v27_;
1797  const T28 v28_;
1798  const T29 v29_;
1799  const T30 v30_;
1800  const T31 v31_;
1801  const T32 v32_;
1802  const T33 v33_;
1803  const T34 v34_;
1804  const T35 v35_;
1805  const T36 v36_;
1806  const T37 v37_;
1807  const T38 v38_;
1808};
1809
1810template <typename T1, typename T2, typename T3, typename T4, typename T5,
1811    typename T6, typename T7, typename T8, typename T9, typename T10,
1812    typename T11, typename T12, typename T13, typename T14, typename T15,
1813    typename T16, typename T17, typename T18, typename T19, typename T20,
1814    typename T21, typename T22, typename T23, typename T24, typename T25,
1815    typename T26, typename T27, typename T28, typename T29, typename T30,
1816    typename T31, typename T32, typename T33, typename T34, typename T35,
1817    typename T36, typename T37, typename T38, typename T39>
1818class ValueArray39 {
1819 public:
1820  ValueArray39(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
1821      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
1822      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
1823      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
1824      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39) : v1_(v1), v2_(v2),
1825      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
1826      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
1827      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
1828      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
1829      v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
1830      v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39) {}
1831
1832  template <typename T>
1833  operator ParamGenerator<T>() const {
1834    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
1835        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
1836        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
1837        v36_, v37_, v38_, v39_};
1838    return ValuesIn(array);
1839  }
1840
1841 private:
1842  // No implementation - assignment is unsupported.
1843  void operator=(const ValueArray39& other);
1844
1845  const T1 v1_;
1846  const T2 v2_;
1847  const T3 v3_;
1848  const T4 v4_;
1849  const T5 v5_;
1850  const T6 v6_;
1851  const T7 v7_;
1852  const T8 v8_;
1853  const T9 v9_;
1854  const T10 v10_;
1855  const T11 v11_;
1856  const T12 v12_;
1857  const T13 v13_;
1858  const T14 v14_;
1859  const T15 v15_;
1860  const T16 v16_;
1861  const T17 v17_;
1862  const T18 v18_;
1863  const T19 v19_;
1864  const T20 v20_;
1865  const T21 v21_;
1866  const T22 v22_;
1867  const T23 v23_;
1868  const T24 v24_;
1869  const T25 v25_;
1870  const T26 v26_;
1871  const T27 v27_;
1872  const T28 v28_;
1873  const T29 v29_;
1874  const T30 v30_;
1875  const T31 v31_;
1876  const T32 v32_;
1877  const T33 v33_;
1878  const T34 v34_;
1879  const T35 v35_;
1880  const T36 v36_;
1881  const T37 v37_;
1882  const T38 v38_;
1883  const T39 v39_;
1884};
1885
1886template <typename T1, typename T2, typename T3, typename T4, typename T5,
1887    typename T6, typename T7, typename T8, typename T9, typename T10,
1888    typename T11, typename T12, typename T13, typename T14, typename T15,
1889    typename T16, typename T17, typename T18, typename T19, typename T20,
1890    typename T21, typename T22, typename T23, typename T24, typename T25,
1891    typename T26, typename T27, typename T28, typename T29, typename T30,
1892    typename T31, typename T32, typename T33, typename T34, typename T35,
1893    typename T36, typename T37, typename T38, typename T39, typename T40>
1894class ValueArray40 {
1895 public:
1896  ValueArray40(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
1897      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
1898      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
1899      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
1900      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) : v1_(v1),
1901      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
1902      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
1903      v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
1904      v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),
1905      v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33),
1906      v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39),
1907      v40_(v40) {}
1908
1909  template <typename T>
1910  operator ParamGenerator<T>() const {
1911    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
1912        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
1913        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
1914        v36_, v37_, v38_, v39_, v40_};
1915    return ValuesIn(array);
1916  }
1917
1918 private:
1919  // No implementation - assignment is unsupported.
1920  void operator=(const ValueArray40& other);
1921
1922  const T1 v1_;
1923  const T2 v2_;
1924  const T3 v3_;
1925  const T4 v4_;
1926  const T5 v5_;
1927  const T6 v6_;
1928  const T7 v7_;
1929  const T8 v8_;
1930  const T9 v9_;
1931  const T10 v10_;
1932  const T11 v11_;
1933  const T12 v12_;
1934  const T13 v13_;
1935  const T14 v14_;
1936  const T15 v15_;
1937  const T16 v16_;
1938  const T17 v17_;
1939  const T18 v18_;
1940  const T19 v19_;
1941  const T20 v20_;
1942  const T21 v21_;
1943  const T22 v22_;
1944  const T23 v23_;
1945  const T24 v24_;
1946  const T25 v25_;
1947  const T26 v26_;
1948  const T27 v27_;
1949  const T28 v28_;
1950  const T29 v29_;
1951  const T30 v30_;
1952  const T31 v31_;
1953  const T32 v32_;
1954  const T33 v33_;
1955  const T34 v34_;
1956  const T35 v35_;
1957  const T36 v36_;
1958  const T37 v37_;
1959  const T38 v38_;
1960  const T39 v39_;
1961  const T40 v40_;
1962};
1963
1964template <typename T1, typename T2, typename T3, typename T4, typename T5,
1965    typename T6, typename T7, typename T8, typename T9, typename T10,
1966    typename T11, typename T12, typename T13, typename T14, typename T15,
1967    typename T16, typename T17, typename T18, typename T19, typename T20,
1968    typename T21, typename T22, typename T23, typename T24, typename T25,
1969    typename T26, typename T27, typename T28, typename T29, typename T30,
1970    typename T31, typename T32, typename T33, typename T34, typename T35,
1971    typename T36, typename T37, typename T38, typename T39, typename T40,
1972    typename T41>
1973class ValueArray41 {
1974 public:
1975  ValueArray41(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
1976      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
1977      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
1978      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
1979      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40,
1980      T41 v41) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
1981      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
1982      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
1983      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
1984      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
1985      v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
1986      v39_(v39), v40_(v40), v41_(v41) {}
1987
1988  template <typename T>
1989  operator ParamGenerator<T>() const {
1990    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
1991        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
1992        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
1993        v36_, v37_, v38_, v39_, v40_, v41_};
1994    return ValuesIn(array);
1995  }
1996
1997 private:
1998  // No implementation - assignment is unsupported.
1999  void operator=(const ValueArray41& other);
2000
2001  const T1 v1_;
2002  const T2 v2_;
2003  const T3 v3_;
2004  const T4 v4_;
2005  const T5 v5_;
2006  const T6 v6_;
2007  const T7 v7_;
2008  const T8 v8_;
2009  const T9 v9_;
2010  const T10 v10_;
2011  const T11 v11_;
2012  const T12 v12_;
2013  const T13 v13_;
2014  const T14 v14_;
2015  const T15 v15_;
2016  const T16 v16_;
2017  const T17 v17_;
2018  const T18 v18_;
2019  const T19 v19_;
2020  const T20 v20_;
2021  const T21 v21_;
2022  const T22 v22_;
2023  const T23 v23_;
2024  const T24 v24_;
2025  const T25 v25_;
2026  const T26 v26_;
2027  const T27 v27_;
2028  const T28 v28_;
2029  const T29 v29_;
2030  const T30 v30_;
2031  const T31 v31_;
2032  const T32 v32_;
2033  const T33 v33_;
2034  const T34 v34_;
2035  const T35 v35_;
2036  const T36 v36_;
2037  const T37 v37_;
2038  const T38 v38_;
2039  const T39 v39_;
2040  const T40 v40_;
2041  const T41 v41_;
2042};
2043
2044template <typename T1, typename T2, typename T3, typename T4, typename T5,
2045    typename T6, typename T7, typename T8, typename T9, typename T10,
2046    typename T11, typename T12, typename T13, typename T14, typename T15,
2047    typename T16, typename T17, typename T18, typename T19, typename T20,
2048    typename T21, typename T22, typename T23, typename T24, typename T25,
2049    typename T26, typename T27, typename T28, typename T29, typename T30,
2050    typename T31, typename T32, typename T33, typename T34, typename T35,
2051    typename T36, typename T37, typename T38, typename T39, typename T40,
2052    typename T41, typename T42>
2053class ValueArray42 {
2054 public:
2055  ValueArray42(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
2056      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
2057      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
2058      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
2059      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
2060      T42 v42) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
2061      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
2062      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
2063      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
2064      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
2065      v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
2066      v39_(v39), v40_(v40), v41_(v41), v42_(v42) {}
2067
2068  template <typename T>
2069  operator ParamGenerator<T>() const {
2070    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
2071        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
2072        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
2073        v36_, v37_, v38_, v39_, v40_, v41_, v42_};
2074    return ValuesIn(array);
2075  }
2076
2077 private:
2078  // No implementation - assignment is unsupported.
2079  void operator=(const ValueArray42& other);
2080
2081  const T1 v1_;
2082  const T2 v2_;
2083  const T3 v3_;
2084  const T4 v4_;
2085  const T5 v5_;
2086  const T6 v6_;
2087  const T7 v7_;
2088  const T8 v8_;
2089  const T9 v9_;
2090  const T10 v10_;
2091  const T11 v11_;
2092  const T12 v12_;
2093  const T13 v13_;
2094  const T14 v14_;
2095  const T15 v15_;
2096  const T16 v16_;
2097  const T17 v17_;
2098  const T18 v18_;
2099  const T19 v19_;
2100  const T20 v20_;
2101  const T21 v21_;
2102  const T22 v22_;
2103  const T23 v23_;
2104  const T24 v24_;
2105  const T25 v25_;
2106  const T26 v26_;
2107  const T27 v27_;
2108  const T28 v28_;
2109  const T29 v29_;
2110  const T30 v30_;
2111  const T31 v31_;
2112  const T32 v32_;
2113  const T33 v33_;
2114  const T34 v34_;
2115  const T35 v35_;
2116  const T36 v36_;
2117  const T37 v37_;
2118  const T38 v38_;
2119  const T39 v39_;
2120  const T40 v40_;
2121  const T41 v41_;
2122  const T42 v42_;
2123};
2124
2125template <typename T1, typename T2, typename T3, typename T4, typename T5,
2126    typename T6, typename T7, typename T8, typename T9, typename T10,
2127    typename T11, typename T12, typename T13, typename T14, typename T15,
2128    typename T16, typename T17, typename T18, typename T19, typename T20,
2129    typename T21, typename T22, typename T23, typename T24, typename T25,
2130    typename T26, typename T27, typename T28, typename T29, typename T30,
2131    typename T31, typename T32, typename T33, typename T34, typename T35,
2132    typename T36, typename T37, typename T38, typename T39, typename T40,
2133    typename T41, typename T42, typename T43>
2134class ValueArray43 {
2135 public:
2136  ValueArray43(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
2137      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
2138      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
2139      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
2140      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
2141      T42 v42, T43 v43) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
2142      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
2143      v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),
2144      v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),
2145      v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31),
2146      v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37),
2147      v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43) {}
2148
2149  template <typename T>
2150  operator ParamGenerator<T>() const {
2151    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
2152        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
2153        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
2154        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_};
2155    return ValuesIn(array);
2156  }
2157
2158 private:
2159  // No implementation - assignment is unsupported.
2160  void operator=(const ValueArray43& other);
2161
2162  const T1 v1_;
2163  const T2 v2_;
2164  const T3 v3_;
2165  const T4 v4_;
2166  const T5 v5_;
2167  const T6 v6_;
2168  const T7 v7_;
2169  const T8 v8_;
2170  const T9 v9_;
2171  const T10 v10_;
2172  const T11 v11_;
2173  const T12 v12_;
2174  const T13 v13_;
2175  const T14 v14_;
2176  const T15 v15_;
2177  const T16 v16_;
2178  const T17 v17_;
2179  const T18 v18_;
2180  const T19 v19_;
2181  const T20 v20_;
2182  const T21 v21_;
2183  const T22 v22_;
2184  const T23 v23_;
2185  const T24 v24_;
2186  const T25 v25_;
2187  const T26 v26_;
2188  const T27 v27_;
2189  const T28 v28_;
2190  const T29 v29_;
2191  const T30 v30_;
2192  const T31 v31_;
2193  const T32 v32_;
2194  const T33 v33_;
2195  const T34 v34_;
2196  const T35 v35_;
2197  const T36 v36_;
2198  const T37 v37_;
2199  const T38 v38_;
2200  const T39 v39_;
2201  const T40 v40_;
2202  const T41 v41_;
2203  const T42 v42_;
2204  const T43 v43_;
2205};
2206
2207template <typename T1, typename T2, typename T3, typename T4, typename T5,
2208    typename T6, typename T7, typename T8, typename T9, typename T10,
2209    typename T11, typename T12, typename T13, typename T14, typename T15,
2210    typename T16, typename T17, typename T18, typename T19, typename T20,
2211    typename T21, typename T22, typename T23, typename T24, typename T25,
2212    typename T26, typename T27, typename T28, typename T29, typename T30,
2213    typename T31, typename T32, typename T33, typename T34, typename T35,
2214    typename T36, typename T37, typename T38, typename T39, typename T40,
2215    typename T41, typename T42, typename T43, typename T44>
2216class ValueArray44 {
2217 public:
2218  ValueArray44(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
2219      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
2220      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
2221      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
2222      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
2223      T42 v42, T43 v43, T44 v44) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
2224      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
2225      v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
2226      v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),
2227      v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30),
2228      v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36),
2229      v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42),
2230      v43_(v43), v44_(v44) {}
2231
2232  template <typename T>
2233  operator ParamGenerator<T>() const {
2234    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
2235        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
2236        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
2237        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_};
2238    return ValuesIn(array);
2239  }
2240
2241 private:
2242  // No implementation - assignment is unsupported.
2243  void operator=(const ValueArray44& other);
2244
2245  const T1 v1_;
2246  const T2 v2_;
2247  const T3 v3_;
2248  const T4 v4_;
2249  const T5 v5_;
2250  const T6 v6_;
2251  const T7 v7_;
2252  const T8 v8_;
2253  const T9 v9_;
2254  const T10 v10_;
2255  const T11 v11_;
2256  const T12 v12_;
2257  const T13 v13_;
2258  const T14 v14_;
2259  const T15 v15_;
2260  const T16 v16_;
2261  const T17 v17_;
2262  const T18 v18_;
2263  const T19 v19_;
2264  const T20 v20_;
2265  const T21 v21_;
2266  const T22 v22_;
2267  const T23 v23_;
2268  const T24 v24_;
2269  const T25 v25_;
2270  const T26 v26_;
2271  const T27 v27_;
2272  const T28 v28_;
2273  const T29 v29_;
2274  const T30 v30_;
2275  const T31 v31_;
2276  const T32 v32_;
2277  const T33 v33_;
2278  const T34 v34_;
2279  const T35 v35_;
2280  const T36 v36_;
2281  const T37 v37_;
2282  const T38 v38_;
2283  const T39 v39_;
2284  const T40 v40_;
2285  const T41 v41_;
2286  const T42 v42_;
2287  const T43 v43_;
2288  const T44 v44_;
2289};
2290
2291template <typename T1, typename T2, typename T3, typename T4, typename T5,
2292    typename T6, typename T7, typename T8, typename T9, typename T10,
2293    typename T11, typename T12, typename T13, typename T14, typename T15,
2294    typename T16, typename T17, typename T18, typename T19, typename T20,
2295    typename T21, typename T22, typename T23, typename T24, typename T25,
2296    typename T26, typename T27, typename T28, typename T29, typename T30,
2297    typename T31, typename T32, typename T33, typename T34, typename T35,
2298    typename T36, typename T37, typename T38, typename T39, typename T40,
2299    typename T41, typename T42, typename T43, typename T44, typename T45>
2300class ValueArray45 {
2301 public:
2302  ValueArray45(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
2303      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
2304      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
2305      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
2306      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
2307      T42 v42, T43 v43, T44 v44, T45 v45) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
2308      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
2309      v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
2310      v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),
2311      v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29),
2312      v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35),
2313      v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41),
2314      v42_(v42), v43_(v43), v44_(v44), v45_(v45) {}
2315
2316  template <typename T>
2317  operator ParamGenerator<T>() const {
2318    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
2319        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
2320        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
2321        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_};
2322    return ValuesIn(array);
2323  }
2324
2325 private:
2326  // No implementation - assignment is unsupported.
2327  void operator=(const ValueArray45& other);
2328
2329  const T1 v1_;
2330  const T2 v2_;
2331  const T3 v3_;
2332  const T4 v4_;
2333  const T5 v5_;
2334  const T6 v6_;
2335  const T7 v7_;
2336  const T8 v8_;
2337  const T9 v9_;
2338  const T10 v10_;
2339  const T11 v11_;
2340  const T12 v12_;
2341  const T13 v13_;
2342  const T14 v14_;
2343  const T15 v15_;
2344  const T16 v16_;
2345  const T17 v17_;
2346  const T18 v18_;
2347  const T19 v19_;
2348  const T20 v20_;
2349  const T21 v21_;
2350  const T22 v22_;
2351  const T23 v23_;
2352  const T24 v24_;
2353  const T25 v25_;
2354  const T26 v26_;
2355  const T27 v27_;
2356  const T28 v28_;
2357  const T29 v29_;
2358  const T30 v30_;
2359  const T31 v31_;
2360  const T32 v32_;
2361  const T33 v33_;
2362  const T34 v34_;
2363  const T35 v35_;
2364  const T36 v36_;
2365  const T37 v37_;
2366  const T38 v38_;
2367  const T39 v39_;
2368  const T40 v40_;
2369  const T41 v41_;
2370  const T42 v42_;
2371  const T43 v43_;
2372  const T44 v44_;
2373  const T45 v45_;
2374};
2375
2376template <typename T1, typename T2, typename T3, typename T4, typename T5,
2377    typename T6, typename T7, typename T8, typename T9, typename T10,
2378    typename T11, typename T12, typename T13, typename T14, typename T15,
2379    typename T16, typename T17, typename T18, typename T19, typename T20,
2380    typename T21, typename T22, typename T23, typename T24, typename T25,
2381    typename T26, typename T27, typename T28, typename T29, typename T30,
2382    typename T31, typename T32, typename T33, typename T34, typename T35,
2383    typename T36, typename T37, typename T38, typename T39, typename T40,
2384    typename T41, typename T42, typename T43, typename T44, typename T45,
2385    typename T46>
2386class ValueArray46 {
2387 public:
2388  ValueArray46(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
2389      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
2390      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
2391      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
2392      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
2393      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) : v1_(v1), v2_(v2), v3_(v3),
2394      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
2395      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
2396      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
2397      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
2398      v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
2399      v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40),
2400      v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46) {}
2401
2402  template <typename T>
2403  operator ParamGenerator<T>() const {
2404    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
2405        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
2406        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
2407        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_};
2408    return ValuesIn(array);
2409  }
2410
2411 private:
2412  // No implementation - assignment is unsupported.
2413  void operator=(const ValueArray46& other);
2414
2415  const T1 v1_;
2416  const T2 v2_;
2417  const T3 v3_;
2418  const T4 v4_;
2419  const T5 v5_;
2420  const T6 v6_;
2421  const T7 v7_;
2422  const T8 v8_;
2423  const T9 v9_;
2424  const T10 v10_;
2425  const T11 v11_;
2426  const T12 v12_;
2427  const T13 v13_;
2428  const T14 v14_;
2429  const T15 v15_;
2430  const T16 v16_;
2431  const T17 v17_;
2432  const T18 v18_;
2433  const T19 v19_;
2434  const T20 v20_;
2435  const T21 v21_;
2436  const T22 v22_;
2437  const T23 v23_;
2438  const T24 v24_;
2439  const T25 v25_;
2440  const T26 v26_;
2441  const T27 v27_;
2442  const T28 v28_;
2443  const T29 v29_;
2444  const T30 v30_;
2445  const T31 v31_;
2446  const T32 v32_;
2447  const T33 v33_;
2448  const T34 v34_;
2449  const T35 v35_;
2450  const T36 v36_;
2451  const T37 v37_;
2452  const T38 v38_;
2453  const T39 v39_;
2454  const T40 v40_;
2455  const T41 v41_;
2456  const T42 v42_;
2457  const T43 v43_;
2458  const T44 v44_;
2459  const T45 v45_;
2460  const T46 v46_;
2461};
2462
2463template <typename T1, typename T2, typename T3, typename T4, typename T5,
2464    typename T6, typename T7, typename T8, typename T9, typename T10,
2465    typename T11, typename T12, typename T13, typename T14, typename T15,
2466    typename T16, typename T17, typename T18, typename T19, typename T20,
2467    typename T21, typename T22, typename T23, typename T24, typename T25,
2468    typename T26, typename T27, typename T28, typename T29, typename T30,
2469    typename T31, typename T32, typename T33, typename T34, typename T35,
2470    typename T36, typename T37, typename T38, typename T39, typename T40,
2471    typename T41, typename T42, typename T43, typename T44, typename T45,
2472    typename T46, typename T47>
2473class ValueArray47 {
2474 public:
2475  ValueArray47(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
2476      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
2477      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
2478      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
2479      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
2480      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) : v1_(v1), v2_(v2),
2481      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
2482      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
2483      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
2484      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
2485      v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
2486      v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40),
2487      v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46),
2488      v47_(v47) {}
2489
2490  template <typename T>
2491  operator ParamGenerator<T>() const {
2492    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
2493        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
2494        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
2495        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_,
2496        v47_};
2497    return ValuesIn(array);
2498  }
2499
2500 private:
2501  // No implementation - assignment is unsupported.
2502  void operator=(const ValueArray47& other);
2503
2504  const T1 v1_;
2505  const T2 v2_;
2506  const T3 v3_;
2507  const T4 v4_;
2508  const T5 v5_;
2509  const T6 v6_;
2510  const T7 v7_;
2511  const T8 v8_;
2512  const T9 v9_;
2513  const T10 v10_;
2514  const T11 v11_;
2515  const T12 v12_;
2516  const T13 v13_;
2517  const T14 v14_;
2518  const T15 v15_;
2519  const T16 v16_;
2520  const T17 v17_;
2521  const T18 v18_;
2522  const T19 v19_;
2523  const T20 v20_;
2524  const T21 v21_;
2525  const T22 v22_;
2526  const T23 v23_;
2527  const T24 v24_;
2528  const T25 v25_;
2529  const T26 v26_;
2530  const T27 v27_;
2531  const T28 v28_;
2532  const T29 v29_;
2533  const T30 v30_;
2534  const T31 v31_;
2535  const T32 v32_;
2536  const T33 v33_;
2537  const T34 v34_;
2538  const T35 v35_;
2539  const T36 v36_;
2540  const T37 v37_;
2541  const T38 v38_;
2542  const T39 v39_;
2543  const T40 v40_;
2544  const T41 v41_;
2545  const T42 v42_;
2546  const T43 v43_;
2547  const T44 v44_;
2548  const T45 v45_;
2549  const T46 v46_;
2550  const T47 v47_;
2551};
2552
2553template <typename T1, typename T2, typename T3, typename T4, typename T5,
2554    typename T6, typename T7, typename T8, typename T9, typename T10,
2555    typename T11, typename T12, typename T13, typename T14, typename T15,
2556    typename T16, typename T17, typename T18, typename T19, typename T20,
2557    typename T21, typename T22, typename T23, typename T24, typename T25,
2558    typename T26, typename T27, typename T28, typename T29, typename T30,
2559    typename T31, typename T32, typename T33, typename T34, typename T35,
2560    typename T36, typename T37, typename T38, typename T39, typename T40,
2561    typename T41, typename T42, typename T43, typename T44, typename T45,
2562    typename T46, typename T47, typename T48>
2563class ValueArray48 {
2564 public:
2565  ValueArray48(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
2566      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
2567      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
2568      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
2569      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
2570      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48) : v1_(v1),
2571      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
2572      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
2573      v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
2574      v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),
2575      v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33),
2576      v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39),
2577      v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45),
2578      v46_(v46), v47_(v47), v48_(v48) {}
2579
2580  template <typename T>
2581  operator ParamGenerator<T>() const {
2582    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
2583        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
2584        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
2585        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_,
2586        v48_};
2587    return ValuesIn(array);
2588  }
2589
2590 private:
2591  // No implementation - assignment is unsupported.
2592  void operator=(const ValueArray48& other);
2593
2594  const T1 v1_;
2595  const T2 v2_;
2596  const T3 v3_;
2597  const T4 v4_;
2598  const T5 v5_;
2599  const T6 v6_;
2600  const T7 v7_;
2601  const T8 v8_;
2602  const T9 v9_;
2603  const T10 v10_;
2604  const T11 v11_;
2605  const T12 v12_;
2606  const T13 v13_;
2607  const T14 v14_;
2608  const T15 v15_;
2609  const T16 v16_;
2610  const T17 v17_;
2611  const T18 v18_;
2612  const T19 v19_;
2613  const T20 v20_;
2614  const T21 v21_;
2615  const T22 v22_;
2616  const T23 v23_;
2617  const T24 v24_;
2618  const T25 v25_;
2619  const T26 v26_;
2620  const T27 v27_;
2621  const T28 v28_;
2622  const T29 v29_;
2623  const T30 v30_;
2624  const T31 v31_;
2625  const T32 v32_;
2626  const T33 v33_;
2627  const T34 v34_;
2628  const T35 v35_;
2629  const T36 v36_;
2630  const T37 v37_;
2631  const T38 v38_;
2632  const T39 v39_;
2633  const T40 v40_;
2634  const T41 v41_;
2635  const T42 v42_;
2636  const T43 v43_;
2637  const T44 v44_;
2638  const T45 v45_;
2639  const T46 v46_;
2640  const T47 v47_;
2641  const T48 v48_;
2642};
2643
2644template <typename T1, typename T2, typename T3, typename T4, typename T5,
2645    typename T6, typename T7, typename T8, typename T9, typename T10,
2646    typename T11, typename T12, typename T13, typename T14, typename T15,
2647    typename T16, typename T17, typename T18, typename T19, typename T20,
2648    typename T21, typename T22, typename T23, typename T24, typename T25,
2649    typename T26, typename T27, typename T28, typename T29, typename T30,
2650    typename T31, typename T32, typename T33, typename T34, typename T35,
2651    typename T36, typename T37, typename T38, typename T39, typename T40,
2652    typename T41, typename T42, typename T43, typename T44, typename T45,
2653    typename T46, typename T47, typename T48, typename T49>
2654class ValueArray49 {
2655 public:
2656  ValueArray49(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
2657      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
2658      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
2659      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
2660      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
2661      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48,
2662      T49 v49) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
2663      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
2664      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
2665      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
2666      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
2667      v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
2668      v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44),
2669      v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49) {}
2670
2671  template <typename T>
2672  operator ParamGenerator<T>() const {
2673    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
2674        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
2675        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
2676        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_,
2677        v48_, v49_};
2678    return ValuesIn(array);
2679  }
2680
2681 private:
2682  // No implementation - assignment is unsupported.
2683  void operator=(const ValueArray49& other);
2684
2685  const T1 v1_;
2686  const T2 v2_;
2687  const T3 v3_;
2688  const T4 v4_;
2689  const T5 v5_;
2690  const T6 v6_;
2691  const T7 v7_;
2692  const T8 v8_;
2693  const T9 v9_;
2694  const T10 v10_;
2695  const T11 v11_;
2696  const T12 v12_;
2697  const T13 v13_;
2698  const T14 v14_;
2699  const T15 v15_;
2700  const T16 v16_;
2701  const T17 v17_;
2702  const T18 v18_;
2703  const T19 v19_;
2704  const T20 v20_;
2705  const T21 v21_;
2706  const T22 v22_;
2707  const T23 v23_;
2708  const T24 v24_;
2709  const T25 v25_;
2710  const T26 v26_;
2711  const T27 v27_;
2712  const T28 v28_;
2713  const T29 v29_;
2714  const T30 v30_;
2715  const T31 v31_;
2716  const T32 v32_;
2717  const T33 v33_;
2718  const T34 v34_;
2719  const T35 v35_;
2720  const T36 v36_;
2721  const T37 v37_;
2722  const T38 v38_;
2723  const T39 v39_;
2724  const T40 v40_;
2725  const T41 v41_;
2726  const T42 v42_;
2727  const T43 v43_;
2728  const T44 v44_;
2729  const T45 v45_;
2730  const T46 v46_;
2731  const T47 v47_;
2732  const T48 v48_;
2733  const T49 v49_;
2734};
2735
2736template <typename T1, typename T2, typename T3, typename T4, typename T5,
2737    typename T6, typename T7, typename T8, typename T9, typename T10,
2738    typename T11, typename T12, typename T13, typename T14, typename T15,
2739    typename T16, typename T17, typename T18, typename T19, typename T20,
2740    typename T21, typename T22, typename T23, typename T24, typename T25,
2741    typename T26, typename T27, typename T28, typename T29, typename T30,
2742    typename T31, typename T32, typename T33, typename T34, typename T35,
2743    typename T36, typename T37, typename T38, typename T39, typename T40,
2744    typename T41, typename T42, typename T43, typename T44, typename T45,
2745    typename T46, typename T47, typename T48, typename T49, typename T50>
2746class ValueArray50 {
2747 public:
2748  ValueArray50(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
2749      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
2750      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
2751      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
2752      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
2753      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49,
2754      T50 v50) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
2755      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
2756      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
2757      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
2758      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
2759      v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
2760      v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44),
2761      v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49), v50_(v50) {}
2762
2763  template <typename T>
2764  operator ParamGenerator<T>() const {
2765    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
2766        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
2767        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
2768        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_,
2769        v48_, v49_, v50_};
2770    return ValuesIn(array);
2771  }
2772
2773 private:
2774  // No implementation - assignment is unsupported.
2775  void operator=(const ValueArray50& other);
2776
2777  const T1 v1_;
2778  const T2 v2_;
2779  const T3 v3_;
2780  const T4 v4_;
2781  const T5 v5_;
2782  const T6 v6_;
2783  const T7 v7_;
2784  const T8 v8_;
2785  const T9 v9_;
2786  const T10 v10_;
2787  const T11 v11_;
2788  const T12 v12_;
2789  const T13 v13_;
2790  const T14 v14_;
2791  const T15 v15_;
2792  const T16 v16_;
2793  const T17 v17_;
2794  const T18 v18_;
2795  const T19 v19_;
2796  const T20 v20_;
2797  const T21 v21_;
2798  const T22 v22_;
2799  const T23 v23_;
2800  const T24 v24_;
2801  const T25 v25_;
2802  const T26 v26_;
2803  const T27 v27_;
2804  const T28 v28_;
2805  const T29 v29_;
2806  const T30 v30_;
2807  const T31 v31_;
2808  const T32 v32_;
2809  const T33 v33_;
2810  const T34 v34_;
2811  const T35 v35_;
2812  const T36 v36_;
2813  const T37 v37_;
2814  const T38 v38_;
2815  const T39 v39_;
2816  const T40 v40_;
2817  const T41 v41_;
2818  const T42 v42_;
2819  const T43 v43_;
2820  const T44 v44_;
2821  const T45 v45_;
2822  const T46 v46_;
2823  const T47 v47_;
2824  const T48 v48_;
2825  const T49 v49_;
2826  const T50 v50_;
2827};
2828
2829#if GTEST_HAS_COMBINE
2830// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
2831//
2832// Generates values from the Cartesian product of values produced
2833// by the argument generators.
2834//
2835template <typename T1, typename T2>
2836class CartesianProductGenerator2
2837    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2> > {
2838 public:
2839  typedef ::std::tr1::tuple<T1, T2> ParamType;
2840
2841  CartesianProductGenerator2(const ParamGenerator<T1>& g1,
2842      const ParamGenerator<T2>& g2)
2843      : g1_(g1), g2_(g2) {}
2844  virtual ~CartesianProductGenerator2() {}
2845
2846  virtual ParamIteratorInterface<ParamType>* Begin() const {
2847    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin());
2848  }
2849  virtual ParamIteratorInterface<ParamType>* End() const {
2850    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end());
2851  }
2852
2853 private:
2854  class Iterator : public ParamIteratorInterface<ParamType> {
2855   public:
2856    Iterator(const ParamGeneratorInterface<ParamType>* base,
2857      const ParamGenerator<T1>& g1,
2858      const typename ParamGenerator<T1>::iterator& current1,
2859      const ParamGenerator<T2>& g2,
2860      const typename ParamGenerator<T2>::iterator& current2)
2861        : base_(base),
2862          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
2863          begin2_(g2.begin()), end2_(g2.end()), current2_(current2)    {
2864      ComputeCurrentValue();
2865    }
2866    virtual ~Iterator() {}
2867
2868    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
2869      return base_;
2870    }
2871    // Advance should not be called on beyond-of-range iterators
2872    // so no component iterators must be beyond end of range, either.
2873    virtual void Advance() {
2874      assert(!AtEnd());
2875      ++current2_;
2876      if (current2_ == end2_) {
2877        current2_ = begin2_;
2878        ++current1_;
2879      }
2880      ComputeCurrentValue();
2881    }
2882    virtual ParamIteratorInterface<ParamType>* Clone() const {
2883      return new Iterator(*this);
2884    }
2885    virtual const ParamType* Current() const { return &current_value_; }
2886    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
2887      // Having the same base generator guarantees that the other
2888      // iterator is of the same type and we can downcast.
2889      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
2890          << "The program attempted to compare iterators "
2891          << "from different generators." << std::endl;
2892      const Iterator* typed_other =
2893          CheckedDowncastToActualType<const Iterator>(&other);
2894      // We must report iterators equal if they both point beyond their
2895      // respective ranges. That can happen in a variety of fashions,
2896      // so we have to consult AtEnd().
2897      return (AtEnd() && typed_other->AtEnd()) ||
2898         (
2899          current1_ == typed_other->current1_ &&
2900          current2_ == typed_other->current2_);
2901    }
2902
2903   private:
2904    Iterator(const Iterator& other)
2905        : base_(other.base_),
2906        begin1_(other.begin1_),
2907        end1_(other.end1_),
2908        current1_(other.current1_),
2909        begin2_(other.begin2_),
2910        end2_(other.end2_),
2911        current2_(other.current2_) {
2912      ComputeCurrentValue();
2913    }
2914
2915    void ComputeCurrentValue() {
2916      if (!AtEnd())
2917        current_value_ = ParamType(*current1_, *current2_);
2918    }
2919    bool AtEnd() const {
2920      // We must report iterator past the end of the range when either of the
2921      // component iterators has reached the end of its range.
2922      return
2923          current1_ == end1_ ||
2924          current2_ == end2_;
2925    }
2926
2927    // No implementation - assignment is unsupported.
2928    void operator=(const Iterator& other);
2929
2930    const ParamGeneratorInterface<ParamType>* const base_;
2931    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
2932    // current[i]_ is the actual traversing iterator.
2933    const typename ParamGenerator<T1>::iterator begin1_;
2934    const typename ParamGenerator<T1>::iterator end1_;
2935    typename ParamGenerator<T1>::iterator current1_;
2936    const typename ParamGenerator<T2>::iterator begin2_;
2937    const typename ParamGenerator<T2>::iterator end2_;
2938    typename ParamGenerator<T2>::iterator current2_;
2939    ParamType current_value_;
2940  };  // class CartesianProductGenerator2::Iterator
2941
2942  // No implementation - assignment is unsupported.
2943  void operator=(const CartesianProductGenerator2& other);
2944
2945  const ParamGenerator<T1> g1_;
2946  const ParamGenerator<T2> g2_;
2947};  // class CartesianProductGenerator2
2948
2949
2950template <typename T1, typename T2, typename T3>
2951class CartesianProductGenerator3
2952    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3> > {
2953 public:
2954  typedef ::std::tr1::tuple<T1, T2, T3> ParamType;
2955
2956  CartesianProductGenerator3(const ParamGenerator<T1>& g1,
2957      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3)
2958      : g1_(g1), g2_(g2), g3_(g3) {}
2959  virtual ~CartesianProductGenerator3() {}
2960
2961  virtual ParamIteratorInterface<ParamType>* Begin() const {
2962    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
2963        g3_.begin());
2964  }
2965  virtual ParamIteratorInterface<ParamType>* End() const {
2966    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end());
2967  }
2968
2969 private:
2970  class Iterator : public ParamIteratorInterface<ParamType> {
2971   public:
2972    Iterator(const ParamGeneratorInterface<ParamType>* base,
2973      const ParamGenerator<T1>& g1,
2974      const typename ParamGenerator<T1>::iterator& current1,
2975      const ParamGenerator<T2>& g2,
2976      const typename ParamGenerator<T2>::iterator& current2,
2977      const ParamGenerator<T3>& g3,
2978      const typename ParamGenerator<T3>::iterator& current3)
2979        : base_(base),
2980          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
2981          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
2982          begin3_(g3.begin()), end3_(g3.end()), current3_(current3)    {
2983      ComputeCurrentValue();
2984    }
2985    virtual ~Iterator() {}
2986
2987    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
2988      return base_;
2989    }
2990    // Advance should not be called on beyond-of-range iterators
2991    // so no component iterators must be beyond end of range, either.
2992    virtual void Advance() {
2993      assert(!AtEnd());
2994      ++current3_;
2995      if (current3_ == end3_) {
2996        current3_ = begin3_;
2997        ++current2_;
2998      }
2999      if (current2_ == end2_) {
3000        current2_ = begin2_;
3001        ++current1_;
3002      }
3003      ComputeCurrentValue();
3004    }
3005    virtual ParamIteratorInterface<ParamType>* Clone() const {
3006      return new Iterator(*this);
3007    }
3008    virtual const ParamType* Current() const { return &current_value_; }
3009    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
3010      // Having the same base generator guarantees that the other
3011      // iterator is of the same type and we can downcast.
3012      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
3013          << "The program attempted to compare iterators "
3014          << "from different generators." << std::endl;
3015      const Iterator* typed_other =
3016          CheckedDowncastToActualType<const Iterator>(&other);
3017      // We must report iterators equal if they both point beyond their
3018      // respective ranges. That can happen in a variety of fashions,
3019      // so we have to consult AtEnd().
3020      return (AtEnd() && typed_other->AtEnd()) ||
3021         (
3022          current1_ == typed_other->current1_ &&
3023          current2_ == typed_other->current2_ &&
3024          current3_ == typed_other->current3_);
3025    }
3026
3027   private:
3028    Iterator(const Iterator& other)
3029        : base_(other.base_),
3030        begin1_(other.begin1_),
3031        end1_(other.end1_),
3032        current1_(other.current1_),
3033        begin2_(other.begin2_),
3034        end2_(other.end2_),
3035        current2_(other.current2_),
3036        begin3_(other.begin3_),
3037        end3_(other.end3_),
3038        current3_(other.current3_) {
3039      ComputeCurrentValue();
3040    }
3041
3042    void ComputeCurrentValue() {
3043      if (!AtEnd())
3044        current_value_ = ParamType(*current1_, *current2_, *current3_);
3045    }
3046    bool AtEnd() const {
3047      // We must report iterator past the end of the range when either of the
3048      // component iterators has reached the end of its range.
3049      return
3050          current1_ == end1_ ||
3051          current2_ == end2_ ||
3052          current3_ == end3_;
3053    }
3054
3055    // No implementation - assignment is unsupported.
3056    void operator=(const Iterator& other);
3057
3058    const ParamGeneratorInterface<ParamType>* const base_;
3059    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
3060    // current[i]_ is the actual traversing iterator.
3061    const typename ParamGenerator<T1>::iterator begin1_;
3062    const typename ParamGenerator<T1>::iterator end1_;
3063    typename ParamGenerator<T1>::iterator current1_;
3064    const typename ParamGenerator<T2>::iterator begin2_;
3065    const typename ParamGenerator<T2>::iterator end2_;
3066    typename ParamGenerator<T2>::iterator current2_;
3067    const typename ParamGenerator<T3>::iterator begin3_;
3068    const typename ParamGenerator<T3>::iterator end3_;
3069    typename ParamGenerator<T3>::iterator current3_;
3070    ParamType current_value_;
3071  };  // class CartesianProductGenerator3::Iterator
3072
3073  // No implementation - assignment is unsupported.
3074  void operator=(const CartesianProductGenerator3& other);
3075
3076  const ParamGenerator<T1> g1_;
3077  const ParamGenerator<T2> g2_;
3078  const ParamGenerator<T3> g3_;
3079};  // class CartesianProductGenerator3
3080
3081
3082template <typename T1, typename T2, typename T3, typename T4>
3083class CartesianProductGenerator4
3084    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4> > {
3085 public:
3086  typedef ::std::tr1::tuple<T1, T2, T3, T4> ParamType;
3087
3088  CartesianProductGenerator4(const ParamGenerator<T1>& g1,
3089      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
3090      const ParamGenerator<T4>& g4)
3091      : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {}
3092  virtual ~CartesianProductGenerator4() {}
3093
3094  virtual ParamIteratorInterface<ParamType>* Begin() const {
3095    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
3096        g3_.begin(), g4_, g4_.begin());
3097  }
3098  virtual ParamIteratorInterface<ParamType>* End() const {
3099    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
3100        g4_, g4_.end());
3101  }
3102
3103 private:
3104  class Iterator : public ParamIteratorInterface<ParamType> {
3105   public:
3106    Iterator(const ParamGeneratorInterface<ParamType>* base,
3107      const ParamGenerator<T1>& g1,
3108      const typename ParamGenerator<T1>::iterator& current1,
3109      const ParamGenerator<T2>& g2,
3110      const typename ParamGenerator<T2>::iterator& current2,
3111      const ParamGenerator<T3>& g3,
3112      const typename ParamGenerator<T3>::iterator& current3,
3113      const ParamGenerator<T4>& g4,
3114      const typename ParamGenerator<T4>::iterator& current4)
3115        : base_(base),
3116          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
3117          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
3118          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
3119          begin4_(g4.begin()), end4_(g4.end()), current4_(current4)    {
3120      ComputeCurrentValue();
3121    }
3122    virtual ~Iterator() {}
3123
3124    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
3125      return base_;
3126    }
3127    // Advance should not be called on beyond-of-range iterators
3128    // so no component iterators must be beyond end of range, either.
3129    virtual void Advance() {
3130      assert(!AtEnd());
3131      ++current4_;
3132      if (current4_ == end4_) {
3133        current4_ = begin4_;
3134        ++current3_;
3135      }
3136      if (current3_ == end3_) {
3137        current3_ = begin3_;
3138        ++current2_;
3139      }
3140      if (current2_ == end2_) {
3141        current2_ = begin2_;
3142        ++current1_;
3143      }
3144      ComputeCurrentValue();
3145    }
3146    virtual ParamIteratorInterface<ParamType>* Clone() const {
3147      return new Iterator(*this);
3148    }
3149    virtual const ParamType* Current() const { return &current_value_; }
3150    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
3151      // Having the same base generator guarantees that the other
3152      // iterator is of the same type and we can downcast.
3153      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
3154          << "The program attempted to compare iterators "
3155          << "from different generators." << std::endl;
3156      const Iterator* typed_other =
3157          CheckedDowncastToActualType<const Iterator>(&other);
3158      // We must report iterators equal if they both point beyond their
3159      // respective ranges. That can happen in a variety of fashions,
3160      // so we have to consult AtEnd().
3161      return (AtEnd() && typed_other->AtEnd()) ||
3162         (
3163          current1_ == typed_other->current1_ &&
3164          current2_ == typed_other->current2_ &&
3165          current3_ == typed_other->current3_ &&
3166          current4_ == typed_other->current4_);
3167    }
3168
3169   private:
3170    Iterator(const Iterator& other)
3171        : base_(other.base_),
3172        begin1_(other.begin1_),
3173        end1_(other.end1_),
3174        current1_(other.current1_),
3175        begin2_(other.begin2_),
3176        end2_(other.end2_),
3177        current2_(other.current2_),
3178        begin3_(other.begin3_),
3179        end3_(other.end3_),
3180        current3_(other.current3_),
3181        begin4_(other.begin4_),
3182        end4_(other.end4_),
3183        current4_(other.current4_) {
3184      ComputeCurrentValue();
3185    }
3186
3187    void ComputeCurrentValue() {
3188      if (!AtEnd())
3189        current_value_ = ParamType(*current1_, *current2_, *current3_,
3190            *current4_);
3191    }
3192    bool AtEnd() const {
3193      // We must report iterator past the end of the range when either of the
3194      // component iterators has reached the end of its range.
3195      return
3196          current1_ == end1_ ||
3197          current2_ == end2_ ||
3198          current3_ == end3_ ||
3199          current4_ == end4_;
3200    }
3201
3202    // No implementation - assignment is unsupported.
3203    void operator=(const Iterator& other);
3204
3205    const ParamGeneratorInterface<ParamType>* const base_;
3206    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
3207    // current[i]_ is the actual traversing iterator.
3208    const typename ParamGenerator<T1>::iterator begin1_;
3209    const typename ParamGenerator<T1>::iterator end1_;
3210    typename ParamGenerator<T1>::iterator current1_;
3211    const typename ParamGenerator<T2>::iterator begin2_;
3212    const typename ParamGenerator<T2>::iterator end2_;
3213    typename ParamGenerator<T2>::iterator current2_;
3214    const typename ParamGenerator<T3>::iterator begin3_;
3215    const typename ParamGenerator<T3>::iterator end3_;
3216    typename ParamGenerator<T3>::iterator current3_;
3217    const typename ParamGenerator<T4>::iterator begin4_;
3218    const typename ParamGenerator<T4>::iterator end4_;
3219    typename ParamGenerator<T4>::iterator current4_;
3220    ParamType current_value_;
3221  };  // class CartesianProductGenerator4::Iterator
3222
3223  // No implementation - assignment is unsupported.
3224  void operator=(const CartesianProductGenerator4& other);
3225
3226  const ParamGenerator<T1> g1_;
3227  const ParamGenerator<T2> g2_;
3228  const ParamGenerator<T3> g3_;
3229  const ParamGenerator<T4> g4_;
3230};  // class CartesianProductGenerator4
3231
3232
3233template <typename T1, typename T2, typename T3, typename T4, typename T5>
3234class CartesianProductGenerator5
3235    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5> > {
3236 public:
3237  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5> ParamType;
3238
3239  CartesianProductGenerator5(const ParamGenerator<T1>& g1,
3240      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
3241      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5)
3242      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {}
3243  virtual ~CartesianProductGenerator5() {}
3244
3245  virtual ParamIteratorInterface<ParamType>* Begin() const {
3246    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
3247        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin());
3248  }
3249  virtual ParamIteratorInterface<ParamType>* End() const {
3250    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
3251        g4_, g4_.end(), g5_, g5_.end());
3252  }
3253
3254 private:
3255  class Iterator : public ParamIteratorInterface<ParamType> {
3256   public:
3257    Iterator(const ParamGeneratorInterface<ParamType>* base,
3258      const ParamGenerator<T1>& g1,
3259      const typename ParamGenerator<T1>::iterator& current1,
3260      const ParamGenerator<T2>& g2,
3261      const typename ParamGenerator<T2>::iterator& current2,
3262      const ParamGenerator<T3>& g3,
3263      const typename ParamGenerator<T3>::iterator& current3,
3264      const ParamGenerator<T4>& g4,
3265      const typename ParamGenerator<T4>::iterator& current4,
3266      const ParamGenerator<T5>& g5,
3267      const typename ParamGenerator<T5>::iterator& current5)
3268        : base_(base),
3269          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
3270          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
3271          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
3272          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
3273          begin5_(g5.begin()), end5_(g5.end()), current5_(current5)    {
3274      ComputeCurrentValue();
3275    }
3276    virtual ~Iterator() {}
3277
3278    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
3279      return base_;
3280    }
3281    // Advance should not be called on beyond-of-range iterators
3282    // so no component iterators must be beyond end of range, either.
3283    virtual void Advance() {
3284      assert(!AtEnd());
3285      ++current5_;
3286      if (current5_ == end5_) {
3287        current5_ = begin5_;
3288        ++current4_;
3289      }
3290      if (current4_ == end4_) {
3291        current4_ = begin4_;
3292        ++current3_;
3293      }
3294      if (current3_ == end3_) {
3295        current3_ = begin3_;
3296        ++current2_;
3297      }
3298      if (current2_ == end2_) {
3299        current2_ = begin2_;
3300        ++current1_;
3301      }
3302      ComputeCurrentValue();
3303    }
3304    virtual ParamIteratorInterface<ParamType>* Clone() const {
3305      return new Iterator(*this);
3306    }
3307    virtual const ParamType* Current() const { return &current_value_; }
3308    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
3309      // Having the same base generator guarantees that the other
3310      // iterator is of the same type and we can downcast.
3311      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
3312          << "The program attempted to compare iterators "
3313          << "from different generators." << std::endl;
3314      const Iterator* typed_other =
3315          CheckedDowncastToActualType<const Iterator>(&other);
3316      // We must report iterators equal if they both point beyond their
3317      // respective ranges. That can happen in a variety of fashions,
3318      // so we have to consult AtEnd().
3319      return (AtEnd() && typed_other->AtEnd()) ||
3320         (
3321          current1_ == typed_other->current1_ &&
3322          current2_ == typed_other->current2_ &&
3323          current3_ == typed_other->current3_ &&
3324          current4_ == typed_other->current4_ &&
3325          current5_ == typed_other->current5_);
3326    }
3327
3328   private:
3329    Iterator(const Iterator& other)
3330        : base_(other.base_),
3331        begin1_(other.begin1_),
3332        end1_(other.end1_),
3333        current1_(other.current1_),
3334        begin2_(other.begin2_),
3335        end2_(other.end2_),
3336        current2_(other.current2_),
3337        begin3_(other.begin3_),
3338        end3_(other.end3_),
3339        current3_(other.current3_),
3340        begin4_(other.begin4_),
3341        end4_(other.end4_),
3342        current4_(other.current4_),
3343        begin5_(other.begin5_),
3344        end5_(other.end5_),
3345        current5_(other.current5_) {
3346      ComputeCurrentValue();
3347    }
3348
3349    void ComputeCurrentValue() {
3350      if (!AtEnd())
3351        current_value_ = ParamType(*current1_, *current2_, *current3_,
3352            *current4_, *current5_);
3353    }
3354    bool AtEnd() const {
3355      // We must report iterator past the end of the range when either of the
3356      // component iterators has reached the end of its range.
3357      return
3358          current1_ == end1_ ||
3359          current2_ == end2_ ||
3360          current3_ == end3_ ||
3361          current4_ == end4_ ||
3362          current5_ == end5_;
3363    }
3364
3365    // No implementation - assignment is unsupported.
3366    void operator=(const Iterator& other);
3367
3368    const ParamGeneratorInterface<ParamType>* const base_;
3369    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
3370    // current[i]_ is the actual traversing iterator.
3371    const typename ParamGenerator<T1>::iterator begin1_;
3372    const typename ParamGenerator<T1>::iterator end1_;
3373    typename ParamGenerator<T1>::iterator current1_;
3374    const typename ParamGenerator<T2>::iterator begin2_;
3375    const typename ParamGenerator<T2>::iterator end2_;
3376    typename ParamGenerator<T2>::iterator current2_;
3377    const typename ParamGenerator<T3>::iterator begin3_;
3378    const typename ParamGenerator<T3>::iterator end3_;
3379    typename ParamGenerator<T3>::iterator current3_;
3380    const typename ParamGenerator<T4>::iterator begin4_;
3381    const typename ParamGenerator<T4>::iterator end4_;
3382    typename ParamGenerator<T4>::iterator current4_;
3383    const typename ParamGenerator<T5>::iterator begin5_;
3384    const typename ParamGenerator<T5>::iterator end5_;
3385    typename ParamGenerator<T5>::iterator current5_;
3386    ParamType current_value_;
3387  };  // class CartesianProductGenerator5::Iterator
3388
3389  // No implementation - assignment is unsupported.
3390  void operator=(const CartesianProductGenerator5& other);
3391
3392  const ParamGenerator<T1> g1_;
3393  const ParamGenerator<T2> g2_;
3394  const ParamGenerator<T3> g3_;
3395  const ParamGenerator<T4> g4_;
3396  const ParamGenerator<T5> g5_;
3397};  // class CartesianProductGenerator5
3398
3399
3400template <typename T1, typename T2, typename T3, typename T4, typename T5,
3401    typename T6>
3402class CartesianProductGenerator6
3403    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5,
3404        T6> > {
3405 public:
3406  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> ParamType;
3407
3408  CartesianProductGenerator6(const ParamGenerator<T1>& g1,
3409      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
3410      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
3411      const ParamGenerator<T6>& g6)
3412      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {}
3413  virtual ~CartesianProductGenerator6() {}
3414
3415  virtual ParamIteratorInterface<ParamType>* Begin() const {
3416    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
3417        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin());
3418  }
3419  virtual ParamIteratorInterface<ParamType>* End() const {
3420    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
3421        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end());
3422  }
3423
3424 private:
3425  class Iterator : public ParamIteratorInterface<ParamType> {
3426   public:
3427    Iterator(const ParamGeneratorInterface<ParamType>* base,
3428      const ParamGenerator<T1>& g1,
3429      const typename ParamGenerator<T1>::iterator& current1,
3430      const ParamGenerator<T2>& g2,
3431      const typename ParamGenerator<T2>::iterator& current2,
3432      const ParamGenerator<T3>& g3,
3433      const typename ParamGenerator<T3>::iterator& current3,
3434      const ParamGenerator<T4>& g4,
3435      const typename ParamGenerator<T4>::iterator& current4,
3436      const ParamGenerator<T5>& g5,
3437      const typename ParamGenerator<T5>::iterator& current5,
3438      const ParamGenerator<T6>& g6,
3439      const typename ParamGenerator<T6>::iterator& current6)
3440        : base_(base),
3441          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
3442          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
3443          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
3444          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
3445          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
3446          begin6_(g6.begin()), end6_(g6.end()), current6_(current6)    {
3447      ComputeCurrentValue();
3448    }
3449    virtual ~Iterator() {}
3450
3451    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
3452      return base_;
3453    }
3454    // Advance should not be called on beyond-of-range iterators
3455    // so no component iterators must be beyond end of range, either.
3456    virtual void Advance() {
3457      assert(!AtEnd());
3458      ++current6_;
3459      if (current6_ == end6_) {
3460        current6_ = begin6_;
3461        ++current5_;
3462      }
3463      if (current5_ == end5_) {
3464        current5_ = begin5_;
3465        ++current4_;
3466      }
3467      if (current4_ == end4_) {
3468        current4_ = begin4_;
3469        ++current3_;
3470      }
3471      if (current3_ == end3_) {
3472        current3_ = begin3_;
3473        ++current2_;
3474      }
3475      if (current2_ == end2_) {
3476        current2_ = begin2_;
3477        ++current1_;
3478      }
3479      ComputeCurrentValue();
3480    }
3481    virtual ParamIteratorInterface<ParamType>* Clone() const {
3482      return new Iterator(*this);
3483    }
3484    virtual const ParamType* Current() const { return &current_value_; }
3485    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
3486      // Having the same base generator guarantees that the other
3487      // iterator is of the same type and we can downcast.
3488      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
3489          << "The program attempted to compare iterators "
3490          << "from different generators." << std::endl;
3491      const Iterator* typed_other =
3492          CheckedDowncastToActualType<const Iterator>(&other);
3493      // We must report iterators equal if they both point beyond their
3494      // respective ranges. That can happen in a variety of fashions,
3495      // so we have to consult AtEnd().
3496      return (AtEnd() && typed_other->AtEnd()) ||
3497         (
3498          current1_ == typed_other->current1_ &&
3499          current2_ == typed_other->current2_ &&
3500          current3_ == typed_other->current3_ &&
3501          current4_ == typed_other->current4_ &&
3502          current5_ == typed_other->current5_ &&
3503          current6_ == typed_other->current6_);
3504    }
3505
3506   private:
3507    Iterator(const Iterator& other)
3508        : base_(other.base_),
3509        begin1_(other.begin1_),
3510        end1_(other.end1_),
3511        current1_(other.current1_),
3512        begin2_(other.begin2_),
3513        end2_(other.end2_),
3514        current2_(other.current2_),
3515        begin3_(other.begin3_),
3516        end3_(other.end3_),
3517        current3_(other.current3_),
3518        begin4_(other.begin4_),
3519        end4_(other.end4_),
3520        current4_(other.current4_),
3521        begin5_(other.begin5_),
3522        end5_(other.end5_),
3523        current5_(other.current5_),
3524        begin6_(other.begin6_),
3525        end6_(other.end6_),
3526        current6_(other.current6_) {
3527      ComputeCurrentValue();
3528    }
3529
3530    void ComputeCurrentValue() {
3531      if (!AtEnd())
3532        current_value_ = ParamType(*current1_, *current2_, *current3_,
3533            *current4_, *current5_, *current6_);
3534    }
3535    bool AtEnd() const {
3536      // We must report iterator past the end of the range when either of the
3537      // component iterators has reached the end of its range.
3538      return
3539          current1_ == end1_ ||
3540          current2_ == end2_ ||
3541          current3_ == end3_ ||
3542          current4_ == end4_ ||
3543          current5_ == end5_ ||
3544          current6_ == end6_;
3545    }
3546
3547    // No implementation - assignment is unsupported.
3548    void operator=(const Iterator& other);
3549
3550    const ParamGeneratorInterface<ParamType>* const base_;
3551    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
3552    // current[i]_ is the actual traversing iterator.
3553    const typename ParamGenerator<T1>::iterator begin1_;
3554    const typename ParamGenerator<T1>::iterator end1_;
3555    typename ParamGenerator<T1>::iterator current1_;
3556    const typename ParamGenerator<T2>::iterator begin2_;
3557    const typename ParamGenerator<T2>::iterator end2_;
3558    typename ParamGenerator<T2>::iterator current2_;
3559    const typename ParamGenerator<T3>::iterator begin3_;
3560    const typename ParamGenerator<T3>::iterator end3_;
3561    typename ParamGenerator<T3>::iterator current3_;
3562    const typename ParamGenerator<T4>::iterator begin4_;
3563    const typename ParamGenerator<T4>::iterator end4_;
3564    typename ParamGenerator<T4>::iterator current4_;
3565    const typename ParamGenerator<T5>::iterator begin5_;
3566    const typename ParamGenerator<T5>::iterator end5_;
3567    typename ParamGenerator<T5>::iterator current5_;
3568    const typename ParamGenerator<T6>::iterator begin6_;
3569    const typename ParamGenerator<T6>::iterator end6_;
3570    typename ParamGenerator<T6>::iterator current6_;
3571    ParamType current_value_;
3572  };  // class CartesianProductGenerator6::Iterator
3573
3574  // No implementation - assignment is unsupported.
3575  void operator=(const CartesianProductGenerator6& other);
3576
3577  const ParamGenerator<T1> g1_;
3578  const ParamGenerator<T2> g2_;
3579  const ParamGenerator<T3> g3_;
3580  const ParamGenerator<T4> g4_;
3581  const ParamGenerator<T5> g5_;
3582  const ParamGenerator<T6> g6_;
3583};  // class CartesianProductGenerator6
3584
3585
3586template <typename T1, typename T2, typename T3, typename T4, typename T5,
3587    typename T6, typename T7>
3588class CartesianProductGenerator7
3589    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
3590        T7> > {
3591 public:
3592  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7> ParamType;
3593
3594  CartesianProductGenerator7(const ParamGenerator<T1>& g1,
3595      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
3596      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
3597      const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7)
3598      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {}
3599  virtual ~CartesianProductGenerator7() {}
3600
3601  virtual ParamIteratorInterface<ParamType>* Begin() const {
3602    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
3603        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
3604        g7_.begin());
3605  }
3606  virtual ParamIteratorInterface<ParamType>* End() const {
3607    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
3608        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end());
3609  }
3610
3611 private:
3612  class Iterator : public ParamIteratorInterface<ParamType> {
3613   public:
3614    Iterator(const ParamGeneratorInterface<ParamType>* base,
3615      const ParamGenerator<T1>& g1,
3616      const typename ParamGenerator<T1>::iterator& current1,
3617      const ParamGenerator<T2>& g2,
3618      const typename ParamGenerator<T2>::iterator& current2,
3619      const ParamGenerator<T3>& g3,
3620      const typename ParamGenerator<T3>::iterator& current3,
3621      const ParamGenerator<T4>& g4,
3622      const typename ParamGenerator<T4>::iterator& current4,
3623      const ParamGenerator<T5>& g5,
3624      const typename ParamGenerator<T5>::iterator& current5,
3625      const ParamGenerator<T6>& g6,
3626      const typename ParamGenerator<T6>::iterator& current6,
3627      const ParamGenerator<T7>& g7,
3628      const typename ParamGenerator<T7>::iterator& current7)
3629        : base_(base),
3630          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
3631          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
3632          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
3633          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
3634          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
3635          begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
3636          begin7_(g7.begin()), end7_(g7.end()), current7_(current7)    {
3637      ComputeCurrentValue();
3638    }
3639    virtual ~Iterator() {}
3640
3641    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
3642      return base_;
3643    }
3644    // Advance should not be called on beyond-of-range iterators
3645    // so no component iterators must be beyond end of range, either.
3646    virtual void Advance() {
3647      assert(!AtEnd());
3648      ++current7_;
3649      if (current7_ == end7_) {
3650        current7_ = begin7_;
3651        ++current6_;
3652      }
3653      if (current6_ == end6_) {
3654        current6_ = begin6_;
3655        ++current5_;
3656      }
3657      if (current5_ == end5_) {
3658        current5_ = begin5_;
3659        ++current4_;
3660      }
3661      if (current4_ == end4_) {
3662        current4_ = begin4_;
3663        ++current3_;
3664      }
3665      if (current3_ == end3_) {
3666        current3_ = begin3_;
3667        ++current2_;
3668      }
3669      if (current2_ == end2_) {
3670        current2_ = begin2_;
3671        ++current1_;
3672      }
3673      ComputeCurrentValue();
3674    }
3675    virtual ParamIteratorInterface<ParamType>* Clone() const {
3676      return new Iterator(*this);
3677    }
3678    virtual const ParamType* Current() const { return &current_value_; }
3679    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
3680      // Having the same base generator guarantees that the other
3681      // iterator is of the same type and we can downcast.
3682      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
3683          << "The program attempted to compare iterators "
3684          << "from different generators." << std::endl;
3685      const Iterator* typed_other =
3686          CheckedDowncastToActualType<const Iterator>(&other);
3687      // We must report iterators equal if they both point beyond their
3688      // respective ranges. That can happen in a variety of fashions,
3689      // so we have to consult AtEnd().
3690      return (AtEnd() && typed_other->AtEnd()) ||
3691         (
3692          current1_ == typed_other->current1_ &&
3693          current2_ == typed_other->current2_ &&
3694          current3_ == typed_other->current3_ &&
3695          current4_ == typed_other->current4_ &&
3696          current5_ == typed_other->current5_ &&
3697          current6_ == typed_other->current6_ &&
3698          current7_ == typed_other->current7_);
3699    }
3700
3701   private:
3702    Iterator(const Iterator& other)
3703        : base_(other.base_),
3704        begin1_(other.begin1_),
3705        end1_(other.end1_),
3706        current1_(other.current1_),
3707        begin2_(other.begin2_),
3708        end2_(other.end2_),
3709        current2_(other.current2_),
3710        begin3_(other.begin3_),
3711        end3_(other.end3_),
3712        current3_(other.current3_),
3713        begin4_(other.begin4_),
3714        end4_(other.end4_),
3715        current4_(other.current4_),
3716        begin5_(other.begin5_),
3717        end5_(other.end5_),
3718        current5_(other.current5_),
3719        begin6_(other.begin6_),
3720        end6_(other.end6_),
3721        current6_(other.current6_),
3722        begin7_(other.begin7_),
3723        end7_(other.end7_),
3724        current7_(other.current7_) {
3725      ComputeCurrentValue();
3726    }
3727
3728    void ComputeCurrentValue() {
3729      if (!AtEnd())
3730        current_value_ = ParamType(*current1_, *current2_, *current3_,
3731            *current4_, *current5_, *current6_, *current7_);
3732    }
3733    bool AtEnd() const {
3734      // We must report iterator past the end of the range when either of the
3735      // component iterators has reached the end of its range.
3736      return
3737          current1_ == end1_ ||
3738          current2_ == end2_ ||
3739          current3_ == end3_ ||
3740          current4_ == end4_ ||
3741          current5_ == end5_ ||
3742          current6_ == end6_ ||
3743          current7_ == end7_;
3744    }
3745
3746    // No implementation - assignment is unsupported.
3747    void operator=(const Iterator& other);
3748
3749    const ParamGeneratorInterface<ParamType>* const base_;
3750    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
3751    // current[i]_ is the actual traversing iterator.
3752    const typename ParamGenerator<T1>::iterator begin1_;
3753    const typename ParamGenerator<T1>::iterator end1_;
3754    typename ParamGenerator<T1>::iterator current1_;
3755    const typename ParamGenerator<T2>::iterator begin2_;
3756    const typename ParamGenerator<T2>::iterator end2_;
3757    typename ParamGenerator<T2>::iterator current2_;
3758    const typename ParamGenerator<T3>::iterator begin3_;
3759    const typename ParamGenerator<T3>::iterator end3_;
3760    typename ParamGenerator<T3>::iterator current3_;
3761    const typename ParamGenerator<T4>::iterator begin4_;
3762    const typename ParamGenerator<T4>::iterator end4_;
3763    typename ParamGenerator<T4>::iterator current4_;
3764    const typename ParamGenerator<T5>::iterator begin5_;
3765    const typename ParamGenerator<T5>::iterator end5_;
3766    typename ParamGenerator<T5>::iterator current5_;
3767    const typename ParamGenerator<T6>::iterator begin6_;
3768    const typename ParamGenerator<T6>::iterator end6_;
3769    typename ParamGenerator<T6>::iterator current6_;
3770    const typename ParamGenerator<T7>::iterator begin7_;
3771    const typename ParamGenerator<T7>::iterator end7_;
3772    typename ParamGenerator<T7>::iterator current7_;
3773    ParamType current_value_;
3774  };  // class CartesianProductGenerator7::Iterator
3775
3776  // No implementation - assignment is unsupported.
3777  void operator=(const CartesianProductGenerator7& other);
3778
3779  const ParamGenerator<T1> g1_;
3780  const ParamGenerator<T2> g2_;
3781  const ParamGenerator<T3> g3_;
3782  const ParamGenerator<T4> g4_;
3783  const ParamGenerator<T5> g5_;
3784  const ParamGenerator<T6> g6_;
3785  const ParamGenerator<T7> g7_;
3786};  // class CartesianProductGenerator7
3787
3788
3789template <typename T1, typename T2, typename T3, typename T4, typename T5,
3790    typename T6, typename T7, typename T8>
3791class CartesianProductGenerator8
3792    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
3793        T7, T8> > {
3794 public:
3795  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8> ParamType;
3796
3797  CartesianProductGenerator8(const ParamGenerator<T1>& g1,
3798      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
3799      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
3800      const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,
3801      const ParamGenerator<T8>& g8)
3802      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7),
3803          g8_(g8) {}
3804  virtual ~CartesianProductGenerator8() {}
3805
3806  virtual ParamIteratorInterface<ParamType>* Begin() const {
3807    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
3808        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
3809        g7_.begin(), g8_, g8_.begin());
3810  }
3811  virtual ParamIteratorInterface<ParamType>* End() const {
3812    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
3813        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,
3814        g8_.end());
3815  }
3816
3817 private:
3818  class Iterator : public ParamIteratorInterface<ParamType> {
3819   public:
3820    Iterator(const ParamGeneratorInterface<ParamType>* base,
3821      const ParamGenerator<T1>& g1,
3822      const typename ParamGenerator<T1>::iterator& current1,
3823      const ParamGenerator<T2>& g2,
3824      const typename ParamGenerator<T2>::iterator& current2,
3825      const ParamGenerator<T3>& g3,
3826      const typename ParamGenerator<T3>::iterator& current3,
3827      const ParamGenerator<T4>& g4,
3828      const typename ParamGenerator<T4>::iterator& current4,
3829      const ParamGenerator<T5>& g5,
3830      const typename ParamGenerator<T5>::iterator& current5,
3831      const ParamGenerator<T6>& g6,
3832      const typename ParamGenerator<T6>::iterator& current6,
3833      const ParamGenerator<T7>& g7,
3834      const typename ParamGenerator<T7>::iterator& current7,
3835      const ParamGenerator<T8>& g8,
3836      const typename ParamGenerator<T8>::iterator& current8)
3837        : base_(base),
3838          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
3839          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
3840          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
3841          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
3842          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
3843          begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
3844          begin7_(g7.begin()), end7_(g7.end()), current7_(current7),
3845          begin8_(g8.begin()), end8_(g8.end()), current8_(current8)    {
3846      ComputeCurrentValue();
3847    }
3848    virtual ~Iterator() {}
3849
3850    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
3851      return base_;
3852    }
3853    // Advance should not be called on beyond-of-range iterators
3854    // so no component iterators must be beyond end of range, either.
3855    virtual void Advance() {
3856      assert(!AtEnd());
3857      ++current8_;
3858      if (current8_ == end8_) {
3859        current8_ = begin8_;
3860        ++current7_;
3861      }
3862      if (current7_ == end7_) {
3863        current7_ = begin7_;
3864        ++current6_;
3865      }
3866      if (current6_ == end6_) {
3867        current6_ = begin6_;
3868        ++current5_;
3869      }
3870      if (current5_ == end5_) {
3871        current5_ = begin5_;
3872        ++current4_;
3873      }
3874      if (current4_ == end4_) {
3875        current4_ = begin4_;
3876        ++current3_;
3877      }
3878      if (current3_ == end3_) {
3879        current3_ = begin3_;
3880        ++current2_;
3881      }
3882      if (current2_ == end2_) {
3883        current2_ = begin2_;
3884        ++current1_;
3885      }
3886      ComputeCurrentValue();
3887    }
3888    virtual ParamIteratorInterface<ParamType>* Clone() const {
3889      return new Iterator(*this);
3890    }
3891    virtual const ParamType* Current() const { return &current_value_; }
3892    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
3893      // Having the same base generator guarantees that the other
3894      // iterator is of the same type and we can downcast.
3895      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
3896          << "The program attempted to compare iterators "
3897          << "from different generators." << std::endl;
3898      const Iterator* typed_other =
3899          CheckedDowncastToActualType<const Iterator>(&other);
3900      // We must report iterators equal if they both point beyond their
3901      // respective ranges. That can happen in a variety of fashions,
3902      // so we have to consult AtEnd().
3903      return (AtEnd() && typed_other->AtEnd()) ||
3904         (
3905          current1_ == typed_other->current1_ &&
3906          current2_ == typed_other->current2_ &&
3907          current3_ == typed_other->current3_ &&
3908          current4_ == typed_other->current4_ &&
3909          current5_ == typed_other->current5_ &&
3910          current6_ == typed_other->current6_ &&
3911          current7_ == typed_other->current7_ &&
3912          current8_ == typed_other->current8_);
3913    }
3914
3915   private:
3916    Iterator(const Iterator& other)
3917        : base_(other.base_),
3918        begin1_(other.begin1_),
3919        end1_(other.end1_),
3920        current1_(other.current1_),
3921        begin2_(other.begin2_),
3922        end2_(other.end2_),
3923        current2_(other.current2_),
3924        begin3_(other.begin3_),
3925        end3_(other.end3_),
3926        current3_(other.current3_),
3927        begin4_(other.begin4_),
3928        end4_(other.end4_),
3929        current4_(other.current4_),
3930        begin5_(other.begin5_),
3931        end5_(other.end5_),
3932        current5_(other.current5_),
3933        begin6_(other.begin6_),
3934        end6_(other.end6_),
3935        current6_(other.current6_),
3936        begin7_(other.begin7_),
3937        end7_(other.end7_),
3938        current7_(other.current7_),
3939        begin8_(other.begin8_),
3940        end8_(other.end8_),
3941        current8_(other.current8_) {
3942      ComputeCurrentValue();
3943    }
3944
3945    void ComputeCurrentValue() {
3946      if (!AtEnd())
3947        current_value_ = ParamType(*current1_, *current2_, *current3_,
3948            *current4_, *current5_, *current6_, *current7_, *current8_);
3949    }
3950    bool AtEnd() const {
3951      // We must report iterator past the end of the range when either of the
3952      // component iterators has reached the end of its range.
3953      return
3954          current1_ == end1_ ||
3955          current2_ == end2_ ||
3956          current3_ == end3_ ||
3957          current4_ == end4_ ||
3958          current5_ == end5_ ||
3959          current6_ == end6_ ||
3960          current7_ == end7_ ||
3961          current8_ == end8_;
3962    }
3963
3964    // No implementation - assignment is unsupported.
3965    void operator=(const Iterator& other);
3966
3967    const ParamGeneratorInterface<ParamType>* const base_;
3968    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
3969    // current[i]_ is the actual traversing iterator.
3970    const typename ParamGenerator<T1>::iterator begin1_;
3971    const typename ParamGenerator<T1>::iterator end1_;
3972    typename ParamGenerator<T1>::iterator current1_;
3973    const typename ParamGenerator<T2>::iterator begin2_;
3974    const typename ParamGenerator<T2>::iterator end2_;
3975    typename ParamGenerator<T2>::iterator current2_;
3976    const typename ParamGenerator<T3>::iterator begin3_;
3977    const typename ParamGenerator<T3>::iterator end3_;
3978    typename ParamGenerator<T3>::iterator current3_;
3979    const typename ParamGenerator<T4>::iterator begin4_;
3980    const typename ParamGenerator<T4>::iterator end4_;
3981    typename ParamGenerator<T4>::iterator current4_;
3982    const typename ParamGenerator<T5>::iterator begin5_;
3983    const typename ParamGenerator<T5>::iterator end5_;
3984    typename ParamGenerator<T5>::iterator current5_;
3985    const typename ParamGenerator<T6>::iterator begin6_;
3986    const typename ParamGenerator<T6>::iterator end6_;
3987    typename ParamGenerator<T6>::iterator current6_;
3988    const typename ParamGenerator<T7>::iterator begin7_;
3989    const typename ParamGenerator<T7>::iterator end7_;
3990    typename ParamGenerator<T7>::iterator current7_;
3991    const typename ParamGenerator<T8>::iterator begin8_;
3992    const typename ParamGenerator<T8>::iterator end8_;
3993    typename ParamGenerator<T8>::iterator current8_;
3994    ParamType current_value_;
3995  };  // class CartesianProductGenerator8::Iterator
3996
3997  // No implementation - assignment is unsupported.
3998  void operator=(const CartesianProductGenerator8& other);
3999
4000  const ParamGenerator<T1> g1_;
4001  const ParamGenerator<T2> g2_;
4002  const ParamGenerator<T3> g3_;
4003  const ParamGenerator<T4> g4_;
4004  const ParamGenerator<T5> g5_;
4005  const ParamGenerator<T6> g6_;
4006  const ParamGenerator<T7> g7_;
4007  const ParamGenerator<T8> g8_;
4008};  // class CartesianProductGenerator8
4009
4010
4011template <typename T1, typename T2, typename T3, typename T4, typename T5,
4012    typename T6, typename T7, typename T8, typename T9>
4013class CartesianProductGenerator9
4014    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
4015        T7, T8, T9> > {
4016 public:
4017  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9> ParamType;
4018
4019  CartesianProductGenerator9(const ParamGenerator<T1>& g1,
4020      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
4021      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
4022      const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,
4023      const ParamGenerator<T8>& g8, const ParamGenerator<T9>& g9)
4024      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
4025          g9_(g9) {}
4026  virtual ~CartesianProductGenerator9() {}
4027
4028  virtual ParamIteratorInterface<ParamType>* Begin() const {
4029    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
4030        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
4031        g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin());
4032  }
4033  virtual ParamIteratorInterface<ParamType>* End() const {
4034    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
4035        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,
4036        g8_.end(), g9_, g9_.end());
4037  }
4038
4039 private:
4040  class Iterator : public ParamIteratorInterface<ParamType> {
4041   public:
4042    Iterator(const ParamGeneratorInterface<ParamType>* base,
4043      const ParamGenerator<T1>& g1,
4044      const typename ParamGenerator<T1>::iterator& current1,
4045      const ParamGenerator<T2>& g2,
4046      const typename ParamGenerator<T2>::iterator& current2,
4047      const ParamGenerator<T3>& g3,
4048      const typename ParamGenerator<T3>::iterator& current3,
4049      const ParamGenerator<T4>& g4,
4050      const typename ParamGenerator<T4>::iterator& current4,
4051      const ParamGenerator<T5>& g5,
4052      const typename ParamGenerator<T5>::iterator& current5,
4053      const ParamGenerator<T6>& g6,
4054      const typename ParamGenerator<T6>::iterator& current6,
4055      const ParamGenerator<T7>& g7,
4056      const typename ParamGenerator<T7>::iterator& current7,
4057      const ParamGenerator<T8>& g8,
4058      const typename ParamGenerator<T8>::iterator& current8,
4059      const ParamGenerator<T9>& g9,
4060      const typename ParamGenerator<T9>::iterator& current9)
4061        : base_(base),
4062          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
4063          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
4064          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
4065          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
4066          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
4067          begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
4068          begin7_(g7.begin()), end7_(g7.end()), current7_(current7),
4069          begin8_(g8.begin()), end8_(g8.end()), current8_(current8),
4070          begin9_(g9.begin()), end9_(g9.end()), current9_(current9)    {
4071      ComputeCurrentValue();
4072    }
4073    virtual ~Iterator() {}
4074
4075    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
4076      return base_;
4077    }
4078    // Advance should not be called on beyond-of-range iterators
4079    // so no component iterators must be beyond end of range, either.
4080    virtual void Advance() {
4081      assert(!AtEnd());
4082      ++current9_;
4083      if (current9_ == end9_) {
4084        current9_ = begin9_;
4085        ++current8_;
4086      }
4087      if (current8_ == end8_) {
4088        current8_ = begin8_;
4089        ++current7_;
4090      }
4091      if (current7_ == end7_) {
4092        current7_ = begin7_;
4093        ++current6_;
4094      }
4095      if (current6_ == end6_) {
4096        current6_ = begin6_;
4097        ++current5_;
4098      }
4099      if (current5_ == end5_) {
4100        current5_ = begin5_;
4101        ++current4_;
4102      }
4103      if (current4_ == end4_) {
4104        current4_ = begin4_;
4105        ++current3_;
4106      }
4107      if (current3_ == end3_) {
4108        current3_ = begin3_;
4109        ++current2_;
4110      }
4111      if (current2_ == end2_) {
4112        current2_ = begin2_;
4113        ++current1_;
4114      }
4115      ComputeCurrentValue();
4116    }
4117    virtual ParamIteratorInterface<ParamType>* Clone() const {
4118      return new Iterator(*this);
4119    }
4120    virtual const ParamType* Current() const { return &current_value_; }
4121    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
4122      // Having the same base generator guarantees that the other
4123      // iterator is of the same type and we can downcast.
4124      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
4125          << "The program attempted to compare iterators "
4126          << "from different generators." << std::endl;
4127      const Iterator* typed_other =
4128          CheckedDowncastToActualType<const Iterator>(&other);
4129      // We must report iterators equal if they both point beyond their
4130      // respective ranges. That can happen in a variety of fashions,
4131      // so we have to consult AtEnd().
4132      return (AtEnd() && typed_other->AtEnd()) ||
4133         (
4134          current1_ == typed_other->current1_ &&
4135          current2_ == typed_other->current2_ &&
4136          current3_ == typed_other->current3_ &&
4137          current4_ == typed_other->current4_ &&
4138          current5_ == typed_other->current5_ &&
4139          current6_ == typed_other->current6_ &&
4140          current7_ == typed_other->current7_ &&
4141          current8_ == typed_other->current8_ &&
4142          current9_ == typed_other->current9_);
4143    }
4144
4145   private:
4146    Iterator(const Iterator& other)
4147        : base_(other.base_),
4148        begin1_(other.begin1_),
4149        end1_(other.end1_),
4150        current1_(other.current1_),
4151        begin2_(other.begin2_),
4152        end2_(other.end2_),
4153        current2_(other.current2_),
4154        begin3_(other.begin3_),
4155        end3_(other.end3_),
4156        current3_(other.current3_),
4157        begin4_(other.begin4_),
4158        end4_(other.end4_),
4159        current4_(other.current4_),
4160        begin5_(other.begin5_),
4161        end5_(other.end5_),
4162        current5_(other.current5_),
4163        begin6_(other.begin6_),
4164        end6_(other.end6_),
4165        current6_(other.current6_),
4166        begin7_(other.begin7_),
4167        end7_(other.end7_),
4168        current7_(other.current7_),
4169        begin8_(other.begin8_),
4170        end8_(other.end8_),
4171        current8_(other.current8_),
4172        begin9_(other.begin9_),
4173        end9_(other.end9_),
4174        current9_(other.current9_) {
4175      ComputeCurrentValue();
4176    }
4177
4178    void ComputeCurrentValue() {
4179      if (!AtEnd())
4180        current_value_ = ParamType(*current1_, *current2_, *current3_,
4181            *current4_, *current5_, *current6_, *current7_, *current8_,
4182            *current9_);
4183    }
4184    bool AtEnd() const {
4185      // We must report iterator past the end of the range when either of the
4186      // component iterators has reached the end of its range.
4187      return
4188          current1_ == end1_ ||
4189          current2_ == end2_ ||
4190          current3_ == end3_ ||
4191          current4_ == end4_ ||
4192          current5_ == end5_ ||
4193          current6_ == end6_ ||
4194          current7_ == end7_ ||
4195          current8_ == end8_ ||
4196          current9_ == end9_;
4197    }
4198
4199    // No implementation - assignment is unsupported.
4200    void operator=(const Iterator& other);
4201
4202    const ParamGeneratorInterface<ParamType>* const base_;
4203    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
4204    // current[i]_ is the actual traversing iterator.
4205    const typename ParamGenerator<T1>::iterator begin1_;
4206    const typename ParamGenerator<T1>::iterator end1_;
4207    typename ParamGenerator<T1>::iterator current1_;
4208    const typename ParamGenerator<T2>::iterator begin2_;
4209    const typename ParamGenerator<T2>::iterator end2_;
4210    typename ParamGenerator<T2>::iterator current2_;
4211    const typename ParamGenerator<T3>::iterator begin3_;
4212    const typename ParamGenerator<T3>::iterator end3_;
4213    typename ParamGenerator<T3>::iterator current3_;
4214    const typename ParamGenerator<T4>::iterator begin4_;
4215    const typename ParamGenerator<T4>::iterator end4_;
4216    typename ParamGenerator<T4>::iterator current4_;
4217    const typename ParamGenerator<T5>::iterator begin5_;
4218    const typename ParamGenerator<T5>::iterator end5_;
4219    typename ParamGenerator<T5>::iterator current5_;
4220    const typename ParamGenerator<T6>::iterator begin6_;
4221    const typename ParamGenerator<T6>::iterator end6_;
4222    typename ParamGenerator<T6>::iterator current6_;
4223    const typename ParamGenerator<T7>::iterator begin7_;
4224    const typename ParamGenerator<T7>::iterator end7_;
4225    typename ParamGenerator<T7>::iterator current7_;
4226    const typename ParamGenerator<T8>::iterator begin8_;
4227    const typename ParamGenerator<T8>::iterator end8_;
4228    typename ParamGenerator<T8>::iterator current8_;
4229    const typename ParamGenerator<T9>::iterator begin9_;
4230    const typename ParamGenerator<T9>::iterator end9_;
4231    typename ParamGenerator<T9>::iterator current9_;
4232    ParamType current_value_;
4233  };  // class CartesianProductGenerator9::Iterator
4234
4235  // No implementation - assignment is unsupported.
4236  void operator=(const CartesianProductGenerator9& other);
4237
4238  const ParamGenerator<T1> g1_;
4239  const ParamGenerator<T2> g2_;
4240  const ParamGenerator<T3> g3_;
4241  const ParamGenerator<T4> g4_;
4242  const ParamGenerator<T5> g5_;
4243  const ParamGenerator<T6> g6_;
4244  const ParamGenerator<T7> g7_;
4245  const ParamGenerator<T8> g8_;
4246  const ParamGenerator<T9> g9_;
4247};  // class CartesianProductGenerator9
4248
4249
4250template <typename T1, typename T2, typename T3, typename T4, typename T5,
4251    typename T6, typename T7, typename T8, typename T9, typename T10>
4252class CartesianProductGenerator10
4253    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
4254        T7, T8, T9, T10> > {
4255 public:
4256  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> ParamType;
4257
4258  CartesianProductGenerator10(const ParamGenerator<T1>& g1,
4259      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
4260      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
4261      const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,
4262      const ParamGenerator<T8>& g8, const ParamGenerator<T9>& g9,
4263      const ParamGenerator<T10>& g10)
4264      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
4265          g9_(g9), g10_(g10) {}
4266  virtual ~CartesianProductGenerator10() {}
4267
4268  virtual ParamIteratorInterface<ParamType>* Begin() const {
4269    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
4270        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
4271        g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin(), g10_, g10_.begin());
4272  }
4273  virtual ParamIteratorInterface<ParamType>* End() const {
4274    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
4275        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,
4276        g8_.end(), g9_, g9_.end(), g10_, g10_.end());
4277  }
4278
4279 private:
4280  class Iterator : public ParamIteratorInterface<ParamType> {
4281   public:
4282    Iterator(const ParamGeneratorInterface<ParamType>* base,
4283      const ParamGenerator<T1>& g1,
4284      const typename ParamGenerator<T1>::iterator& current1,
4285      const ParamGenerator<T2>& g2,
4286      const typename ParamGenerator<T2>::iterator& current2,
4287      const ParamGenerator<T3>& g3,
4288      const typename ParamGenerator<T3>::iterator& current3,
4289      const ParamGenerator<T4>& g4,
4290      const typename ParamGenerator<T4>::iterator& current4,
4291      const ParamGenerator<T5>& g5,
4292      const typename ParamGenerator<T5>::iterator& current5,
4293      const ParamGenerator<T6>& g6,
4294      const typename ParamGenerator<T6>::iterator& current6,
4295      const ParamGenerator<T7>& g7,
4296      const typename ParamGenerator<T7>::iterator& current7,
4297      const ParamGenerator<T8>& g8,
4298      const typename ParamGenerator<T8>::iterator& current8,
4299      const ParamGenerator<T9>& g9,
4300      const typename ParamGenerator<T9>::iterator& current9,
4301      const ParamGenerator<T10>& g10,
4302      const typename ParamGenerator<T10>::iterator& current10)
4303        : base_(base),
4304          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
4305          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
4306          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
4307          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
4308          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
4309          begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
4310          begin7_(g7.begin()), end7_(g7.end()), current7_(current7),
4311          begin8_(g8.begin()), end8_(g8.end()), current8_(current8),
4312          begin9_(g9.begin()), end9_(g9.end()), current9_(current9),
4313          begin10_(g10.begin()), end10_(g10.end()), current10_(current10)    {
4314      ComputeCurrentValue();
4315    }
4316    virtual ~Iterator() {}
4317
4318    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
4319      return base_;
4320    }
4321    // Advance should not be called on beyond-of-range iterators
4322    // so no component iterators must be beyond end of range, either.
4323    virtual void Advance() {
4324      assert(!AtEnd());
4325      ++current10_;
4326      if (current10_ == end10_) {
4327        current10_ = begin10_;
4328        ++current9_;
4329      }
4330      if (current9_ == end9_) {
4331        current9_ = begin9_;
4332        ++current8_;
4333      }
4334      if (current8_ == end8_) {
4335        current8_ = begin8_;
4336        ++current7_;
4337      }
4338      if (current7_ == end7_) {
4339        current7_ = begin7_;
4340        ++current6_;
4341      }
4342      if (current6_ == end6_) {
4343        current6_ = begin6_;
4344        ++current5_;
4345      }
4346      if (current5_ == end5_) {
4347        current5_ = begin5_;
4348        ++current4_;
4349      }
4350      if (current4_ == end4_) {
4351        current4_ = begin4_;
4352        ++current3_;
4353      }
4354      if (current3_ == end3_) {
4355        current3_ = begin3_;
4356        ++current2_;
4357      }
4358      if (current2_ == end2_) {
4359        current2_ = begin2_;
4360        ++current1_;
4361      }
4362      ComputeCurrentValue();
4363    }
4364    virtual ParamIteratorInterface<ParamType>* Clone() const {
4365      return new Iterator(*this);
4366    }
4367    virtual const ParamType* Current() const { return &current_value_; }
4368    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
4369      // Having the same base generator guarantees that the other
4370      // iterator is of the same type and we can downcast.
4371      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
4372          << "The program attempted to compare iterators "
4373          << "from different generators." << std::endl;
4374      const Iterator* typed_other =
4375          CheckedDowncastToActualType<const Iterator>(&other);
4376      // We must report iterators equal if they both point beyond their
4377      // respective ranges. That can happen in a variety of fashions,
4378      // so we have to consult AtEnd().
4379      return (AtEnd() && typed_other->AtEnd()) ||
4380         (
4381          current1_ == typed_other->current1_ &&
4382          current2_ == typed_other->current2_ &&
4383          current3_ == typed_other->current3_ &&
4384          current4_ == typed_other->current4_ &&
4385          current5_ == typed_other->current5_ &&
4386          current6_ == typed_other->current6_ &&
4387          current7_ == typed_other->current7_ &&
4388          current8_ == typed_other->current8_ &&
4389          current9_ == typed_other->current9_ &&
4390          current10_ == typed_other->current10_);
4391    }
4392
4393   private:
4394    Iterator(const Iterator& other)
4395        : base_(other.base_),
4396        begin1_(other.begin1_),
4397        end1_(other.end1_),
4398        current1_(other.current1_),
4399        begin2_(other.begin2_),
4400        end2_(other.end2_),
4401        current2_(other.current2_),
4402        begin3_(other.begin3_),
4403        end3_(other.end3_),
4404        current3_(other.current3_),
4405        begin4_(other.begin4_),
4406        end4_(other.end4_),
4407        current4_(other.current4_),
4408        begin5_(other.begin5_),
4409        end5_(other.end5_),
4410        current5_(other.current5_),
4411        begin6_(other.begin6_),
4412        end6_(other.end6_),
4413        current6_(other.current6_),
4414        begin7_(other.begin7_),
4415        end7_(other.end7_),
4416        current7_(other.current7_),
4417        begin8_(other.begin8_),
4418        end8_(other.end8_),
4419        current8_(other.current8_),
4420        begin9_(other.begin9_),
4421        end9_(other.end9_),
4422        current9_(other.current9_),
4423        begin10_(other.begin10_),
4424        end10_(other.end10_),
4425        current10_(other.current10_) {
4426      ComputeCurrentValue();
4427    }
4428
4429    void ComputeCurrentValue() {
4430      if (!AtEnd())
4431        current_value_ = ParamType(*current1_, *current2_, *current3_,
4432            *current4_, *current5_, *current6_, *current7_, *current8_,
4433            *current9_, *current10_);
4434    }
4435    bool AtEnd() const {
4436      // We must report iterator past the end of the range when either of the
4437      // component iterators has reached the end of its range.
4438      return
4439          current1_ == end1_ ||
4440          current2_ == end2_ ||
4441          current3_ == end3_ ||
4442          current4_ == end4_ ||
4443          current5_ == end5_ ||
4444          current6_ == end6_ ||
4445          current7_ == end7_ ||
4446          current8_ == end8_ ||
4447          current9_ == end9_ ||
4448          current10_ == end10_;
4449    }
4450
4451    // No implementation - assignment is unsupported.
4452    void operator=(const Iterator& other);
4453
4454    const ParamGeneratorInterface<ParamType>* const base_;
4455    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
4456    // current[i]_ is the actual traversing iterator.
4457    const typename ParamGenerator<T1>::iterator begin1_;
4458    const typename ParamGenerator<T1>::iterator end1_;
4459    typename ParamGenerator<T1>::iterator current1_;
4460    const typename ParamGenerator<T2>::iterator begin2_;
4461    const typename ParamGenerator<T2>::iterator end2_;
4462    typename ParamGenerator<T2>::iterator current2_;
4463    const typename ParamGenerator<T3>::iterator begin3_;
4464    const typename ParamGenerator<T3>::iterator end3_;
4465    typename ParamGenerator<T3>::iterator current3_;
4466    const typename ParamGenerator<T4>::iterator begin4_;
4467    const typename ParamGenerator<T4>::iterator end4_;
4468    typename ParamGenerator<T4>::iterator current4_;
4469    const typename ParamGenerator<T5>::iterator begin5_;
4470    const typename ParamGenerator<T5>::iterator end5_;
4471    typename ParamGenerator<T5>::iterator current5_;
4472    const typename ParamGenerator<T6>::iterator begin6_;
4473    const typename ParamGenerator<T6>::iterator end6_;
4474    typename ParamGenerator<T6>::iterator current6_;
4475    const typename ParamGenerator<T7>::iterator begin7_;
4476    const typename ParamGenerator<T7>::iterator end7_;
4477    typename ParamGenerator<T7>::iterator current7_;
4478    const typename ParamGenerator<T8>::iterator begin8_;
4479    const typename ParamGenerator<T8>::iterator end8_;
4480    typename ParamGenerator<T8>::iterator current8_;
4481    const typename ParamGenerator<T9>::iterator begin9_;
4482    const typename ParamGenerator<T9>::iterator end9_;
4483    typename ParamGenerator<T9>::iterator current9_;
4484    const typename ParamGenerator<T10>::iterator begin10_;
4485    const typename ParamGenerator<T10>::iterator end10_;
4486    typename ParamGenerator<T10>::iterator current10_;
4487    ParamType current_value_;
4488  };  // class CartesianProductGenerator10::Iterator
4489
4490  // No implementation - assignment is unsupported.
4491  void operator=(const CartesianProductGenerator10& other);
4492
4493  const ParamGenerator<T1> g1_;
4494  const ParamGenerator<T2> g2_;
4495  const ParamGenerator<T3> g3_;
4496  const ParamGenerator<T4> g4_;
4497  const ParamGenerator<T5> g5_;
4498  const ParamGenerator<T6> g6_;
4499  const ParamGenerator<T7> g7_;
4500  const ParamGenerator<T8> g8_;
4501  const ParamGenerator<T9> g9_;
4502  const ParamGenerator<T10> g10_;
4503};  // class CartesianProductGenerator10
4504
4505
4506// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
4507//
4508// Helper classes providing Combine() with polymorphic features. They allow
4509// casting CartesianProductGeneratorN<T> to ParamGenerator<U> if T is
4510// convertible to U.
4511//
4512template <class Generator1, class Generator2>
4513class CartesianProductHolder2 {
4514 public:
4515CartesianProductHolder2(const Generator1& g1, const Generator2& g2)
4516      : g1_(g1), g2_(g2) {}
4517  template <typename T1, typename T2>
4518  operator ParamGenerator< ::std::tr1::tuple<T1, T2> >() const {
4519    return ParamGenerator< ::std::tr1::tuple<T1, T2> >(
4520        new CartesianProductGenerator2<T1, T2>(
4521        static_cast<ParamGenerator<T1> >(g1_),
4522        static_cast<ParamGenerator<T2> >(g2_)));
4523  }
4524
4525 private:
4526  // No implementation - assignment is unsupported.
4527  void operator=(const CartesianProductHolder2& other);
4528
4529  const Generator1 g1_;
4530  const Generator2 g2_;
4531};  // class CartesianProductHolder2
4532
4533template <class Generator1, class Generator2, class Generator3>
4534class CartesianProductHolder3 {
4535 public:
4536CartesianProductHolder3(const Generator1& g1, const Generator2& g2,
4537    const Generator3& g3)
4538      : g1_(g1), g2_(g2), g3_(g3) {}
4539  template <typename T1, typename T2, typename T3>
4540  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3> >() const {
4541    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3> >(
4542        new CartesianProductGenerator3<T1, T2, T3>(
4543        static_cast<ParamGenerator<T1> >(g1_),
4544        static_cast<ParamGenerator<T2> >(g2_),
4545        static_cast<ParamGenerator<T3> >(g3_)));
4546  }
4547
4548 private:
4549  // No implementation - assignment is unsupported.
4550  void operator=(const CartesianProductHolder3& other);
4551
4552  const Generator1 g1_;
4553  const Generator2 g2_;
4554  const Generator3 g3_;
4555};  // class CartesianProductHolder3
4556
4557template <class Generator1, class Generator2, class Generator3,
4558    class Generator4>
4559class CartesianProductHolder4 {
4560 public:
4561CartesianProductHolder4(const Generator1& g1, const Generator2& g2,
4562    const Generator3& g3, const Generator4& g4)
4563      : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {}
4564  template <typename T1, typename T2, typename T3, typename T4>
4565  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4> >() const {
4566    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4> >(
4567        new CartesianProductGenerator4<T1, T2, T3, T4>(
4568        static_cast<ParamGenerator<T1> >(g1_),
4569        static_cast<ParamGenerator<T2> >(g2_),
4570        static_cast<ParamGenerator<T3> >(g3_),
4571        static_cast<ParamGenerator<T4> >(g4_)));
4572  }
4573
4574 private:
4575  // No implementation - assignment is unsupported.
4576  void operator=(const CartesianProductHolder4& other);
4577
4578  const Generator1 g1_;
4579  const Generator2 g2_;
4580  const Generator3 g3_;
4581  const Generator4 g4_;
4582};  // class CartesianProductHolder4
4583
4584template <class Generator1, class Generator2, class Generator3,
4585    class Generator4, class Generator5>
4586class CartesianProductHolder5 {
4587 public:
4588CartesianProductHolder5(const Generator1& g1, const Generator2& g2,
4589    const Generator3& g3, const Generator4& g4, const Generator5& g5)
4590      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {}
4591  template <typename T1, typename T2, typename T3, typename T4, typename T5>
4592  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5> >() const {
4593    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5> >(
4594        new CartesianProductGenerator5<T1, T2, T3, T4, T5>(
4595        static_cast<ParamGenerator<T1> >(g1_),
4596        static_cast<ParamGenerator<T2> >(g2_),
4597        static_cast<ParamGenerator<T3> >(g3_),
4598        static_cast<ParamGenerator<T4> >(g4_),
4599        static_cast<ParamGenerator<T5> >(g5_)));
4600  }
4601
4602 private:
4603  // No implementation - assignment is unsupported.
4604  void operator=(const CartesianProductHolder5& other);
4605
4606  const Generator1 g1_;
4607  const Generator2 g2_;
4608  const Generator3 g3_;
4609  const Generator4 g4_;
4610  const Generator5 g5_;
4611};  // class CartesianProductHolder5
4612
4613template <class Generator1, class Generator2, class Generator3,
4614    class Generator4, class Generator5, class Generator6>
4615class CartesianProductHolder6 {
4616 public:
4617CartesianProductHolder6(const Generator1& g1, const Generator2& g2,
4618    const Generator3& g3, const Generator4& g4, const Generator5& g5,
4619    const Generator6& g6)
4620      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {}
4621  template <typename T1, typename T2, typename T3, typename T4, typename T5,
4622      typename T6>
4623  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> >() const {
4624    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> >(
4625        new CartesianProductGenerator6<T1, T2, T3, T4, T5, T6>(
4626        static_cast<ParamGenerator<T1> >(g1_),
4627        static_cast<ParamGenerator<T2> >(g2_),
4628        static_cast<ParamGenerator<T3> >(g3_),
4629        static_cast<ParamGenerator<T4> >(g4_),
4630        static_cast<ParamGenerator<T5> >(g5_),
4631        static_cast<ParamGenerator<T6> >(g6_)));
4632  }
4633
4634 private:
4635  // No implementation - assignment is unsupported.
4636  void operator=(const CartesianProductHolder6& other);
4637
4638  const Generator1 g1_;
4639  const Generator2 g2_;
4640  const Generator3 g3_;
4641  const Generator4 g4_;
4642  const Generator5 g5_;
4643  const Generator6 g6_;
4644};  // class CartesianProductHolder6
4645
4646template <class Generator1, class Generator2, class Generator3,
4647    class Generator4, class Generator5, class Generator6, class Generator7>
4648class CartesianProductHolder7 {
4649 public:
4650CartesianProductHolder7(const Generator1& g1, const Generator2& g2,
4651    const Generator3& g3, const Generator4& g4, const Generator5& g5,
4652    const Generator6& g6, const Generator7& g7)
4653      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {}
4654  template <typename T1, typename T2, typename T3, typename T4, typename T5,
4655      typename T6, typename T7>
4656  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
4657      T7> >() const {
4658    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7> >(
4659        new CartesianProductGenerator7<T1, T2, T3, T4, T5, T6, T7>(
4660        static_cast<ParamGenerator<T1> >(g1_),
4661        static_cast<ParamGenerator<T2> >(g2_),
4662        static_cast<ParamGenerator<T3> >(g3_),
4663        static_cast<ParamGenerator<T4> >(g4_),
4664        static_cast<ParamGenerator<T5> >(g5_),
4665        static_cast<ParamGenerator<T6> >(g6_),
4666        static_cast<ParamGenerator<T7> >(g7_)));
4667  }
4668
4669 private:
4670  // No implementation - assignment is unsupported.
4671  void operator=(const CartesianProductHolder7& other);
4672
4673  const Generator1 g1_;
4674  const Generator2 g2_;
4675  const Generator3 g3_;
4676  const Generator4 g4_;
4677  const Generator5 g5_;
4678  const Generator6 g6_;
4679  const Generator7 g7_;
4680};  // class CartesianProductHolder7
4681
4682template <class Generator1, class Generator2, class Generator3,
4683    class Generator4, class Generator5, class Generator6, class Generator7,
4684    class Generator8>
4685class CartesianProductHolder8 {
4686 public:
4687CartesianProductHolder8(const Generator1& g1, const Generator2& g2,
4688    const Generator3& g3, const Generator4& g4, const Generator5& g5,
4689    const Generator6& g6, const Generator7& g7, const Generator8& g8)
4690      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7),
4691          g8_(g8) {}
4692  template <typename T1, typename T2, typename T3, typename T4, typename T5,
4693      typename T6, typename T7, typename T8>
4694  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7,
4695      T8> >() const {
4696    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8> >(
4697        new CartesianProductGenerator8<T1, T2, T3, T4, T5, T6, T7, T8>(
4698        static_cast<ParamGenerator<T1> >(g1_),
4699        static_cast<ParamGenerator<T2> >(g2_),
4700        static_cast<ParamGenerator<T3> >(g3_),
4701        static_cast<ParamGenerator<T4> >(g4_),
4702        static_cast<ParamGenerator<T5> >(g5_),
4703        static_cast<ParamGenerator<T6> >(g6_),
4704        static_cast<ParamGenerator<T7> >(g7_),
4705        static_cast<ParamGenerator<T8> >(g8_)));
4706  }
4707
4708 private:
4709  // No implementation - assignment is unsupported.
4710  void operator=(const CartesianProductHolder8& other);
4711
4712  const Generator1 g1_;
4713  const Generator2 g2_;
4714  const Generator3 g3_;
4715  const Generator4 g4_;
4716  const Generator5 g5_;
4717  const Generator6 g6_;
4718  const Generator7 g7_;
4719  const Generator8 g8_;
4720};  // class CartesianProductHolder8
4721
4722template <class Generator1, class Generator2, class Generator3,
4723    class Generator4, class Generator5, class Generator6, class Generator7,
4724    class Generator8, class Generator9>
4725class CartesianProductHolder9 {
4726 public:
4727CartesianProductHolder9(const Generator1& g1, const Generator2& g2,
4728    const Generator3& g3, const Generator4& g4, const Generator5& g5,
4729    const Generator6& g6, const Generator7& g7, const Generator8& g8,
4730    const Generator9& g9)
4731      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
4732          g9_(g9) {}
4733  template <typename T1, typename T2, typename T3, typename T4, typename T5,
4734      typename T6, typename T7, typename T8, typename T9>
4735  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
4736      T9> >() const {
4737    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
4738        T9> >(
4739        new CartesianProductGenerator9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(
4740        static_cast<ParamGenerator<T1> >(g1_),
4741        static_cast<ParamGenerator<T2> >(g2_),
4742        static_cast<ParamGenerator<T3> >(g3_),
4743        static_cast<ParamGenerator<T4> >(g4_),
4744        static_cast<ParamGenerator<T5> >(g5_),
4745        static_cast<ParamGenerator<T6> >(g6_),
4746        static_cast<ParamGenerator<T7> >(g7_),
4747        static_cast<ParamGenerator<T8> >(g8_),
4748        static_cast<ParamGenerator<T9> >(g9_)));
4749  }
4750
4751 private:
4752  // No implementation - assignment is unsupported.
4753  void operator=(const CartesianProductHolder9& other);
4754
4755  const Generator1 g1_;
4756  const Generator2 g2_;
4757  const Generator3 g3_;
4758  const Generator4 g4_;
4759  const Generator5 g5_;
4760  const Generator6 g6_;
4761  const Generator7 g7_;
4762  const Generator8 g8_;
4763  const Generator9 g9_;
4764};  // class CartesianProductHolder9
4765
4766template <class Generator1, class Generator2, class Generator3,
4767    class Generator4, class Generator5, class Generator6, class Generator7,
4768    class Generator8, class Generator9, class Generator10>
4769class CartesianProductHolder10 {
4770 public:
4771CartesianProductHolder10(const Generator1& g1, const Generator2& g2,
4772    const Generator3& g3, const Generator4& g4, const Generator5& g5,
4773    const Generator6& g6, const Generator7& g7, const Generator8& g8,
4774    const Generator9& g9, const Generator10& g10)
4775      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
4776          g9_(g9), g10_(g10) {}
4777  template <typename T1, typename T2, typename T3, typename T4, typename T5,
4778      typename T6, typename T7, typename T8, typename T9, typename T10>
4779  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
4780      T9, T10> >() const {
4781    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
4782        T9, T10> >(
4783        new CartesianProductGenerator10<T1, T2, T3, T4, T5, T6, T7, T8, T9,
4784            T10>(
4785        static_cast<ParamGenerator<T1> >(g1_),
4786        static_cast<ParamGenerator<T2> >(g2_),
4787        static_cast<ParamGenerator<T3> >(g3_),
4788        static_cast<ParamGenerator<T4> >(g4_),
4789        static_cast<ParamGenerator<T5> >(g5_),
4790        static_cast<ParamGenerator<T6> >(g6_),
4791        static_cast<ParamGenerator<T7> >(g7_),
4792        static_cast<ParamGenerator<T8> >(g8_),
4793        static_cast<ParamGenerator<T9> >(g9_),
4794        static_cast<ParamGenerator<T10> >(g10_)));
4795  }
4796
4797 private:
4798  // No implementation - assignment is unsupported.
4799  void operator=(const CartesianProductHolder10& other);
4800
4801  const Generator1 g1_;
4802  const Generator2 g2_;
4803  const Generator3 g3_;
4804  const Generator4 g4_;
4805  const Generator5 g5_;
4806  const Generator6 g6_;
4807  const Generator7 g7_;
4808  const Generator8 g8_;
4809  const Generator9 g9_;
4810  const Generator10 g10_;
4811};  // class CartesianProductHolder10
4812
4813#endif  // GTEST_HAS_COMBINE
4814
4815}  // namespace internal
4816}  // namespace testing
4817
4818#endif  //  GTEST_HAS_PARAM_TEST
4819
4820#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
4821