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