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