Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
googletest
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
googletest
Commits
82987067
Commit
82987067
authored
Oct 22, 2018
by
Abseil Team
Committed by
Gennadiy Civil
Oct 22, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Googletest export
Change ValuesArray to require much less template instantiation depth. PiperOrigin-RevId: 218170842
parent
32dbcac0
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
193 additions
and
37 deletions
+193
-37
gtest-internal.h
googletest/include/gtest/internal/gtest-internal.h
+106
-0
gtest-param-util.h
googletest/include/gtest/internal/gtest-param-util.h
+9
-37
gtest_unittest.cc
googletest/test/gtest_unittest.cc
+78
-0
No files found.
googletest/include/gtest/internal/gtest-internal.h
View file @
82987067
...
...
@@ -1176,6 +1176,112 @@ class NativeArray {
GTEST_DISALLOW_ASSIGN_
(
NativeArray
);
};
// Backport of std::index_sequence.
template
<
size_t
...
Is
>
struct
IndexSequence
{
using
type
=
IndexSequence
;
};
// Double the IndexSequence, and one if plus_one is true.
template
<
bool
plus_one
,
typename
T
,
size_t
sizeofT
>
struct
DoubleSequence
;
template
<
size_t
...
I
,
size_t
sizeofT
>
struct
DoubleSequence
<
true
,
IndexSequence
<
I
...
>
,
sizeofT
>
{
using
type
=
IndexSequence
<
I
...,
(
sizeofT
+
I
)...,
2
*
sizeofT
>
;
};
template
<
size_t
...
I
,
size_t
sizeofT
>
struct
DoubleSequence
<
false
,
IndexSequence
<
I
...
>
,
sizeofT
>
{
using
type
=
IndexSequence
<
I
...,
(
sizeofT
+
I
)...
>
;
};
// Backport of std::make_index_sequence.
// It uses O(ln(N)) instantiation depth.
template
<
size_t
N
>
struct
MakeIndexSequence
:
DoubleSequence
<
N
%
2
==
1
,
typename
MakeIndexSequence
<
N
/
2
>::
type
,
N
/
2
>::
type
{};
template
<>
struct
MakeIndexSequence
<
0
>
:
IndexSequence
<>
{};
// FIXME: This implementation of ElemFromList is O(1) in instantiation depth,
// but it is O(N^2) in total instantiations. Not sure if this is the best
// tradeoff, as it will make it somewhat slow to compile.
template
<
typename
T
,
size_t
,
size_t
>
struct
ElemFromListImpl
{};
template
<
typename
T
,
size_t
I
>
struct
ElemFromListImpl
<
T
,
I
,
I
>
{
using
type
=
T
;
};
// Get the Nth element from T...
// It uses O(1) instantiation depth.
template
<
size_t
N
,
typename
I
,
typename
...
T
>
struct
ElemFromList
;
template
<
size_t
N
,
size_t
...
I
,
typename
...
T
>
struct
ElemFromList
<
N
,
IndexSequence
<
I
...
>
,
T
...
>
:
ElemFromListImpl
<
T
,
N
,
I
>
...
{};
template
<
typename
...
T
>
class
FlatTuple
;
template
<
typename
Derived
,
size_t
I
>
struct
FlatTupleElemBase
;
template
<
typename
...
T
,
size_t
I
>
struct
FlatTupleElemBase
<
FlatTuple
<
T
...
>
,
I
>
{
using
value_type
=
typename
ElemFromList
<
I
,
typename
MakeIndexSequence
<
sizeof
...(
T
)
>::
type
,
T
...
>::
type
;
FlatTupleElemBase
()
=
default
;
explicit
FlatTupleElemBase
(
value_type
t
)
:
value
(
std
::
move
(
t
))
{}
value_type
value
;
};
template
<
typename
Derived
,
typename
Idx
>
struct
FlatTupleBase
;
template
<
size_t
...
Idx
,
typename
...
T
>
struct
FlatTupleBase
<
FlatTuple
<
T
...
>
,
IndexSequence
<
Idx
...
>>
:
FlatTupleElemBase
<
FlatTuple
<
T
...
>
,
Idx
>
...
{
using
Indices
=
IndexSequence
<
Idx
...
>
;
FlatTupleBase
()
=
default
;
explicit
FlatTupleBase
(
T
...
t
)
:
FlatTupleElemBase
<
FlatTuple
<
T
...
>
,
Idx
>
(
std
::
move
(
t
))...
{}
};
// Analog to std::tuple but with different tradeoffs.
// This class minimizes the template instantiation depth, thus allowing more
// elements that std::tuple would. std::tuple has been seen to require an
// instantiation depth of more than 10x the number of elements in some
// implementations.
// FlatTuple and ElemFromList are not recursive and have a fixed depth
// regardless of T...
// MakeIndexSequence, on the other hand, it is recursive but with an
// instantiation depth of O(ln(N)).
template
<
typename
...
T
>
class
FlatTuple
:
private
FlatTupleBase
<
FlatTuple
<
T
...
>
,
typename
MakeIndexSequence
<
sizeof
...(
T
)
>::
type
>
{
using
Indices
=
typename
FlatTuple
::
FlatTupleBase
::
Indices
;
public
:
FlatTuple
()
=
default
;
explicit
FlatTuple
(
T
...
t
)
:
FlatTuple
::
FlatTupleBase
(
std
::
move
(
t
)...)
{}
template
<
size_t
I
>
const
typename
ElemFromList
<
I
,
Indices
,
T
...
>::
type
&
Get
()
const
{
return
static_cast
<
const
FlatTupleElemBase
<
FlatTuple
,
I
>*>
(
this
)
->
value
;
}
template
<
size_t
I
>
typename
ElemFromList
<
I
,
Indices
,
T
...
>::
type
&
Get
()
{
return
static_cast
<
FlatTupleElemBase
<
FlatTuple
,
I
>*>
(
this
)
->
value
;
}
};
}
// namespace internal
}
// namespace testing
...
...
googletest/include/gtest/internal/gtest-param-util.h
View file @
82987067
...
...
@@ -74,27 +74,6 @@ namespace internal {
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
// Utility Functions
// Block of code creating for_each_in_tuple
template
<
int
...
Is
>
struct
sequence
{};
template
<
int
N
,
int
...
Is
>
struct
generate_sequence
:
generate_sequence
<
N
-
1
,
N
-
1
,
Is
...
>
{};
template
<
int
...
Is
>
struct
generate_sequence
<
0
,
Is
...
>
:
sequence
<
Is
...
>
{};
template
<
typename
T
,
typename
F
,
int
...
Is
>
void
ForEachInTupleImpl
(
T
&&
t
,
F
f_gtest
,
sequence
<
Is
...
>
)
{
int
l
[]
=
{(
f_gtest
(
std
::
get
<
Is
>
(
t
)),
0
)...};
(
void
)
l
;
// silence "unused variable warning"
}
template
<
typename
...
T
,
typename
F
>
void
ForEachInTuple
(
const
std
::
tuple
<
T
...
>&
t
,
F
f_gtest
)
{
internal
::
ForEachInTupleImpl
(
t
,
f_gtest
,
internal
::
generate_sequence
<
sizeof
...(
T
)
>
());
}
// Outputs a message explaining invalid registration of different
// fixture class for the same test case. This may happen when
// TEST_P macro is used to define two tests with the same name
...
...
@@ -747,30 +726,23 @@ internal::ParamGenerator<typename Container::value_type> ValuesIn(
namespace
internal
{
// Used in the Values() function to provide polymorphic capabilities.
template
<
typename
T
>
struct
PushBack
{
template
<
typename
U
>
void
operator
()(
const
U
&
u
)
{
v_
.
push_back
(
static_cast
<
T
>
(
u
));
}
std
::
vector
<
T
>&
v_
;
};
template
<
typename
...
Ts
>
class
ValueArray
{
public
:
ValueArray
(
Ts
...
v
)
:
v_
{
std
::
move
(
v
)...}
{}
template
<
typename
Tn
>
operator
ParamGenerator
<
Tn
>
()
const
{
std
::
vector
<
Tn
>
vc_accumulate
;
PushBack
<
Tn
>
fnc
{
vc_accumulate
};
ForEachInTuple
(
v_
,
fnc
);
return
ValuesIn
(
std
::
move
(
vc_accumulate
));
template
<
typename
T
>
operator
ParamGenerator
<
T
>
()
const
{
// NOLINT
return
ValuesIn
(
MakeVector
<
T
>
(
MakeIndexSequence
<
sizeof
...(
Ts
)
>
()));
}
private
:
std
::
tuple
<
Ts
...
>
v_
;
template
<
typename
T
,
size_t
...
I
>
std
::
vector
<
T
>
MakeVector
(
IndexSequence
<
I
...
>
)
const
{
return
std
::
vector
<
T
>
{
static_cast
<
T
>
(
v_
.
template
Get
<
I
>
())...};
}
FlatTuple
<
Ts
...
>
v_
;
};
}
// namespace internal
...
...
googletest/test/gtest_unittest.cc
View file @
82987067
...
...
@@ -7450,6 +7450,84 @@ TEST(NativeArrayTest, WorksForTwoDimensionalArray) {
EXPECT_EQ
(
a
,
na
.
begin
());
}
// IndexSequence
TEST
(
IndexSequence
,
MakeIndexSequence
)
{
using
testing
::
internal
::
IndexSequence
;
using
testing
::
internal
::
MakeIndexSequence
;
EXPECT_TRUE
(
(
std
::
is_same
<
IndexSequence
<>
,
MakeIndexSequence
<
0
>::
type
>::
value
));
EXPECT_TRUE
(
(
std
::
is_same
<
IndexSequence
<
0
>
,
MakeIndexSequence
<
1
>::
type
>::
value
));
EXPECT_TRUE
(
(
std
::
is_same
<
IndexSequence
<
0
,
1
>
,
MakeIndexSequence
<
2
>::
type
>::
value
));
EXPECT_TRUE
((
std
::
is_same
<
IndexSequence
<
0
,
1
,
2
>
,
MakeIndexSequence
<
3
>::
type
>::
value
));
EXPECT_TRUE
(
(
std
::
is_base_of
<
IndexSequence
<
0
,
1
,
2
>
,
MakeIndexSequence
<
3
>>::
value
));
}
// ElemFromList
TEST
(
ElemFromList
,
Basic
)
{
using
testing
::
internal
::
ElemFromList
;
using
Idx
=
testing
::
internal
::
MakeIndexSequence
<
3
>::
type
;
EXPECT_TRUE
((
std
::
is_same
<
int
,
ElemFromList
<
0
,
Idx
,
int
,
double
,
char
>::
type
>::
value
));
EXPECT_TRUE
(
(
std
::
is_same
<
double
,
ElemFromList
<
1
,
Idx
,
int
,
double
,
char
>::
type
>::
value
));
EXPECT_TRUE
(
(
std
::
is_same
<
char
,
ElemFromList
<
2
,
Idx
,
int
,
double
,
char
>::
type
>::
value
));
EXPECT_TRUE
(
(
std
::
is_same
<
char
,
ElemFromList
<
7
,
testing
::
internal
::
MakeIndexSequence
<
12
>::
type
,
int
,
int
,
int
,
int
,
int
,
int
,
int
,
char
,
int
,
int
,
int
,
int
>::
type
>::
value
));
}
// FlatTuple
TEST
(
FlatTuple
,
Basic
)
{
using
testing
::
internal
::
FlatTuple
;
FlatTuple
<
int
,
double
,
const
char
*>
tuple
=
{};
EXPECT_EQ
(
0
,
tuple
.
Get
<
0
>
());
EXPECT_EQ
(
0.0
,
tuple
.
Get
<
1
>
());
EXPECT_EQ
(
nullptr
,
tuple
.
Get
<
2
>
());
tuple
=
FlatTuple
<
int
,
double
,
const
char
*>
(
7
,
3.2
,
"Foo"
);
EXPECT_EQ
(
7
,
tuple
.
Get
<
0
>
());
EXPECT_EQ
(
3.2
,
tuple
.
Get
<
1
>
());
EXPECT_EQ
(
std
::
string
(
"Foo"
),
tuple
.
Get
<
2
>
());
tuple
.
Get
<
1
>
()
=
5.1
;
EXPECT_EQ
(
5.1
,
tuple
.
Get
<
1
>
());
}
TEST
(
FlatTuple
,
ManyTypes
)
{
using
testing
::
internal
::
FlatTuple
;
// Instantiate FlatTuple with 257 ints.
// Tests show that we can do it with thousands of elements, but very long
// compile times makes it unusuitable for this test.
#define GTEST_FLAT_TUPLE_INT8 int, int, int, int, int, int, int, int,
#define GTEST_FLAT_TUPLE_INT16 GTEST_FLAT_TUPLE_INT8 GTEST_FLAT_TUPLE_INT8
#define GTEST_FLAT_TUPLE_INT32 GTEST_FLAT_TUPLE_INT16 GTEST_FLAT_TUPLE_INT16
#define GTEST_FLAT_TUPLE_INT64 GTEST_FLAT_TUPLE_INT32 GTEST_FLAT_TUPLE_INT32
#define GTEST_FLAT_TUPLE_INT128 GTEST_FLAT_TUPLE_INT64 GTEST_FLAT_TUPLE_INT64
#define GTEST_FLAT_TUPLE_INT256 GTEST_FLAT_TUPLE_INT128 GTEST_FLAT_TUPLE_INT128
// Let's make sure that we can have a very long list of types without blowing
// up the template instantiation depth.
FlatTuple
<
GTEST_FLAT_TUPLE_INT256
int
>
tuple
;
tuple
.
Get
<
0
>
()
=
7
;
tuple
.
Get
<
99
>
()
=
17
;
tuple
.
Get
<
256
>
()
=
1000
;
EXPECT_EQ
(
7
,
tuple
.
Get
<
0
>
());
EXPECT_EQ
(
17
,
tuple
.
Get
<
99
>
());
EXPECT_EQ
(
1000
,
tuple
.
Get
<
256
>
());
}
// Tests SkipPrefix().
TEST
(
SkipPrefixTest
,
SkipsWhenPrefixMatches
)
{
...
...
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