Commit 3d704217 authored by vladlosev's avatar vladlosev
Browse files

Value-parameterized tests and many bugfixes

parent b6a296d0
...@@ -9,6 +9,7 @@ Bharat Mediratta <bharat@menalto.com> ...@@ -9,6 +9,7 @@ Bharat Mediratta <bharat@menalto.com>
Chandler Carruth <chandlerc@google.com> Chandler Carruth <chandlerc@google.com>
Chris Prince <cprince@google.com> Chris Prince <cprince@google.com>
Chris Taylor <taylorc@google.com> Chris Taylor <taylorc@google.com>
Dan Egnor <egnor@google.com>
Jeffrey Yasskin <jyasskin@google.com> Jeffrey Yasskin <jyasskin@google.com>
Jói Sigurðsson <joi@google.com> Jói Sigurðsson <joi@google.com>
Keir Mierle <mierle@gmail.com> Keir Mierle <mierle@gmail.com>
...@@ -26,5 +27,6 @@ Russ Rufer <russ@pentad.com> ...@@ -26,5 +27,6 @@ Russ Rufer <russ@pentad.com>
Sean Mcafee <eefacm@gmail.com> Sean Mcafee <eefacm@gmail.com>
Sigurður Ásgeirsson <siggi@google.com> Sigurður Ásgeirsson <siggi@google.com>
Tracy Bialik <tracy@pentad.com> Tracy Bialik <tracy@pentad.com>
Vadim Berman <vadimb@google.com>
Vlad Losev <vladl@google.com> Vlad Losev <vladl@google.com>
Zhanyong Wan <wan@google.com> Zhanyong Wan <wan@google.com>
...@@ -6,7 +6,9 @@ ...@@ -6,7 +6,9 @@
EXTRA_DIST = \ EXTRA_DIST = \
CHANGES \ CHANGES \
CONTRIBUTORS \ CONTRIBUTORS \
include/gtest/gtest-param-test.h.pump \
include/gtest/internal/gtest-type-util.h.pump \ include/gtest/internal/gtest-type-util.h.pump \
include/gtest/internal/gtest-param-util-generated.h.pump \
scons/SConscript \ scons/SConscript \
scripts/gen_gtest_pred_impl.py \ scripts/gen_gtest_pred_impl.py \
src/gtest-all.cc src/gtest-all.cc
...@@ -77,9 +79,10 @@ lib_libgtest_la_SOURCES = src/gtest.cc \ ...@@ -77,9 +79,10 @@ lib_libgtest_la_SOURCES = src/gtest.cc \
pkginclude_HEADERS = include/gtest/gtest.h \ pkginclude_HEADERS = include/gtest/gtest.h \
include/gtest/gtest-death-test.h \ include/gtest/gtest-death-test.h \
include/gtest/gtest-message.h \ include/gtest/gtest-message.h \
include/gtest/gtest-spi.h \ include/gtest/gtest-param-test.h \
include/gtest/gtest_pred_impl.h \ include/gtest/gtest_pred_impl.h \
include/gtest/gtest_prod.h \ include/gtest/gtest_prod.h \
include/gtest/gtest-spi.h \
include/gtest/gtest-test-part.h \ include/gtest/gtest-test-part.h \
include/gtest/gtest-typed-test.h include/gtest/gtest-typed-test.h
...@@ -88,6 +91,9 @@ pkginclude_internal_HEADERS = \ ...@@ -88,6 +91,9 @@ pkginclude_internal_HEADERS = \
include/gtest/internal/gtest-death-test-internal.h \ include/gtest/internal/gtest-death-test-internal.h \
include/gtest/internal/gtest-filepath.h \ include/gtest/internal/gtest-filepath.h \
include/gtest/internal/gtest-internal.h \ include/gtest/internal/gtest-internal.h \
include/gtest/internal/gtest-linked_ptr.h \
include/gtest/internal/gtest-param-util-generated.h \
include/gtest/internal/gtest-param-util.h \
include/gtest/internal/gtest-port.h \ include/gtest/internal/gtest-port.h \
include/gtest/internal/gtest-string.h \ include/gtest/internal/gtest-string.h \
include/gtest/internal/gtest-type-util.h include/gtest/internal/gtest-type-util.h
...@@ -149,10 +155,25 @@ samples_sample5_unittest_LDADD = lib/libgtest_main.la \ ...@@ -149,10 +155,25 @@ samples_sample5_unittest_LDADD = lib/libgtest_main.la \
TESTS += samples/sample6_unittest TESTS += samples/sample6_unittest
check_PROGRAMS += samples/sample6_unittest check_PROGRAMS += samples/sample6_unittest
samples_sample6_unittest_SOURCES = samples/sample6_unittest.cc samples_sample6_unittest_SOURCES = samples/prime_tables.h \
samples/sample6_unittest.cc
samples_sample6_unittest_LDADD = lib/libgtest_main.la \ samples_sample6_unittest_LDADD = lib/libgtest_main.la \
samples/libsamples.la samples/libsamples.la
TESTS += samples/sample7_unittest
check_PROGRAMS += samples/sample7_unittest
samples_sample7_unittest_SOURCES = samples/prime_tables.h \
samples/sample7_unittest.cc
samples_sample7_unittest_LDADD = lib/libgtest_main.la \
samples/libsamples.la
TESTS += samples/sample8_unittest
check_PROGRAMS += samples/sample8_unittest
samples_sample8_unittest_SOURCES = samples/prime_tables.h \
samples/sample8_unittest.cc
samples_sample8_unittest_LDADD = lib/libgtest_main.la \
samples/libsamples.la
TESTS += test/gtest_unittest TESTS += test/gtest_unittest
check_PROGRAMS += test/gtest_unittest check_PROGRAMS += test/gtest_unittest
test_gtest_unittest_SOURCES = test/gtest_unittest.cc test_gtest_unittest_SOURCES = test/gtest_unittest.cc
...@@ -189,6 +210,11 @@ check_PROGRAMS += test/gtest_environment_test ...@@ -189,6 +210,11 @@ check_PROGRAMS += test/gtest_environment_test
test_gtest_environment_test_SOURCES = test/gtest_environment_test.cc test_gtest_environment_test_SOURCES = test/gtest_environment_test.cc
test_gtest_environment_test_LDADD = lib/libgtest.la test_gtest_environment_test_LDADD = lib/libgtest.la
TESTS += test/gtest-linked_ptr_test
check_PROGRAMS += test/gtest-linked_ptr_test
test_gtest_linked_ptr_test_SOURCES = test/gtest-linked_ptr_test.cc
test_gtest_linked_ptr_test_LDADD = lib/libgtest_main.la
TESTS += test/gtest_no_test_unittest TESTS += test/gtest_no_test_unittest
check_PROGRAMS += test/gtest_no_test_unittest check_PROGRAMS += test/gtest_no_test_unittest
test_gtest_no_test_unittest_SOURCES = test/gtest_no_test_unittest.cc test_gtest_no_test_unittest_SOURCES = test/gtest_no_test_unittest.cc
...@@ -199,6 +225,18 @@ check_PROGRAMS += test/gtest_main_unittest ...@@ -199,6 +225,18 @@ check_PROGRAMS += test/gtest_main_unittest
test_gtest_main_unittest_SOURCES = test/gtest_main_unittest.cc test_gtest_main_unittest_SOURCES = test/gtest_main_unittest.cc
test_gtest_main_unittest_LDADD = lib/libgtest_main.la test_gtest_main_unittest_LDADD = lib/libgtest_main.la
TESTS += test/gtest-param-test_test
check_PROGRAMS += test/gtest-param-test_test
test_gtest_param_test_test_SOURCES = test/gtest-param-test_test.cc \
test/gtest-param-test2_test.cc \
test/gtest-param-test_test.h
test_gtest_param_test_test_LDADD = lib/libgtest.la
TESTS += test/gtest-port_test
check_PROGRAMS += test/gtest-port_test
test_gtest_port_test_SOURCES = test/gtest-port_test.cc
test_gtest_port_test_LDADD = lib/libgtest_main.la
TESTS += test/gtest_prod_test TESTS += test/gtest_prod_test
check_PROGRAMS += test/gtest_prod_test check_PROGRAMS += test/gtest_prod_test
test_gtest_prod_test_SOURCES = test/gtest_prod_test.cc \ test_gtest_prod_test_SOURCES = test/gtest_prod_test.cc \
......
// This file was GENERATED by a script. DO NOT EDIT BY HAND!!!
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: vladl@google.com (Vlad Losev)
//
// Macros and functions for implementing parameterized tests
// in Google C++ Testing Framework (Google Test)
//
// This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
//
#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
// Value-parameterized tests allow you to test your code with different
// parameters without writing multiple copies of the same test.
//
// Here is how you use value-parameterized tests:
#if 0
// To write value-parameterized tests, first you should define a fixture
// class. It must be derived from testing::TestWithParam<T>, where T is
// the type of your parameter values. TestWithParam<T> is itself derived
// from testing::Test. T can be any copyable type. If it's a raw pointer,
// you are responsible for managing the lifespan of the pointed values.
class FooTest : public ::testing::TestWithParam<const char*> {
// You can implement all the usual class fixture members here.
};
// Then, use the TEST_P macro to define as many parameterized tests
// for this fixture as you want. The _P suffix is for "parameterized"
// or "pattern", whichever you prefer to think.
TEST_P(FooTest, DoesBlah) {
// Inside a test, access the test parameter with the GetParam() method
// of the TestWithParam<T> class:
EXPECT_TRUE(foo.Blah(GetParam()));
...
}
TEST_P(FooTest, HasBlahBlah) {
...
}
// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test
// case with any set of parameters you want. Google Test defines a number
// of functions for generating test parameters. They return what we call
// (surprise!) parameter generators. Here is a summary of them, which
// are all in the testing namespace:
//
//
// Range(begin, end [, step]) - Yields values {begin, begin+step,
// begin+step+step, ...}. The values do not
// include end. step defaults to 1.
// Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}.
// ValuesIn(container) - Yields values from a C-style array, an STL
// ValuesIn(begin,end) container, or an iterator range [begin, end).
// Bool() - Yields sequence {false, true}.
// Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product
// for the math savvy) of the values generated
// by the N generators.
//
// For more details, see comments at the definitions of these functions below
// in this file.
//
// The following statement will instantiate tests from the FooTest test case
// each with parameter values "meeny", "miny", and "moe".
INSTANTIATE_TEST_CASE_P(InstantiationName,
FooTest,
Values("meeny", "miny", "moe"));
// To distinguish different instances of the pattern, (yes, you
// can instantiate it more then once) the first argument to the
// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the
// actual test case name. Remember to pick unique prefixes for different
// instantiations. The tests from the instantiation above will have
// these names:
//
// * InstantiationName/FooTest.DoesBlah/0 for "meeny"
// * InstantiationName/FooTest.DoesBlah/1 for "miny"
// * InstantiationName/FooTest.DoesBlah/2 for "moe"
// * InstantiationName/FooTest.HasBlahBlah/0 for "meeny"
// * InstantiationName/FooTest.HasBlahBlah/1 for "miny"
// * InstantiationName/FooTest.HasBlahBlah/2 for "moe"
//
// You can use these names in --gtest_filter.
//
// This statement will instantiate all tests from FooTest again, each
// with parameter values "cat" and "dog":
const char* pets[] = {"cat", "dog"};
INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));
// The tests from the instantiation above will have these names:
//
// * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat"
// * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog"
// * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat"
// * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog"
//
// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests
// in the given test case, whether their definitions come before or
// AFTER the INSTANTIATE_TEST_CASE_P statement.
//
// Please also note that generator expressions are evaluated in
// RUN_ALL_TESTS(), after main() has started. This allows evaluation of
// parameter list based on command line parameters.
//
// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc
// for more examples.
//
// In the future, we plan to publish the API for defining new parameter
// generators. But for now this interface remains part of the internal
// implementation and is subject to change.
#endif // 0
#include <utility>
#include <gtest/internal/gtest-port.h>
#ifdef GTEST_HAS_PARAM_TEST
#include <gtest/internal/gtest-internal.h>
#include <gtest/internal/gtest-param-util.h>
#include <gtest/internal/gtest-param-util-generated.h>
#ifdef GTEST_HAS_COMBINE
#include <tr1/tuple>
#endif // GTEST_HAS_COMBINE
namespace testing {
// Functions producing parameter generators.
//
// Google Test uses these generators to produce parameters for value-
// parameterized tests. When a parameterized test case is instantiated
// with a particular generator, Google Test creates and runs tests
// for each element in the sequence produced by the generator.
//
// In the following sample, tests from test case FooTest are instantiated
// each three times with parameter values 3, 5, and 8:
//
// class FooTest : public TestWithParam<int> { ... };
//
// TEST_P(FooTest, TestThis) {
// }
// TEST_P(FooTest, TestThat) {
// }
// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8));
//
// Range() returns generators providing sequences of values in a range.
//
// Synopsis:
// Range(start, end)
// - returns a generator producing a sequence of values {start, start+1,
// start+2, ..., }.
// Range(start, end, step)
// - returns a generator producing a sequence of values {start, start+step,
// start+step+step, ..., }.
// Notes:
// * The generated sequences never include end. For example, Range(1, 5)
// returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2)
// returns a generator producing {1, 3, 5, 7}.
// * start and end must have the same type. That type may be any integral or
// floating-point type or a user defined type satisfying these conditions:
// * It must be assignable (have operator=() defined).
// * It must have operator+() (operator+(int-compatible type) for
// two-operand version).
// * It must have operator<() defined.
// Elements in the resulting sequences will also have that type.
// * Condition start < end must be satisfied in order for resulting sequences
// to contain any elements.
//
template <typename T, typename IncrementT>
internal::ParamGenerator<T> Range(T start, T end, IncrementT step) {
return internal::ParamGenerator<T>(
new internal::RangeGenerator<T, IncrementT>(start, end, step));
}
template <typename T>
internal::ParamGenerator<T> Range(T start, T end) {
return Range(start, end, 1);
}
// ValuesIn() function allows generation of tests with parameters coming from
// a container.
//
// Synopsis:
// ValuesIn(const T (&array)[N])
// - returns a generator producing sequences with elements from
// a C-style array.
// ValuesIn(const Container& container)
// - returns a generator producing sequences with elements from
// an STL-style container.
// ValuesIn(Iterator begin, Iterator end)
// - returns a generator producing sequences with elements from
// a range [begin, end) defined by a pair of STL-style iterators. These
// iterators can also be plain C pointers.
//
// Please note that ValuesIn copies the values from the containers
// passed in and keeps them to generate tests in RUN_ALL_TESTS().
//
// Examples:
//
// This instantiates tests from test case StringTest
// each with C-string values of "foo", "bar", and "baz":
//
// const char* strings[] = {"foo", "bar", "baz"};
// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings));
//
// This instantiates tests from test case StlStringTest
// each with STL strings with values "a" and "b":
//
// ::std::vector< ::std::string> GetParameterStrings() {
// ::std::vector< ::std::string> v;
// v.push_back("a");
// v.push_back("b");
// return v;
// }
//
// INSTANTIATE_TEST_CASE_P(CharSequence,
// StlStringTest,
// ValuesIn(GetParameterStrings()));
//
//
// This will also instantiate tests from CharTest
// each with parameter values 'a' and 'b':
//
// ::std::list<char> GetParameterChars() {
// ::std::list<char> list;
// list.push_back('a');
// list.push_back('b');
// return list;
// }
// ::std::list<char> l = GetParameterChars();
// INSTANTIATE_TEST_CASE_P(CharSequence2,
// CharTest,
// ValuesIn(l.begin(), l.end()));
//
template <typename ForwardIterator>
internal::ParamGenerator<
typename ::std::iterator_traits<ForwardIterator>::value_type> ValuesIn(
ForwardIterator begin,
ForwardIterator end) {
typedef typename ::std::iterator_traits<ForwardIterator>::value_type
ParamType;
return internal::ParamGenerator<ParamType>(
new internal::ValuesInIteratorRangeGenerator<ParamType>(begin, end));
}
template <typename T, size_t N>
internal::ParamGenerator<T> ValuesIn(const T (&array)[N]) {
return ValuesIn(array, array + N);
}
template <class Container>
internal::ParamGenerator<typename Container::value_type> ValuesIn(
const Container& container) {
return ValuesIn(container.begin(), container.end());
}
// Values() allows generating tests from explicitly specified list of
// parameters.
//
// Synopsis:
// Values(T v1, T v2, ..., T vN)
// - returns a generator producing sequences with elements v1, v2, ..., vN.
//
// For example, this instantiates tests from test case BarTest each
// with values "one", "two", and "three":
//
// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three"));
//
// This instantiates tests from test case BazTest each with values 1, 2, 3.5.
// The exact type of values will depend on the type of parameter in BazTest.
//
// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5));
//
// Currently, Values() supports from 1 to 50 parameters.
//
template <typename T1>
internal::ValueArray1<T1> Values(T1 v1) {
return internal::ValueArray1<T1>(v1);
}
template <typename T1, typename T2>
internal::ValueArray2<T1, T2> Values(T1 v1, T2 v2) {
return internal::ValueArray2<T1, T2>(v1, v2);
}
template <typename T1, typename T2, typename T3>
internal::ValueArray3<T1, T2, T3> Values(T1 v1, T2 v2, T3 v3) {
return internal::ValueArray3<T1, T2, T3>(v1, v2, v3);
}
template <typename T1, typename T2, typename T3, typename T4>
internal::ValueArray4<T1, T2, T3, T4> Values(T1 v1, T2 v2, T3 v3, T4 v4) {
return internal::ValueArray4<T1, T2, T3, T4>(v1, v2, v3, v4);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
internal::ValueArray5<T1, T2, T3, T4, T5> Values(T1 v1, T2 v2, T3 v3, T4 v4,
T5 v5) {
return internal::ValueArray5<T1, T2, T3, T4, T5>(v1, v2, v3, v4, v5);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6>
internal::ValueArray6<T1, T2, T3, T4, T5, T6> Values(T1 v1, T2 v2, T3 v3,
T4 v4, T5 v5, T6 v6) {
return internal::ValueArray6<T1, T2, T3, T4, T5, T6>(v1, v2, v3, v4, v5, v6);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7>
internal::ValueArray7<T1, T2, T3, T4, T5, T6, T7> Values(T1 v1, T2 v2, T3 v3,
T4 v4, T5 v5, T6 v6, T7 v7) {
return internal::ValueArray7<T1, T2, T3, T4, T5, T6, T7>(v1, v2, v3, v4, v5,
v6, v7);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8>
internal::ValueArray8<T1, T2, T3, T4, T5, T6, T7, T8> Values(T1 v1, T2 v2,
T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) {
return internal::ValueArray8<T1, T2, T3, T4, T5, T6, T7, T8>(v1, v2, v3, v4,
v5, v6, v7, v8);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9>
internal::ValueArray9<T1, T2, T3, T4, T5, T6, T7, T8, T9> Values(T1 v1, T2 v2,
T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) {
return internal::ValueArray9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(v1, v2, v3,
v4, v5, v6, v7, v8, v9);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10>
internal::ValueArray10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> Values(T1 v1,
T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) {
return internal::ValueArray10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(v1,
v2, v3, v4, v5, v6, v7, v8, v9, v10);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11>
internal::ValueArray11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,
T11> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11) {
return internal::ValueArray11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,
T11>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12>
internal::ValueArray12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12) {
return internal::ValueArray12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13>
internal::ValueArray13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
T13> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13) {
return internal::ValueArray13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14>
internal::ValueArray14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) {
return internal::ValueArray14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13,
v14);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15>
internal::ValueArray15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) {
return internal::ValueArray15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12,
v13, v14, v15);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16>
internal::ValueArray16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
T16 v16) {
return internal::ValueArray16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11,
v12, v13, v14, v15, v16);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17>
internal::ValueArray17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
T16 v16, T17 v17) {
return internal::ValueArray17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,
v11, v12, v13, v14, v15, v16, v17);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18>
internal::ValueArray18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6,
T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
T16 v16, T17 v17, T18 v18) {
return internal::ValueArray18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18>(v1, v2, v3, v4, v5, v6, v7, v8, v9,
v10, v11, v12, v13, v14, v15, v16, v17, v18);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19>
internal::ValueArray19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18, T19> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5,
T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14,
T15 v15, T16 v16, T17 v17, T18 v18, T19 v19) {
return internal::ValueArray19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18, T19>(v1, v2, v3, v4, v5, v6, v7, v8,
v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20>
internal::ValueArray20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18, T19, T20> Values(T1 v1, T2 v2, T3 v3, T4 v4,
T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20) {
return internal::ValueArray20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18, T19, T20>(v1, v2, v3, v4, v5, v6, v7,
v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21>
internal::ValueArray21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18, T19, T20, T21> Values(T1 v1, T2 v2, T3 v3, T4 v4,
T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21) {
return internal::ValueArray21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>(v1, v2, v3, v4, v5, v6,
v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22>
internal::ValueArray22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18, T19, T20, T21, T22> Values(T1 v1, T2 v2, T3 v3,
T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
T21 v21, T22 v22) {
return internal::ValueArray22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22>(v1, v2, v3, v4,
v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
v20, v21, v22);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23>
internal::ValueArray23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> Values(T1 v1, T2 v2,
T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
T21 v21, T22 v22, T23 v23) {
return internal::ValueArray23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23>(v1, v2, v3,
v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
v20, v21, v22, v23);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24>
internal::ValueArray24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> Values(T1 v1, T2 v2,
T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
T21 v21, T22 v22, T23 v23, T24 v24) {
return internal::ValueArray24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24>(v1, v2,
v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18,
v19, v20, v21, v22, v23, v24);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25>
internal::ValueArray25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Values(T1 v1,
T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11,
T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19,
T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25) {
return internal::ValueArray25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25>(v1,
v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17,
v18, v19, v20, v21, v22, v23, v24, v25);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26>
internal::ValueArray26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
T26> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26) {
return internal::ValueArray26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
T26>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15,
v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27>
internal::ValueArray27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
T27> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26, T27 v27) {
return internal::ValueArray27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
T26, T27>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14,
v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28>
internal::ValueArray28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
T28> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26, T27 v27, T28 v28) {
return internal::ValueArray28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
T26, T27, T28>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13,
v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27,
v28);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29>
internal::ValueArray29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
T29> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26, T27 v27, T28 v28, T29 v29) {
return internal::ValueArray29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
T26, T27, T28, T29>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12,
v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26,
v27, v28, v29);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30>
internal::ValueArray30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
T29, T30> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16,
T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24,
T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) {
return internal::ValueArray30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
T26, T27, T28, T29, T30>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11,
v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25,
v26, v27, v28, v29, v30);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31>
internal::ValueArray31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
T29, T30, T31> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) {
return internal::ValueArray31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
T26, T27, T28, T29, T30, T31>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,
v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24,
v25, v26, v27, v28, v29, v30, v31);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32>
internal::ValueArray32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
T29, T30, T31, T32> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
T32 v32) {
return internal::ValueArray32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
T26, T27, T28, T29, T30, T31, T32>(v1, v2, v3, v4, v5, v6, v7, v8, v9,
v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,
v24, v25, v26, v27, v28, v29, v30, v31, v32);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33>
internal::ValueArray33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
T29, T30, T31, T32, T33> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6,
T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
T32 v32, T33 v33) {
return internal::ValueArray33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
T26, T27, T28, T29, T30, T31, T32, T33>(v1, v2, v3, v4, v5, v6, v7, v8,
v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,
v24, v25, v26, v27, v28, v29, v30, v31, v32, v33);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34>
internal::ValueArray34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
T29, T30, T31, T32, T33, T34> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5,
T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14,
T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22,
T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30,
T31 v31, T32 v32, T33 v33, T34 v34) {
return internal::ValueArray34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
T26, T27, T28, T29, T30, T31, T32, T33, T34>(v1, v2, v3, v4, v5, v6, v7,
v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22,
v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34, typename T35>
internal::ValueArray35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
T29, T30, T31, T32, T33, T34, T35> Values(T1 v1, T2 v2, T3 v3, T4 v4,
T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21,
T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29,
T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35) {
return internal::ValueArray35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
T26, T27, T28, T29, T30, T31, T32, T33, T34, T35>(v1, v2, v3, v4, v5, v6,
v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21,
v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34, typename T35,
typename T36>
internal::ValueArray36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
T29, T30, T31, T32, T33, T34, T35, T36> Values(T1 v1, T2 v2, T3 v3, T4 v4,
T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21,
T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29,
T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36) {
return internal::ValueArray36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36>(v1, v2, v3, v4,
v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33,
v34, v35, v36);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34, typename T35,
typename T36, typename T37>
internal::ValueArray37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
T29, T30, T31, T32, T33, T34, T35, T36, T37> Values(T1 v1, T2 v2, T3 v3,
T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28,
T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36,
T37 v37) {
return internal::ValueArray37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37>(v1, v2, v3,
v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33,
v34, v35, v36, v37);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34, typename T35,
typename T36, typename T37, typename T38>
internal::ValueArray38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> Values(T1 v1, T2 v2,
T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28,
T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36,
T37 v37, T38 v38) {
return internal::ValueArray38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38>(v1, v2,
v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18,
v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32,
v33, v34, v35, v36, v37, v38);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34, typename T35,
typename T36, typename T37, typename T38, typename T39>
internal::ValueArray39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Values(T1 v1, T2 v2,
T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28,
T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36,
T37 v37, T38 v38, T39 v39) {
return internal::ValueArray39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39>(v1,
v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17,
v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31,
v32, v33, v34, v35, v36, v37, v38, v39);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34, typename T35,
typename T36, typename T37, typename T38, typename T39, typename T40>
internal::ValueArray40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Values(T1 v1,
T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11,
T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19,
T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27,
T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35,
T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) {
return internal::ValueArray40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
T40>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15,
v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29,
v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34, typename T35,
typename T36, typename T37, typename T38, typename T39, typename T40,
typename T41>
internal::ValueArray41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
T41> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41) {
return internal::ValueArray41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
T40, T41>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14,
v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28,
v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34, typename T35,
typename T36, typename T37, typename T38, typename T39, typename T40,
typename T41, typename T42>
internal::ValueArray42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
T42> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
T42 v42) {
return internal::ValueArray42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
T40, T41, T42>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13,
v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27,
v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41,
v42);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34, typename T35,
typename T36, typename T37, typename T38, typename T39, typename T40,
typename T41, typename T42, typename T43>
internal::ValueArray43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
T43> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
T42 v42, T43 v43) {
return internal::ValueArray43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
T40, T41, T42, T43>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12,
v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26,
v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40,
v41, v42, v43);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34, typename T35,
typename T36, typename T37, typename T38, typename T39, typename T40,
typename T41, typename T42, typename T43, typename T44>
internal::ValueArray44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
T44> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
T42 v42, T43 v43, T44 v44) {
return internal::ValueArray44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
T40, T41, T42, T43, T44>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11,
v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25,
v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39,
v40, v41, v42, v43, v44);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34, typename T35,
typename T36, typename T37, typename T38, typename T39, typename T40,
typename T41, typename T42, typename T43, typename T44, typename T45>
internal::ValueArray45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
T44, T45> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16,
T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24,
T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32,
T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40,
T41 v41, T42 v42, T43 v43, T44 v44, T45 v45) {
return internal::ValueArray45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
T40, T41, T42, T43, T44, T45>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,
v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24,
v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38,
v39, v40, v41, v42, v43, v44, v45);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34, typename T35,
typename T36, typename T37, typename T38, typename T39, typename T40,
typename T41, typename T42, typename T43, typename T44, typename T45,
typename T46>
internal::ValueArray46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
T44, T45, T46> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39,
T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) {
return internal::ValueArray46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
T40, T41, T42, T43, T44, T45, T46>(v1, v2, v3, v4, v5, v6, v7, v8, v9,
v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,
v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37,
v38, v39, v40, v41, v42, v43, v44, v45, v46);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34, typename T35,
typename T36, typename T37, typename T38, typename T39, typename T40,
typename T41, typename T42, typename T43, typename T44, typename T45,
typename T46, typename T47>
internal::ValueArray47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
T44, T45, T46, T47> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39,
T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) {
return internal::ValueArray47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
T40, T41, T42, T43, T44, T45, T46, T47>(v1, v2, v3, v4, v5, v6, v7, v8,
v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,
v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37,
v38, v39, v40, v41, v42, v43, v44, v45, v46, v47);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34, typename T35,
typename T36, typename T37, typename T38, typename T39, typename T40,
typename T41, typename T42, typename T43, typename T44, typename T45,
typename T46, typename T47, typename T48>
internal::ValueArray48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
T44, T45, T46, T47, T48> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6,
T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39,
T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47,
T48 v48) {
return internal::ValueArray48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
T40, T41, T42, T43, T44, T45, T46, T47, T48>(v1, v2, v3, v4, v5, v6, v7,
v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22,
v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36,
v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34, typename T35,
typename T36, typename T37, typename T38, typename T39, typename T40,
typename T41, typename T42, typename T43, typename T44, typename T45,
typename T46, typename T47, typename T48, typename T49>
internal::ValueArray49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
T44, T45, T46, T47, T48, T49> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5,
T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14,
T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22,
T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30,
T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38,
T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46,
T47 v47, T48 v48, T49 v49) {
return internal::ValueArray49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
T40, T41, T42, T43, T44, T45, T46, T47, T48, T49>(v1, v2, v3, v4, v5, v6,
v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21,
v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35,
v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34, typename T35,
typename T36, typename T37, typename T38, typename T39, typename T40,
typename T41, typename T42, typename T43, typename T44, typename T45,
typename T46, typename T47, typename T48, typename T49, typename T50>
internal::ValueArray50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
T44, T45, T46, T47, T48, T49, T50> Values(T1 v1, T2 v2, T3 v3, T4 v4,
T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21,
T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29,
T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37,
T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45,
T46 v46, T47 v47, T48 v48, T49 v49, T50 v50) {
return internal::ValueArray50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
T40, T41, T42, T43, T44, T45, T46, T47, T48, T49, T50>(v1, v2, v3, v4,
v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33,
v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47,
v48, v49, v50);
}
// Bool() allows generating tests with parameters in a set of (false, true).
//
// Synopsis:
// Bool()
// - returns a generator producing sequences with elements {false, true}.
//
// It is useful when testing code that depends on Boolean flags. Combinations
// of multiple flags can be tested when several Bool()'s are combined using
// Combine() function.
//
// In the following example all tests in the test case FlagDependentTest
// will be instantiated twice with parameters false and true.
//
// class FlagDependentTest : public testing::TestWithParam<bool> {
// virtual void SetUp() {
// external_flag = GetParam();
// }
// }
// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool());
//
inline internal::ParamGenerator<bool> Bool() {
return Values(false, true);
}
#ifdef GTEST_HAS_COMBINE
// Combine() allows the user to combine two or more sequences to produce
// values of a Cartesian product of those sequences' elements.
//
// Synopsis:
// Combine(gen1, gen2, ..., genN)
// - returns a generator producing sequences with elements coming from
// the Cartesian product of elements from the sequences generated by
// gen1, gen2, ..., genN. The sequence elements will have a type of
// tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types
// of elements from sequences produces by gen1, gen2, ..., genN.
//
// Combine can have up to 10 arguments. This number is currently limited
// by the maximum number of elements in the tuple implementation used by Google
// Test.
//
// Example:
//
// This will instantiate tests in test case AnimalTest each one with
// the parameter values tuple("cat", BLACK), tuple("cat", WHITE),
// tuple("dog", BLACK), and tuple("dog", WHITE):
//
// enum Color { BLACK, GRAY, WHITE };
// class AnimalTest
// : public testing::TestWithParam<tuple<const char*, Color> > {...};
//
// TEST_P(AnimalTest, AnimalLooksNice) {...}
//
// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest,
// Combine(Values("cat", "dog"),
// Values(BLACK, WHITE)));
//
// This will instantiate tests in FlagDependentTest with all variations of two
// Boolean flags:
//
// class FlagDependentTest
// : public testing::TestWithParam<tuple(bool, bool)> > {
// virtual void SetUp() {
// // Assigns external_flag_1 and external_flag_2 values from the tuple.
// tie(external_flag_1, external_flag_2) = GetParam();
// }
// };
//
// TEST_P(FlagDependentTest, TestFeature1) {
// // Test your code using external_flag_1 and external_flag_2 here.
// }
// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest,
// Combine(Bool(), Bool()));
//
template <typename Generator1, typename Generator2>
internal::CartesianProductHolder2<Generator1, Generator2> Combine(
const Generator1& g1, const Generator2& g2) {
return internal::CartesianProductHolder2<Generator1, Generator2>(
g1, g2);
}
template <typename Generator1, typename Generator2, typename Generator3>
internal::CartesianProductHolder3<Generator1, Generator2, Generator3> Combine(
const Generator1& g1, const Generator2& g2, const Generator3& g3) {
return internal::CartesianProductHolder3<Generator1, Generator2, Generator3>(
g1, g2, g3);
}
template <typename Generator1, typename Generator2, typename Generator3,
typename Generator4>
internal::CartesianProductHolder4<Generator1, Generator2, Generator3,
Generator4> Combine(
const Generator1& g1, const Generator2& g2, const Generator3& g3,
const Generator4& g4) {
return internal::CartesianProductHolder4<Generator1, Generator2, Generator3,
Generator4>(
g1, g2, g3, g4);
}
template <typename Generator1, typename Generator2, typename Generator3,
typename Generator4, typename Generator5>
internal::CartesianProductHolder5<Generator1, Generator2, Generator3,
Generator4, Generator5> Combine(
const Generator1& g1, const Generator2& g2, const Generator3& g3,
const Generator4& g4, const Generator5& g5) {
return internal::CartesianProductHolder5<Generator1, Generator2, Generator3,
Generator4, Generator5>(
g1, g2, g3, g4, g5);
}
template <typename Generator1, typename Generator2, typename Generator3,
typename Generator4, typename Generator5, typename Generator6>
internal::CartesianProductHolder6<Generator1, Generator2, Generator3,
Generator4, Generator5, Generator6> Combine(
const Generator1& g1, const Generator2& g2, const Generator3& g3,
const Generator4& g4, const Generator5& g5, const Generator6& g6) {
return internal::CartesianProductHolder6<Generator1, Generator2, Generator3,
Generator4, Generator5, Generator6>(
g1, g2, g3, g4, g5, g6);
}
template <typename Generator1, typename Generator2, typename Generator3,
typename Generator4, typename Generator5, typename Generator6,
typename Generator7>
internal::CartesianProductHolder7<Generator1, Generator2, Generator3,
Generator4, Generator5, Generator6, Generator7> Combine(
const Generator1& g1, const Generator2& g2, const Generator3& g3,
const Generator4& g4, const Generator5& g5, const Generator6& g6,
const Generator7& g7) {
return internal::CartesianProductHolder7<Generator1, Generator2, Generator3,
Generator4, Generator5, Generator6, Generator7>(
g1, g2, g3, g4, g5, g6, g7);
}
template <typename Generator1, typename Generator2, typename Generator3,
typename Generator4, typename Generator5, typename Generator6,
typename Generator7, typename Generator8>
internal::CartesianProductHolder8<Generator1, Generator2, Generator3,
Generator4, Generator5, Generator6, Generator7, Generator8> Combine(
const Generator1& g1, const Generator2& g2, const Generator3& g3,
const Generator4& g4, const Generator5& g5, const Generator6& g6,
const Generator7& g7, const Generator8& g8) {
return internal::CartesianProductHolder8<Generator1, Generator2, Generator3,
Generator4, Generator5, Generator6, Generator7, Generator8>(
g1, g2, g3, g4, g5, g6, g7, g8);
}
template <typename Generator1, typename Generator2, typename Generator3,
typename Generator4, typename Generator5, typename Generator6,
typename Generator7, typename Generator8, typename Generator9>
internal::CartesianProductHolder9<Generator1, Generator2, Generator3,
Generator4, Generator5, Generator6, Generator7, Generator8,
Generator9> Combine(
const Generator1& g1, const Generator2& g2, const Generator3& g3,
const Generator4& g4, const Generator5& g5, const Generator6& g6,
const Generator7& g7, const Generator8& g8, const Generator9& g9) {
return internal::CartesianProductHolder9<Generator1, Generator2, Generator3,
Generator4, Generator5, Generator6, Generator7, Generator8, Generator9>(
g1, g2, g3, g4, g5, g6, g7, g8, g9);
}
template <typename Generator1, typename Generator2, typename Generator3,
typename Generator4, typename Generator5, typename Generator6,
typename Generator7, typename Generator8, typename Generator9,
typename Generator10>
internal::CartesianProductHolder10<Generator1, Generator2, Generator3,
Generator4, Generator5, Generator6, Generator7, Generator8, Generator9,
Generator10> Combine(
const Generator1& g1, const Generator2& g2, const Generator3& g3,
const Generator4& g4, const Generator5& g5, const Generator6& g6,
const Generator7& g7, const Generator8& g8, const Generator9& g9,
const Generator10& g10) {
return internal::CartesianProductHolder10<Generator1, Generator2, Generator3,
Generator4, Generator5, Generator6, Generator7, Generator8, Generator9,
Generator10>(
g1, g2, g3, g4, g5, g6, g7, g8, g9, g10);
}
#endif // GTEST_HAS_COMBINE
#define TEST_P(test_case_name, test_name) \
class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \
: public test_case_name { \
public: \
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \
virtual void TestBody(); \
private: \
static int AddToRegistry() { \
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
GetTestCasePatternHolder<test_case_name>(\
#test_case_name, __FILE__, __LINE__)->AddTestPattern(\
#test_case_name, \
#test_name, \
new ::testing::internal::TestMetaFactory< \
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \
return 0; \
} \
static int gtest_registering_dummy_; \
GTEST_DISALLOW_COPY_AND_ASSIGN_(\
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \
}; \
int GTEST_TEST_CLASS_NAME_(test_case_name, \
test_name)::gtest_registering_dummy_ = \
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \
void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
#define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \
::testing::internal::ParamGenerator<test_case_name::ParamType> \
gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \
int gtest_##prefix##test_case_name##_dummy_ = \
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
GetTestCasePatternHolder<test_case_name>(\
#test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\
#prefix, \
&gtest_##prefix##test_case_name##_EvalGenerator_, \
__FILE__, __LINE__)
} // namespace testing
#endif // GTEST_HAS_PARAM_TEST
#endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
$$ -*- mode: c++; -*-
$var n = 50 $$ Maximum length of Values arguments we want to support.
$var maxtuple = 10 $$ Maximum number of Combine arguments we want to support.
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: vladl@google.com (Vlad Losev)
//
// Macros and functions for implementing parameterized tests
// in Google C++ Testing Framework (Google Test)
//
// This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
//
#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
// Value-parameterized tests allow you to test your code with different
// parameters without writing multiple copies of the same test.
//
// Here is how you use value-parameterized tests:
#if 0
// To write value-parameterized tests, first you should define a fixture
// class. It must be derived from testing::TestWithParam<T>, where T is
// the type of your parameter values. TestWithParam<T> is itself derived
// from testing::Test. T can be any copyable type. If it's a raw pointer,
// you are responsible for managing the lifespan of the pointed values.
class FooTest : public ::testing::TestWithParam<const char*> {
// You can implement all the usual class fixture members here.
};
// Then, use the TEST_P macro to define as many parameterized tests
// for this fixture as you want. The _P suffix is for "parameterized"
// or "pattern", whichever you prefer to think.
TEST_P(FooTest, DoesBlah) {
// Inside a test, access the test parameter with the GetParam() method
// of the TestWithParam<T> class:
EXPECT_TRUE(foo.Blah(GetParam()));
...
}
TEST_P(FooTest, HasBlahBlah) {
...
}
// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test
// case with any set of parameters you want. Google Test defines a number
// of functions for generating test parameters. They return what we call
// (surprise!) parameter generators. Here is a summary of them, which
// are all in the testing namespace:
//
//
// Range(begin, end [, step]) - Yields values {begin, begin+step,
// begin+step+step, ...}. The values do not
// include end. step defaults to 1.
// Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}.
// ValuesIn(container) - Yields values from a C-style array, an STL
// ValuesIn(begin,end) container, or an iterator range [begin, end).
// Bool() - Yields sequence {false, true}.
// Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product
// for the math savvy) of the values generated
// by the N generators.
//
// For more details, see comments at the definitions of these functions below
// in this file.
//
// The following statement will instantiate tests from the FooTest test case
// each with parameter values "meeny", "miny", and "moe".
INSTANTIATE_TEST_CASE_P(InstantiationName,
FooTest,
Values("meeny", "miny", "moe"));
// To distinguish different instances of the pattern, (yes, you
// can instantiate it more then once) the first argument to the
// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the
// actual test case name. Remember to pick unique prefixes for different
// instantiations. The tests from the instantiation above will have
// these names:
//
// * InstantiationName/FooTest.DoesBlah/0 for "meeny"
// * InstantiationName/FooTest.DoesBlah/1 for "miny"
// * InstantiationName/FooTest.DoesBlah/2 for "moe"
// * InstantiationName/FooTest.HasBlahBlah/0 for "meeny"
// * InstantiationName/FooTest.HasBlahBlah/1 for "miny"
// * InstantiationName/FooTest.HasBlahBlah/2 for "moe"
//
// You can use these names in --gtest_filter.
//
// This statement will instantiate all tests from FooTest again, each
// with parameter values "cat" and "dog":
const char* pets[] = {"cat", "dog"};
INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));
// The tests from the instantiation above will have these names:
//
// * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat"
// * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog"
// * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat"
// * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog"
//
// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests
// in the given test case, whether their definitions come before or
// AFTER the INSTANTIATE_TEST_CASE_P statement.
//
// Please also note that generator expressions are evaluated in
// RUN_ALL_TESTS(), after main() has started. This allows evaluation of
// parameter list based on command line parameters.
//
// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc
// for more examples.
//
// In the future, we plan to publish the API for defining new parameter
// generators. But for now this interface remains part of the internal
// implementation and is subject to change.
#endif // 0
#include <utility>
#include <gtest/internal/gtest-port.h>
#ifdef GTEST_HAS_PARAM_TEST
#include <gtest/internal/gtest-internal.h>
#include <gtest/internal/gtest-param-util.h>
#include <gtest/internal/gtest-param-util-generated.h>
#ifdef GTEST_HAS_COMBINE
#include <tr1/tuple>
#endif // GTEST_HAS_COMBINE
namespace testing {
// Functions producing parameter generators.
//
// Google Test uses these generators to produce parameters for value-
// parameterized tests. When a parameterized test case is instantiated
// with a particular generator, Google Test creates and runs tests
// for each element in the sequence produced by the generator.
//
// In the following sample, tests from test case FooTest are instantiated
// each three times with parameter values 3, 5, and 8:
//
// class FooTest : public TestWithParam<int> { ... };
//
// TEST_P(FooTest, TestThis) {
// }
// TEST_P(FooTest, TestThat) {
// }
// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8));
//
// Range() returns generators providing sequences of values in a range.
//
// Synopsis:
// Range(start, end)
// - returns a generator producing a sequence of values {start, start+1,
// start+2, ..., }.
// Range(start, end, step)
// - returns a generator producing a sequence of values {start, start+step,
// start+step+step, ..., }.
// Notes:
// * The generated sequences never include end. For example, Range(1, 5)
// returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2)
// returns a generator producing {1, 3, 5, 7}.
// * start and end must have the same type. That type may be any integral or
// floating-point type or a user defined type satisfying these conditions:
// * It must be assignable (have operator=() defined).
// * It must have operator+() (operator+(int-compatible type) for
// two-operand version).
// * It must have operator<() defined.
// Elements in the resulting sequences will also have that type.
// * Condition start < end must be satisfied in order for resulting sequences
// to contain any elements.
//
template <typename T, typename IncrementT>
internal::ParamGenerator<T> Range(T start, T end, IncrementT step) {
return internal::ParamGenerator<T>(
new internal::RangeGenerator<T, IncrementT>(start, end, step));
}
template <typename T>
internal::ParamGenerator<T> Range(T start, T end) {
return Range(start, end, 1);
}
// ValuesIn() function allows generation of tests with parameters coming from
// a container.
//
// Synopsis:
// ValuesIn(const T (&array)[N])
// - returns a generator producing sequences with elements from
// a C-style array.
// ValuesIn(const Container& container)
// - returns a generator producing sequences with elements from
// an STL-style container.
// ValuesIn(Iterator begin, Iterator end)
// - returns a generator producing sequences with elements from
// a range [begin, end) defined by a pair of STL-style iterators. These
// iterators can also be plain C pointers.
//
// Please note that ValuesIn copies the values from the containers
// passed in and keeps them to generate tests in RUN_ALL_TESTS().
//
// Examples:
//
// This instantiates tests from test case StringTest
// each with C-string values of "foo", "bar", and "baz":
//
// const char* strings[] = {"foo", "bar", "baz"};
// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings));
//
// This instantiates tests from test case StlStringTest
// each with STL strings with values "a" and "b":
//
// ::std::vector< ::std::string> GetParameterStrings() {
// ::std::vector< ::std::string> v;
// v.push_back("a");
// v.push_back("b");
// return v;
// }
//
// INSTANTIATE_TEST_CASE_P(CharSequence,
// StlStringTest,
// ValuesIn(GetParameterStrings()));
//
//
// This will also instantiate tests from CharTest
// each with parameter values 'a' and 'b':
//
// ::std::list<char> GetParameterChars() {
// ::std::list<char> list;
// list.push_back('a');
// list.push_back('b');
// return list;
// }
// ::std::list<char> l = GetParameterChars();
// INSTANTIATE_TEST_CASE_P(CharSequence2,
// CharTest,
// ValuesIn(l.begin(), l.end()));
//
template <typename ForwardIterator>
internal::ParamGenerator<
typename ::std::iterator_traits<ForwardIterator>::value_type> ValuesIn(
ForwardIterator begin,
ForwardIterator end) {
typedef typename ::std::iterator_traits<ForwardIterator>::value_type
ParamType;
return internal::ParamGenerator<ParamType>(
new internal::ValuesInIteratorRangeGenerator<ParamType>(begin, end));
}
template <typename T, size_t N>
internal::ParamGenerator<T> ValuesIn(const T (&array)[N]) {
return ValuesIn(array, array + N);
}
template <class Container>
internal::ParamGenerator<typename Container::value_type> ValuesIn(
const Container& container) {
return ValuesIn(container.begin(), container.end());
}
// Values() allows generating tests from explicitly specified list of
// parameters.
//
// Synopsis:
// Values(T v1, T v2, ..., T vN)
// - returns a generator producing sequences with elements v1, v2, ..., vN.
//
// For example, this instantiates tests from test case BarTest each
// with values "one", "two", and "three":
//
// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three"));
//
// This instantiates tests from test case BazTest each with values 1, 2, 3.5.
// The exact type of values will depend on the type of parameter in BazTest.
//
// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5));
//
// Currently, Values() supports from 1 to $n parameters.
//
$range i 1..n
$for i [[
$range j 1..i
template <$for j, [[typename T$j]]>
internal::ValueArray$i<$for j, [[T$j]]> Values($for j, [[T$j v$j]]) {
return internal::ValueArray$i<$for j, [[T$j]]>($for j, [[v$j]]);
}
]]
// Bool() allows generating tests with parameters in a set of (false, true).
//
// Synopsis:
// Bool()
// - returns a generator producing sequences with elements {false, true}.
//
// It is useful when testing code that depends on Boolean flags. Combinations
// of multiple flags can be tested when several Bool()'s are combined using
// Combine() function.
//
// In the following example all tests in the test case FlagDependentTest
// will be instantiated twice with parameters false and true.
//
// class FlagDependentTest : public testing::TestWithParam<bool> {
// virtual void SetUp() {
// external_flag = GetParam();
// }
// }
// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool());
//
inline internal::ParamGenerator<bool> Bool() {
return Values(false, true);
}
#ifdef GTEST_HAS_COMBINE
// Combine() allows the user to combine two or more sequences to produce
// values of a Cartesian product of those sequences' elements.
//
// Synopsis:
// Combine(gen1, gen2, ..., genN)
// - returns a generator producing sequences with elements coming from
// the Cartesian product of elements from the sequences generated by
// gen1, gen2, ..., genN. The sequence elements will have a type of
// tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types
// of elements from sequences produces by gen1, gen2, ..., genN.
//
// Combine can have up to $maxtuple arguments. This number is currently limited
// by the maximum number of elements in the tuple implementation used by Google
// Test.
//
// Example:
//
// This will instantiate tests in test case AnimalTest each one with
// the parameter values tuple("cat", BLACK), tuple("cat", WHITE),
// tuple("dog", BLACK), and tuple("dog", WHITE):
//
// enum Color { BLACK, GRAY, WHITE };
// class AnimalTest
// : public testing::TestWithParam<tuple<const char*, Color> > {...};
//
// TEST_P(AnimalTest, AnimalLooksNice) {...}
//
// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest,
// Combine(Values("cat", "dog"),
// Values(BLACK, WHITE)));
//
// This will instantiate tests in FlagDependentTest with all variations of two
// Boolean flags:
//
// class FlagDependentTest
// : public testing::TestWithParam<tuple(bool, bool)> > {
// virtual void SetUp() {
// // Assigns external_flag_1 and external_flag_2 values from the tuple.
// tie(external_flag_1, external_flag_2) = GetParam();
// }
// };
//
// TEST_P(FlagDependentTest, TestFeature1) {
// // Test your code using external_flag_1 and external_flag_2 here.
// }
// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest,
// Combine(Bool(), Bool()));
//
$range i 2..maxtuple
$for i [[
$range j 1..i
template <$for j, [[typename Generator$j]]>
internal::CartesianProductHolder$i<$for j, [[Generator$j]]> Combine(
$for j, [[const Generator$j& g$j]]) {
return internal::CartesianProductHolder$i<$for j, [[Generator$j]]>(
$for j, [[g$j]]);
}
]]
#endif // GTEST_HAS_COMBINE
#define TEST_P(test_case_name, test_name) \
class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \
: public test_case_name { \
public: \
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \
virtual void TestBody(); \
private: \
static int AddToRegistry() { \
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
GetTestCasePatternHolder<test_case_name>(\
#test_case_name, __FILE__, __LINE__)->AddTestPattern(\
#test_case_name, \
#test_name, \
new ::testing::internal::TestMetaFactory< \
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \
return 0; \
} \
static int gtest_registering_dummy_; \
GTEST_DISALLOW_COPY_AND_ASSIGN_(\
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \
}; \
int GTEST_TEST_CLASS_NAME_(test_case_name, \
test_name)::gtest_registering_dummy_ = \
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \
void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
#define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \
::testing::internal::ParamGenerator<test_case_name::ParamType> \
gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \
int gtest_##prefix##test_case_name##_dummy_ = \
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
GetTestCasePatternHolder<test_case_name>(\
#test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\
#prefix, \
&gtest_##prefix##test_case_name##_EvalGenerator_, \
__FILE__, __LINE__)
} // namespace testing
#endif // GTEST_HAS_PARAM_TEST
#endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
...@@ -108,21 +108,6 @@ class SingleFailureChecker { ...@@ -108,21 +108,6 @@ class SingleFailureChecker {
GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker); GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker);
}; };
// Helper macro to test that statement generates exactly one fatal failure,
// which contains the substring 'substr' in its failure message, when a scoped
// test result reporter of the given interception mode is used.
#define GTEST_EXPECT_NONFATAL_FAILURE_(statement, substr, intercept_mode)\
do {\
::testing::TestPartResultArray gtest_failures;\
::testing::internal::SingleFailureChecker gtest_checker(\
&gtest_failures, ::testing::TPRT_NONFATAL_FAILURE, (substr));\
{\
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
intercept_mode, &gtest_failures);\
statement;\
}\
} while (false)
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
......
...@@ -66,6 +66,7 @@ ...@@ -66,6 +66,7 @@
#include <gtest/internal/gtest-string.h> #include <gtest/internal/gtest-string.h>
#include <gtest/gtest-death-test.h> #include <gtest/gtest-death-test.h>
#include <gtest/gtest-message.h> #include <gtest/gtest-message.h>
#include <gtest/gtest-param-test.h>
#include <gtest/gtest_prod.h> #include <gtest/gtest_prod.h>
#include <gtest/gtest-test-part.h> #include <gtest/gtest-test-part.h>
#include <gtest/gtest-typed-test.h> #include <gtest/gtest-typed-test.h>
...@@ -483,6 +484,12 @@ class UnitTest { ...@@ -483,6 +484,12 @@ class UnitTest {
// or NULL if no test is running. // or NULL if no test is running.
const TestInfo* current_test_info() const; const TestInfo* current_test_info() const;
#ifdef GTEST_HAS_PARAM_TEST
// Returns the ParameterizedTestCaseRegistry object used to keep track of
// value-parameterized tests and instantiate and register them.
internal::ParameterizedTestCaseRegistry& parameterized_test_registry();
#endif // GTEST_HAS_PARAM_TEST
// Accessors for the implementation object. // Accessors for the implementation object.
internal::UnitTestImpl* impl() { return impl_; } internal::UnitTestImpl* impl() { return impl_; }
const internal::UnitTestImpl* impl() const { return impl_; } const internal::UnitTestImpl* impl() const { return impl_; }
...@@ -886,6 +893,65 @@ class AssertHelper { ...@@ -886,6 +893,65 @@ class AssertHelper {
} // namespace internal } // namespace internal
#ifdef GTEST_HAS_PARAM_TEST
// The abstract base class that all value-parameterized tests inherit from.
//
// This class adds support for accessing the test parameter value via
// the GetParam() method.
//
// Use it with one of the parameter generator defining functions, like Range(),
// Values(), ValuesIn(), Bool(), and Combine().
//
// class FooTest : public ::testing::TestWithParam<int> {
// protected:
// FooTest() {
// // Can use GetParam() here.
// }
// virtual ~FooTest() {
// // Can use GetParam() here.
// }
// virtual void SetUp() {
// // Can use GetParam() here.
// }
// virtual void TearDown {
// // Can use GetParam() here.
// }
// };
// TEST_P(FooTest, DoesBar) {
// // Can use GetParam() method here.
// Foo foo;
// ASSERT_TRUE(foo.DoesBar(GetParam()));
// }
// INSTANTIATE_TEST_CASE_P(OneToTenRange, FooTest, ::testing::Range(1, 10));
template <typename T>
class TestWithParam : public Test {
public:
typedef T ParamType;
// The current parameter value. Is also available in the test fixture's
// constructor.
const ParamType& GetParam() const { return *parameter_; }
private:
// Sets parameter value. The caller is responsible for making sure the value
// remains alive and unchanged throughout the current test.
static void SetParam(const ParamType* parameter) {
parameter_ = parameter;
}
// Static value used for accessing parameter during a test lifetime.
static const ParamType* parameter_;
// TestClass must be a subclass of TestWithParam<T>.
template <class TestClass> friend class internal::ParameterizedTestFactory;
};
template <typename T>
const T* TestWithParam<T>::parameter_ = NULL;
#endif // GTEST_HAS_PARAM_TEST
// Macros for indicating success/failure in test code. // Macros for indicating success/failure in test code.
// ADD_FAILURE unconditionally adds a failure to the current test. // ADD_FAILURE unconditionally adds a failure to the current test.
......
...@@ -711,6 +711,21 @@ class TypeParameterizedTestCase<Fixture, Templates0, Types> { ...@@ -711,6 +711,21 @@ class TypeParameterizedTestCase<Fixture, Templates0, Types> {
#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P #endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
// Returns the current OS stack trace as a String.
//
// The maximum number of stack frames to be included is specified by
// the gtest_stack_trace_depth flag. The skip_count parameter
// specifies the number of top frames to be skipped, which doesn't
// count against the number of frames to be included.
//
// For example, if Foo() calls Bar(), which in turn calls
// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in
// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.
String GetCurrentOsStackTraceExceptTop(UnitTest* unit_test, int skip_count);
// Returns the number of failed test parts in the given test result object.
int GetFailedPartCount(const TestResult* result);
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
...@@ -727,7 +742,6 @@ class TypeParameterizedTestCase<Fixture, Templates0, Types> { ...@@ -727,7 +742,6 @@ class TypeParameterizedTestCase<Fixture, Templates0, Types> {
#define GTEST_SUCCESS_(message) \ #define GTEST_SUCCESS_(message) \
GTEST_MESSAGE_(message, ::testing::TPRT_SUCCESS) GTEST_MESSAGE_(message, ::testing::TPRT_SUCCESS)
#define GTEST_TEST_THROW_(statement, expected_exception, fail) \ #define GTEST_TEST_THROW_(statement, expected_exception, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (const char* gtest_msg = "") { \ if (const char* gtest_msg = "") { \
...@@ -837,5 +851,4 @@ class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\ ...@@ -837,5 +851,4 @@ class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\
void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
// Copyright 2003 Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Dan Egnor (egnor@google.com)
//
// A "smart" pointer type with reference tracking. Every pointer to a
// particular object is kept on a circular linked list. When the last pointer
// to an object is destroyed or reassigned, the object is deleted.
//
// Used properly, this deletes the object when the last reference goes away.
// There are several caveats:
// - Like all reference counting schemes, cycles lead to leaks.
// - Each smart pointer is actually two pointers (8 bytes instead of 4).
// - Every time a pointer is assigned, the entire list of pointers to that
// object is traversed. This class is therefore NOT SUITABLE when there
// will often be more than two or three pointers to a particular object.
// - References are only tracked as long as linked_ptr<> objects are copied.
// If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS
// will happen (double deletion).
//
// A good use of this class is storing object references in STL containers.
// You can safely put linked_ptr<> in a vector<>.
// Other uses may not be as good.
//
// Note: If you use an incomplete type with linked_ptr<>, the class
// *containing* linked_ptr<> must have a constructor and destructor (even
// if they do nothing!).
//
// Bill Gibbons suggested we use something like this.
//
// Thread Safety:
// Unlike other linked_ptr implementations, in this implementation
// a linked_ptr object is thread-safe in the sense that:
// - it's safe to copy linked_ptr objects concurrently,
// - it's safe to copy *from* a linked_ptr and read its underlying
// raw pointer (e.g. via get()) concurrently, and
// - it's safe to write to two linked_ptrs that point to the same
// shared object concurrently.
// TODO(wan@google.com): rename this to safe_linked_ptr to avoid
// confusion with normal linked_ptr.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
#include <stdlib.h>
#include <assert.h>
#include <gtest/internal/gtest-port.h>
namespace testing {
namespace internal {
// Protects copying of all linked_ptr objects.
extern Mutex g_linked_ptr_mutex;
// This is used internally by all instances of linked_ptr<>. It needs to be
// a non-template class because different types of linked_ptr<> can refer to
// the same object (linked_ptr<Superclass>(obj) vs linked_ptr<Subclass>(obj)).
// So, it needs to be possible for different types of linked_ptr to participate
// in the same circular linked list, so we need a single class type here.
//
// DO NOT USE THIS CLASS DIRECTLY YOURSELF. Use linked_ptr<T>.
class linked_ptr_internal {
public:
// Create a new circle that includes only this instance.
void join_new() {
next_ = this;
}
// Many linked_ptr operations may change p.link_ for some linked_ptr
// variable p in the same circle as this object. Therefore we need
// to prevent two such operations from occurring concurrently.
//
// Note that different types of linked_ptr objects can coexist in a
// circle (e.g. linked_ptr<Base>, linked_ptr<Derived1>, and
// linked_ptr<Derived2>). Therefore we must use a single mutex to
// protect all linked_ptr objects. This can create serious
// contention in production code, but is acceptable in a testing
// framework.
// Join an existing circle.
// L < g_linked_ptr_mutex
void join(linked_ptr_internal const* ptr) {
MutexLock lock(&g_linked_ptr_mutex);
linked_ptr_internal const* p = ptr;
while (p->next_ != ptr) p = p->next_;
p->next_ = this;
next_ = ptr;
}
// Leave whatever circle we're part of. Returns true if we were the
// last member of the circle. Once this is done, you can join() another.
// L < g_linked_ptr_mutex
bool depart() {
MutexLock lock(&g_linked_ptr_mutex);
if (next_ == this) return true;
linked_ptr_internal const* p = next_;
while (p->next_ != this) p = p->next_;
p->next_ = next_;
return false;
}
private:
mutable linked_ptr_internal const* next_;
};
template <typename T>
class linked_ptr {
public:
typedef T element_type;
// Take over ownership of a raw pointer. This should happen as soon as
// possible after the object is created.
explicit linked_ptr(T* ptr = NULL) { capture(ptr); }
~linked_ptr() { depart(); }
// Copy an existing linked_ptr<>, adding ourselves to the list of references.
template <typename U> linked_ptr(linked_ptr<U> const& ptr) { copy(&ptr); }
linked_ptr(linked_ptr const& ptr) { // NOLINT
assert(&ptr != this);
copy(&ptr);
}
// Assignment releases the old value and acquires the new.
template <typename U> linked_ptr& operator=(linked_ptr<U> const& ptr) {
depart();
copy(&ptr);
return *this;
}
linked_ptr& operator=(linked_ptr const& ptr) {
if (&ptr != this) {
depart();
copy(&ptr);
}
return *this;
}
// Smart pointer members.
void reset(T* ptr = NULL) {
depart();
capture(ptr);
}
T* get() const { return value_; }
T* operator->() const { return value_; }
T& operator*() const { return *value_; }
// Release ownership of the pointed object and returns it.
// Sole ownership by this linked_ptr object is required.
T* release() {
bool last = link_.depart();
assert(last);
T* v = value_;
value_ = NULL;
return v;
}
bool operator==(T* p) const { return value_ == p; }
bool operator!=(T* p) const { return value_ != p; }
template <typename U>
bool operator==(linked_ptr<U> const& ptr) const {
return value_ == ptr.get();
}
template <typename U>
bool operator!=(linked_ptr<U> const& ptr) const {
return value_ != ptr.get();
}
private:
template <typename U>
friend class linked_ptr;
T* value_;
linked_ptr_internal link_;
void depart() {
if (link_.depart()) delete value_;
}
void capture(T* ptr) {
value_ = ptr;
link_.join_new();
}
template <typename U> void copy(linked_ptr<U> const* ptr) {
value_ = ptr->get();
if (value_)
link_.join(&ptr->link_);
else
link_.join_new();
}
};
template<typename T> inline
bool operator==(T* ptr, const linked_ptr<T>& x) {
return ptr == x.get();
}
template<typename T> inline
bool operator!=(T* ptr, const linked_ptr<T>& x) {
return ptr != x.get();
}
// A function to convert T* into linked_ptr<T>
// Doing e.g. make_linked_ptr(new FooBarBaz<type>(arg)) is a shorter notation
// for linked_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg))
template <typename T>
linked_ptr<T> make_linked_ptr(T* ptr) {
return linked_ptr<T>(ptr);
}
} // namespace internal
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
// This file was GENERATED by a script. DO NOT EDIT BY HAND!!!
// Copyright 2008 Google Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: vladl@google.com (Vlad Losev)
// Type and function utilities for implementing parameterized tests.
// This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
//
// Currently Google Test supports at most 50 arguments in Values,
// and at most 10 arguments in Combine. Please contact
// googletestframework@googlegroups.com if you need more.
// Please note that the number of arguments to Combine is limited
// by the maximum arity of the implementation of tr1::tuple which is
// currently set at 10.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
#include <gtest/internal/gtest-port.h>
#ifdef GTEST_HAS_PARAM_TEST
#ifdef GTEST_HAS_COMBINE
#include <tr1/tuple>
#endif // GTEST_HAS_COMBINE
#include <gtest/internal/gtest-param-util.h>
namespace testing {
namespace internal {
// Used in the Values() function to provide polymorphic capabilities.
template <typename T1>
class ValueArray1 {
public:
explicit ValueArray1(T1 v1) : v1_(v1) {}
template <typename T>
operator ParamGenerator<T>() const { return ValuesIn(&v1_, &v1_ + 1); }
private:
const T1 v1_;
};
template <typename T1, typename T2>
class ValueArray2 {
public:
ValueArray2(T1 v1, T2 v2) : v1_(v1), v2_(v2) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
};
template <typename T1, typename T2, typename T3>
class ValueArray3 {
public:
ValueArray3(T1 v1, T2 v2, T3 v3) : v1_(v1), v2_(v2), v3_(v3) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
};
template <typename T1, typename T2, typename T3, typename T4>
class ValueArray4 {
public:
ValueArray4(T1 v1, T2 v2, T3 v3, T4 v4) : v1_(v1), v2_(v2), v3_(v3),
v4_(v4) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5>
class ValueArray5 {
public:
ValueArray5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) : v1_(v1), v2_(v2), v3_(v3),
v4_(v4), v5_(v5) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6>
class ValueArray6 {
public:
ValueArray6(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) : v1_(v1), v2_(v2),
v3_(v3), v4_(v4), v5_(v5), v6_(v6) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7>
class ValueArray7 {
public:
ValueArray7(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) : v1_(v1),
v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8>
class ValueArray8 {
public:
ValueArray8(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
T8 v8) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
v8_(v8) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9>
class ValueArray9 {
public:
ValueArray9(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
T9 v9) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
v8_(v8), v9_(v9) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10>
class ValueArray10 {
public:
ValueArray10(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
v8_(v8), v9_(v9), v10_(v10) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11>
class ValueArray11 {
public:
ValueArray11(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12>
class ValueArray12 {
public:
ValueArray12(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13>
class ValueArray13 {
public:
ValueArray13(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
v12_(v12), v13_(v13) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14>
class ValueArray14 {
public:
ValueArray14(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) : v1_(v1), v2_(v2), v3_(v3),
v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
v11_(v11), v12_(v12), v13_(v13), v14_(v14) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15>
class ValueArray15 {
public:
ValueArray15(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) : v1_(v1), v2_(v2),
v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16>
class ValueArray16 {
public:
ValueArray16(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) : v1_(v1),
v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
v16_(v16) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17>
class ValueArray17 {
public:
ValueArray17(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16,
T17 v17) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
v15_(v15), v16_(v16), v17_(v17) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18>
class ValueArray18 {
public:
ValueArray18(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
v15_(v15), v16_(v16), v17_(v17), v18_(v18) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19>
class ValueArray19 {
public:
ValueArray19(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
const T19 v19_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20>
class ValueArray20 {
public:
ValueArray20(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
v19_(v19), v20_(v20) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
const T19 v19_;
const T20 v20_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21>
class ValueArray21 {
public:
ValueArray21(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
v18_(v18), v19_(v19), v20_(v20), v21_(v21) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
const T19 v19_;
const T20 v20_;
const T21 v21_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22>
class ValueArray22 {
public:
ValueArray22(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22) : v1_(v1), v2_(v2), v3_(v3),
v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
const T19 v19_;
const T20 v20_;
const T21 v21_;
const T22 v22_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23>
class ValueArray23 {
public:
ValueArray23(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23) : v1_(v1), v2_(v2),
v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
v23_(v23) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_,
v23_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
const T19 v19_;
const T20 v20_;
const T21 v21_;
const T22 v22_;
const T23 v23_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24>
class ValueArray24 {
public:
ValueArray24(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24) : v1_(v1),
v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
v22_(v22), v23_(v23), v24_(v24) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
v24_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
const T19 v19_;
const T20 v20_;
const T21 v21_;
const T22 v22_;
const T23 v23_;
const T24 v24_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25>
class ValueArray25 {
public:
ValueArray25(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24,
T25 v25) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
v24_, v25_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
const T19 v19_;
const T20 v20_;
const T21 v21_;
const T22 v22_;
const T23 v23_;
const T24 v24_;
const T25 v25_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26>
class ValueArray26 {
public:
ValueArray26(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
v24_, v25_, v26_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
const T19 v19_;
const T20 v20_;
const T21 v21_;
const T22 v22_;
const T23 v23_;
const T24 v24_;
const T25 v25_;
const T26 v26_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27>
class ValueArray27 {
public:
ValueArray27(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26, T27 v27) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),
v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),
v26_(v26), v27_(v27) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
v24_, v25_, v26_, v27_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
const T19 v19_;
const T20 v20_;
const T21 v21_;
const T22 v22_;
const T23 v23_;
const T24 v24_;
const T25 v25_;
const T26 v26_;
const T27 v27_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28>
class ValueArray28 {
public:
ValueArray28(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26, T27 v27, T28 v28) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),
v25_(v25), v26_(v26), v27_(v27), v28_(v28) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
v24_, v25_, v26_, v27_, v28_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
const T19 v19_;
const T20 v20_;
const T21 v21_;
const T22 v22_;
const T23 v23_;
const T24 v24_;
const T25 v25_;
const T26 v26_;
const T27 v27_;
const T28 v28_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29>
class ValueArray29 {
public:
ValueArray29(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26, T27 v27, T28 v28, T29 v29) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),
v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
v24_, v25_, v26_, v27_, v28_, v29_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
const T19 v19_;
const T20 v20_;
const T21 v21_;
const T22 v22_;
const T23 v23_;
const T24 v24_;
const T25 v25_;
const T26 v26_;
const T27 v27_;
const T28 v28_;
const T29 v29_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30>
class ValueArray30 {
public:
ValueArray30(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) : v1_(v1), v2_(v2), v3_(v3),
v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
v29_(v29), v30_(v30) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
v24_, v25_, v26_, v27_, v28_, v29_, v30_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
const T19 v19_;
const T20 v20_;
const T21 v21_;
const T22 v22_;
const T23 v23_;
const T24 v24_;
const T25 v25_;
const T26 v26_;
const T27 v27_;
const T28 v28_;
const T29 v29_;
const T30 v30_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31>
class ValueArray31 {
public:
ValueArray31(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) : v1_(v1), v2_(v2),
v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
v29_(v29), v30_(v30), v31_(v31) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
const T19 v19_;
const T20 v20_;
const T21 v21_;
const T22 v22_;
const T23 v23_;
const T24 v24_;
const T25 v25_;
const T26 v26_;
const T27 v27_;
const T28 v28_;
const T29 v29_;
const T30 v30_;
const T31 v31_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32>
class ValueArray32 {
public:
ValueArray32(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32) : v1_(v1),
v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),
v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
const T19 v19_;
const T20 v20_;
const T21 v21_;
const T22 v22_;
const T23 v23_;
const T24 v24_;
const T25 v25_;
const T26 v26_;
const T27 v27_;
const T28 v28_;
const T29 v29_;
const T30 v30_;
const T31 v31_;
const T32 v32_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33>
class ValueArray33 {
public:
ValueArray33(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32,
T33 v33) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
v33_(v33) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
const T19 v19_;
const T20 v20_;
const T21 v21_;
const T22 v22_;
const T23 v23_;
const T24 v24_;
const T25 v25_;
const T26 v26_;
const T27 v27_;
const T28 v28_;
const T29 v29_;
const T30 v30_;
const T31 v31_;
const T32 v32_;
const T33 v33_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34>
class ValueArray34 {
public:
ValueArray34(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
T34 v34) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
v33_(v33), v34_(v34) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
const T19 v19_;
const T20 v20_;
const T21 v21_;
const T22 v22_;
const T23 v23_;
const T24 v24_;
const T25 v25_;
const T26 v26_;
const T27 v27_;
const T28 v28_;
const T29 v29_;
const T30 v30_;
const T31 v31_;
const T32 v32_;
const T33 v33_;
const T34 v34_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34, typename T35>
class ValueArray35 {
public:
ValueArray35(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
T34 v34, T35 v35) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),
v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),
v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31),
v32_(v32), v33_(v33), v34_(v34), v35_(v35) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_,
v35_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
const T19 v19_;
const T20 v20_;
const T21 v21_;
const T22 v22_;
const T23 v23_;
const T24 v24_;
const T25 v25_;
const T26 v26_;
const T27 v27_;
const T28 v28_;
const T29 v29_;
const T30 v30_;
const T31 v31_;
const T32 v32_;
const T33 v33_;
const T34 v34_;
const T35 v35_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34, typename T35,
typename T36>
class ValueArray36 {
public:
ValueArray36(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
T34 v34, T35 v35, T36 v36) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),
v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30),
v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
v36_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
const T19 v19_;
const T20 v20_;
const T21 v21_;
const T22 v22_;
const T23 v23_;
const T24 v24_;
const T25 v25_;
const T26 v26_;
const T27 v27_;
const T28 v28_;
const T29 v29_;
const T30 v30_;
const T31 v31_;
const T32 v32_;
const T33 v33_;
const T34 v34_;
const T35 v35_;
const T36 v36_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34, typename T35,
typename T36, typename T37>
class ValueArray37 {
public:
ValueArray37(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
T34 v34, T35 v35, T36 v36, T37 v37) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),
v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29),
v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35),
v36_(v36), v37_(v37) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
v36_, v37_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
const T19 v19_;
const T20 v20_;
const T21 v21_;
const T22 v22_;
const T23 v23_;
const T24 v24_;
const T25 v25_;
const T26 v26_;
const T27 v27_;
const T28 v28_;
const T29 v29_;
const T30 v30_;
const T31 v31_;
const T32 v32_;
const T33 v33_;
const T34 v34_;
const T35 v35_;
const T36 v36_;
const T37 v37_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34, typename T35,
typename T36, typename T37, typename T38>
class ValueArray38 {
public:
ValueArray38(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
T34 v34, T35 v35, T36 v36, T37 v37, T38 v38) : v1_(v1), v2_(v2), v3_(v3),
v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
v35_(v35), v36_(v36), v37_(v37), v38_(v38) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
v36_, v37_, v38_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
const T19 v19_;
const T20 v20_;
const T21 v21_;
const T22 v22_;
const T23 v23_;
const T24 v24_;
const T25 v25_;
const T26 v26_;
const T27 v27_;
const T28 v28_;
const T29 v29_;
const T30 v30_;
const T31 v31_;
const T32 v32_;
const T33 v33_;
const T34 v34_;
const T35 v35_;
const T36 v36_;
const T37 v37_;
const T38 v38_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34, typename T35,
typename T36, typename T37, typename T38, typename T39>
class ValueArray39 {
public:
ValueArray39(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39) : v1_(v1), v2_(v2),
v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
v36_, v37_, v38_, v39_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
const T19 v19_;
const T20 v20_;
const T21 v21_;
const T22 v22_;
const T23 v23_;
const T24 v24_;
const T25 v25_;
const T26 v26_;
const T27 v27_;
const T28 v28_;
const T29 v29_;
const T30 v30_;
const T31 v31_;
const T32 v32_;
const T33 v33_;
const T34 v34_;
const T35 v35_;
const T36 v36_;
const T37 v37_;
const T38 v38_;
const T39 v39_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34, typename T35,
typename T36, typename T37, typename T38, typename T39, typename T40>
class ValueArray40 {
public:
ValueArray40(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) : v1_(v1),
v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),
v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33),
v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39),
v40_(v40) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
v36_, v37_, v38_, v39_, v40_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
const T19 v19_;
const T20 v20_;
const T21 v21_;
const T22 v22_;
const T23 v23_;
const T24 v24_;
const T25 v25_;
const T26 v26_;
const T27 v27_;
const T28 v28_;
const T29 v29_;
const T30 v30_;
const T31 v31_;
const T32 v32_;
const T33 v33_;
const T34 v34_;
const T35 v35_;
const T36 v36_;
const T37 v37_;
const T38 v38_;
const T39 v39_;
const T40 v40_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34, typename T35,
typename T36, typename T37, typename T38, typename T39, typename T40,
typename T41>
class ValueArray41 {
public:
ValueArray41(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40,
T41 v41) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
v39_(v39), v40_(v40), v41_(v41) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
v36_, v37_, v38_, v39_, v40_, v41_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
const T19 v19_;
const T20 v20_;
const T21 v21_;
const T22 v22_;
const T23 v23_;
const T24 v24_;
const T25 v25_;
const T26 v26_;
const T27 v27_;
const T28 v28_;
const T29 v29_;
const T30 v30_;
const T31 v31_;
const T32 v32_;
const T33 v33_;
const T34 v34_;
const T35 v35_;
const T36 v36_;
const T37 v37_;
const T38 v38_;
const T39 v39_;
const T40 v40_;
const T41 v41_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34, typename T35,
typename T36, typename T37, typename T38, typename T39, typename T40,
typename T41, typename T42>
class ValueArray42 {
public:
ValueArray42(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
T42 v42) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
v39_(v39), v40_(v40), v41_(v41), v42_(v42) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
v36_, v37_, v38_, v39_, v40_, v41_, v42_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
const T19 v19_;
const T20 v20_;
const T21 v21_;
const T22 v22_;
const T23 v23_;
const T24 v24_;
const T25 v25_;
const T26 v26_;
const T27 v27_;
const T28 v28_;
const T29 v29_;
const T30 v30_;
const T31 v31_;
const T32 v32_;
const T33 v33_;
const T34 v34_;
const T35 v35_;
const T36 v36_;
const T37 v37_;
const T38 v38_;
const T39 v39_;
const T40 v40_;
const T41 v41_;
const T42 v42_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34, typename T35,
typename T36, typename T37, typename T38, typename T39, typename T40,
typename T41, typename T42, typename T43>
class ValueArray43 {
public:
ValueArray43(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
T42 v42, T43 v43) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),
v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),
v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31),
v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37),
v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
const T19 v19_;
const T20 v20_;
const T21 v21_;
const T22 v22_;
const T23 v23_;
const T24 v24_;
const T25 v25_;
const T26 v26_;
const T27 v27_;
const T28 v28_;
const T29 v29_;
const T30 v30_;
const T31 v31_;
const T32 v32_;
const T33 v33_;
const T34 v34_;
const T35 v35_;
const T36 v36_;
const T37 v37_;
const T38 v38_;
const T39 v39_;
const T40 v40_;
const T41 v41_;
const T42 v42_;
const T43 v43_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34, typename T35,
typename T36, typename T37, typename T38, typename T39, typename T40,
typename T41, typename T42, typename T43, typename T44>
class ValueArray44 {
public:
ValueArray44(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
T42 v42, T43 v43, T44 v44) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),
v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30),
v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36),
v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42),
v43_(v43), v44_(v44) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
const T19 v19_;
const T20 v20_;
const T21 v21_;
const T22 v22_;
const T23 v23_;
const T24 v24_;
const T25 v25_;
const T26 v26_;
const T27 v27_;
const T28 v28_;
const T29 v29_;
const T30 v30_;
const T31 v31_;
const T32 v32_;
const T33 v33_;
const T34 v34_;
const T35 v35_;
const T36 v36_;
const T37 v37_;
const T38 v38_;
const T39 v39_;
const T40 v40_;
const T41 v41_;
const T42 v42_;
const T43 v43_;
const T44 v44_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34, typename T35,
typename T36, typename T37, typename T38, typename T39, typename T40,
typename T41, typename T42, typename T43, typename T44, typename T45>
class ValueArray45 {
public:
ValueArray45(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
T42 v42, T43 v43, T44 v44, T45 v45) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),
v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29),
v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35),
v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41),
v42_(v42), v43_(v43), v44_(v44), v45_(v45) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
const T19 v19_;
const T20 v20_;
const T21 v21_;
const T22 v22_;
const T23 v23_;
const T24 v24_;
const T25 v25_;
const T26 v26_;
const T27 v27_;
const T28 v28_;
const T29 v29_;
const T30 v30_;
const T31 v31_;
const T32 v32_;
const T33 v33_;
const T34 v34_;
const T35 v35_;
const T36 v36_;
const T37 v37_;
const T38 v38_;
const T39 v39_;
const T40 v40_;
const T41 v41_;
const T42 v42_;
const T43 v43_;
const T44 v44_;
const T45 v45_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34, typename T35,
typename T36, typename T37, typename T38, typename T39, typename T40,
typename T41, typename T42, typename T43, typename T44, typename T45,
typename T46>
class ValueArray46 {
public:
ValueArray46(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) : v1_(v1), v2_(v2), v3_(v3),
v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40),
v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
const T19 v19_;
const T20 v20_;
const T21 v21_;
const T22 v22_;
const T23 v23_;
const T24 v24_;
const T25 v25_;
const T26 v26_;
const T27 v27_;
const T28 v28_;
const T29 v29_;
const T30 v30_;
const T31 v31_;
const T32 v32_;
const T33 v33_;
const T34 v34_;
const T35 v35_;
const T36 v36_;
const T37 v37_;
const T38 v38_;
const T39 v39_;
const T40 v40_;
const T41 v41_;
const T42 v42_;
const T43 v43_;
const T44 v44_;
const T45 v45_;
const T46 v46_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34, typename T35,
typename T36, typename T37, typename T38, typename T39, typename T40,
typename T41, typename T42, typename T43, typename T44, typename T45,
typename T46, typename T47>
class ValueArray47 {
public:
ValueArray47(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) : v1_(v1), v2_(v2),
v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40),
v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46),
v47_(v47) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_,
v47_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
const T19 v19_;
const T20 v20_;
const T21 v21_;
const T22 v22_;
const T23 v23_;
const T24 v24_;
const T25 v25_;
const T26 v26_;
const T27 v27_;
const T28 v28_;
const T29 v29_;
const T30 v30_;
const T31 v31_;
const T32 v32_;
const T33 v33_;
const T34 v34_;
const T35 v35_;
const T36 v36_;
const T37 v37_;
const T38 v38_;
const T39 v39_;
const T40 v40_;
const T41 v41_;
const T42 v42_;
const T43 v43_;
const T44 v44_;
const T45 v45_;
const T46 v46_;
const T47 v47_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34, typename T35,
typename T36, typename T37, typename T38, typename T39, typename T40,
typename T41, typename T42, typename T43, typename T44, typename T45,
typename T46, typename T47, typename T48>
class ValueArray48 {
public:
ValueArray48(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48) : v1_(v1),
v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),
v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33),
v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39),
v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45),
v46_(v46), v47_(v47), v48_(v48) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_,
v48_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
const T19 v19_;
const T20 v20_;
const T21 v21_;
const T22 v22_;
const T23 v23_;
const T24 v24_;
const T25 v25_;
const T26 v26_;
const T27 v27_;
const T28 v28_;
const T29 v29_;
const T30 v30_;
const T31 v31_;
const T32 v32_;
const T33 v33_;
const T34 v34_;
const T35 v35_;
const T36 v36_;
const T37 v37_;
const T38 v38_;
const T39 v39_;
const T40 v40_;
const T41 v41_;
const T42 v42_;
const T43 v43_;
const T44 v44_;
const T45 v45_;
const T46 v46_;
const T47 v47_;
const T48 v48_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34, typename T35,
typename T36, typename T37, typename T38, typename T39, typename T40,
typename T41, typename T42, typename T43, typename T44, typename T45,
typename T46, typename T47, typename T48, typename T49>
class ValueArray49 {
public:
ValueArray49(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48,
T49 v49) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44),
v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_,
v48_, v49_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
const T19 v19_;
const T20 v20_;
const T21 v21_;
const T22 v22_;
const T23 v23_;
const T24 v24_;
const T25 v25_;
const T26 v26_;
const T27 v27_;
const T28 v28_;
const T29 v29_;
const T30 v30_;
const T31 v31_;
const T32 v32_;
const T33 v33_;
const T34 v34_;
const T35 v35_;
const T36 v36_;
const T37 v37_;
const T38 v38_;
const T39 v39_;
const T40 v40_;
const T41 v41_;
const T42 v42_;
const T43 v43_;
const T44 v44_;
const T45 v45_;
const T46 v46_;
const T47 v47_;
const T48 v48_;
const T49 v49_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10,
typename T11, typename T12, typename T13, typename T14, typename T15,
typename T16, typename T17, typename T18, typename T19, typename T20,
typename T21, typename T22, typename T23, typename T24, typename T25,
typename T26, typename T27, typename T28, typename T29, typename T30,
typename T31, typename T32, typename T33, typename T34, typename T35,
typename T36, typename T37, typename T38, typename T39, typename T40,
typename T41, typename T42, typename T43, typename T44, typename T45,
typename T46, typename T47, typename T48, typename T49, typename T50>
class ValueArray50 {
public:
ValueArray50(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49,
T50 v50) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44),
v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49), v50_(v50) {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_,
v48_, v49_, v50_};
return ValuesIn(array);
}
private:
const T1 v1_;
const T2 v2_;
const T3 v3_;
const T4 v4_;
const T5 v5_;
const T6 v6_;
const T7 v7_;
const T8 v8_;
const T9 v9_;
const T10 v10_;
const T11 v11_;
const T12 v12_;
const T13 v13_;
const T14 v14_;
const T15 v15_;
const T16 v16_;
const T17 v17_;
const T18 v18_;
const T19 v19_;
const T20 v20_;
const T21 v21_;
const T22 v22_;
const T23 v23_;
const T24 v24_;
const T25 v25_;
const T26 v26_;
const T27 v27_;
const T28 v28_;
const T29 v29_;
const T30 v30_;
const T31 v31_;
const T32 v32_;
const T33 v33_;
const T34 v34_;
const T35 v35_;
const T36 v36_;
const T37 v37_;
const T38 v38_;
const T39 v39_;
const T40 v40_;
const T41 v41_;
const T42 v42_;
const T43 v43_;
const T44 v44_;
const T45 v45_;
const T46 v46_;
const T47 v47_;
const T48 v48_;
const T49 v49_;
const T50 v50_;
};
#ifdef GTEST_HAS_COMBINE
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Generates values from the Cartesian product of values produced
// by the argument generators.
//
template <typename T1, typename T2>
class CartesianProductGenerator2
: public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2> > {
public:
typedef ::std::tr1::tuple<T1, T2> ParamType;
CartesianProductGenerator2(const ParamGenerator<T1>& g1,
const ParamGenerator<T2>& g2)
: g1_(g1), g2_(g2) {}
virtual ~CartesianProductGenerator2() {}
virtual ParamIteratorInterface<ParamType>* Begin() const {
return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin());
}
virtual ParamIteratorInterface<ParamType>* End() const {
return new Iterator(this, g1_, g1_.end(), g2_, g2_.end());
}
private:
class Iterator : public ParamIteratorInterface<ParamType> {
public:
Iterator(const ParamGeneratorInterface<ParamType>* base,
const ParamGenerator<T1>& g1,
const typename ParamGenerator<T1>::iterator& current1,
const ParamGenerator<T2>& g2,
const typename ParamGenerator<T2>::iterator& current2)
: base_(base),
begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
begin2_(g2.begin()), end2_(g2.end()), current2_(current2) {
ComputeCurrentValue();
}
virtual ~Iterator() {}
virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
return base_;
}
// Advance should not be called on beyond-of-range iterators
// so no component iterators must be beyond end of range, either.
virtual void Advance() {
assert(!AtEnd());
++current2_;
if (current2_ == end2_) {
current2_ = begin2_;
++current1_;
}
ComputeCurrentValue();
}
virtual ParamIteratorInterface<ParamType>* Clone() const {
return new Iterator(*this);
}
virtual const ParamType* Current() const { return &current_value_; }
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
// Having the same base generator guarantees that the other
// iterator is of the same type and we can downcast.
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
<< "The program attempted to compare iterators "
<< "from different generators." << std::endl;
const Iterator* typed_other =
CheckedDowncastToActualType<const Iterator>(&other);
// We must report iterators equal if they both point beyond their
// respective ranges. That can happen in a variety of fashions,
// so we have to consult AtEnd().
return (AtEnd() && typed_other->AtEnd()) ||
(
current1_ == typed_other->current1_ &&
current2_ == typed_other->current2_);
}
private:
Iterator(const Iterator& other)
: base_(other.base_),
begin1_(other.begin1_),
end1_(other.end1_),
current1_(other.current1_),
begin2_(other.begin2_),
end2_(other.end2_),
current2_(other.current2_) {
ComputeCurrentValue();
}
void ComputeCurrentValue() {
if (!AtEnd())
current_value_ = ParamType(*current1_, *current2_);
}
bool AtEnd() const {
// We must report iterator past the end of the range when either of the
// component iterators has reached the end of its range.
return
current1_ == end1_ ||
current2_ == end2_;
}
const ParamGeneratorInterface<ParamType>* const base_;
// begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
// current[i]_ is the actual traversing iterator.
const typename ParamGenerator<T1>::iterator begin1_;
const typename ParamGenerator<T1>::iterator end1_;
typename ParamGenerator<T1>::iterator current1_;
const typename ParamGenerator<T2>::iterator begin2_;
const typename ParamGenerator<T2>::iterator end2_;
typename ParamGenerator<T2>::iterator current2_;
ParamType current_value_;
};
const ParamGenerator<T1> g1_;
const ParamGenerator<T2> g2_;
};
template <typename T1, typename T2, typename T3>
class CartesianProductGenerator3
: public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3> > {
public:
typedef ::std::tr1::tuple<T1, T2, T3> ParamType;
CartesianProductGenerator3(const ParamGenerator<T1>& g1,
const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3)
: g1_(g1), g2_(g2), g3_(g3) {}
virtual ~CartesianProductGenerator3() {}
virtual ParamIteratorInterface<ParamType>* Begin() const {
return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
g3_.begin());
}
virtual ParamIteratorInterface<ParamType>* End() const {
return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end());
}
private:
class Iterator : public ParamIteratorInterface<ParamType> {
public:
Iterator(const ParamGeneratorInterface<ParamType>* base,
const ParamGenerator<T1>& g1,
const typename ParamGenerator<T1>::iterator& current1,
const ParamGenerator<T2>& g2,
const typename ParamGenerator<T2>::iterator& current2,
const ParamGenerator<T3>& g3,
const typename ParamGenerator<T3>::iterator& current3)
: base_(base),
begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
begin3_(g3.begin()), end3_(g3.end()), current3_(current3) {
ComputeCurrentValue();
}
virtual ~Iterator() {}
virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
return base_;
}
// Advance should not be called on beyond-of-range iterators
// so no component iterators must be beyond end of range, either.
virtual void Advance() {
assert(!AtEnd());
++current3_;
if (current3_ == end3_) {
current3_ = begin3_;
++current2_;
}
if (current2_ == end2_) {
current2_ = begin2_;
++current1_;
}
ComputeCurrentValue();
}
virtual ParamIteratorInterface<ParamType>* Clone() const {
return new Iterator(*this);
}
virtual const ParamType* Current() const { return &current_value_; }
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
// Having the same base generator guarantees that the other
// iterator is of the same type and we can downcast.
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
<< "The program attempted to compare iterators "
<< "from different generators." << std::endl;
const Iterator* typed_other =
CheckedDowncastToActualType<const Iterator>(&other);
// We must report iterators equal if they both point beyond their
// respective ranges. That can happen in a variety of fashions,
// so we have to consult AtEnd().
return (AtEnd() && typed_other->AtEnd()) ||
(
current1_ == typed_other->current1_ &&
current2_ == typed_other->current2_ &&
current3_ == typed_other->current3_);
}
private:
Iterator(const Iterator& other)
: base_(other.base_),
begin1_(other.begin1_),
end1_(other.end1_),
current1_(other.current1_),
begin2_(other.begin2_),
end2_(other.end2_),
current2_(other.current2_),
begin3_(other.begin3_),
end3_(other.end3_),
current3_(other.current3_) {
ComputeCurrentValue();
}
void ComputeCurrentValue() {
if (!AtEnd())
current_value_ = ParamType(*current1_, *current2_, *current3_);
}
bool AtEnd() const {
// We must report iterator past the end of the range when either of the
// component iterators has reached the end of its range.
return
current1_ == end1_ ||
current2_ == end2_ ||
current3_ == end3_;
}
const ParamGeneratorInterface<ParamType>* const base_;
// begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
// current[i]_ is the actual traversing iterator.
const typename ParamGenerator<T1>::iterator begin1_;
const typename ParamGenerator<T1>::iterator end1_;
typename ParamGenerator<T1>::iterator current1_;
const typename ParamGenerator<T2>::iterator begin2_;
const typename ParamGenerator<T2>::iterator end2_;
typename ParamGenerator<T2>::iterator current2_;
const typename ParamGenerator<T3>::iterator begin3_;
const typename ParamGenerator<T3>::iterator end3_;
typename ParamGenerator<T3>::iterator current3_;
ParamType current_value_;
};
const ParamGenerator<T1> g1_;
const ParamGenerator<T2> g2_;
const ParamGenerator<T3> g3_;
};
template <typename T1, typename T2, typename T3, typename T4>
class CartesianProductGenerator4
: public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4> > {
public:
typedef ::std::tr1::tuple<T1, T2, T3, T4> ParamType;
CartesianProductGenerator4(const ParamGenerator<T1>& g1,
const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
const ParamGenerator<T4>& g4)
: g1_(g1), g2_(g2), g3_(g3), g4_(g4) {}
virtual ~CartesianProductGenerator4() {}
virtual ParamIteratorInterface<ParamType>* Begin() const {
return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
g3_.begin(), g4_, g4_.begin());
}
virtual ParamIteratorInterface<ParamType>* End() const {
return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
g4_, g4_.end());
}
private:
class Iterator : public ParamIteratorInterface<ParamType> {
public:
Iterator(const ParamGeneratorInterface<ParamType>* base,
const ParamGenerator<T1>& g1,
const typename ParamGenerator<T1>::iterator& current1,
const ParamGenerator<T2>& g2,
const typename ParamGenerator<T2>::iterator& current2,
const ParamGenerator<T3>& g3,
const typename ParamGenerator<T3>::iterator& current3,
const ParamGenerator<T4>& g4,
const typename ParamGenerator<T4>::iterator& current4)
: base_(base),
begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
begin4_(g4.begin()), end4_(g4.end()), current4_(current4) {
ComputeCurrentValue();
}
virtual ~Iterator() {}
virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
return base_;
}
// Advance should not be called on beyond-of-range iterators
// so no component iterators must be beyond end of range, either.
virtual void Advance() {
assert(!AtEnd());
++current4_;
if (current4_ == end4_) {
current4_ = begin4_;
++current3_;
}
if (current3_ == end3_) {
current3_ = begin3_;
++current2_;
}
if (current2_ == end2_) {
current2_ = begin2_;
++current1_;
}
ComputeCurrentValue();
}
virtual ParamIteratorInterface<ParamType>* Clone() const {
return new Iterator(*this);
}
virtual const ParamType* Current() const { return &current_value_; }
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
// Having the same base generator guarantees that the other
// iterator is of the same type and we can downcast.
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
<< "The program attempted to compare iterators "
<< "from different generators." << std::endl;
const Iterator* typed_other =
CheckedDowncastToActualType<const Iterator>(&other);
// We must report iterators equal if they both point beyond their
// respective ranges. That can happen in a variety of fashions,
// so we have to consult AtEnd().
return (AtEnd() && typed_other->AtEnd()) ||
(
current1_ == typed_other->current1_ &&
current2_ == typed_other->current2_ &&
current3_ == typed_other->current3_ &&
current4_ == typed_other->current4_);
}
private:
Iterator(const Iterator& other)
: base_(other.base_),
begin1_(other.begin1_),
end1_(other.end1_),
current1_(other.current1_),
begin2_(other.begin2_),
end2_(other.end2_),
current2_(other.current2_),
begin3_(other.begin3_),
end3_(other.end3_),
current3_(other.current3_),
begin4_(other.begin4_),
end4_(other.end4_),
current4_(other.current4_) {
ComputeCurrentValue();
}
void ComputeCurrentValue() {
if (!AtEnd())
current_value_ = ParamType(*current1_, *current2_, *current3_,
*current4_);
}
bool AtEnd() const {
// We must report iterator past the end of the range when either of the
// component iterators has reached the end of its range.
return
current1_ == end1_ ||
current2_ == end2_ ||
current3_ == end3_ ||
current4_ == end4_;
}
const ParamGeneratorInterface<ParamType>* const base_;
// begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
// current[i]_ is the actual traversing iterator.
const typename ParamGenerator<T1>::iterator begin1_;
const typename ParamGenerator<T1>::iterator end1_;
typename ParamGenerator<T1>::iterator current1_;
const typename ParamGenerator<T2>::iterator begin2_;
const typename ParamGenerator<T2>::iterator end2_;
typename ParamGenerator<T2>::iterator current2_;
const typename ParamGenerator<T3>::iterator begin3_;
const typename ParamGenerator<T3>::iterator end3_;
typename ParamGenerator<T3>::iterator current3_;
const typename ParamGenerator<T4>::iterator begin4_;
const typename ParamGenerator<T4>::iterator end4_;
typename ParamGenerator<T4>::iterator current4_;
ParamType current_value_;
};
const ParamGenerator<T1> g1_;
const ParamGenerator<T2> g2_;
const ParamGenerator<T3> g3_;
const ParamGenerator<T4> g4_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5>
class CartesianProductGenerator5
: public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5> > {
public:
typedef ::std::tr1::tuple<T1, T2, T3, T4, T5> ParamType;
CartesianProductGenerator5(const ParamGenerator<T1>& g1,
const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5)
: g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {}
virtual ~CartesianProductGenerator5() {}
virtual ParamIteratorInterface<ParamType>* Begin() const {
return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin());
}
virtual ParamIteratorInterface<ParamType>* End() const {
return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
g4_, g4_.end(), g5_, g5_.end());
}
private:
class Iterator : public ParamIteratorInterface<ParamType> {
public:
Iterator(const ParamGeneratorInterface<ParamType>* base,
const ParamGenerator<T1>& g1,
const typename ParamGenerator<T1>::iterator& current1,
const ParamGenerator<T2>& g2,
const typename ParamGenerator<T2>::iterator& current2,
const ParamGenerator<T3>& g3,
const typename ParamGenerator<T3>::iterator& current3,
const ParamGenerator<T4>& g4,
const typename ParamGenerator<T4>::iterator& current4,
const ParamGenerator<T5>& g5,
const typename ParamGenerator<T5>::iterator& current5)
: base_(base),
begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
begin5_(g5.begin()), end5_(g5.end()), current5_(current5) {
ComputeCurrentValue();
}
virtual ~Iterator() {}
virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
return base_;
}
// Advance should not be called on beyond-of-range iterators
// so no component iterators must be beyond end of range, either.
virtual void Advance() {
assert(!AtEnd());
++current5_;
if (current5_ == end5_) {
current5_ = begin5_;
++current4_;
}
if (current4_ == end4_) {
current4_ = begin4_;
++current3_;
}
if (current3_ == end3_) {
current3_ = begin3_;
++current2_;
}
if (current2_ == end2_) {
current2_ = begin2_;
++current1_;
}
ComputeCurrentValue();
}
virtual ParamIteratorInterface<ParamType>* Clone() const {
return new Iterator(*this);
}
virtual const ParamType* Current() const { return &current_value_; }
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
// Having the same base generator guarantees that the other
// iterator is of the same type and we can downcast.
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
<< "The program attempted to compare iterators "
<< "from different generators." << std::endl;
const Iterator* typed_other =
CheckedDowncastToActualType<const Iterator>(&other);
// We must report iterators equal if they both point beyond their
// respective ranges. That can happen in a variety of fashions,
// so we have to consult AtEnd().
return (AtEnd() && typed_other->AtEnd()) ||
(
current1_ == typed_other->current1_ &&
current2_ == typed_other->current2_ &&
current3_ == typed_other->current3_ &&
current4_ == typed_other->current4_ &&
current5_ == typed_other->current5_);
}
private:
Iterator(const Iterator& other)
: base_(other.base_),
begin1_(other.begin1_),
end1_(other.end1_),
current1_(other.current1_),
begin2_(other.begin2_),
end2_(other.end2_),
current2_(other.current2_),
begin3_(other.begin3_),
end3_(other.end3_),
current3_(other.current3_),
begin4_(other.begin4_),
end4_(other.end4_),
current4_(other.current4_),
begin5_(other.begin5_),
end5_(other.end5_),
current5_(other.current5_) {
ComputeCurrentValue();
}
void ComputeCurrentValue() {
if (!AtEnd())
current_value_ = ParamType(*current1_, *current2_, *current3_,
*current4_, *current5_);
}
bool AtEnd() const {
// We must report iterator past the end of the range when either of the
// component iterators has reached the end of its range.
return
current1_ == end1_ ||
current2_ == end2_ ||
current3_ == end3_ ||
current4_ == end4_ ||
current5_ == end5_;
}
const ParamGeneratorInterface<ParamType>* const base_;
// begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
// current[i]_ is the actual traversing iterator.
const typename ParamGenerator<T1>::iterator begin1_;
const typename ParamGenerator<T1>::iterator end1_;
typename ParamGenerator<T1>::iterator current1_;
const typename ParamGenerator<T2>::iterator begin2_;
const typename ParamGenerator<T2>::iterator end2_;
typename ParamGenerator<T2>::iterator current2_;
const typename ParamGenerator<T3>::iterator begin3_;
const typename ParamGenerator<T3>::iterator end3_;
typename ParamGenerator<T3>::iterator current3_;
const typename ParamGenerator<T4>::iterator begin4_;
const typename ParamGenerator<T4>::iterator end4_;
typename ParamGenerator<T4>::iterator current4_;
const typename ParamGenerator<T5>::iterator begin5_;
const typename ParamGenerator<T5>::iterator end5_;
typename ParamGenerator<T5>::iterator current5_;
ParamType current_value_;
};
const ParamGenerator<T1> g1_;
const ParamGenerator<T2> g2_;
const ParamGenerator<T3> g3_;
const ParamGenerator<T4> g4_;
const ParamGenerator<T5> g5_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6>
class CartesianProductGenerator6
: public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5,
T6> > {
public:
typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> ParamType;
CartesianProductGenerator6(const ParamGenerator<T1>& g1,
const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
const ParamGenerator<T6>& g6)
: g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {}
virtual ~CartesianProductGenerator6() {}
virtual ParamIteratorInterface<ParamType>* Begin() const {
return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin());
}
virtual ParamIteratorInterface<ParamType>* End() const {
return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end());
}
private:
class Iterator : public ParamIteratorInterface<ParamType> {
public:
Iterator(const ParamGeneratorInterface<ParamType>* base,
const ParamGenerator<T1>& g1,
const typename ParamGenerator<T1>::iterator& current1,
const ParamGenerator<T2>& g2,
const typename ParamGenerator<T2>::iterator& current2,
const ParamGenerator<T3>& g3,
const typename ParamGenerator<T3>::iterator& current3,
const ParamGenerator<T4>& g4,
const typename ParamGenerator<T4>::iterator& current4,
const ParamGenerator<T5>& g5,
const typename ParamGenerator<T5>::iterator& current5,
const ParamGenerator<T6>& g6,
const typename ParamGenerator<T6>::iterator& current6)
: base_(base),
begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
begin6_(g6.begin()), end6_(g6.end()), current6_(current6) {
ComputeCurrentValue();
}
virtual ~Iterator() {}
virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
return base_;
}
// Advance should not be called on beyond-of-range iterators
// so no component iterators must be beyond end of range, either.
virtual void Advance() {
assert(!AtEnd());
++current6_;
if (current6_ == end6_) {
current6_ = begin6_;
++current5_;
}
if (current5_ == end5_) {
current5_ = begin5_;
++current4_;
}
if (current4_ == end4_) {
current4_ = begin4_;
++current3_;
}
if (current3_ == end3_) {
current3_ = begin3_;
++current2_;
}
if (current2_ == end2_) {
current2_ = begin2_;
++current1_;
}
ComputeCurrentValue();
}
virtual ParamIteratorInterface<ParamType>* Clone() const {
return new Iterator(*this);
}
virtual const ParamType* Current() const { return &current_value_; }
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
// Having the same base generator guarantees that the other
// iterator is of the same type and we can downcast.
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
<< "The program attempted to compare iterators "
<< "from different generators." << std::endl;
const Iterator* typed_other =
CheckedDowncastToActualType<const Iterator>(&other);
// We must report iterators equal if they both point beyond their
// respective ranges. That can happen in a variety of fashions,
// so we have to consult AtEnd().
return (AtEnd() && typed_other->AtEnd()) ||
(
current1_ == typed_other->current1_ &&
current2_ == typed_other->current2_ &&
current3_ == typed_other->current3_ &&
current4_ == typed_other->current4_ &&
current5_ == typed_other->current5_ &&
current6_ == typed_other->current6_);
}
private:
Iterator(const Iterator& other)
: base_(other.base_),
begin1_(other.begin1_),
end1_(other.end1_),
current1_(other.current1_),
begin2_(other.begin2_),
end2_(other.end2_),
current2_(other.current2_),
begin3_(other.begin3_),
end3_(other.end3_),
current3_(other.current3_),
begin4_(other.begin4_),
end4_(other.end4_),
current4_(other.current4_),
begin5_(other.begin5_),
end5_(other.end5_),
current5_(other.current5_),
begin6_(other.begin6_),
end6_(other.end6_),
current6_(other.current6_) {
ComputeCurrentValue();
}
void ComputeCurrentValue() {
if (!AtEnd())
current_value_ = ParamType(*current1_, *current2_, *current3_,
*current4_, *current5_, *current6_);
}
bool AtEnd() const {
// We must report iterator past the end of the range when either of the
// component iterators has reached the end of its range.
return
current1_ == end1_ ||
current2_ == end2_ ||
current3_ == end3_ ||
current4_ == end4_ ||
current5_ == end5_ ||
current6_ == end6_;
}
const ParamGeneratorInterface<ParamType>* const base_;
// begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
// current[i]_ is the actual traversing iterator.
const typename ParamGenerator<T1>::iterator begin1_;
const typename ParamGenerator<T1>::iterator end1_;
typename ParamGenerator<T1>::iterator current1_;
const typename ParamGenerator<T2>::iterator begin2_;
const typename ParamGenerator<T2>::iterator end2_;
typename ParamGenerator<T2>::iterator current2_;
const typename ParamGenerator<T3>::iterator begin3_;
const typename ParamGenerator<T3>::iterator end3_;
typename ParamGenerator<T3>::iterator current3_;
const typename ParamGenerator<T4>::iterator begin4_;
const typename ParamGenerator<T4>::iterator end4_;
typename ParamGenerator<T4>::iterator current4_;
const typename ParamGenerator<T5>::iterator begin5_;
const typename ParamGenerator<T5>::iterator end5_;
typename ParamGenerator<T5>::iterator current5_;
const typename ParamGenerator<T6>::iterator begin6_;
const typename ParamGenerator<T6>::iterator end6_;
typename ParamGenerator<T6>::iterator current6_;
ParamType current_value_;
};
const ParamGenerator<T1> g1_;
const ParamGenerator<T2> g2_;
const ParamGenerator<T3> g3_;
const ParamGenerator<T4> g4_;
const ParamGenerator<T5> g5_;
const ParamGenerator<T6> g6_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7>
class CartesianProductGenerator7
: public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
T7> > {
public:
typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7> ParamType;
CartesianProductGenerator7(const ParamGenerator<T1>& g1,
const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7)
: g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {}
virtual ~CartesianProductGenerator7() {}
virtual ParamIteratorInterface<ParamType>* Begin() const {
return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
g7_.begin());
}
virtual ParamIteratorInterface<ParamType>* End() const {
return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end());
}
private:
class Iterator : public ParamIteratorInterface<ParamType> {
public:
Iterator(const ParamGeneratorInterface<ParamType>* base,
const ParamGenerator<T1>& g1,
const typename ParamGenerator<T1>::iterator& current1,
const ParamGenerator<T2>& g2,
const typename ParamGenerator<T2>::iterator& current2,
const ParamGenerator<T3>& g3,
const typename ParamGenerator<T3>::iterator& current3,
const ParamGenerator<T4>& g4,
const typename ParamGenerator<T4>::iterator& current4,
const ParamGenerator<T5>& g5,
const typename ParamGenerator<T5>::iterator& current5,
const ParamGenerator<T6>& g6,
const typename ParamGenerator<T6>::iterator& current6,
const ParamGenerator<T7>& g7,
const typename ParamGenerator<T7>::iterator& current7)
: base_(base),
begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
begin7_(g7.begin()), end7_(g7.end()), current7_(current7) {
ComputeCurrentValue();
}
virtual ~Iterator() {}
virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
return base_;
}
// Advance should not be called on beyond-of-range iterators
// so no component iterators must be beyond end of range, either.
virtual void Advance() {
assert(!AtEnd());
++current7_;
if (current7_ == end7_) {
current7_ = begin7_;
++current6_;
}
if (current6_ == end6_) {
current6_ = begin6_;
++current5_;
}
if (current5_ == end5_) {
current5_ = begin5_;
++current4_;
}
if (current4_ == end4_) {
current4_ = begin4_;
++current3_;
}
if (current3_ == end3_) {
current3_ = begin3_;
++current2_;
}
if (current2_ == end2_) {
current2_ = begin2_;
++current1_;
}
ComputeCurrentValue();
}
virtual ParamIteratorInterface<ParamType>* Clone() const {
return new Iterator(*this);
}
virtual const ParamType* Current() const { return &current_value_; }
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
// Having the same base generator guarantees that the other
// iterator is of the same type and we can downcast.
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
<< "The program attempted to compare iterators "
<< "from different generators." << std::endl;
const Iterator* typed_other =
CheckedDowncastToActualType<const Iterator>(&other);
// We must report iterators equal if they both point beyond their
// respective ranges. That can happen in a variety of fashions,
// so we have to consult AtEnd().
return (AtEnd() && typed_other->AtEnd()) ||
(
current1_ == typed_other->current1_ &&
current2_ == typed_other->current2_ &&
current3_ == typed_other->current3_ &&
current4_ == typed_other->current4_ &&
current5_ == typed_other->current5_ &&
current6_ == typed_other->current6_ &&
current7_ == typed_other->current7_);
}
private:
Iterator(const Iterator& other)
: base_(other.base_),
begin1_(other.begin1_),
end1_(other.end1_),
current1_(other.current1_),
begin2_(other.begin2_),
end2_(other.end2_),
current2_(other.current2_),
begin3_(other.begin3_),
end3_(other.end3_),
current3_(other.current3_),
begin4_(other.begin4_),
end4_(other.end4_),
current4_(other.current4_),
begin5_(other.begin5_),
end5_(other.end5_),
current5_(other.current5_),
begin6_(other.begin6_),
end6_(other.end6_),
current6_(other.current6_),
begin7_(other.begin7_),
end7_(other.end7_),
current7_(other.current7_) {
ComputeCurrentValue();
}
void ComputeCurrentValue() {
if (!AtEnd())
current_value_ = ParamType(*current1_, *current2_, *current3_,
*current4_, *current5_, *current6_, *current7_);
}
bool AtEnd() const {
// We must report iterator past the end of the range when either of the
// component iterators has reached the end of its range.
return
current1_ == end1_ ||
current2_ == end2_ ||
current3_ == end3_ ||
current4_ == end4_ ||
current5_ == end5_ ||
current6_ == end6_ ||
current7_ == end7_;
}
const ParamGeneratorInterface<ParamType>* const base_;
// begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
// current[i]_ is the actual traversing iterator.
const typename ParamGenerator<T1>::iterator begin1_;
const typename ParamGenerator<T1>::iterator end1_;
typename ParamGenerator<T1>::iterator current1_;
const typename ParamGenerator<T2>::iterator begin2_;
const typename ParamGenerator<T2>::iterator end2_;
typename ParamGenerator<T2>::iterator current2_;
const typename ParamGenerator<T3>::iterator begin3_;
const typename ParamGenerator<T3>::iterator end3_;
typename ParamGenerator<T3>::iterator current3_;
const typename ParamGenerator<T4>::iterator begin4_;
const typename ParamGenerator<T4>::iterator end4_;
typename ParamGenerator<T4>::iterator current4_;
const typename ParamGenerator<T5>::iterator begin5_;
const typename ParamGenerator<T5>::iterator end5_;
typename ParamGenerator<T5>::iterator current5_;
const typename ParamGenerator<T6>::iterator begin6_;
const typename ParamGenerator<T6>::iterator end6_;
typename ParamGenerator<T6>::iterator current6_;
const typename ParamGenerator<T7>::iterator begin7_;
const typename ParamGenerator<T7>::iterator end7_;
typename ParamGenerator<T7>::iterator current7_;
ParamType current_value_;
};
const ParamGenerator<T1> g1_;
const ParamGenerator<T2> g2_;
const ParamGenerator<T3> g3_;
const ParamGenerator<T4> g4_;
const ParamGenerator<T5> g5_;
const ParamGenerator<T6> g6_;
const ParamGenerator<T7> g7_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8>
class CartesianProductGenerator8
: public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
T7, T8> > {
public:
typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8> ParamType;
CartesianProductGenerator8(const ParamGenerator<T1>& g1,
const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,
const ParamGenerator<T8>& g8)
: g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7),
g8_(g8) {}
virtual ~CartesianProductGenerator8() {}
virtual ParamIteratorInterface<ParamType>* Begin() const {
return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
g7_.begin(), g8_, g8_.begin());
}
virtual ParamIteratorInterface<ParamType>* End() const {
return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,
g8_.end());
}
private:
class Iterator : public ParamIteratorInterface<ParamType> {
public:
Iterator(const ParamGeneratorInterface<ParamType>* base,
const ParamGenerator<T1>& g1,
const typename ParamGenerator<T1>::iterator& current1,
const ParamGenerator<T2>& g2,
const typename ParamGenerator<T2>::iterator& current2,
const ParamGenerator<T3>& g3,
const typename ParamGenerator<T3>::iterator& current3,
const ParamGenerator<T4>& g4,
const typename ParamGenerator<T4>::iterator& current4,
const ParamGenerator<T5>& g5,
const typename ParamGenerator<T5>::iterator& current5,
const ParamGenerator<T6>& g6,
const typename ParamGenerator<T6>::iterator& current6,
const ParamGenerator<T7>& g7,
const typename ParamGenerator<T7>::iterator& current7,
const ParamGenerator<T8>& g8,
const typename ParamGenerator<T8>::iterator& current8)
: base_(base),
begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
begin7_(g7.begin()), end7_(g7.end()), current7_(current7),
begin8_(g8.begin()), end8_(g8.end()), current8_(current8) {
ComputeCurrentValue();
}
virtual ~Iterator() {}
virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
return base_;
}
// Advance should not be called on beyond-of-range iterators
// so no component iterators must be beyond end of range, either.
virtual void Advance() {
assert(!AtEnd());
++current8_;
if (current8_ == end8_) {
current8_ = begin8_;
++current7_;
}
if (current7_ == end7_) {
current7_ = begin7_;
++current6_;
}
if (current6_ == end6_) {
current6_ = begin6_;
++current5_;
}
if (current5_ == end5_) {
current5_ = begin5_;
++current4_;
}
if (current4_ == end4_) {
current4_ = begin4_;
++current3_;
}
if (current3_ == end3_) {
current3_ = begin3_;
++current2_;
}
if (current2_ == end2_) {
current2_ = begin2_;
++current1_;
}
ComputeCurrentValue();
}
virtual ParamIteratorInterface<ParamType>* Clone() const {
return new Iterator(*this);
}
virtual const ParamType* Current() const { return &current_value_; }
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
// Having the same base generator guarantees that the other
// iterator is of the same type and we can downcast.
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
<< "The program attempted to compare iterators "
<< "from different generators." << std::endl;
const Iterator* typed_other =
CheckedDowncastToActualType<const Iterator>(&other);
// We must report iterators equal if they both point beyond their
// respective ranges. That can happen in a variety of fashions,
// so we have to consult AtEnd().
return (AtEnd() && typed_other->AtEnd()) ||
(
current1_ == typed_other->current1_ &&
current2_ == typed_other->current2_ &&
current3_ == typed_other->current3_ &&
current4_ == typed_other->current4_ &&
current5_ == typed_other->current5_ &&
current6_ == typed_other->current6_ &&
current7_ == typed_other->current7_ &&
current8_ == typed_other->current8_);
}
private:
Iterator(const Iterator& other)
: base_(other.base_),
begin1_(other.begin1_),
end1_(other.end1_),
current1_(other.current1_),
begin2_(other.begin2_),
end2_(other.end2_),
current2_(other.current2_),
begin3_(other.begin3_),
end3_(other.end3_),
current3_(other.current3_),
begin4_(other.begin4_),
end4_(other.end4_),
current4_(other.current4_),
begin5_(other.begin5_),
end5_(other.end5_),
current5_(other.current5_),
begin6_(other.begin6_),
end6_(other.end6_),
current6_(other.current6_),
begin7_(other.begin7_),
end7_(other.end7_),
current7_(other.current7_),
begin8_(other.begin8_),
end8_(other.end8_),
current8_(other.current8_) {
ComputeCurrentValue();
}
void ComputeCurrentValue() {
if (!AtEnd())
current_value_ = ParamType(*current1_, *current2_, *current3_,
*current4_, *current5_, *current6_, *current7_, *current8_);
}
bool AtEnd() const {
// We must report iterator past the end of the range when either of the
// component iterators has reached the end of its range.
return
current1_ == end1_ ||
current2_ == end2_ ||
current3_ == end3_ ||
current4_ == end4_ ||
current5_ == end5_ ||
current6_ == end6_ ||
current7_ == end7_ ||
current8_ == end8_;
}
const ParamGeneratorInterface<ParamType>* const base_;
// begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
// current[i]_ is the actual traversing iterator.
const typename ParamGenerator<T1>::iterator begin1_;
const typename ParamGenerator<T1>::iterator end1_;
typename ParamGenerator<T1>::iterator current1_;
const typename ParamGenerator<T2>::iterator begin2_;
const typename ParamGenerator<T2>::iterator end2_;
typename ParamGenerator<T2>::iterator current2_;
const typename ParamGenerator<T3>::iterator begin3_;
const typename ParamGenerator<T3>::iterator end3_;
typename ParamGenerator<T3>::iterator current3_;
const typename ParamGenerator<T4>::iterator begin4_;
const typename ParamGenerator<T4>::iterator end4_;
typename ParamGenerator<T4>::iterator current4_;
const typename ParamGenerator<T5>::iterator begin5_;
const typename ParamGenerator<T5>::iterator end5_;
typename ParamGenerator<T5>::iterator current5_;
const typename ParamGenerator<T6>::iterator begin6_;
const typename ParamGenerator<T6>::iterator end6_;
typename ParamGenerator<T6>::iterator current6_;
const typename ParamGenerator<T7>::iterator begin7_;
const typename ParamGenerator<T7>::iterator end7_;
typename ParamGenerator<T7>::iterator current7_;
const typename ParamGenerator<T8>::iterator begin8_;
const typename ParamGenerator<T8>::iterator end8_;
typename ParamGenerator<T8>::iterator current8_;
ParamType current_value_;
};
const ParamGenerator<T1> g1_;
const ParamGenerator<T2> g2_;
const ParamGenerator<T3> g3_;
const ParamGenerator<T4> g4_;
const ParamGenerator<T5> g5_;
const ParamGenerator<T6> g6_;
const ParamGenerator<T7> g7_;
const ParamGenerator<T8> g8_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9>
class CartesianProductGenerator9
: public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
T7, T8, T9> > {
public:
typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9> ParamType;
CartesianProductGenerator9(const ParamGenerator<T1>& g1,
const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,
const ParamGenerator<T8>& g8, const ParamGenerator<T9>& g9)
: g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
g9_(g9) {}
virtual ~CartesianProductGenerator9() {}
virtual ParamIteratorInterface<ParamType>* Begin() const {
return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin());
}
virtual ParamIteratorInterface<ParamType>* End() const {
return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,
g8_.end(), g9_, g9_.end());
}
private:
class Iterator : public ParamIteratorInterface<ParamType> {
public:
Iterator(const ParamGeneratorInterface<ParamType>* base,
const ParamGenerator<T1>& g1,
const typename ParamGenerator<T1>::iterator& current1,
const ParamGenerator<T2>& g2,
const typename ParamGenerator<T2>::iterator& current2,
const ParamGenerator<T3>& g3,
const typename ParamGenerator<T3>::iterator& current3,
const ParamGenerator<T4>& g4,
const typename ParamGenerator<T4>::iterator& current4,
const ParamGenerator<T5>& g5,
const typename ParamGenerator<T5>::iterator& current5,
const ParamGenerator<T6>& g6,
const typename ParamGenerator<T6>::iterator& current6,
const ParamGenerator<T7>& g7,
const typename ParamGenerator<T7>::iterator& current7,
const ParamGenerator<T8>& g8,
const typename ParamGenerator<T8>::iterator& current8,
const ParamGenerator<T9>& g9,
const typename ParamGenerator<T9>::iterator& current9)
: base_(base),
begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
begin7_(g7.begin()), end7_(g7.end()), current7_(current7),
begin8_(g8.begin()), end8_(g8.end()), current8_(current8),
begin9_(g9.begin()), end9_(g9.end()), current9_(current9) {
ComputeCurrentValue();
}
virtual ~Iterator() {}
virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
return base_;
}
// Advance should not be called on beyond-of-range iterators
// so no component iterators must be beyond end of range, either.
virtual void Advance() {
assert(!AtEnd());
++current9_;
if (current9_ == end9_) {
current9_ = begin9_;
++current8_;
}
if (current8_ == end8_) {
current8_ = begin8_;
++current7_;
}
if (current7_ == end7_) {
current7_ = begin7_;
++current6_;
}
if (current6_ == end6_) {
current6_ = begin6_;
++current5_;
}
if (current5_ == end5_) {
current5_ = begin5_;
++current4_;
}
if (current4_ == end4_) {
current4_ = begin4_;
++current3_;
}
if (current3_ == end3_) {
current3_ = begin3_;
++current2_;
}
if (current2_ == end2_) {
current2_ = begin2_;
++current1_;
}
ComputeCurrentValue();
}
virtual ParamIteratorInterface<ParamType>* Clone() const {
return new Iterator(*this);
}
virtual const ParamType* Current() const { return &current_value_; }
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
// Having the same base generator guarantees that the other
// iterator is of the same type and we can downcast.
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
<< "The program attempted to compare iterators "
<< "from different generators." << std::endl;
const Iterator* typed_other =
CheckedDowncastToActualType<const Iterator>(&other);
// We must report iterators equal if they both point beyond their
// respective ranges. That can happen in a variety of fashions,
// so we have to consult AtEnd().
return (AtEnd() && typed_other->AtEnd()) ||
(
current1_ == typed_other->current1_ &&
current2_ == typed_other->current2_ &&
current3_ == typed_other->current3_ &&
current4_ == typed_other->current4_ &&
current5_ == typed_other->current5_ &&
current6_ == typed_other->current6_ &&
current7_ == typed_other->current7_ &&
current8_ == typed_other->current8_ &&
current9_ == typed_other->current9_);
}
private:
Iterator(const Iterator& other)
: base_(other.base_),
begin1_(other.begin1_),
end1_(other.end1_),
current1_(other.current1_),
begin2_(other.begin2_),
end2_(other.end2_),
current2_(other.current2_),
begin3_(other.begin3_),
end3_(other.end3_),
current3_(other.current3_),
begin4_(other.begin4_),
end4_(other.end4_),
current4_(other.current4_),
begin5_(other.begin5_),
end5_(other.end5_),
current5_(other.current5_),
begin6_(other.begin6_),
end6_(other.end6_),
current6_(other.current6_),
begin7_(other.begin7_),
end7_(other.end7_),
current7_(other.current7_),
begin8_(other.begin8_),
end8_(other.end8_),
current8_(other.current8_),
begin9_(other.begin9_),
end9_(other.end9_),
current9_(other.current9_) {
ComputeCurrentValue();
}
void ComputeCurrentValue() {
if (!AtEnd())
current_value_ = ParamType(*current1_, *current2_, *current3_,
*current4_, *current5_, *current6_, *current7_, *current8_,
*current9_);
}
bool AtEnd() const {
// We must report iterator past the end of the range when either of the
// component iterators has reached the end of its range.
return
current1_ == end1_ ||
current2_ == end2_ ||
current3_ == end3_ ||
current4_ == end4_ ||
current5_ == end5_ ||
current6_ == end6_ ||
current7_ == end7_ ||
current8_ == end8_ ||
current9_ == end9_;
}
const ParamGeneratorInterface<ParamType>* const base_;
// begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
// current[i]_ is the actual traversing iterator.
const typename ParamGenerator<T1>::iterator begin1_;
const typename ParamGenerator<T1>::iterator end1_;
typename ParamGenerator<T1>::iterator current1_;
const typename ParamGenerator<T2>::iterator begin2_;
const typename ParamGenerator<T2>::iterator end2_;
typename ParamGenerator<T2>::iterator current2_;
const typename ParamGenerator<T3>::iterator begin3_;
const typename ParamGenerator<T3>::iterator end3_;
typename ParamGenerator<T3>::iterator current3_;
const typename ParamGenerator<T4>::iterator begin4_;
const typename ParamGenerator<T4>::iterator end4_;
typename ParamGenerator<T4>::iterator current4_;
const typename ParamGenerator<T5>::iterator begin5_;
const typename ParamGenerator<T5>::iterator end5_;
typename ParamGenerator<T5>::iterator current5_;
const typename ParamGenerator<T6>::iterator begin6_;
const typename ParamGenerator<T6>::iterator end6_;
typename ParamGenerator<T6>::iterator current6_;
const typename ParamGenerator<T7>::iterator begin7_;
const typename ParamGenerator<T7>::iterator end7_;
typename ParamGenerator<T7>::iterator current7_;
const typename ParamGenerator<T8>::iterator begin8_;
const typename ParamGenerator<T8>::iterator end8_;
typename ParamGenerator<T8>::iterator current8_;
const typename ParamGenerator<T9>::iterator begin9_;
const typename ParamGenerator<T9>::iterator end9_;
typename ParamGenerator<T9>::iterator current9_;
ParamType current_value_;
};
const ParamGenerator<T1> g1_;
const ParamGenerator<T2> g2_;
const ParamGenerator<T3> g3_;
const ParamGenerator<T4> g4_;
const ParamGenerator<T5> g5_;
const ParamGenerator<T6> g6_;
const ParamGenerator<T7> g7_;
const ParamGenerator<T8> g8_;
const ParamGenerator<T9> g9_;
};
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10>
class CartesianProductGenerator10
: public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
T7, T8, T9, T10> > {
public:
typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> ParamType;
CartesianProductGenerator10(const ParamGenerator<T1>& g1,
const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,
const ParamGenerator<T8>& g8, const ParamGenerator<T9>& g9,
const ParamGenerator<T10>& g10)
: g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
g9_(g9), g10_(g10) {}
virtual ~CartesianProductGenerator10() {}
virtual ParamIteratorInterface<ParamType>* Begin() const {
return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin(), g10_, g10_.begin());
}
virtual ParamIteratorInterface<ParamType>* End() const {
return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,
g8_.end(), g9_, g9_.end(), g10_, g10_.end());
}
private:
class Iterator : public ParamIteratorInterface<ParamType> {
public:
Iterator(const ParamGeneratorInterface<ParamType>* base,
const ParamGenerator<T1>& g1,
const typename ParamGenerator<T1>::iterator& current1,
const ParamGenerator<T2>& g2,
const typename ParamGenerator<T2>::iterator& current2,
const ParamGenerator<T3>& g3,
const typename ParamGenerator<T3>::iterator& current3,
const ParamGenerator<T4>& g4,
const typename ParamGenerator<T4>::iterator& current4,
const ParamGenerator<T5>& g5,
const typename ParamGenerator<T5>::iterator& current5,
const ParamGenerator<T6>& g6,
const typename ParamGenerator<T6>::iterator& current6,
const ParamGenerator<T7>& g7,
const typename ParamGenerator<T7>::iterator& current7,
const ParamGenerator<T8>& g8,
const typename ParamGenerator<T8>::iterator& current8,
const ParamGenerator<T9>& g9,
const typename ParamGenerator<T9>::iterator& current9,
const ParamGenerator<T10>& g10,
const typename ParamGenerator<T10>::iterator& current10)
: base_(base),
begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
begin7_(g7.begin()), end7_(g7.end()), current7_(current7),
begin8_(g8.begin()), end8_(g8.end()), current8_(current8),
begin9_(g9.begin()), end9_(g9.end()), current9_(current9),
begin10_(g10.begin()), end10_(g10.end()), current10_(current10) {
ComputeCurrentValue();
}
virtual ~Iterator() {}
virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
return base_;
}
// Advance should not be called on beyond-of-range iterators
// so no component iterators must be beyond end of range, either.
virtual void Advance() {
assert(!AtEnd());
++current10_;
if (current10_ == end10_) {
current10_ = begin10_;
++current9_;
}
if (current9_ == end9_) {
current9_ = begin9_;
++current8_;
}
if (current8_ == end8_) {
current8_ = begin8_;
++current7_;
}
if (current7_ == end7_) {
current7_ = begin7_;
++current6_;
}
if (current6_ == end6_) {
current6_ = begin6_;
++current5_;
}
if (current5_ == end5_) {
current5_ = begin5_;
++current4_;
}
if (current4_ == end4_) {
current4_ = begin4_;
++current3_;
}
if (current3_ == end3_) {
current3_ = begin3_;
++current2_;
}
if (current2_ == end2_) {
current2_ = begin2_;
++current1_;
}
ComputeCurrentValue();
}
virtual ParamIteratorInterface<ParamType>* Clone() const {
return new Iterator(*this);
}
virtual const ParamType* Current() const { return &current_value_; }
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
// Having the same base generator guarantees that the other
// iterator is of the same type and we can downcast.
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
<< "The program attempted to compare iterators "
<< "from different generators." << std::endl;
const Iterator* typed_other =
CheckedDowncastToActualType<const Iterator>(&other);
// We must report iterators equal if they both point beyond their
// respective ranges. That can happen in a variety of fashions,
// so we have to consult AtEnd().
return (AtEnd() && typed_other->AtEnd()) ||
(
current1_ == typed_other->current1_ &&
current2_ == typed_other->current2_ &&
current3_ == typed_other->current3_ &&
current4_ == typed_other->current4_ &&
current5_ == typed_other->current5_ &&
current6_ == typed_other->current6_ &&
current7_ == typed_other->current7_ &&
current8_ == typed_other->current8_ &&
current9_ == typed_other->current9_ &&
current10_ == typed_other->current10_);
}
private:
Iterator(const Iterator& other)
: base_(other.base_),
begin1_(other.begin1_),
end1_(other.end1_),
current1_(other.current1_),
begin2_(other.begin2_),
end2_(other.end2_),
current2_(other.current2_),
begin3_(other.begin3_),
end3_(other.end3_),
current3_(other.current3_),
begin4_(other.begin4_),
end4_(other.end4_),
current4_(other.current4_),
begin5_(other.begin5_),
end5_(other.end5_),
current5_(other.current5_),
begin6_(other.begin6_),
end6_(other.end6_),
current6_(other.current6_),
begin7_(other.begin7_),
end7_(other.end7_),
current7_(other.current7_),
begin8_(other.begin8_),
end8_(other.end8_),
current8_(other.current8_),
begin9_(other.begin9_),
end9_(other.end9_),
current9_(other.current9_),
begin10_(other.begin10_),
end10_(other.end10_),
current10_(other.current10_) {
ComputeCurrentValue();
}
void ComputeCurrentValue() {
if (!AtEnd())
current_value_ = ParamType(*current1_, *current2_, *current3_,
*current4_, *current5_, *current6_, *current7_, *current8_,
*current9_, *current10_);
}
bool AtEnd() const {
// We must report iterator past the end of the range when either of the
// component iterators has reached the end of its range.
return
current1_ == end1_ ||
current2_ == end2_ ||
current3_ == end3_ ||
current4_ == end4_ ||
current5_ == end5_ ||
current6_ == end6_ ||
current7_ == end7_ ||
current8_ == end8_ ||
current9_ == end9_ ||
current10_ == end10_;
}
const ParamGeneratorInterface<ParamType>* const base_;
// begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
// current[i]_ is the actual traversing iterator.
const typename ParamGenerator<T1>::iterator begin1_;
const typename ParamGenerator<T1>::iterator end1_;
typename ParamGenerator<T1>::iterator current1_;
const typename ParamGenerator<T2>::iterator begin2_;
const typename ParamGenerator<T2>::iterator end2_;
typename ParamGenerator<T2>::iterator current2_;
const typename ParamGenerator<T3>::iterator begin3_;
const typename ParamGenerator<T3>::iterator end3_;
typename ParamGenerator<T3>::iterator current3_;
const typename ParamGenerator<T4>::iterator begin4_;
const typename ParamGenerator<T4>::iterator end4_;
typename ParamGenerator<T4>::iterator current4_;
const typename ParamGenerator<T5>::iterator begin5_;
const typename ParamGenerator<T5>::iterator end5_;
typename ParamGenerator<T5>::iterator current5_;
const typename ParamGenerator<T6>::iterator begin6_;
const typename ParamGenerator<T6>::iterator end6_;
typename ParamGenerator<T6>::iterator current6_;
const typename ParamGenerator<T7>::iterator begin7_;
const typename ParamGenerator<T7>::iterator end7_;
typename ParamGenerator<T7>::iterator current7_;
const typename ParamGenerator<T8>::iterator begin8_;
const typename ParamGenerator<T8>::iterator end8_;
typename ParamGenerator<T8>::iterator current8_;
const typename ParamGenerator<T9>::iterator begin9_;
const typename ParamGenerator<T9>::iterator end9_;
typename ParamGenerator<T9>::iterator current9_;
const typename ParamGenerator<T10>::iterator begin10_;
const typename ParamGenerator<T10>::iterator end10_;
typename ParamGenerator<T10>::iterator current10_;
ParamType current_value_;
};
const ParamGenerator<T1> g1_;
const ParamGenerator<T2> g2_;
const ParamGenerator<T3> g3_;
const ParamGenerator<T4> g4_;
const ParamGenerator<T5> g5_;
const ParamGenerator<T6> g6_;
const ParamGenerator<T7> g7_;
const ParamGenerator<T8> g8_;
const ParamGenerator<T9> g9_;
const ParamGenerator<T10> g10_;
};
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Helper classes providing Combine() with polymorphic features. They allow
// casting CartesianProductGeneratorN<T> to ParamGenerator<U> if T is
// convertible to U.
//
template <class Generator1, class Generator2>
class CartesianProductHolder2 {
public:
CartesianProductHolder2(const Generator1& g1, const Generator2& g2)
: g1_(g1), g2_(g2) {}
template <typename T1, typename T2>
operator ParamGenerator< ::std::tr1::tuple<T1, T2> >() const {
return ParamGenerator< ::std::tr1::tuple<T1, T2> >(
new CartesianProductGenerator2<T1, T2>(
static_cast<ParamGenerator<T1> >(g1_),
static_cast<ParamGenerator<T2> >(g2_)));
}
private:
const Generator1 g1_;
const Generator2 g2_;
};
template <class Generator1, class Generator2, class Generator3>
class CartesianProductHolder3 {
public:
CartesianProductHolder3(const Generator1& g1, const Generator2& g2,
const Generator3& g3)
: g1_(g1), g2_(g2), g3_(g3) {}
template <typename T1, typename T2, typename T3>
operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3> >() const {
return ParamGenerator< ::std::tr1::tuple<T1, T2, T3> >(
new CartesianProductGenerator3<T1, T2, T3>(
static_cast<ParamGenerator<T1> >(g1_),
static_cast<ParamGenerator<T2> >(g2_),
static_cast<ParamGenerator<T3> >(g3_)));
}
private:
const Generator1 g1_;
const Generator2 g2_;
const Generator3 g3_;
};
template <class Generator1, class Generator2, class Generator3,
class Generator4>
class CartesianProductHolder4 {
public:
CartesianProductHolder4(const Generator1& g1, const Generator2& g2,
const Generator3& g3, const Generator4& g4)
: g1_(g1), g2_(g2), g3_(g3), g4_(g4) {}
template <typename T1, typename T2, typename T3, typename T4>
operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4> >() const {
return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4> >(
new CartesianProductGenerator4<T1, T2, T3, T4>(
static_cast<ParamGenerator<T1> >(g1_),
static_cast<ParamGenerator<T2> >(g2_),
static_cast<ParamGenerator<T3> >(g3_),
static_cast<ParamGenerator<T4> >(g4_)));
}
private:
const Generator1 g1_;
const Generator2 g2_;
const Generator3 g3_;
const Generator4 g4_;
};
template <class Generator1, class Generator2, class Generator3,
class Generator4, class Generator5>
class CartesianProductHolder5 {
public:
CartesianProductHolder5(const Generator1& g1, const Generator2& g2,
const Generator3& g3, const Generator4& g4, const Generator5& g5)
: g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5> >() const {
return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5> >(
new CartesianProductGenerator5<T1, T2, T3, T4, T5>(
static_cast<ParamGenerator<T1> >(g1_),
static_cast<ParamGenerator<T2> >(g2_),
static_cast<ParamGenerator<T3> >(g3_),
static_cast<ParamGenerator<T4> >(g4_),
static_cast<ParamGenerator<T5> >(g5_)));
}
private:
const Generator1 g1_;
const Generator2 g2_;
const Generator3 g3_;
const Generator4 g4_;
const Generator5 g5_;
};
template <class Generator1, class Generator2, class Generator3,
class Generator4, class Generator5, class Generator6>
class CartesianProductHolder6 {
public:
CartesianProductHolder6(const Generator1& g1, const Generator2& g2,
const Generator3& g3, const Generator4& g4, const Generator5& g5,
const Generator6& g6)
: g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6>
operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> >() const {
return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> >(
new CartesianProductGenerator6<T1, T2, T3, T4, T5, T6>(
static_cast<ParamGenerator<T1> >(g1_),
static_cast<ParamGenerator<T2> >(g2_),
static_cast<ParamGenerator<T3> >(g3_),
static_cast<ParamGenerator<T4> >(g4_),
static_cast<ParamGenerator<T5> >(g5_),
static_cast<ParamGenerator<T6> >(g6_)));
}
private:
const Generator1 g1_;
const Generator2 g2_;
const Generator3 g3_;
const Generator4 g4_;
const Generator5 g5_;
const Generator6 g6_;
};
template <class Generator1, class Generator2, class Generator3,
class Generator4, class Generator5, class Generator6, class Generator7>
class CartesianProductHolder7 {
public:
CartesianProductHolder7(const Generator1& g1, const Generator2& g2,
const Generator3& g3, const Generator4& g4, const Generator5& g5,
const Generator6& g6, const Generator7& g7)
: g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7>
operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
T7> >() const {
return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7> >(
new CartesianProductGenerator7<T1, T2, T3, T4, T5, T6, T7>(
static_cast<ParamGenerator<T1> >(g1_),
static_cast<ParamGenerator<T2> >(g2_),
static_cast<ParamGenerator<T3> >(g3_),
static_cast<ParamGenerator<T4> >(g4_),
static_cast<ParamGenerator<T5> >(g5_),
static_cast<ParamGenerator<T6> >(g6_),
static_cast<ParamGenerator<T7> >(g7_)));
}
private:
const Generator1 g1_;
const Generator2 g2_;
const Generator3 g3_;
const Generator4 g4_;
const Generator5 g5_;
const Generator6 g6_;
const Generator7 g7_;
};
template <class Generator1, class Generator2, class Generator3,
class Generator4, class Generator5, class Generator6, class Generator7,
class Generator8>
class CartesianProductHolder8 {
public:
CartesianProductHolder8(const Generator1& g1, const Generator2& g2,
const Generator3& g3, const Generator4& g4, const Generator5& g5,
const Generator6& g6, const Generator7& g7, const Generator8& g8)
: g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7),
g8_(g8) {}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8>
operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7,
T8> >() const {
return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8> >(
new CartesianProductGenerator8<T1, T2, T3, T4, T5, T6, T7, T8>(
static_cast<ParamGenerator<T1> >(g1_),
static_cast<ParamGenerator<T2> >(g2_),
static_cast<ParamGenerator<T3> >(g3_),
static_cast<ParamGenerator<T4> >(g4_),
static_cast<ParamGenerator<T5> >(g5_),
static_cast<ParamGenerator<T6> >(g6_),
static_cast<ParamGenerator<T7> >(g7_),
static_cast<ParamGenerator<T8> >(g8_)));
}
private:
const Generator1 g1_;
const Generator2 g2_;
const Generator3 g3_;
const Generator4 g4_;
const Generator5 g5_;
const Generator6 g6_;
const Generator7 g7_;
const Generator8 g8_;
};
template <class Generator1, class Generator2, class Generator3,
class Generator4, class Generator5, class Generator6, class Generator7,
class Generator8, class Generator9>
class CartesianProductHolder9 {
public:
CartesianProductHolder9(const Generator1& g1, const Generator2& g2,
const Generator3& g3, const Generator4& g4, const Generator5& g5,
const Generator6& g6, const Generator7& g7, const Generator8& g8,
const Generator9& g9)
: g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
g9_(g9) {}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9>
operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
T9> >() const {
return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
T9> >(
new CartesianProductGenerator9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(
static_cast<ParamGenerator<T1> >(g1_),
static_cast<ParamGenerator<T2> >(g2_),
static_cast<ParamGenerator<T3> >(g3_),
static_cast<ParamGenerator<T4> >(g4_),
static_cast<ParamGenerator<T5> >(g5_),
static_cast<ParamGenerator<T6> >(g6_),
static_cast<ParamGenerator<T7> >(g7_),
static_cast<ParamGenerator<T8> >(g8_),
static_cast<ParamGenerator<T9> >(g9_)));
}
private:
const Generator1 g1_;
const Generator2 g2_;
const Generator3 g3_;
const Generator4 g4_;
const Generator5 g5_;
const Generator6 g6_;
const Generator7 g7_;
const Generator8 g8_;
const Generator9 g9_;
};
template <class Generator1, class Generator2, class Generator3,
class Generator4, class Generator5, class Generator6, class Generator7,
class Generator8, class Generator9, class Generator10>
class CartesianProductHolder10 {
public:
CartesianProductHolder10(const Generator1& g1, const Generator2& g2,
const Generator3& g3, const Generator4& g4, const Generator5& g5,
const Generator6& g6, const Generator7& g7, const Generator8& g8,
const Generator9& g9, const Generator10& g10)
: g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
g9_(g9), g10_(g10) {}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10>
operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
T9, T10> >() const {
return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
T9, T10> >(
new CartesianProductGenerator10<T1, T2, T3, T4, T5, T6, T7, T8, T9,
T10>(
static_cast<ParamGenerator<T1> >(g1_),
static_cast<ParamGenerator<T2> >(g2_),
static_cast<ParamGenerator<T3> >(g3_),
static_cast<ParamGenerator<T4> >(g4_),
static_cast<ParamGenerator<T5> >(g5_),
static_cast<ParamGenerator<T6> >(g6_),
static_cast<ParamGenerator<T7> >(g7_),
static_cast<ParamGenerator<T8> >(g8_),
static_cast<ParamGenerator<T9> >(g9_),
static_cast<ParamGenerator<T10> >(g10_)));
}
private:
const Generator1 g1_;
const Generator2 g2_;
const Generator3 g3_;
const Generator4 g4_;
const Generator5 g5_;
const Generator6 g6_;
const Generator7 g7_;
const Generator8 g8_;
const Generator9 g9_;
const Generator10 g10_;
};
#endif // GTEST_HAS_COMBINE
} // namespace internal
} // namespace testing
#endif // GTEST_HAS_PARAM_TEST
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
$$ -*- mode: c++; -*-
$var n = 50 $$ Maximum length of Values arguments we want to support.
$var maxtuple = 10 $$ Maximum number of Combine arguments we want to support.
// Copyright 2008 Google Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: vladl@google.com (Vlad Losev)
// Type and function utilities for implementing parameterized tests.
// This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
//
// Currently Google Test supports at most $n arguments in Values,
// and at most $maxtuple arguments in Combine. Please contact
// googletestframework@googlegroups.com if you need more.
// Please note that the number of arguments to Combine is limited
// by the maximum arity of the implementation of tr1::tuple which is
// currently set at $maxtuple.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
#include <gtest/internal/gtest-port.h>
#ifdef GTEST_HAS_PARAM_TEST
#ifdef GTEST_HAS_COMBINE
#include <tr1/tuple>
#endif // GTEST_HAS_COMBINE
#include <gtest/internal/gtest-param-util.h>
namespace testing {
namespace internal {
// Used in the Values() function to provide polymorphic capabilities.
template <typename T1>
class ValueArray1 {
public:
explicit ValueArray1(T1 v1) : v1_(v1) {}
template <typename T>
operator ParamGenerator<T>() const { return ValuesIn(&v1_, &v1_ + 1); }
private:
const T1 v1_;
};
$range i 2..n
$for i [[
$range j 1..i
template <$for j, [[typename T$j]]>
class ValueArray$i {
public:
ValueArray$i($for j, [[T$j v$j]]) : $for j, [[v$(j)_(v$j)]] {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {$for j, [[v$(j)_]]};
return ValuesIn(array);
}
private:
$for j [[
const T$j v$(j)_;
]]
};
]]
#ifdef GTEST_HAS_COMBINE
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Generates values from the Cartesian product of values produced
// by the argument generators.
//
$range i 2..maxtuple
$for i [[
$range j 1..i
$range k 2..i
template <$for j, [[typename T$j]]>
class CartesianProductGenerator$i
: public ParamGeneratorInterface< ::std::tr1::tuple<$for j, [[T$j]]> > {
public:
typedef ::std::tr1::tuple<$for j, [[T$j]]> ParamType;
CartesianProductGenerator$i($for j, [[const ParamGenerator<T$j>& g$j]])
: $for j, [[g$(j)_(g$j)]] {}
virtual ~CartesianProductGenerator$i() {}
virtual ParamIteratorInterface<ParamType>* Begin() const {
return new Iterator(this, $for j, [[g$(j)_, g$(j)_.begin()]]);
}
virtual ParamIteratorInterface<ParamType>* End() const {
return new Iterator(this, $for j, [[g$(j)_, g$(j)_.end()]]);
}
private:
class Iterator : public ParamIteratorInterface<ParamType> {
public:
Iterator(const ParamGeneratorInterface<ParamType>* base, $for j, [[
const ParamGenerator<T$j>& g$j,
const typename ParamGenerator<T$j>::iterator& current$(j)]])
: base_(base),
$for j, [[
begin$(j)_(g$j.begin()), end$(j)_(g$j.end()), current$(j)_(current$j)
]] {
ComputeCurrentValue();
}
virtual ~Iterator() {}
virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
return base_;
}
// Advance should not be called on beyond-of-range iterators
// so no component iterators must be beyond end of range, either.
virtual void Advance() {
assert(!AtEnd());
++current$(i)_;
$for k [[
if (current$(i+2-k)_ == end$(i+2-k)_) {
current$(i+2-k)_ = begin$(i+2-k)_;
++current$(i+2-k-1)_;
}
]]
ComputeCurrentValue();
}
virtual ParamIteratorInterface<ParamType>* Clone() const {
return new Iterator(*this);
}
virtual const ParamType* Current() const { return &current_value_; }
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
// Having the same base generator guarantees that the other
// iterator is of the same type and we can downcast.
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
<< "The program attempted to compare iterators "
<< "from different generators." << std::endl;
const Iterator* typed_other =
CheckedDowncastToActualType<const Iterator>(&other);
// We must report iterators equal if they both point beyond their
// respective ranges. That can happen in a variety of fashions,
// so we have to consult AtEnd().
return (AtEnd() && typed_other->AtEnd()) ||
($for j && [[
current$(j)_ == typed_other->current$(j)_
]]);
}
private:
Iterator(const Iterator& other)
: base_(other.base_), $for j, [[
begin$(j)_(other.begin$(j)_),
end$(j)_(other.end$(j)_),
current$(j)_(other.current$(j)_)
]] {
ComputeCurrentValue();
}
void ComputeCurrentValue() {
if (!AtEnd())
current_value_ = ParamType($for j, [[*current$(j)_]]);
}
bool AtEnd() const {
// We must report iterator past the end of the range when either of the
// component iterators has reached the end of its range.
return
$for j || [[
current$(j)_ == end$(j)_
]];
}
const ParamGeneratorInterface<ParamType>* const base_;
// begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
// current[i]_ is the actual traversing iterator.
$for j [[
const typename ParamGenerator<T$j>::iterator begin$(j)_;
const typename ParamGenerator<T$j>::iterator end$(j)_;
typename ParamGenerator<T$j>::iterator current$(j)_;
]]
ParamType current_value_;
};
$for j [[
const ParamGenerator<T$j> g$(j)_;
]]
};
]]
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Helper classes providing Combine() with polymorphic features. They allow
// casting CartesianProductGeneratorN<T> to ParamGenerator<U> if T is
// convertible to U.
//
$range i 2..maxtuple
$for i [[
$range j 1..i
template <$for j, [[class Generator$j]]>
class CartesianProductHolder$i {
public:
CartesianProductHolder$i($for j, [[const Generator$j& g$j]])
: $for j, [[g$(j)_(g$j)]] {}
template <$for j, [[typename T$j]]>
operator ParamGenerator< ::std::tr1::tuple<$for j, [[T$j]]> >() const {
return ParamGenerator< ::std::tr1::tuple<$for j, [[T$j]]> >(
new CartesianProductGenerator$i<$for j, [[T$j]]>(
$for j,[[
static_cast<ParamGenerator<T$j> >(g$(j)_)
]]));
}
private:
$for j [[
const Generator$j g$(j)_;
]]
};
]]
#endif // GTEST_HAS_COMBINE
} // namespace internal
} // namespace testing
#endif // GTEST_HAS_PARAM_TEST
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
// Copyright 2008 Google Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: vladl@google.com (Vlad Losev)
// Type and function utilities for implementing parameterized tests.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
#include <iterator>
#include <utility>
#include <vector>
#include <gtest/internal/gtest-port.h>
#ifdef GTEST_HAS_PARAM_TEST
#if GTEST_HAS_RTTI
#include <typeinfo>
#endif // GTEST_HAS_RTTI
#include <gtest/internal/gtest-linked_ptr.h>
#include <gtest/internal/gtest-internal.h>
namespace testing {
namespace internal {
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Outputs a message explaining invalid registration of different
// fixture class for the same test case. This may happen when
// TEST_P macro is used to define two tests with the same name
// but in different namespaces.
void ReportInvalidTestCaseType(const char* test_case_name,
const char* file, int line);
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Downcasts the pointer of type Base to Derived.
// Derived must be a subclass of Base. The parameter MUST
// point to a class of type Derived, not any subclass of it.
// When RTTI is available, the function performs a runtime
// check to enforce this.
template <class Derived, class Base>
Derived* CheckedDowncastToActualType(Base* base) {
#if GTEST_HAS_RTTI
GTEST_CHECK_(typeid(*base) == typeid(Derived));
Derived* derived = dynamic_cast<Derived*>(base); // NOLINT
#else
Derived* derived = static_cast<Derived*>(base); // Poor man's downcast.
#endif // GTEST_HAS_RTTI
return derived;
}
template <typename> class ParamGeneratorInterface;
template <typename> class ParamGenerator;
// Interface for iterating over elements provided by an implementation
// of ParamGeneratorInterface<T>.
template <typename T>
class ParamIteratorInterface {
public:
virtual ~ParamIteratorInterface() {}
// A pointer to the base generator instance.
// Used only for the purposes of iterator comparison
// to make sure that two iterators belong to the same generator.
virtual const ParamGeneratorInterface<T>* BaseGenerator() const = 0;
// Advances iterator to point to the next element
// provided by the generator. The caller is responsible
// for not calling Advance() on an iterator equal to
// BaseGenerator()->End().
virtual void Advance() = 0;
// Clones the iterator object. Used for implementing copy semantics
// of ParamIterator<T>.
virtual ParamIteratorInterface* Clone() const = 0;
// Dereferences the current iterator and provides (read-only) access
// to the pointed value. It is the caller's responsibility not to call
// Current() on an iterator equal to BaseGenerator()->End().
// Used for implementing ParamGenerator<T>::operator*().
virtual const T* Current() const = 0;
// Determines whether the given iterator and other point to the same
// element in the sequence generated by the generator.
// Used for implementing ParamGenerator<T>::operator==().
virtual bool Equals(const ParamIteratorInterface& other) const = 0;
};
// Class iterating over elements provided by an implementation of
// ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T>
// and implements the const forward iterator concept.
template <typename T>
class ParamIterator {
public:
typedef T value_type;
typedef const T& reference;
typedef ptrdiff_t difference_type;
// ParamIterator assumes ownership of the impl_ pointer.
ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {}
ParamIterator& operator=(const ParamIterator& other) {
if (this != &other)
impl_.reset(other.impl_->Clone());
return *this;
}
const T& operator*() const { return *impl_->Current(); }
const T* operator->() const { return impl_->Current(); }
// Prefix version of operator++.
ParamIterator& operator++() {
impl_->Advance();
return *this;
}
// Postfix version of operator++.
ParamIterator operator++(int /*unused*/) {
ParamIteratorInterface<T>* clone = impl_->Clone();
impl_->Advance();
return ParamIterator(clone);
}
bool operator==(const ParamIterator& other) const {
return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_);
}
bool operator!=(const ParamIterator& other) const {
return !(*this == other);
}
private:
friend class ParamGenerator<T>;
explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {}
scoped_ptr<ParamIteratorInterface<T> > impl_;
};
// ParamGeneratorInterface<T> is the binary interface to access generators
// defined in other translation units.
template <typename T>
class ParamGeneratorInterface {
public:
typedef T ParamType;
virtual ~ParamGeneratorInterface() {}
// Generator interface definition
virtual ParamIteratorInterface<T>* Begin() const = 0;
virtual ParamIteratorInterface<T>* End() const = 0;
};
// Wraps ParamGeneratorInetrface<T> and provides general generator syntax
// compatible with the STL Container concept.
// This class implements copy initialization semantics and the contained
// ParamGeneratorInterface<T> instance is shared among all copies
// of the original object. This is possible because that instance is immutable.
template<typename T>
class ParamGenerator {
public:
typedef ParamIterator<T> iterator;
explicit ParamGenerator(ParamGeneratorInterface<T>* impl) : impl_(impl) {}
ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {}
ParamGenerator& operator=(const ParamGenerator& other) {
impl_ = other.impl_;
return *this;
}
iterator begin() const { return iterator(impl_->Begin()); }
iterator end() const { return iterator(impl_->End()); }
private:
::testing::internal::linked_ptr<const ParamGeneratorInterface<T> > impl_;
};
// Generates values from a range of two comparable values. Can be used to
// generate sequences of user-defined types that implement operator+() and
// operator<().
// This class is used in the Range() function.
template <typename T, typename IncrementT>
class RangeGenerator : public ParamGeneratorInterface<T> {
public:
RangeGenerator(T begin, T end, IncrementT step)
: begin_(begin), end_(end),
step_(step), end_index_(CalculateEndIndex(begin, end, step)) {}
virtual ~RangeGenerator() {}
virtual ParamIteratorInterface<T>* Begin() const {
return new Iterator(this, begin_, 0, step_);
}
virtual ParamIteratorInterface<T>* End() const {
return new Iterator(this, end_, end_index_, step_);
}
private:
class Iterator : public ParamIteratorInterface<T> {
public:
Iterator(const ParamGeneratorInterface<T>* base, T value, int index,
IncrementT step)
: base_(base), value_(value), index_(index), step_(step) {}
virtual ~Iterator() {}
virtual const ParamGeneratorInterface<T>* BaseGenerator() const {
return base_;
}
virtual void Advance() {
value_ = value_ + step_;
index_++;
}
virtual ParamIteratorInterface<T>* Clone() const {
return new Iterator(*this);
}
virtual const T* Current() const { return &value_; }
virtual bool Equals(const ParamIteratorInterface<T>& other) const {
// Having the same base generator guarantees that the other
// iterator is of the same type and we can downcast.
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
<< "The program attempted to compare iterators "
<< "from different generators." << std::endl;
const int other_index =
CheckedDowncastToActualType<const Iterator>(&other)->index_;
return index_ == other_index;
}
private:
Iterator(const Iterator& other)
: base_(other.base_), value_(other.value_), index_(other.index_),
step_(other.step_) {}
const ParamGeneratorInterface<T>* const base_;
T value_;
int index_;
const IncrementT step_;
}; // class RangeGenerator::Iterator
static int CalculateEndIndex(const T& begin,
const T& end,
const IncrementT& step) {
int end_index = 0;
for (T i = begin; i < end; i = i + step)
end_index++;
return end_index;
}
const T begin_;
const T end_;
const IncrementT step_;
// The index for the end() iterator. All the elements in the generated
// sequence are indexed (0-based) to aid iterator comparison.
const int end_index_;
}; // class RangeGenerator
// Generates values from a pair of STL-style iterators. Used in the
// ValuesIn() function. The elements are copied from the source range
// since the source can be located on the stack, and the generator
// is likely to persist beyond that stack frame.
template <typename T>
class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
public:
template <typename ForwardIterator>
ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
: container_(begin, end) {}
virtual ~ValuesInIteratorRangeGenerator() {}
virtual ParamIteratorInterface<T>* Begin() const {
return new Iterator(this, container_.begin());
}
virtual ParamIteratorInterface<T>* End() const {
return new Iterator(this, container_.end());
}
private:
typedef typename ::std::vector<T> ContainerType;
class Iterator : public ParamIteratorInterface<T> {
public:
Iterator(const ParamGeneratorInterface<T>* base,
typename ContainerType::const_iterator iterator)
: base_(base), iterator_(iterator) {}
virtual ~Iterator() {}
virtual const ParamGeneratorInterface<T>* BaseGenerator() const {
return base_;
}
virtual void Advance() {
++iterator_;
value_.reset();
}
virtual ParamIteratorInterface<T>* Clone() const {
return new Iterator(*this);
}
// We need to use cached value referenced by iterator_ because *iterator_
// can return a temporary object (and of type other then T), so just
// having "return &*iterator_;" doesn't work.
// value_ is updated here and not in Advance() because Advance()
// can advance iterator_ beyond the end of the range, and we cannot
// detect that fact. The client code, on the other hand, is
// responsible for not calling Current() on an out-of-range iterator.
virtual const T* Current() const {
if (value_.get() == NULL)
value_.reset(new T(*iterator_));
return value_.get();
}
virtual bool Equals(const ParamIteratorInterface<T>& other) const {
// Having the same base generator guarantees that the other
// iterator is of the same type and we can downcast.
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
<< "The program attempted to compare iterators "
<< "from different generators." << std::endl;
return iterator_ ==
CheckedDowncastToActualType<const Iterator>(&other)->iterator_;
}
private:
Iterator(const Iterator& other)
// The explicit constructor call suppresses a false warning
// emitted by gcc when supplied with the -Wextra option.
: ParamIteratorInterface<T>(),
base_(other.base_),
iterator_(other.iterator_) {}
const ParamGeneratorInterface<T>* const base_;
typename ContainerType::const_iterator iterator_;
// A cached value of *iterator_. We keep it here to allow access by
// pointer in the wrapping iterator's operator->().
// value_ needs to be mutable to be accessed in Current().
// Use of scoped_ptr helps manage cached value's lifetime,
// which is bound by the lifespan of the iterator itself.
mutable scoped_ptr<const T> value_;
};
const ContainerType container_;
}; // class ValuesInIteratorRangeGenerator
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Stores a parameter value and later creates tests parameterized with that
// value.
template <class TestClass>
class ParameterizedTestFactory : public TestFactoryBase {
public:
typedef typename TestClass::ParamType ParamType;
explicit ParameterizedTestFactory(ParamType parameter) :
parameter_(parameter) {}
virtual Test* CreateTest() {
TestClass::SetParam(&parameter_);
return new TestClass();
}
private:
const ParamType parameter_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory);
};
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// TestMetaFactoryBase is a base class for meta-factories that create
// test factories for passing into MakeAndRegisterTestInfo function.
template <class ParamType>
class TestMetaFactoryBase {
public:
virtual ~TestMetaFactoryBase() {}
virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0;
};
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// TestMetaFactory creates test factories for passing into
// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives
// ownership of test factory pointer, same factory object cannot be passed
// into that method twice. But ParameterizedTestCaseInfo is going to call
// it for each Test/Parameter value combination. Thus it needs meta factory
// creator class.
template <class TestCase>
class TestMetaFactory
: public TestMetaFactoryBase<typename TestCase::ParamType> {
public:
typedef typename TestCase::ParamType ParamType;
TestMetaFactory() {}
virtual TestFactoryBase* CreateTestFactory(ParamType parameter) {
return new ParameterizedTestFactory<TestCase>(parameter);
}
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory);
};
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// ParameterizedTestCaseInfoBase is a generic interface
// to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase
// accumulates test information provided by TEST_P macro invocations
// and generators provided by INSTANTIATE_TEST_CASE_P macro invocations
// and uses that information to register all resulting test instances
// in RegisterTests method. The ParameterizeTestCaseRegistry class holds
// a collection of pointers to the ParameterizedTestCaseInfo objects
// and calls RegisterTests() on each of them when asked.
class ParameterizedTestCaseInfoBase {
public:
virtual ~ParameterizedTestCaseInfoBase() {}
// Base part of test case name for display purposes.
virtual const String& GetTestCaseName() const = 0;
// Test case id to verify identity.
virtual TypeId GetTestCaseTypeId() const = 0;
// UnitTest class invokes this method to register tests in this
// test case right before running them in RUN_ALL_TESTS macro.
// This method should not be called more then once on any single
// instance of a ParameterizedTestCaseInfoBase derived class.
virtual void RegisterTests() = 0;
protected:
ParameterizedTestCaseInfoBase() {}
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase);
};
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// ParameterizedTestCaseInfo accumulates tests obtained from TEST_P
// macro invocations for a particular test case and generators
// obtained from INSTANTIATE_TEST_CASE_P macro invocations for that
// test case. It registers tests with all values generated by all
// generators when asked.
template <class TestCase>
class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
public:
// ParamType and GeneratorCreationFunc are private types but are required
// for declarations of public methods AddTestPattern() and
// AddTestCaseInstantiation().
typedef typename TestCase::ParamType ParamType;
// A function that returns an instance of appropriate generator type.
typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
explicit ParameterizedTestCaseInfo(const char* name)
: test_case_name_(name) {}
// Test case base name for display purposes.
virtual const String& GetTestCaseName() const { return test_case_name_; }
// Test case id to verify identity.
virtual TypeId GetTestCaseTypeId() const { return GetTypeId<TestCase>(); }
// TEST_P macro uses AddTestPattern() to record information
// about a single test in a LocalTestInfo structure.
// test_case_name is the base name of the test case (without invocation
// prefix). test_base_name is the name of an individual test without
// parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
// test case base name and DoBar is test base name.
void AddTestPattern(const char* test_case_name,
const char* test_base_name,
TestMetaFactoryBase<ParamType>* meta_factory) {
tests_.push_back(linked_ptr<TestInfo>(new TestInfo(test_case_name,
test_base_name,
meta_factory)));
}
// INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information
// about a generator.
int AddTestCaseInstantiation(const char* instantiation_name,
GeneratorCreationFunc* func,
const char* file,
int line) {
instantiations_.push_back(::std::make_pair(instantiation_name, func));
return 0; // Return value used only to run this method in namespace scope.
}
// UnitTest class invokes this method to register tests in this test case
// test cases right before running tests in RUN_ALL_TESTS macro.
// This method should not be called more then once on any single
// instance of a ParameterizedTestCaseInfoBase derived class.
// UnitTest has a guard to prevent from calling this method more then once.
virtual void RegisterTests() {
for (typename TestInfoContainer::iterator test_it = tests_.begin();
test_it != tests_.end(); ++test_it) {
linked_ptr<TestInfo> test_info = *test_it;
for (typename InstantiationContainer::iterator gen_it =
instantiations_.begin(); gen_it != instantiations_.end();
++gen_it) {
const String& instantiation_name = gen_it->first;
ParamGenerator<ParamType> generator((*gen_it->second)());
Message test_case_name_stream;
if ( !instantiation_name.empty() )
test_case_name_stream << instantiation_name.c_str() << "/";
test_case_name_stream << test_info->test_case_base_name.c_str();
int i = 0;
for (typename ParamGenerator<ParamType>::iterator param_it =
generator.begin();
param_it != generator.end(); ++param_it, ++i) {
Message test_name_stream;
test_name_stream << test_info->test_base_name.c_str() << "/" << i;
::testing::internal::MakeAndRegisterTestInfo(
test_case_name_stream.GetString().c_str(),
test_name_stream.GetString().c_str(),
"", // test_case_comment
"", // comment; TODO(vladl@google.com): provide parameter value
// representation.
GetTestCaseTypeId(),
TestCase::SetUpTestCase,
TestCase::TearDownTestCase,
test_info->test_meta_factory->CreateTestFactory(*param_it));
} // for param_it
} // for gen_it
} // for test_it
} // RegisterTests
private:
// LocalTestInfo structure keeps information about a single test registered
// with TEST_P macro.
struct TestInfo {
TestInfo(const char* test_case_base_name,
const char* test_base_name,
TestMetaFactoryBase<ParamType>* test_meta_factory) :
test_case_base_name(test_case_base_name),
test_base_name(test_base_name),
test_meta_factory(test_meta_factory) {}
const String test_case_base_name;
const String test_base_name;
const scoped_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory;
};
typedef ::std::vector<linked_ptr<TestInfo> > TestInfoContainer;
// Keeps pairs of <Instantiation name, Sequence generator creation function>
// received from INSTANTIATE_TEST_CASE_P macros.
typedef ::std::vector<std::pair<String, GeneratorCreationFunc*> >
InstantiationContainer;
const String test_case_name_;
TestInfoContainer tests_;
InstantiationContainer instantiations_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo);
}; // class ParameterizedTestCaseInfo
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase
// classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P
// macros use it to locate their corresponding ParameterizedTestCaseInfo
// descriptors.
class ParameterizedTestCaseRegistry {
public:
ParameterizedTestCaseRegistry() {}
~ParameterizedTestCaseRegistry() {
for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
it != test_case_infos_.end(); ++it) {
delete *it;
}
}
// Looks up or creates and returns a structure containing information about
// tests and instantiations of a particular test case.
template <class TestCase>
ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
const char* test_case_name,
const char* file,
int line) {
ParameterizedTestCaseInfo<TestCase>* typed_test_info = NULL;
for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
it != test_case_infos_.end(); ++it) {
if ((*it)->GetTestCaseName() == test_case_name) {
if ((*it)->GetTestCaseTypeId() != GetTypeId<TestCase>()) {
// Complain about incorrect usage of Google Test facilities
// and terminate the program since we cannot guaranty correct
// test case setup and tear-down in this case.
ReportInvalidTestCaseType(test_case_name, file, line);
abort();
} else {
// At this point we are sure that the object we found is of the same
// type we are looking for, so we downcast it to that type
// without further checks.
typed_test_info = CheckedDowncastToActualType<
ParameterizedTestCaseInfo<TestCase> >(*it);
}
break;
}
}
if (typed_test_info == NULL) {
typed_test_info = new ParameterizedTestCaseInfo<TestCase>(test_case_name);
test_case_infos_.push_back(typed_test_info);
}
return typed_test_info;
}
void RegisterTests() {
for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
it != test_case_infos_.end(); ++it) {
(*it)->RegisterTests();
}
}
private:
typedef ::std::vector<ParameterizedTestCaseInfoBase*> TestCaseInfoContainer;
TestCaseInfoContainer test_case_infos_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry);
};
} // namespace internal
} // namespace testing
#endif // GTEST_HAS_PARAM_TEST
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
...@@ -56,6 +56,8 @@ ...@@ -56,6 +56,8 @@
// enabled. // enabled.
// GTEST_HAS_PTHREAD - Define it to 1/0 to indicate that <pthread.h> // GTEST_HAS_PTHREAD - Define it to 1/0 to indicate that <pthread.h>
// is/isn't available. // is/isn't available.
// GTEST_HAS_TR1_TUPLE 1 - Define it to 1/0 to indicate tr1::tuple
// is/isn't available.
// This header defines the following utilities: // This header defines the following utilities:
// //
...@@ -85,7 +87,11 @@ ...@@ -85,7 +87,11 @@
// Note that it is possible that none of the GTEST_OS_ macros are defined. // Note that it is possible that none of the GTEST_OS_ macros are defined.
// //
// Macros indicating available Google Test features: // Macros indicating available Google Test features:
// GTEST_HAS_COMBINE - defined iff Combine construct is supported
// in value-parameterized tests.
// GTEST_HAS_DEATH_TEST - defined iff death tests are supported. // GTEST_HAS_DEATH_TEST - defined iff death tests are supported.
// GTEST_HAS_PARAM_TEST - defined iff value-parameterized tests are
// supported.
// GTEST_HAS_TYPED_TEST - defined iff typed tests are supported. // GTEST_HAS_TYPED_TEST - defined iff typed tests are supported.
// GTEST_HAS_TYPED_TEST_P - defined iff type-parameterized tests are // GTEST_HAS_TYPED_TEST_P - defined iff type-parameterized tests are
// supported. // supported.
...@@ -145,6 +151,7 @@ ...@@ -145,6 +151,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <iostream> // Used for GTEST_CHECK_
#define GTEST_NAME "Google Test" #define GTEST_NAME "Google Test"
#define GTEST_FLAG_PREFIX "gtest_" #define GTEST_FLAG_PREFIX "gtest_"
...@@ -292,6 +299,22 @@ ...@@ -292,6 +299,22 @@
#endif // GTEST_HAS_PTHREAD #endif // GTEST_HAS_PTHREAD
// Determines whether <tr1/tuple> is available. If you have <tr1/tuple>
// on your platform, define GTEST_HAS_TR1_TUPLE=1 for both the Google
// Test project and your tests. If you would like Google Test to detect
// <tr1/tuple> on your platform automatically, please open an issue
// ticket at http://code.google.com/p/googletest.
#ifndef GTEST_HAS_TR1_TUPLE
// The user didn't tell us, so we need to figure it out.
// GCC provides <tr1/tuple> since 4.0.0.
#if defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000)
#define GTEST_HAS_TR1_TUPLE 1
#else
#define GTEST_HAS_TR1_TUPLE 0
#endif // __GNUC__
#endif // GTEST_HAS_TR1_TUPLE
// Determines whether to support death tests. // Determines whether to support death tests.
#if GTEST_HAS_STD_STRING && defined(GTEST_OS_LINUX) #if GTEST_HAS_STD_STRING && defined(GTEST_OS_LINUX)
#define GTEST_HAS_DEATH_TEST #define GTEST_HAS_DEATH_TEST
...@@ -305,6 +328,14 @@ ...@@ -305,6 +328,14 @@
#include <sys/mman.h> #include <sys/mman.h>
#endif // GTEST_HAS_STD_STRING && defined(GTEST_OS_LINUX) #endif // GTEST_HAS_STD_STRING && defined(GTEST_OS_LINUX)
// Determines whether to support value-parameterized tests.
#if defined(__GNUC__) || (_MSC_VER >= 1400)
// TODO(vladl@google.com): get the implementation rid of vector and list
// to compile on MSVC 7.1.
#define GTEST_HAS_PARAM_TEST
#endif // defined(__GNUC__) || (_MSC_VER >= 1400)
// Determines whether to support type-driven tests. // Determines whether to support type-driven tests.
// Typed tests need <typeinfo> and variadic macros, which gcc and VC // Typed tests need <typeinfo> and variadic macros, which gcc and VC
...@@ -314,6 +345,12 @@ ...@@ -314,6 +345,12 @@
#define GTEST_HAS_TYPED_TEST_P #define GTEST_HAS_TYPED_TEST_P
#endif // defined(__GNUC__) || (_MSC_VER >= 1400) #endif // defined(__GNUC__) || (_MSC_VER >= 1400)
// Determines whether to support Combine(). This only makes sense when
// value-parameterized tests are enabled.
#if defined(GTEST_HAS_PARAM_TEST) && GTEST_HAS_TR1_TUPLE
#define GTEST_HAS_COMBINE
#endif // defined(GTEST_HAS_PARAM_TEST) && GTEST_HAS_TR1_TUPLE
// Determines whether the system compiler uses UTF-16 for encoding wide strings. // Determines whether the system compiler uses UTF-16 for encoding wide strings.
#if defined(GTEST_OS_WINDOWS) || defined(GTEST_OS_CYGWIN) || \ #if defined(GTEST_OS_WINDOWS) || defined(GTEST_OS_CYGWIN) || \
defined(GTEST_OS_SYMBIAN) defined(GTEST_OS_SYMBIAN)
...@@ -421,7 +458,7 @@ class scoped_ptr { ...@@ -421,7 +458,7 @@ class scoped_ptr {
#ifdef GTEST_HAS_DEATH_TEST #ifdef GTEST_HAS_DEATH_TEST
// Defines RE. Currently only needed for death tests. // Defines RE.
// A simple C++ wrapper for <regex.h>. It uses the POSIX Enxtended // A simple C++ wrapper for <regex.h>. It uses the POSIX Enxtended
// Regular Expression syntax. // Regular Expression syntax.
...@@ -442,22 +479,32 @@ class RE { ...@@ -442,22 +479,32 @@ class RE {
// Returns the string representation of the regex. // Returns the string representation of the regex.
const char* pattern() const { return pattern_; } const char* pattern() const { return pattern_; }
// Returns true iff str contains regular expression re. // FullMatch(str, re) returns true iff regular expression re matches
// the entire str.
// TODO(wan): make PartialMatch() work when str contains NUL // PartialMatch(str, re) returns true iff regular expression re
// characters. // matches a substring of str (including str itself).
//
// TODO(wan@google.com): make FullMatch() and PartialMatch() work
// when str contains NUL characters.
#if GTEST_HAS_STD_STRING #if GTEST_HAS_STD_STRING
static bool FullMatch(const ::std::string& str, const RE& re) {
return FullMatch(str.c_str(), re);
}
static bool PartialMatch(const ::std::string& str, const RE& re) { static bool PartialMatch(const ::std::string& str, const RE& re) {
return PartialMatch(str.c_str(), re); return PartialMatch(str.c_str(), re);
} }
#endif // GTEST_HAS_STD_STRING #endif // GTEST_HAS_STD_STRING
#if GTEST_HAS_GLOBAL_STRING #if GTEST_HAS_GLOBAL_STRING
static bool FullMatch(const ::string& str, const RE& re) {
return FullMatch(str.c_str(), re);
}
static bool PartialMatch(const ::string& str, const RE& re) { static bool PartialMatch(const ::string& str, const RE& re) {
return PartialMatch(str.c_str(), re); return PartialMatch(str.c_str(), re);
} }
#endif // GTEST_HAS_GLOBAL_STRING #endif // GTEST_HAS_GLOBAL_STRING
static bool FullMatch(const char* str, const RE& re);
static bool PartialMatch(const char* str, const RE& re); static bool PartialMatch(const char* str, const RE& re);
private: private:
...@@ -468,7 +515,8 @@ class RE { ...@@ -468,7 +515,8 @@ class RE {
// String type here, in order to simplify dependencies between the // String type here, in order to simplify dependencies between the
// files. // files.
const char* pattern_; const char* pattern_;
regex_t regex_; regex_t full_regex_; // For FullMatch().
regex_t partial_regex_; // For PartialMatch().
bool is_valid_; bool is_valid_;
}; };
...@@ -697,6 +745,53 @@ void abort(); ...@@ -697,6 +745,53 @@ void abort();
inline void abort() { ::abort(); } inline void abort() { ::abort(); }
#endif // _WIN32_WCE #endif // _WIN32_WCE
// INTERNAL IMPLEMENTATION - DO NOT USE.
//
// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition
// is not satisfied.
// Synopsys:
// GTEST_CHECK_(boolean_condition);
// or
// GTEST_CHECK_(boolean_condition) << "Additional message";
//
// This checks the condition and if the condition is not satisfied
// it prints message about the condition violation, including the
// condition itself, plus additional message streamed into it, if any,
// and then it aborts the program. It aborts the program irrespective of
// whether it is built in the debug mode or not.
class GTestCheckProvider {
public:
GTestCheckProvider(const char* condition, const char* file, int line) {
FormatFileLocation(file, line);
::std::cerr << " ERROR: Condition " << condition << " failed. ";
}
~GTestCheckProvider() {
::std::cerr << ::std::endl;
abort();
}
void FormatFileLocation(const char* file, int line) {
if (file == NULL)
file = "unknown file";
if (line < 0) {
::std::cerr << file << ":";
} else {
#if _MSC_VER
::std::cerr << file << "(" << line << "):";
#else
::std::cerr << file << ":" << line << ":";
#endif
}
}
::std::ostream& GetStream() { return ::std::cerr; }
};
#define GTEST_CHECK_(condition) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (condition) \
; \
else \
::testing::internal::GTestCheckProvider(\
#condition, __FILE__, __LINE__).GetStream()
// Macro for referencing flags. // Macro for referencing flags.
#define GTEST_FLAG(name) FLAGS_gtest_##name #define GTEST_FLAG(name) FLAGS_gtest_##name
......
// Copyright 2008 Google Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Author: vladl@google.com (Vlad Losev)
// This provides interface PrimeTable that determines whether a number is a
// prime and determines a next prime number. This interface is used
// in Google Test samples demonstrating use of parameterized tests.
#ifndef GTEST_SAMPLES_PRIME_TABLES_H_
#define GTEST_SAMPLES_PRIME_TABLES_H_
#include <algorithm>
// The prime table interface.
class PrimeTable {
public:
virtual ~PrimeTable() {}
// Returns true iff n is a prime number.
virtual bool IsPrime(int n) const = 0;
// Returns the smallest prime number greater than p; or returns -1
// if the next prime is beyond the capacity of the table.
virtual int GetNextPrime(int p) const = 0;
};
// Implementation #1 calculates the primes on-the-fly.
class OnTheFlyPrimeTable : public PrimeTable {
public:
virtual bool IsPrime(int n) const {
if (n <= 1) return false;
for (int i = 2; i*i <= n; i++) {
// n is divisible by an integer other than 1 and itself.
if ((n % i) == 0) return false;
}
return true;
}
virtual int GetNextPrime(int p) const {
for (int n = p + 1; n > 0; n++) {
if (IsPrime(n)) return n;
}
return -1;
}
};
// Implementation #2 pre-calculates the primes and stores the result
// in an array.
class PreCalculatedPrimeTable : public PrimeTable {
public:
// 'max' specifies the maximum number the prime table holds.
explicit PreCalculatedPrimeTable(int max)
: is_prime_size_(max + 1), is_prime_(new bool[max + 1]) {
CalculatePrimesUpTo(max);
}
virtual ~PreCalculatedPrimeTable() { delete[] is_prime_; }
virtual bool IsPrime(int n) const {
return 0 <= n && n < is_prime_size_ && is_prime_[n];
}
virtual int GetNextPrime(int p) const {
for (int n = p + 1; n < is_prime_size_; n++) {
if (is_prime_[n]) return n;
}
return -1;
}
private:
void CalculatePrimesUpTo(int max) {
::std::fill(is_prime_, is_prime_ + is_prime_size_, true);
is_prime_[0] = is_prime_[1] = false;
for (int i = 2; i <= max; i++) {
if (!is_prime_[i]) continue;
// Marks all multiples of i (except i itself) as non-prime.
for (int j = 2*i; j <= max; j += i) {
is_prime_[j] = false;
}
}
}
const int is_prime_size_;
bool* const is_prime_;
};
#endif // GTEST_SAMPLES_PRIME_TABLES_H_
...@@ -33,13 +33,15 @@ ...@@ -33,13 +33,15 @@
#include "sample2.h" #include "sample2.h"
#include <string.h>
// Clones a 0-terminated C string, allocating memory using new. // Clones a 0-terminated C string, allocating memory using new.
const char * MyString::CloneCString(const char * c_string) { const char * MyString::CloneCString(const char * c_string) {
if (c_string == NULL) return NULL; if (c_string == NULL) return NULL;
const size_t len = strlen(c_string); const size_t len = strlen(c_string);
char * const clone = new char[ len + 1 ]; char * const clone = new char[ len + 1 ];
strcpy(clone, c_string); memcpy(clone, c_string, len + 1);
return clone; return clone;
} }
......
...@@ -30,91 +30,12 @@ ...@@ -30,91 +30,12 @@
// Author: wan@google.com (Zhanyong Wan) // Author: wan@google.com (Zhanyong Wan)
// This sample shows how to test common properties of multiple // This sample shows how to test common properties of multiple
// implementations of the same interface (aka interface tests). We // implementations of the same interface (aka interface tests).
// put the code to be tested and the tests in the same file for
// simplicity.
#include <vector> // The interface and its implementations are in this header.
#include <gtest/gtest.h> #include "prime_tables.h"
// Section 1. the interface and its implementations.
// The prime table interface.
class PrimeTable {
public:
virtual ~PrimeTable() {}
// Returns true iff n is a prime number.
virtual bool IsPrime(int n) const = 0;
// Returns the smallest prime number greater than p; or returns -1
// if the next prime is beyond the capacity of the table.
virtual int GetNextPrime(int p) const = 0;
};
// Implementation #1 calculates the primes on-the-fly. #include <gtest/gtest.h>
class OnTheFlyPrimeTable : public PrimeTable {
public:
virtual bool IsPrime(int n) const {
if (n <= 1) return false;
for (int i = 2; i*i <= n; i++) {
// n is divisible by an integer other than 1 and itself.
if ((n % i) == 0) return false;
}
return true;
}
virtual int GetNextPrime(int p) const {
for (int n = p + 1; n > 0; n++) {
if (IsPrime(n)) return n;
}
return -1;
}
};
// Implementation #2 pre-calculates the primes and stores the result
// in a vector.
class PreCalculatedPrimeTable : public PrimeTable {
public:
// 'max' specifies the maximum number the prime table holds.
explicit PreCalculatedPrimeTable(int max) : is_prime_(max + 1) {
CalculatePrimesUpTo(max);
}
virtual bool IsPrime(int n) const {
return 0 <= n && n < is_prime_.size() && is_prime_[n];
}
virtual int GetNextPrime(int p) const {
for (int n = p + 1; n < is_prime_.size(); n++) {
if (is_prime_[n]) return n;
}
return -1;
}
private:
void CalculatePrimesUpTo(int max) {
fill(is_prime_.begin(), is_prime_.end(), true);
is_prime_[0] = is_prime_[1] = false;
for (int i = 2; i <= max; i++) {
if (!is_prime_[i]) continue;
// Marks all multiples of i (except i itself) as non-prime.
for (int j = 2*i; j <= max; j += i) {
is_prime_[j] = false;
}
}
}
std::vector<bool> is_prime_;
};
// Sections 2. the tests.
// First, we define some factory functions for creating instances of // First, we define some factory functions for creating instances of
// the implementations. You may be able to skip this step if all your // the implementations. You may be able to skip this step if all your
...@@ -153,10 +74,10 @@ class PrimeTableTest : public testing::Test { ...@@ -153,10 +74,10 @@ class PrimeTableTest : public testing::Test {
PrimeTable* const table_; PrimeTable* const table_;
}; };
using testing::Types;
#ifdef GTEST_HAS_TYPED_TEST #ifdef GTEST_HAS_TYPED_TEST
using testing::Types;
// Google Test offers two ways for reusing tests for different types. // Google Test offers two ways for reusing tests for different types.
// The first is called "typed tests". You should use it if you // The first is called "typed tests". You should use it if you
// already know *all* the types you are gonna exercise when you write // already know *all* the types you are gonna exercise when you write
...@@ -218,6 +139,8 @@ TYPED_TEST(PrimeTableTest, CanGetNextPrime) { ...@@ -218,6 +139,8 @@ TYPED_TEST(PrimeTableTest, CanGetNextPrime) {
#ifdef GTEST_HAS_TYPED_TEST_P #ifdef GTEST_HAS_TYPED_TEST_P
using testing::Types;
// Sometimes, however, you don't yet know all the types that you want // Sometimes, however, you don't yet know all the types that you want
// to test when you write the tests. For example, if you are the // to test when you write the tests. For example, if you are the
// author of an interface and expect other people to implement it, you // author of an interface and expect other people to implement it, you
......
// Copyright 2008 Google Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: vladl@google.com (Vlad Losev)
// This sample shows how to test common properties of multiple
// implementations of an interface (aka interface tests) using
// value-parameterized tests. Each test in the test case has
// a parameter that is an interface pointer to an implementation
// tested.
// The interface and its implementations are in this header.
#include "prime_tables.h"
#include <gtest/gtest.h>
#ifdef GTEST_HAS_PARAM_TEST
using ::testing::TestWithParam;
using ::testing::Values;
// As a general rule, tested objects should not be reused between tests.
// Also, their constructors and destructors of tested objects can have
// side effects. Thus you should create and destroy them for each test.
// In this sample we will define a simple factory function for PrimeTable
// objects. We will instantiate objects in test's SetUp() method and
// delete them in TearDown() method.
typedef PrimeTable* CreatePrimeTableFunc();
PrimeTable* CreateOnTheFlyPrimeTable() {
return new OnTheFlyPrimeTable();
}
template <size_t max_precalculated>
PrimeTable* CreatePreCalculatedPrimeTable() {
return new PreCalculatedPrimeTable(max_precalculated);
}
// Inside the test body, fixture constructor, SetUp(), and TearDown()
// you can refer to the test parameter by GetParam().
// In this case, the test parameter is a PrimeTableFactory interface pointer
// which we use in fixture's SetUp() to create and store an instance of
// PrimeTable.
class PrimeTableTest : public TestWithParam<CreatePrimeTableFunc*> {
public:
virtual ~PrimeTableTest() { delete table_; }
virtual void SetUp() { table_ = (*GetParam())(); }
virtual void TearDown() {
delete table_;
table_ = NULL;
}
protected:
PrimeTable* table_;
};
TEST_P(PrimeTableTest, ReturnsFalseForNonPrimes) {
EXPECT_FALSE(table_->IsPrime(-5));
EXPECT_FALSE(table_->IsPrime(0));
EXPECT_FALSE(table_->IsPrime(1));
EXPECT_FALSE(table_->IsPrime(4));
EXPECT_FALSE(table_->IsPrime(6));
EXPECT_FALSE(table_->IsPrime(100));
}
TEST_P(PrimeTableTest, ReturnsTrueForPrimes) {
EXPECT_TRUE(table_->IsPrime(2));
EXPECT_TRUE(table_->IsPrime(3));
EXPECT_TRUE(table_->IsPrime(5));
EXPECT_TRUE(table_->IsPrime(7));
EXPECT_TRUE(table_->IsPrime(11));
EXPECT_TRUE(table_->IsPrime(131));
}
TEST_P(PrimeTableTest, CanGetNextPrime) {
EXPECT_EQ(2, table_->GetNextPrime(0));
EXPECT_EQ(3, table_->GetNextPrime(2));
EXPECT_EQ(5, table_->GetNextPrime(3));
EXPECT_EQ(7, table_->GetNextPrime(5));
EXPECT_EQ(11, table_->GetNextPrime(7));
EXPECT_EQ(131, table_->GetNextPrime(128));
}
// In order to run value-parameterized tests, you need to instantiate them,
// or bind them to a list of values which will be used as test parameters.
// You can instantiate them in a different translation module, or even
// instantiate them several times.
//
// Here, we instantiate our tests with a list of two PrimeTable object
// factory functions:
INSTANTIATE_TEST_CASE_P(
OnTheFlyAndPreCalculated,
PrimeTableTest,
Values(&CreateOnTheFlyPrimeTable, &CreatePreCalculatedPrimeTable<1000>));
#else
// Google Test doesn't support value-parameterized tests on some platforms
// and compilers, such as MSVC 7.1. If we use conditional compilation to
// compile out all code referring to the gtest_main library, MSVC linker
// will not link that library at all and consequently complain about
// missing entry point defined in that library (fatal error LNK1561:
// entry point must be defined). This dummy test keeps gtest_main linked in.
TEST(DummyTest, ValueParameterizedTestsAreNotSupportedOnThisPlatform) {}
#endif // GTEST_HAS_PARAM_TEST
// Copyright 2008 Google Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: vladl@google.com (Vlad Losev)
// This sample shows how to test code relying on some global flag variables.
// Combine() helps with generating all possible combinations of such flags,
// and each test is given one combination as a parameter.
// Use class definitions to test from this header.
#include "prime_tables.h"
#include <gtest/gtest.h>
#ifdef GTEST_HAS_COMBINE
// Suppose we want to introduce a new, improved implementation of PrimeTable
// which combines speed of PrecalcPrimeTable and versatility of
// OnTheFlyPrimeTable (see prime_tables.h). Inside it instantiates both
// PrecalcPrimeTable and OnTheFlyPrimeTable and uses the one that is more
// appropriate under the circumstances. But in low memory conditions, it can be
// told to instantiate without PrecalcPrimeTable instance at all and use only
// OnTheFlyPrimeTable.
class HybridPrimeTable : public PrimeTable {
public:
HybridPrimeTable(bool force_on_the_fly, int max_precalculated)
: on_the_fly_impl_(new OnTheFlyPrimeTable),
precalc_impl_(force_on_the_fly ? NULL :
new PreCalculatedPrimeTable(max_precalculated)),
max_precalculated_(max_precalculated) {}
virtual ~HybridPrimeTable() {
delete on_the_fly_impl_;
delete precalc_impl_;
}
virtual bool IsPrime(int n) const {
if (precalc_impl_ != NULL && n < max_precalculated_)
return precalc_impl_->IsPrime(n);
else
return on_the_fly_impl_->IsPrime(n);
}
virtual int GetNextPrime(int p) const {
int next_prime = -1;
if (precalc_impl_ != NULL && p < max_precalculated_)
next_prime = precalc_impl_->GetNextPrime(p);
return next_prime != -1 ? next_prime : on_the_fly_impl_->GetNextPrime(p);
}
private:
OnTheFlyPrimeTable* on_the_fly_impl_;
PreCalculatedPrimeTable* precalc_impl_;
int max_precalculated_;
};
using ::testing::TestWithParam;
using ::testing::Bool;
using ::testing::Values;
using ::testing::Combine;
// To test all code paths for HybridPrimeTable we must test it with numbers
// both within and outside PreCalculatedPrimeTable's capacity and also with
// PreCalculatedPrimeTable disabled. We do this by defining fixture which will
// accept different combinations of parameters for instantiating a
// HybridPrimeTable instance.
class PrimeTableTest : public TestWithParam< ::std::tr1::tuple<bool, int> > {
protected:
virtual void SetUp() {
// This can be written as
//
// bool force_on_the_fly;
// int max_precalculated;
// tie(force_on_the_fly, max_precalculated) = GetParam();
//
// once the Google C++ Style Guide allows use of ::std::tr1::tie.
//
bool force_on_the_fly = ::std::tr1::get<0>(GetParam());
int max_precalculated = ::std::tr1::get<1>(GetParam());
table_ = new HybridPrimeTable(force_on_the_fly, max_precalculated);
}
virtual void TearDown() {
delete table_;
table_ = NULL;
}
HybridPrimeTable* table_;
};
TEST_P(PrimeTableTest, ReturnsFalseForNonPrimes) {
// Inside the test body, you can refer to the test parameter by GetParam().
// In this case, the test parameter is a PrimeTable interface pointer which
// we can use directly.
// Please note that you can also save it in the fixture's SetUp() method
// or constructor and use saved copy in the tests.
EXPECT_FALSE(table_->IsPrime(-5));
EXPECT_FALSE(table_->IsPrime(0));
EXPECT_FALSE(table_->IsPrime(1));
EXPECT_FALSE(table_->IsPrime(4));
EXPECT_FALSE(table_->IsPrime(6));
EXPECT_FALSE(table_->IsPrime(100));
}
TEST_P(PrimeTableTest, ReturnsTrueForPrimes) {
EXPECT_TRUE(table_->IsPrime(2));
EXPECT_TRUE(table_->IsPrime(3));
EXPECT_TRUE(table_->IsPrime(5));
EXPECT_TRUE(table_->IsPrime(7));
EXPECT_TRUE(table_->IsPrime(11));
EXPECT_TRUE(table_->IsPrime(131));
}
TEST_P(PrimeTableTest, CanGetNextPrime) {
EXPECT_EQ(2, table_->GetNextPrime(0));
EXPECT_EQ(3, table_->GetNextPrime(2));
EXPECT_EQ(5, table_->GetNextPrime(3));
EXPECT_EQ(7, table_->GetNextPrime(5));
EXPECT_EQ(11, table_->GetNextPrime(7));
EXPECT_EQ(131, table_->GetNextPrime(128));
}
// In order to run value-parameterized tests, you need to instantiate them,
// or bind them to a list of values which will be used as test parameters.
// You can instantiate them in a different translation module, or even
// instantiate them several times.
//
// Here, we instantiate our tests with a list of parameters. We must combine
// all variations of the boolean flag suppressing PrecalcPrimeTable and some
// meaningful values for tests. We choose a small value (1), and a value that
// will put some of the tested numbers beyond the capability of the
// PrecalcPrimeTable instance and some inside it (10). Combine will produce all
// possible combinations.
INSTANTIATE_TEST_CASE_P(MeaningfulTestParameters,
PrimeTableTest,
Combine(Bool(), Values(1, 10)));
#else
// Google Test doesn't support Combine() on some platforms and compilers,
// such as MSVC 7.1. If we use conditional compilation to compile out
// all code referring to the gtest_main library, MSVC linker will not
// link that library at all and consequently complain about missing entry
// point defined in that library (fatal error LNK1561: entry point must
// be defined). This dummy test keeps gtest_main linked in.
TEST(DummyTest, CombineIsNotSupportedOnThisPlatform) {}
#endif // GTEST_HAS_COMBINE
...@@ -67,7 +67,7 @@ to the following: ...@@ -67,7 +67,7 @@ to the following:
# Build gtest library; as it is outside of our source root, we need to # Build gtest library; as it is outside of our source root, we need to
# tell SCons that the directory it will refer to as # tell SCons that the directory it will refer to as
# e.g. $BUIlD_DIR/gtest is actually on disk in original form as # e.g. $BUILD_DIR/gtest is actually on disk in original form as
# ../../gtest (relative to your project root directory). Recall that # ../../gtest (relative to your project root directory). Recall that
# SCons by default copies all source files into the build directory # SCons by default copies all source files into the build directory
# before building. # before building.
...@@ -102,11 +102,6 @@ env = env.Clone() ...@@ -102,11 +102,6 @@ env = env.Clone()
env.Prepend(CPPPATH = ['..', env.Prepend(CPPPATH = ['..',
'../include']) '../include'])
# TODO(joi@google.com) Fix the code that causes this warning so that
# we see all warnings from the compiler about possible 64-bit porting
# issues.
env.Append(CCFLAGS=['-wd4267'])
# Sources shared by base library and library that includes main. # Sources shared by base library and library that includes main.
gtest_sources = ['../src/gtest-all.cc'] gtest_sources = ['../src/gtest-all.cc']
...@@ -125,23 +120,32 @@ if 'LIB_OUTPUT' in env.Dictionary(): ...@@ -125,23 +120,32 @@ if 'LIB_OUTPUT' in env.Dictionary():
env.Install('$LIB_OUTPUT', source=[gtest, gtest_main]) env.Install('$LIB_OUTPUT', source=[gtest, gtest_main])
def GtestUnitTest(env, target, gtest_lib, additional_sources=None): def GtestBinary(env, target, dir_prefix, gtest_lib, additional_sources=None):
"""Helper to create gtest unit tests. """Helper to create gtest binaries: tests, samples, etc.
Args: Args:
env: The SCons construction environment to use to build. env: The SCons construction environment to use to build.
target: The basename of the target unit test .cc file. target: The basename of the target's main source file, also used as target
name.
dir_prefix: The path to prefix the main source file.
gtest_lib: The gtest lib to use. gtest_lib: The gtest lib to use.
""" """
source = [env.File('%s.cc' % target, env.Dir('../test'))] source = [env.File('%s.cc' % target, env.Dir(dir_prefix))]
if additional_sources: if additional_sources:
source += additional_sources source += additional_sources
unit_test = env.Program(target=target, unit_test = env.Program(target=target, source=source, LIBS=[gtest_lib])
source=source,
LIBS=[gtest_lib, 'kernel32.lib', 'user32.lib'])
if 'EXE_OUTPUT' in env.Dictionary(): if 'EXE_OUTPUT' in env.Dictionary():
env.Install('$EXE_OUTPUT', source=[unit_test]) env.Install('$EXE_OUTPUT', source=[unit_test])
def GtestUnitTest(env, target, gtest_lib, additional_sources=None):
"""Helper to create gtest unit tests.
Args:
env: The SCons construction environment to use to build.
target: The basename of the target unit test .cc file.
gtest_lib: The gtest lib to use.
"""
GtestBinary(env, target, "../test", gtest_lib, additional_sources)
GtestUnitTest(env, 'gtest-filepath_test', gtest_main) GtestUnitTest(env, 'gtest-filepath_test', gtest_main)
GtestUnitTest(env, 'gtest-message_test', gtest_main) GtestUnitTest(env, 'gtest-message_test', gtest_main)
...@@ -157,9 +161,13 @@ GtestUnitTest(env, 'gtest_sole_header_test', gtest_main) ...@@ -157,9 +161,13 @@ GtestUnitTest(env, 'gtest_sole_header_test', gtest_main)
GtestUnitTest(env, 'gtest-test-part_test', gtest_main) GtestUnitTest(env, 'gtest-test-part_test', gtest_main)
GtestUnitTest(env, 'gtest-typed-test_test', gtest_main, GtestUnitTest(env, 'gtest-typed-test_test', gtest_main,
additional_sources=['../test/gtest-typed-test2_test.cc']) additional_sources=['../test/gtest-typed-test2_test.cc'])
GtestUnitTest(env, 'gtest-param-test_test', gtest,
additional_sources=['../test/gtest-param-test2_test.cc'])
GtestUnitTest(env, 'gtest_unittest', gtest) GtestUnitTest(env, 'gtest_unittest', gtest)
GtestUnitTest(env, 'gtest_output_test_', gtest) GtestUnitTest(env, 'gtest_output_test_', gtest)
GtestUnitTest(env, 'gtest_color_test_', gtest) GtestUnitTest(env, 'gtest_color_test_', gtest)
GtestUnitTest(env, 'gtest-linked_ptr_test', gtest_main)
GtestUnitTest(env, 'gtest-port_test', gtest_main)
# TODO(wan@google.com) Add these unit tests: # TODO(wan@google.com) Add these unit tests:
# - gtest_break_on_failure_unittest_ # - gtest_break_on_failure_unittest_
...@@ -179,3 +187,33 @@ for flag in ["/O1", "/Os", "/Og", "/Oy"]: ...@@ -179,3 +187,33 @@ for flag in ["/O1", "/Os", "/Og", "/Oy"]:
linker_flags.remove(flag) linker_flags.remove(flag)
GtestUnitTest(special_env, 'gtest_env_var_test_', gtest) GtestUnitTest(special_env, 'gtest_env_var_test_', gtest)
GtestUnitTest(special_env, 'gtest_uninitialized_test_', gtest) GtestUnitTest(special_env, 'gtest_uninitialized_test_', gtest)
def GtestSample(env, target, gtest_lib, additional_sources=None):
"""Helper to create gtest samples.
Args:
env: The SCons construction environment to use to build.
target: The basename of the target unit test .cc file.
gtest_lib: The gtest lib to use.
"""
GtestBinary(env, target, "../samples", gtest_lib, additional_sources)
# Use the GTEST_BUILD_SAMPLES build variable to control building of samples.
# In your SConstruct file, add
# vars = Variables()
# vars.Add(BoolVariable('GTEST_BUILD_SAMPLES', 'Build samples', True))
# my_environment = Environment(variables = vars, ...)
# Then, in the command line use GTEST_BUILD_SAMPLES=true to enable them.
#
if env.get('GTEST_BUILD_SAMPLES', False):
sample1_obj = env.Object('../samples/sample1.cc')
GtestSample(env, 'sample1_unittest', gtest_main,
additional_sources=[sample1_obj])
GtestSample(env, 'sample2_unittest', gtest_main,
additional_sources=['../samples/sample2.cc'])
GtestSample(env, 'sample3_unittest', gtest_main)
GtestSample(env, 'sample5_unittest', gtest_main,
additional_sources=[sample1_obj])
GtestSample(env, 'sample6_unittest', gtest_main)
GtestSample(env, 'sample7_unittest', gtest_main)
GtestSample(env, 'sample8_unittest', gtest_main)
...@@ -53,7 +53,6 @@ ...@@ -53,7 +53,6 @@
#include <windows.h> // NOLINT #include <windows.h> // NOLINT
#endif // GTEST_OS_WINDOWS #endif // GTEST_OS_WINDOWS
#include <ostream> // NOLINT
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <gtest/gtest-spi.h> #include <gtest/gtest-spi.h>
...@@ -846,7 +845,7 @@ class OsStackTraceGetterInterface { ...@@ -846,7 +845,7 @@ class OsStackTraceGetterInterface {
GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface); GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface);
}; };
// A working implemenation of the OsStackTraceGetterInterface interface. // A working implementation of the OsStackTraceGetterInterface interface.
class OsStackTraceGetter : public OsStackTraceGetterInterface { class OsStackTraceGetter : public OsStackTraceGetterInterface {
public: public:
OsStackTraceGetter() {} OsStackTraceGetter() {}
...@@ -1063,6 +1062,14 @@ class UnitTestImpl { ...@@ -1063,6 +1062,14 @@ class UnitTestImpl {
tear_down_tc)->AddTestInfo(test_info); tear_down_tc)->AddTestInfo(test_info);
} }
#ifdef GTEST_HAS_PARAM_TEST
// Returns ParameterizedTestCaseRegistry object used to keep track of
// value-parameterized tests and instantiate and register them.
internal::ParameterizedTestCaseRegistry& parameterized_test_registry() {
return parameterized_test_registry_;
}
#endif // GTEST_HAS_PARAM_TEST
// Sets the TestCase object for the test that's currently running. // Sets the TestCase object for the test that's currently running.
void set_current_test_case(TestCase* current_test_case) { void set_current_test_case(TestCase* current_test_case) {
current_test_case_ = current_test_case; current_test_case_ = current_test_case;
...@@ -1075,6 +1082,14 @@ class UnitTestImpl { ...@@ -1075,6 +1082,14 @@ class UnitTestImpl {
current_test_info_ = current_test_info; current_test_info_ = current_test_info;
} }
// Registers all parameterized tests defined using TEST_P and
// INSTANTIATE_TEST_P, creating regular tests for each test/parameter
// combination. This method can be called more then once; it has
// guards protecting from registering the tests more then once.
// If value-parameterized tests are disabled, RegisterParameterizedTests
// is present but does nothing.
void RegisterParameterizedTests();
// Runs all tests in this UnitTest object, prints the result, and // Runs all tests in this UnitTest object, prints the result, and
// returns 0 if all tests are successful, or 1 otherwise. If any // returns 0 if all tests are successful, or 1 otherwise. If any
// exception is thrown during a test on Windows, this test is // exception is thrown during a test on Windows, this test is
...@@ -1169,6 +1184,15 @@ class UnitTestImpl { ...@@ -1169,6 +1184,15 @@ class UnitTestImpl {
internal::List<TestCase*> test_cases_; // The list of TestCases. internal::List<TestCase*> test_cases_; // The list of TestCases.
#ifdef GTEST_HAS_PARAM_TEST
// ParameterizedTestRegistry object used to register value-parameterized
// tests.
internal::ParameterizedTestCaseRegistry parameterized_test_registry_;
// Indicates whether RegisterParameterizedTests() has been called already.
bool parameterized_tests_registered_;
#endif // GTEST_HAS_PARAM_TEST
// Points to the last death test case registered. Initially NULL. // Points to the last death test case registered. Initially NULL.
internal::ListNode<TestCase*>* last_death_test_case_; internal::ListNode<TestCase*>* last_death_test_case_;
......
...@@ -56,25 +56,49 @@ namespace internal { ...@@ -56,25 +56,49 @@ namespace internal {
// Implements RE. Currently only needed for death tests. // Implements RE. Currently only needed for death tests.
RE::~RE() { RE::~RE() {
regfree(&regex_); regfree(&partial_regex_);
regfree(&full_regex_);
free(const_cast<char*>(pattern_)); free(const_cast<char*>(pattern_));
} }
// Returns true iff str contains regular expression re. // Returns true iff regular expression re matches the entire str.
bool RE::FullMatch(const char* str, const RE& re) {
if (!re.is_valid_) return false;
regmatch_t match;
return regexec(&re.full_regex_, str, 1, &match, 0) == 0;
}
// Returns true iff regular expression re matches a substring of str
// (including str itself).
bool RE::PartialMatch(const char* str, const RE& re) { bool RE::PartialMatch(const char* str, const RE& re) {
if (!re.is_valid_) return false; if (!re.is_valid_) return false;
regmatch_t match; regmatch_t match;
return regexec(&re.regex_, str, 1, &match, 0) == 0; return regexec(&re.partial_regex_, str, 1, &match, 0) == 0;
} }
// Initializes an RE from its string representation. // Initializes an RE from its string representation.
void RE::Init(const char* regex) { void RE::Init(const char* regex) {
pattern_ = strdup(regex); pattern_ = strdup(regex);
is_valid_ = regcomp(&regex_, regex, REG_EXTENDED) == 0;
// Reserves enough bytes to hold the regular expression used for a
// full match.
const size_t full_regex_len = strlen(regex) + 10;
char* const full_pattern = new char[full_regex_len];
snprintf(full_pattern, full_regex_len, "^(%s)$", regex);
is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0;
// We want to call regcomp(&partial_regex_, ...) even if the
// previous expression returns false. Otherwise partial_regex_ may
// not be properly initialized can may cause trouble when it's
// freed.
is_valid_ = (regcomp(&partial_regex_, regex, REG_EXTENDED) == 0) && is_valid_;
EXPECT_TRUE(is_valid_) EXPECT_TRUE(is_valid_)
<< "Regular expression \"" << regex << "Regular expression \"" << regex
<< "\" is not a valid POSIX Extended regular expression."; << "\" is not a valid POSIX Extended regular expression.";
delete[] full_pattern;
} }
#endif // GTEST_HAS_DEATH_TEST #endif // GTEST_HAS_DEATH_TEST
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment