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