Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
yangql
googletest
Commits
efecb0bf
Commit
efecb0bf
authored
Feb 25, 2019
by
Abseil Team
Committed by
Gennadiy Civil
Feb 25, 2019
Browse files
Googletest export
Replace more pump'd code with variadic templates. PiperOrigin-RevId: 235584585
parent
5154386c
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
134 additions
and
2883 deletions
+134
-2883
googletest/Makefile.am
googletest/Makefile.am
+0
-3
googletest/include/gtest/gtest-param-test.h
googletest/include/gtest/gtest-param-test.h
+3
-107
googletest/include/gtest/gtest-param-test.h.pump
googletest/include/gtest/gtest-param-test.h.pump
+0
-493
googletest/include/gtest/internal/gtest-param-util-generated.h
...etest/include/gtest/internal/gtest-param-util-generated.h
+0
-2043
googletest/include/gtest/internal/gtest-param-util-generated.h.pump
.../include/gtest/internal/gtest-param-util-generated.h.pump
+0
-237
googletest/include/gtest/internal/gtest-param-util.h
googletest/include/gtest/internal/gtest-param-util.h
+131
-0
No files found.
googletest/Makefile.am
View file @
efecb0bf
...
...
@@ -6,8 +6,6 @@ ACLOCAL_AMFLAGS = -I m4
EXTRA_DIST
=
\
CONTRIBUTORS
\
LICENSE
\
include/gtest/gtest-param-test.h.pump
\
include/gtest/internal/gtest-param-util-generated.h.pump
\
include/gtest/internal/gtest-type-util.h.pump
\
make/Makefile
\
scripts/fuse_gtest_files.py
\
...
...
@@ -200,7 +198,6 @@ pkginclude_internal_HEADERS = \
include/gtest/internal/gtest-death-test-internal.h
\
include/gtest/internal/gtest-filepath.h
\
include/gtest/internal/gtest-internal.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-arch.h
\
...
...
googletest/include/gtest/gtest-param-test.h
View file @
efecb0bf
// This file was GENERATED by command:
// pump.py gtest-param-test.h.pump
// DO NOT EDIT BY HAND!!!
// Copyright 2008, Google Inc.
// All rights reserved.
//
...
...
@@ -182,7 +178,6 @@ TEST_P(DerivedTest, DoesBlah) {
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-param-util.h"
#include "gtest/internal/gtest-param-util-generated.h"
#include "gtest/internal/gtest-port.h"
namespace
testing
{
...
...
@@ -411,108 +406,9 @@ inline internal::ParamGenerator<bool> Bool() {
// INSTANTIATE_TEST_SUITE_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
);
template
<
typename
...
Generator
>
internal
::
CartesianProductHolder
<
Generator
...
>
Combine
(
const
Generator
&
...
g
)
{
return
internal
::
CartesianProductHolder
<
Generator
...
>
(
g
...);
}
#define TEST_P(test_suite_name, test_name) \
...
...
googletest/include/gtest/gtest-param-test.h.pump
deleted
100644 → 0
View file @
5154386c
$$
-*-
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.
//
// Macros and functions for implementing parameterized tests
// in Google C++ Testing and Mocking Framework (Google Test)
//
// This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
//
// GOOGLETEST_CM0001 DO NOT DELETE
#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 is usually derived from testing::TestWithParam<T> (see below for
// another inheritance scheme that's sometimes useful in more complicated
// class hierarchies), where 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_SUITE_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 suite
// each with parameter values "meeny", "miny", and "moe".
INSTANTIATE_TEST_SUITE_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_SUITE_P macro is a prefix that will be added to the
// actual test suite 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_SUITE_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_SUITE_P will instantiate all tests
// in the given test suite, whether their definitions come before or
// AFTER the INSTANTIATE_TEST_SUITE_P statement.
//
// Please also note that generator expressions (including parameters to the
// generators) are evaluated in InitGoogleTest(), after main() has started.
// This allows the user on one hand, to adjust generator parameters in order
// to dynamically determine a set of tests to run and on the other hand,
// give the user a chance to inspect the generated tests with Google Test
// reflection API before RUN_ALL_TESTS() is executed.
//
// 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.
//
//
// A parameterized test fixture must be derived from testing::Test and from
// testing::WithParamInterface<T>, where T is the type of the parameter
// values. Inheriting from TestWithParam<T> satisfies that requirement because
// TestWithParam<T> inherits from both Test and WithParamInterface. In more
// complicated hierarchies, however, it is occasionally useful to inherit
// separately from Test and WithParamInterface. For example:
class BaseTest : public ::testing::Test {
// You can inherit all the usual members for a non-parameterized test
// fixture here.
};
class DerivedTest : public BaseTest, public ::testing::WithParamInterface<int> {
// The usual test fixture members go here too.
};
TEST_F(BaseTest, HasFoo) {
// This is an ordinary non-parameterized test.
}
TEST_P(DerivedTest, DoesBlah) {
// GetParam works just the same here as if you inherit from TestWithParam.
EXPECT_TRUE(foo.Blah(GetParam()));
}
#endif // 0
#include <utility>
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-param-util.h"
#include "gtest/internal/gtest-param-util-generated.h"
#include "gtest/internal/gtest-port.h"
namespace
testing
{
// Functions producing parameter generators.
//
// Google Test uses these generators to produce parameters for value-
// parameterized tests. When a parameterized test suite 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 suite 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_SUITE_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 suite StringTest
// each with C-string values of "foo", "bar", and "baz":
//
// const char* strings[] = {"foo", "bar", "baz"};
// INSTANTIATE_TEST_SUITE_P(StringSequence, StringTest, ValuesIn(strings));
//
// This instantiates tests from test suite 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_SUITE_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_SUITE_P(CharSequence2,
// CharTest,
// ValuesIn(l.begin(), l.end()));
//
template
<
typename
ForwardIterator
>
internal
::
ParamGenerator
<
typename
::
testing
::
internal
::
IteratorTraits
<
ForwardIterator
>::
value_type
>
ValuesIn
(
ForwardIterator
begin
,
ForwardIterator
end
)
{
typedef
typename
::
testing
::
internal
::
IteratorTraits
<
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 suite BarTest each
// with values "one", "two", and "three":
//
// INSTANTIATE_TEST_SUITE_P(NumSequence,
// BarTest,
// Values("one", "two", "three"));
//
// This instantiates tests from test suite BazTest each with values 1, 2, 3.5.
// The exact type of values will depend on the type of parameter in BazTest.
//
// INSTANTIATE_TEST_SUITE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5));
//
//
template
<
typename
...
T
>
internal
::
ValueArray
<
T
...
>
Values
(
T
...
v
)
{
return
internal
::
ValueArray
<
T
...
>
(
std
::
move
(
v
)...);
}
// 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 suite FlagDependentTest
// will be instantiated twice with parameters false and true.
//
// class FlagDependentTest : public testing::TestWithParam<bool> {
// virtual void SetUp() {
// external_flag = GetParam();
// }
// }
// INSTANTIATE_TEST_SUITE_P(BoolSequence, FlagDependentTest, Bool());
//
inline
internal
::
ParamGenerator
<
bool
>
Bool
()
{
return
Values
(
false
,
true
);
}
// 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
// std::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.
//
// Example:
//
// This will instantiate tests in test suite 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<std::tuple<const char*, Color> > {...};
//
// TEST_P(AnimalTest, AnimalLooksNice) {...}
//
// INSTANTIATE_TEST_SUITE_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<std::tuple<bool, bool> > {
// virtual void SetUp() {
// // Assigns external_flag_1 and external_flag_2 values from the tuple.
// std::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_SUITE_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
]]);
}
]]
# define TEST_P(test_suite_name, test_name) \
class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
: public test_suite_name { \
public: \
GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() {} \
virtual void TestBody(); \
private: \
static int AddToRegistry() { \
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
GetTestSuitePatternHolder<test_suite_name>(\
#test_suite_name, \
::testing::internal::CodeLocation(\
__FILE__, __LINE__))->AddTestPattern(\
GTEST_STRINGIFY_(test_suite_name), \
GTEST_STRINGIFY_(test_name), \
new ::testing::internal::TestMetaFactory< \
GTEST_TEST_CLASS_NAME_(\
test_suite_name, test_name)>()); \
return 0; \
} \
static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \
GTEST_DISALLOW_COPY_AND_ASSIGN_(\
GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)); \
}; \
int GTEST_TEST_CLASS_NAME_(test_suite_name, \
test_name)::gtest_registering_dummy_ = \
GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::AddToRegistry(); \
void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody()
// The optional last argument to INSTANTIATE_TEST_SUITE_P allows the user
// to specify a function or functor that generates custom test name suffixes
// based on the test parameters. The function should accept one argument of
// type testing::TestParamInfo<class ParamType>, and return std::string.
//
// testing::PrintToStringParamName is a builtin test suffix generator that
// returns the value of testing::PrintToString(GetParam()).
//
// Note: test names must be non-empty, unique, and may only contain ASCII
// alphanumeric characters or underscore. Because PrintToString adds quotes
// to std::string and C strings, it won't work for these types.
# define INSTANTIATE_TEST_SUITE_P(prefix, test_suite_name, generator, ...) \
static ::testing::internal::ParamGenerator<test_suite_name::ParamType> \
gtest_##prefix##test_suite_name##_EvalGenerator_() { return generator; } \
static ::std::string gtest_##prefix##test_suite_name##_EvalGenerateName_( \
const ::testing::TestParamInfo<test_suite_name::ParamType>& info) { \
return ::testing::internal::GetParamNameGen<test_suite_name::ParamType> \
(__VA_ARGS__)(info); \
} \
static int gtest_##prefix##test_suite_name##_dummy_ GTEST_ATTRIBUTE_UNUSED_ = \
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
GetTestSuitePatternHolder<test_suite_name>(\
#test_suite_name, \
::testing::internal::CodeLocation(\
__FILE__, __LINE__))->AddTestSuiteInstantiation(\
#prefix, \
>est_##prefix##test_suite_name##_EvalGenerator_, \
>est_##prefix##test_suite_name##_EvalGenerateName_, \
__FILE__, __LINE__)
// Legacy API is deprecated but still available
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
#define INSTANTIATE_TEST_CASE_P INSTANTIATE_TEST_SUITE_P
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
}
// namespace testing
#endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
googletest/include/gtest/internal/gtest-param-util-generated.h
deleted
100644 → 0
View file @
5154386c
// This file was GENERATED by command:
// pump.py gtest-param-util-generated.h.pump
// 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.
// 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 tuple which is
// currently set at 10.
// GOOGLETEST_CM0001 DO NOT DELETE
#include <assert.h>
#include <memory>
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
#include "gtest/internal/gtest-param-util.h"
#include "gtest/internal/gtest-port.h"
namespace
testing
{
namespace
internal
{
// 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
::
tuple
<
T1
,
T2
>
>
{
public:
typedef
::
std
::
tuple
<
T1
,
T2
>
ParamType
;
CartesianProductGenerator2
(
const
ParamGenerator
<
T1
>&
g1
,
const
ParamGenerator
<
T2
>&
g2
)
:
g1_
(
g1
),
g2_
(
g2
)
{}
~
CartesianProductGenerator2
()
override
{}
ParamIteratorInterface
<
ParamType
>*
Begin
()
const
override
{
return
new
Iterator
(
this
,
g1_
,
g1_
.
begin
(),
g2_
,
g2_
.
begin
());
}
ParamIteratorInterface
<
ParamType
>*
End
()
const
override
{
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
();
}
~
Iterator
()
override
{}
const
ParamGeneratorInterface
<
ParamType
>*
BaseGenerator
()
const
override
{
return
base_
;
}
// Advance should not be called on beyond-of-range iterators
// so no component iterators must be beyond end of range, either.
void
Advance
()
override
{
assert
(
!
AtEnd
());
++
current2_
;
if
(
current2_
==
end2_
)
{
current2_
=
begin2_
;
++
current1_
;
}
ComputeCurrentValue
();
}
ParamIteratorInterface
<
ParamType
>*
Clone
()
const
override
{
return
new
Iterator
(
*
this
);
}
const
ParamType
*
Current
()
const
override
{
return
current_value_
.
get
();
}
bool
Equals
(
const
ParamIteratorInterface
<
ParamType
>&
other
)
const
override
{
// 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_
.
reset
(
new
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_
;
}
// No implementation - assignment is unsupported.
void
operator
=
(
const
Iterator
&
other
);
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_
;
std
::
shared_ptr
<
ParamType
>
current_value_
;
};
// class CartesianProductGenerator2::Iterator
// No implementation - assignment is unsupported.
void
operator
=
(
const
CartesianProductGenerator2
&
other
);
const
ParamGenerator
<
T1
>
g1_
;
const
ParamGenerator
<
T2
>
g2_
;
};
// class CartesianProductGenerator2
template
<
typename
T1
,
typename
T2
,
typename
T3
>
class
CartesianProductGenerator3
:
public
ParamGeneratorInterface
<
::
std
::
tuple
<
T1
,
T2
,
T3
>
>
{
public:
typedef
::
std
::
tuple
<
T1
,
T2
,
T3
>
ParamType
;
CartesianProductGenerator3
(
const
ParamGenerator
<
T1
>&
g1
,
const
ParamGenerator
<
T2
>&
g2
,
const
ParamGenerator
<
T3
>&
g3
)
:
g1_
(
g1
),
g2_
(
g2
),
g3_
(
g3
)
{}
~
CartesianProductGenerator3
()
override
{}
ParamIteratorInterface
<
ParamType
>*
Begin
()
const
override
{
return
new
Iterator
(
this
,
g1_
,
g1_
.
begin
(),
g2_
,
g2_
.
begin
(),
g3_
,
g3_
.
begin
());
}
ParamIteratorInterface
<
ParamType
>*
End
()
const
override
{
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
();
}
~
Iterator
()
override
{}
const
ParamGeneratorInterface
<
ParamType
>*
BaseGenerator
()
const
override
{
return
base_
;
}
// Advance should not be called on beyond-of-range iterators
// so no component iterators must be beyond end of range, either.
void
Advance
()
override
{
assert
(
!
AtEnd
());
++
current3_
;
if
(
current3_
==
end3_
)
{
current3_
=
begin3_
;
++
current2_
;
}
if
(
current2_
==
end2_
)
{
current2_
=
begin2_
;
++
current1_
;
}
ComputeCurrentValue
();
}
ParamIteratorInterface
<
ParamType
>*
Clone
()
const
override
{
return
new
Iterator
(
*
this
);
}
const
ParamType
*
Current
()
const
override
{
return
current_value_
.
get
();
}
bool
Equals
(
const
ParamIteratorInterface
<
ParamType
>&
other
)
const
override
{
// 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_
.
reset
(
new
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_
;
}
// No implementation - assignment is unsupported.
void
operator
=
(
const
Iterator
&
other
);
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_
;
std
::
shared_ptr
<
ParamType
>
current_value_
;
};
// class CartesianProductGenerator3::Iterator
// No implementation - assignment is unsupported.
void
operator
=
(
const
CartesianProductGenerator3
&
other
);
const
ParamGenerator
<
T1
>
g1_
;
const
ParamGenerator
<
T2
>
g2_
;
const
ParamGenerator
<
T3
>
g3_
;
};
// class CartesianProductGenerator3
template
<
typename
T1
,
typename
T2
,
typename
T3
,
typename
T4
>
class
CartesianProductGenerator4
:
public
ParamGeneratorInterface
<
::
std
::
tuple
<
T1
,
T2
,
T3
,
T4
>
>
{
public:
typedef
::
std
::
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
)
{}
~
CartesianProductGenerator4
()
override
{}
ParamIteratorInterface
<
ParamType
>*
Begin
()
const
override
{
return
new
Iterator
(
this
,
g1_
,
g1_
.
begin
(),
g2_
,
g2_
.
begin
(),
g3_
,
g3_
.
begin
(),
g4_
,
g4_
.
begin
());
}
ParamIteratorInterface
<
ParamType
>*
End
()
const
override
{
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
();
}
~
Iterator
()
override
{}
const
ParamGeneratorInterface
<
ParamType
>*
BaseGenerator
()
const
override
{
return
base_
;
}
// Advance should not be called on beyond-of-range iterators
// so no component iterators must be beyond end of range, either.
void
Advance
()
override
{
assert
(
!
AtEnd
());
++
current4_
;
if
(
current4_
==
end4_
)
{
current4_
=
begin4_
;
++
current3_
;
}
if
(
current3_
==
end3_
)
{
current3_
=
begin3_
;
++
current2_
;
}
if
(
current2_
==
end2_
)
{
current2_
=
begin2_
;
++
current1_
;
}
ComputeCurrentValue
();
}
ParamIteratorInterface
<
ParamType
>*
Clone
()
const
override
{
return
new
Iterator
(
*
this
);
}
const
ParamType
*
Current
()
const
override
{
return
current_value_
.
get
();
}
bool
Equals
(
const
ParamIteratorInterface
<
ParamType
>&
other
)
const
override
{
// 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_
.
reset
(
new
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_
;
}
// No implementation - assignment is unsupported.
void
operator
=
(
const
Iterator
&
other
);
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_
;
std
::
shared_ptr
<
ParamType
>
current_value_
;
};
// class CartesianProductGenerator4::Iterator
// No implementation - assignment is unsupported.
void
operator
=
(
const
CartesianProductGenerator4
&
other
);
const
ParamGenerator
<
T1
>
g1_
;
const
ParamGenerator
<
T2
>
g2_
;
const
ParamGenerator
<
T3
>
g3_
;
const
ParamGenerator
<
T4
>
g4_
;
};
// class CartesianProductGenerator4
template
<
typename
T1
,
typename
T2
,
typename
T3
,
typename
T4
,
typename
T5
>
class
CartesianProductGenerator5
:
public
ParamGeneratorInterface
<
::
std
::
tuple
<
T1
,
T2
,
T3
,
T4
,
T5
>
>
{
public:
typedef
::
std
::
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
)
{}
~
CartesianProductGenerator5
()
override
{}
ParamIteratorInterface
<
ParamType
>*
Begin
()
const
override
{
return
new
Iterator
(
this
,
g1_
,
g1_
.
begin
(),
g2_
,
g2_
.
begin
(),
g3_
,
g3_
.
begin
(),
g4_
,
g4_
.
begin
(),
g5_
,
g5_
.
begin
());
}
ParamIteratorInterface
<
ParamType
>*
End
()
const
override
{
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
();
}
~
Iterator
()
override
{}
const
ParamGeneratorInterface
<
ParamType
>*
BaseGenerator
()
const
override
{
return
base_
;
}
// Advance should not be called on beyond-of-range iterators
// so no component iterators must be beyond end of range, either.
void
Advance
()
override
{
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
();
}
ParamIteratorInterface
<
ParamType
>*
Clone
()
const
override
{
return
new
Iterator
(
*
this
);
}
const
ParamType
*
Current
()
const
override
{
return
current_value_
.
get
();
}
bool
Equals
(
const
ParamIteratorInterface
<
ParamType
>&
other
)
const
override
{
// 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_
.
reset
(
new
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_
;
}
// No implementation - assignment is unsupported.
void
operator
=
(
const
Iterator
&
other
);
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_
;
std
::
shared_ptr
<
ParamType
>
current_value_
;
};
// class CartesianProductGenerator5::Iterator
// No implementation - assignment is unsupported.
void
operator
=
(
const
CartesianProductGenerator5
&
other
);
const
ParamGenerator
<
T1
>
g1_
;
const
ParamGenerator
<
T2
>
g2_
;
const
ParamGenerator
<
T3
>
g3_
;
const
ParamGenerator
<
T4
>
g4_
;
const
ParamGenerator
<
T5
>
g5_
;
};
// class CartesianProductGenerator5
template
<
typename
T1
,
typename
T2
,
typename
T3
,
typename
T4
,
typename
T5
,
typename
T6
>
class
CartesianProductGenerator6
:
public
ParamGeneratorInterface
<
::
std
::
tuple
<
T1
,
T2
,
T3
,
T4
,
T5
,
T6
>
>
{
public:
typedef
::
std
::
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
)
{}
~
CartesianProductGenerator6
()
override
{}
ParamIteratorInterface
<
ParamType
>*
Begin
()
const
override
{
return
new
Iterator
(
this
,
g1_
,
g1_
.
begin
(),
g2_
,
g2_
.
begin
(),
g3_
,
g3_
.
begin
(),
g4_
,
g4_
.
begin
(),
g5_
,
g5_
.
begin
(),
g6_
,
g6_
.
begin
());
}
ParamIteratorInterface
<
ParamType
>*
End
()
const
override
{
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
();
}
~
Iterator
()
override
{}
const
ParamGeneratorInterface
<
ParamType
>*
BaseGenerator
()
const
override
{
return
base_
;
}
// Advance should not be called on beyond-of-range iterators
// so no component iterators must be beyond end of range, either.
void
Advance
()
override
{
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
();
}
ParamIteratorInterface
<
ParamType
>*
Clone
()
const
override
{
return
new
Iterator
(
*
this
);
}
const
ParamType
*
Current
()
const
override
{
return
current_value_
.
get
();
}
bool
Equals
(
const
ParamIteratorInterface
<
ParamType
>&
other
)
const
override
{
// 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_
.
reset
(
new
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_
;
}
// No implementation - assignment is unsupported.
void
operator
=
(
const
Iterator
&
other
);
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_
;
std
::
shared_ptr
<
ParamType
>
current_value_
;
};
// class CartesianProductGenerator6::Iterator
// No implementation - assignment is unsupported.
void
operator
=
(
const
CartesianProductGenerator6
&
other
);
const
ParamGenerator
<
T1
>
g1_
;
const
ParamGenerator
<
T2
>
g2_
;
const
ParamGenerator
<
T3
>
g3_
;
const
ParamGenerator
<
T4
>
g4_
;
const
ParamGenerator
<
T5
>
g5_
;
const
ParamGenerator
<
T6
>
g6_
;
};
// class CartesianProductGenerator6
template
<
typename
T1
,
typename
T2
,
typename
T3
,
typename
T4
,
typename
T5
,
typename
T6
,
typename
T7
>
class
CartesianProductGenerator7
:
public
ParamGeneratorInterface
<
::
std
::
tuple
<
T1
,
T2
,
T3
,
T4
,
T5
,
T6
,
T7
>
>
{
public:
typedef
::
std
::
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
)
{}
~
CartesianProductGenerator7
()
override
{}
ParamIteratorInterface
<
ParamType
>*
Begin
()
const
override
{
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
());
}
ParamIteratorInterface
<
ParamType
>*
End
()
const
override
{
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
();
}
~
Iterator
()
override
{}
const
ParamGeneratorInterface
<
ParamType
>*
BaseGenerator
()
const
override
{
return
base_
;
}
// Advance should not be called on beyond-of-range iterators
// so no component iterators must be beyond end of range, either.
void
Advance
()
override
{
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
();
}
ParamIteratorInterface
<
ParamType
>*
Clone
()
const
override
{
return
new
Iterator
(
*
this
);
}
const
ParamType
*
Current
()
const
override
{
return
current_value_
.
get
();
}
bool
Equals
(
const
ParamIteratorInterface
<
ParamType
>&
other
)
const
override
{
// 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_
.
reset
(
new
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_
;
}
// No implementation - assignment is unsupported.
void
operator
=
(
const
Iterator
&
other
);
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_
;
std
::
shared_ptr
<
ParamType
>
current_value_
;
};
// class CartesianProductGenerator7::Iterator
// No implementation - assignment is unsupported.
void
operator
=
(
const
CartesianProductGenerator7
&
other
);
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_
;
};
// class CartesianProductGenerator7
template
<
typename
T1
,
typename
T2
,
typename
T3
,
typename
T4
,
typename
T5
,
typename
T6
,
typename
T7
,
typename
T8
>
class
CartesianProductGenerator8
:
public
ParamGeneratorInterface
<
::
std
::
tuple
<
T1
,
T2
,
T3
,
T4
,
T5
,
T6
,
T7
,
T8
>
>
{
public:
typedef
::
std
::
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
)
{}
~
CartesianProductGenerator8
()
override
{}
ParamIteratorInterface
<
ParamType
>*
Begin
()
const
override
{
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
());
}
ParamIteratorInterface
<
ParamType
>*
End
()
const
override
{
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
();
}
~
Iterator
()
override
{}
const
ParamGeneratorInterface
<
ParamType
>*
BaseGenerator
()
const
override
{
return
base_
;
}
// Advance should not be called on beyond-of-range iterators
// so no component iterators must be beyond end of range, either.
void
Advance
()
override
{
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
();
}
ParamIteratorInterface
<
ParamType
>*
Clone
()
const
override
{
return
new
Iterator
(
*
this
);
}
const
ParamType
*
Current
()
const
override
{
return
current_value_
.
get
();
}
bool
Equals
(
const
ParamIteratorInterface
<
ParamType
>&
other
)
const
override
{
// 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_
.
reset
(
new
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_
;
}
// No implementation - assignment is unsupported.
void
operator
=
(
const
Iterator
&
other
);
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_
;
std
::
shared_ptr
<
ParamType
>
current_value_
;
};
// class CartesianProductGenerator8::Iterator
// No implementation - assignment is unsupported.
void
operator
=
(
const
CartesianProductGenerator8
&
other
);
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_
;
};
// class CartesianProductGenerator8
template
<
typename
T1
,
typename
T2
,
typename
T3
,
typename
T4
,
typename
T5
,
typename
T6
,
typename
T7
,
typename
T8
,
typename
T9
>
class
CartesianProductGenerator9
:
public
ParamGeneratorInterface
<
::
std
::
tuple
<
T1
,
T2
,
T3
,
T4
,
T5
,
T6
,
T7
,
T8
,
T9
>
>
{
public:
typedef
::
std
::
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
)
{}
~
CartesianProductGenerator9
()
override
{}
ParamIteratorInterface
<
ParamType
>*
Begin
()
const
override
{
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
());
}
ParamIteratorInterface
<
ParamType
>*
End
()
const
override
{
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
();
}
~
Iterator
()
override
{}
const
ParamGeneratorInterface
<
ParamType
>*
BaseGenerator
()
const
override
{
return
base_
;
}
// Advance should not be called on beyond-of-range iterators
// so no component iterators must be beyond end of range, either.
void
Advance
()
override
{
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
();
}
ParamIteratorInterface
<
ParamType
>*
Clone
()
const
override
{
return
new
Iterator
(
*
this
);
}
const
ParamType
*
Current
()
const
override
{
return
current_value_
.
get
();
}
bool
Equals
(
const
ParamIteratorInterface
<
ParamType
>&
other
)
const
override
{
// 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_
.
reset
(
new
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_
;
}
// No implementation - assignment is unsupported.
void
operator
=
(
const
Iterator
&
other
);
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_
;
std
::
shared_ptr
<
ParamType
>
current_value_
;
};
// class CartesianProductGenerator9::Iterator
// No implementation - assignment is unsupported.
void
operator
=
(
const
CartesianProductGenerator9
&
other
);
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_
;
};
// class CartesianProductGenerator9
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
::
tuple
<
T1
,
T2
,
T3
,
T4
,
T5
,
T6
,
T7
,
T8
,
T9
,
T10
>
>
{
public:
typedef
::
std
::
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
)
{}
~
CartesianProductGenerator10
()
override
{}
ParamIteratorInterface
<
ParamType
>*
Begin
()
const
override
{
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
());
}
ParamIteratorInterface
<
ParamType
>*
End
()
const
override
{
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
();
}
~
Iterator
()
override
{}
const
ParamGeneratorInterface
<
ParamType
>*
BaseGenerator
()
const
override
{
return
base_
;
}
// Advance should not be called on beyond-of-range iterators
// so no component iterators must be beyond end of range, either.
void
Advance
()
override
{
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
();
}
ParamIteratorInterface
<
ParamType
>*
Clone
()
const
override
{
return
new
Iterator
(
*
this
);
}
const
ParamType
*
Current
()
const
override
{
return
current_value_
.
get
();
}
bool
Equals
(
const
ParamIteratorInterface
<
ParamType
>&
other
)
const
override
{
// 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_
.
reset
(
new
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_
;
}
// No implementation - assignment is unsupported.
void
operator
=
(
const
Iterator
&
other
);
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_
;
std
::
shared_ptr
<
ParamType
>
current_value_
;
};
// class CartesianProductGenerator10::Iterator
// No implementation - assignment is unsupported.
void
operator
=
(
const
CartesianProductGenerator10
&
other
);
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_
;
};
// class CartesianProductGenerator10
// 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
::
tuple
<
T1
,
T2
>
>
()
const
{
return
ParamGenerator
<
::
std
::
tuple
<
T1
,
T2
>
>
(
new
CartesianProductGenerator2
<
T1
,
T2
>
(
static_cast
<
ParamGenerator
<
T1
>
>
(
g1_
),
static_cast
<
ParamGenerator
<
T2
>
>
(
g2_
)));
}
private:
// No implementation - assignment is unsupported.
void
operator
=
(
const
CartesianProductHolder2
&
other
);
const
Generator1
g1_
;
const
Generator2
g2_
;
};
// class CartesianProductHolder2
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
::
tuple
<
T1
,
T2
,
T3
>
>
()
const
{
return
ParamGenerator
<
::
std
::
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:
// No implementation - assignment is unsupported.
void
operator
=
(
const
CartesianProductHolder3
&
other
);
const
Generator1
g1_
;
const
Generator2
g2_
;
const
Generator3
g3_
;
};
// class CartesianProductHolder3
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
::
tuple
<
T1
,
T2
,
T3
,
T4
>
>
()
const
{
return
ParamGenerator
<
::
std
::
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:
// No implementation - assignment is unsupported.
void
operator
=
(
const
CartesianProductHolder4
&
other
);
const
Generator1
g1_
;
const
Generator2
g2_
;
const
Generator3
g3_
;
const
Generator4
g4_
;
};
// class CartesianProductHolder4
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
::
tuple
<
T1
,
T2
,
T3
,
T4
,
T5
>
>
()
const
{
return
ParamGenerator
<
::
std
::
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:
// No implementation - assignment is unsupported.
void
operator
=
(
const
CartesianProductHolder5
&
other
);
const
Generator1
g1_
;
const
Generator2
g2_
;
const
Generator3
g3_
;
const
Generator4
g4_
;
const
Generator5
g5_
;
};
// class CartesianProductHolder5
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
::
tuple
<
T1
,
T2
,
T3
,
T4
,
T5
,
T6
>
>
()
const
{
return
ParamGenerator
<
::
std
::
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:
// No implementation - assignment is unsupported.
void
operator
=
(
const
CartesianProductHolder6
&
other
);
const
Generator1
g1_
;
const
Generator2
g2_
;
const
Generator3
g3_
;
const
Generator4
g4_
;
const
Generator5
g5_
;
const
Generator6
g6_
;
};
// class CartesianProductHolder6
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
::
tuple
<
T1
,
T2
,
T3
,
T4
,
T5
,
T6
,
T7
>
>
()
const
{
return
ParamGenerator
<
::
std
::
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:
// No implementation - assignment is unsupported.
void
operator
=
(
const
CartesianProductHolder7
&
other
);
const
Generator1
g1_
;
const
Generator2
g2_
;
const
Generator3
g3_
;
const
Generator4
g4_
;
const
Generator5
g5_
;
const
Generator6
g6_
;
const
Generator7
g7_
;
};
// class CartesianProductHolder7
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
::
tuple
<
T1
,
T2
,
T3
,
T4
,
T5
,
T6
,
T7
,
T8
>
>
()
const
{
return
ParamGenerator
<
::
std
::
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:
// No implementation - assignment is unsupported.
void
operator
=
(
const
CartesianProductHolder8
&
other
);
const
Generator1
g1_
;
const
Generator2
g2_
;
const
Generator3
g3_
;
const
Generator4
g4_
;
const
Generator5
g5_
;
const
Generator6
g6_
;
const
Generator7
g7_
;
const
Generator8
g8_
;
};
// class CartesianProductHolder8
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
::
tuple
<
T1
,
T2
,
T3
,
T4
,
T5
,
T6
,
T7
,
T8
,
T9
>
>
()
const
{
return
ParamGenerator
<
::
std
::
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:
// No implementation - assignment is unsupported.
void
operator
=
(
const
CartesianProductHolder9
&
other
);
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_
;
};
// class CartesianProductHolder9
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
::
tuple
<
T1
,
T2
,
T3
,
T4
,
T5
,
T6
,
T7
,
T8
,
T9
,
T10
>
>
()
const
{
return
ParamGenerator
<
::
std
::
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:
// No implementation - assignment is unsupported.
void
operator
=
(
const
CartesianProductHolder10
&
other
);
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_
;
};
// class CartesianProductHolder10
}
// namespace internal
}
// namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
googletest/include/gtest/internal/gtest-param-util-generated.h.pump
deleted
100644 → 0
View file @
5154386c
$$
-*-
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.
// 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 tuple which is
// currently set at $maxtuple.
// GOOGLETEST_CM0001 DO NOT DELETE
#include <assert.h>
#include <memory>
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
#include "gtest/internal/gtest-param-util.h"
#include "gtest/internal/gtest-port.h"
namespace
testing
{
namespace
internal
{
// 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
::
tuple
<
$
for
j
,
[[
T
$
j
]]
>
>
{
public:
typedef
::
std
::
tuple
<
$
for
j
,
[[
T
$
j
]]
>
ParamType
;
CartesianProductGenerator
$
i
(
$
for
j
,
[[
const
ParamGenerator
<
T
$
j
>&
g
$
j
]])
:
$
for
j
,
[[
g
$
(
j
)
_
(
g
$
j
)]]
{}
~
CartesianProductGenerator
$
i
()
override
{}
ParamIteratorInterface
<
ParamType
>*
Begin
()
const
override
{
return
new
Iterator
(
this
,
$
for
j
,
[[
g
$
(
j
)
_
,
g
$
(
j
)
_
.
begin
()]]);
}
ParamIteratorInterface
<
ParamType
>*
End
()
const
override
{
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
();
}
~
Iterator
()
override
{}
const
ParamGeneratorInterface
<
ParamType
>*
BaseGenerator
()
const
override
{
return
base_
;
}
// Advance should not be called on beyond-of-range iterators
// so no component iterators must be beyond end of range, either.
void
Advance
()
override
{
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
();
}
ParamIteratorInterface
<
ParamType
>*
Clone
()
const
override
{
return
new
Iterator
(
*
this
);
}
const
ParamType
*
Current
()
const
override
{
return
current_value_
.
get
();
}
bool
Equals
(
const
ParamIteratorInterface
<
ParamType
>&
other
)
const
override
{
// 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_
.
reset
(
new
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
)
_
]];
}
// No implementation - assignment is unsupported.
void
operator
=
(
const
Iterator
&
other
);
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
)
_
;
]]
std
::
shared_ptr
<
ParamType
>
current_value_
;
};
// class CartesianProductGenerator$i::Iterator
// No implementation - assignment is unsupported.
void
operator
=
(
const
CartesianProductGenerator
$
i
&
other
);
$
for
j
[[
const
ParamGenerator
<
T
$
j
>
g
$
(
j
)
_
;
]]
};
// class CartesianProductGenerator$i
]]
// 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
::
tuple
<
$
for
j
,
[[
T
$
j
]]
>
>
()
const
{
return
ParamGenerator
<
::
std
::
tuple
<
$
for
j
,
[[
T
$
j
]]
>
>
(
new
CartesianProductGenerator
$
i
<
$
for
j
,
[[
T
$
j
]]
>
(
$
for
j
,[[
static_cast
<
ParamGenerator
<
T
$
j
>
>
(
g
$
(
j
)
_
)
]]));
}
private:
// No implementation - assignment is unsupported.
void
operator
=
(
const
CartesianProductHolder
$
i
&
other
);
$
for
j
[[
const
Generator
$
j
g
$
(
j
)
_
;
]]
};
// class CartesianProductHolder$i
]]
}
// namespace internal
}
// namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
googletest/include/gtest/internal/gtest-param-util.h
View file @
efecb0bf
...
...
@@ -37,6 +37,7 @@
#include <ctype.h>
#include <cassert>
#include <iterator>
#include <memory>
#include <set>
...
...
@@ -743,6 +744,136 @@ class ValueArray {
FlatTuple
<
Ts
...
>
v_
;
};
template
<
typename
...
T
>
class
CartesianProductGenerator
:
public
ParamGeneratorInterface
<::
std
::
tuple
<
T
...
>>
{
public:
typedef
::
std
::
tuple
<
T
...
>
ParamType
;
CartesianProductGenerator
(
const
std
::
tuple
<
ParamGenerator
<
T
>
...
>&
g
)
:
generators_
(
g
)
{}
~
CartesianProductGenerator
()
override
{}
ParamIteratorInterface
<
ParamType
>*
Begin
()
const
override
{
return
new
Iterator
(
this
,
generators_
,
false
);
}
ParamIteratorInterface
<
ParamType
>*
End
()
const
override
{
return
new
Iterator
(
this
,
generators_
,
true
);
}
private:
template
<
class
I
>
class
IteratorImpl
;
template
<
size_t
...
I
>
class
IteratorImpl
<
IndexSequence
<
I
...
>>
:
public
ParamIteratorInterface
<
ParamType
>
{
public:
IteratorImpl
(
const
ParamGeneratorInterface
<
ParamType
>*
base
,
const
std
::
tuple
<
ParamGenerator
<
T
>
...
>&
generators
,
bool
is_end
)
:
base_
(
base
),
begin_
(
std
::
get
<
I
>
(
generators
).
begin
()...),
end_
(
std
::
get
<
I
>
(
generators
).
end
()...),
current_
(
is_end
?
end_
:
begin_
)
{
ComputeCurrentValue
();
}
~
IteratorImpl
()
override
{}
const
ParamGeneratorInterface
<
ParamType
>*
BaseGenerator
()
const
override
{
return
base_
;
}
// Advance should not be called on beyond-of-range iterators
// so no component iterators must be beyond end of range, either.
void
Advance
()
override
{
assert
(
!
AtEnd
());
// Advance the last iterator.
++
std
::
get
<
sizeof
...(
T
)
-
1
>
(
current_
);
// if that reaches end, propagate that up.
AdvanceIfEnd
<
sizeof
...(
T
)
-
1
>
();
ComputeCurrentValue
();
}
ParamIteratorInterface
<
ParamType
>*
Clone
()
const
override
{
return
new
IteratorImpl
(
*
this
);
}
const
ParamType
*
Current
()
const
override
{
return
current_value_
.
get
();
}
bool
Equals
(
const
ParamIteratorInterface
<
ParamType
>&
other
)
const
override
{
// 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
IteratorImpl
*
typed_other
=
CheckedDowncastToActualType
<
const
IteratorImpl
>
(
&
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().
if
(
AtEnd
()
&&
typed_other
->
AtEnd
())
return
true
;
bool
same
=
true
;
bool
dummy
[]
=
{
(
same
=
same
&&
std
::
get
<
I
>
(
current_
)
==
std
::
get
<
I
>
(
typed_other
->
current_
))...};
(
void
)
dummy
;
return
same
;
}
private:
template
<
size_t
ThisI
>
void
AdvanceIfEnd
()
{
if
(
std
::
get
<
ThisI
>
(
current_
)
!=
std
::
get
<
ThisI
>
(
end_
))
return
;
bool
last
=
ThisI
==
0
;
if
(
last
)
{
// We are done. Nothing else to propagate.
return
;
}
constexpr
size_t
NextI
=
ThisI
-
(
ThisI
!=
0
);
std
::
get
<
ThisI
>
(
current_
)
=
std
::
get
<
ThisI
>
(
begin_
);
++
std
::
get
<
NextI
>
(
current_
);
AdvanceIfEnd
<
NextI
>
();
}
void
ComputeCurrentValue
()
{
if
(
!
AtEnd
())
current_value_
=
std
::
make_shared
<
ParamType
>
(
*
std
::
get
<
I
>
(
current_
)...);
}
bool
AtEnd
()
const
{
bool
at_end
=
false
;
bool
dummy
[]
=
{
(
at_end
=
at_end
||
std
::
get
<
I
>
(
current_
)
==
std
::
get
<
I
>
(
end_
))...};
(
void
)
dummy
;
return
at_end
;
}
const
ParamGeneratorInterface
<
ParamType
>*
const
base_
;
std
::
tuple
<
typename
ParamGenerator
<
T
>::
iterator
...
>
begin_
;
std
::
tuple
<
typename
ParamGenerator
<
T
>::
iterator
...
>
end_
;
std
::
tuple
<
typename
ParamGenerator
<
T
>::
iterator
...
>
current_
;
std
::
shared_ptr
<
ParamType
>
current_value_
;
};
using
Iterator
=
IteratorImpl
<
typename
MakeIndexSequence
<
sizeof
...(
T
)
>::
type
>
;
std
::
tuple
<
ParamGenerator
<
T
>
...
>
generators_
;
};
template
<
class
...
Gen
>
class
CartesianProductHolder
{
public:
CartesianProductHolder
(
const
Gen
&
...
g
)
:
generators_
(
g
...)
{}
template
<
typename
...
T
>
operator
ParamGenerator
<::
std
::
tuple
<
T
...
>>
()
const
{
return
ParamGenerator
<::
std
::
tuple
<
T
...
>>
(
new
CartesianProductGenerator
<
T
...
>
(
generators_
));
}
private:
std
::
tuple
<
Gen
...
>
generators_
;
};
}
// namespace internal
}
// namespace testing
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment