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