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
db13ff1f
Commit
db13ff1f
authored
Nov 26, 2019
by
Gennadiy Rozental
Browse files
Merge pull request #2597 from kuzkry:remove-workaround_Nokia-Sybian-SafeMatcherCastImpl
PiperOrigin-RevId: 282581402
parents
be74b4b2
bbbc5d8a
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
36 additions
and
49 deletions
+36
-49
googlemock/include/gmock/gmock-matchers.h
googlemock/include/gmock/gmock-matchers.h
+36
-49
No files found.
googlemock/include/gmock/gmock-matchers.h
View file @
db13ff1f
...
...
@@ -247,56 +247,43 @@ inline Matcher<T> MatcherCast(const M& matcher) {
return
internal
::
MatcherCastImpl
<
T
,
M
>::
Cast
(
matcher
);
}
// Implements SafeMatcherCast().
//
// FIXME: The intermediate SafeMatcherCastImpl class was introduced as a
// workaround for a compiler bug, and can now be removed.
template
<
typename
T
>
class
SafeMatcherCastImpl
{
public:
// This overload handles polymorphic matchers and values only since
// monomorphic matchers are handled by the next one.
template
<
typename
M
>
static
inline
Matcher
<
T
>
Cast
(
const
M
&
polymorphic_matcher_or_value
)
{
return
internal
::
MatcherCastImpl
<
T
,
M
>::
Cast
(
polymorphic_matcher_or_value
);
}
// This overload handles monomorphic matchers.
//
// In general, if type T can be implicitly converted to type U, we can
// safely convert a Matcher<U> to a Matcher<T> (i.e. Matcher is
// contravariant): just keep a copy of the original Matcher<U>, convert the
// argument from type T to U, and then pass it to the underlying Matcher<U>.
// The only exception is when U is a reference and T is not, as the
// underlying Matcher<U> may be interested in the argument's address, which
// is not preserved in the conversion from T to U.
template
<
typename
U
>
static
inline
Matcher
<
T
>
Cast
(
const
Matcher
<
U
>&
matcher
)
{
// Enforce that T can be implicitly converted to U.
GTEST_COMPILE_ASSERT_
((
std
::
is_convertible
<
T
,
U
>::
value
),
"T must be implicitly convertible to U"
);
// Enforce that we are not converting a non-reference type T to a reference
// type U.
GTEST_COMPILE_ASSERT_
(
std
::
is_reference
<
T
>::
value
||
!
std
::
is_reference
<
U
>::
value
,
cannot_convert_non_reference_arg_to_reference
);
// In case both T and U are arithmetic types, enforce that the
// conversion is not lossy.
typedef
GTEST_REMOVE_REFERENCE_AND_CONST_
(
T
)
RawT
;
typedef
GTEST_REMOVE_REFERENCE_AND_CONST_
(
U
)
RawU
;
const
bool
kTIsOther
=
GMOCK_KIND_OF_
(
RawT
)
==
internal
::
kOther
;
const
bool
kUIsOther
=
GMOCK_KIND_OF_
(
RawU
)
==
internal
::
kOther
;
GTEST_COMPILE_ASSERT_
(
kTIsOther
||
kUIsOther
||
(
internal
::
LosslessArithmeticConvertible
<
RawT
,
RawU
>::
value
),
conversion_of_arithmetic_types_must_be_lossless
);
return
MatcherCast
<
T
>
(
matcher
);
}
};
// This overload handles polymorphic matchers and values only since
// monomorphic matchers are handled by the next one.
template
<
typename
T
,
typename
M
>
inline
Matcher
<
T
>
SafeMatcherCast
(
const
M
&
polymorphic_matcher
)
{
return
SafeMatcherCastImpl
<
T
>::
Cast
(
polymorphic_matcher
);
inline
Matcher
<
T
>
SafeMatcherCast
(
const
M
&
polymorphic_matcher_or_value
)
{
return
MatcherCast
<
T
>
(
polymorphic_matcher_or_value
);
}
// This overload handles monomorphic matchers.
//
// In general, if type T can be implicitly converted to type U, we can
// safely convert a Matcher<U> to a Matcher<T> (i.e. Matcher is
// contravariant): just keep a copy of the original Matcher<U>, convert the
// argument from type T to U, and then pass it to the underlying Matcher<U>.
// The only exception is when U is a reference and T is not, as the
// underlying Matcher<U> may be interested in the argument's address, which
// is not preserved in the conversion from T to U.
template
<
typename
T
,
typename
U
>
inline
Matcher
<
T
>
SafeMatcherCast
(
const
Matcher
<
U
>&
matcher
)
{
// Enforce that T can be implicitly converted to U.
GTEST_COMPILE_ASSERT_
((
std
::
is_convertible
<
T
,
U
>::
value
),
"T must be implicitly convertible to U"
);
// Enforce that we are not converting a non-reference type T to a reference
// type U.
GTEST_COMPILE_ASSERT_
(
std
::
is_reference
<
T
>::
value
||
!
std
::
is_reference
<
U
>::
value
,
cannot_convert_non_reference_arg_to_reference
);
// In case both T and U are arithmetic types, enforce that the
// conversion is not lossy.
typedef
GTEST_REMOVE_REFERENCE_AND_CONST_
(
T
)
RawT
;
typedef
GTEST_REMOVE_REFERENCE_AND_CONST_
(
U
)
RawU
;
constexpr
bool
kTIsOther
=
GMOCK_KIND_OF_
(
RawT
)
==
internal
::
kOther
;
constexpr
bool
kUIsOther
=
GMOCK_KIND_OF_
(
RawU
)
==
internal
::
kOther
;
GTEST_COMPILE_ASSERT_
(
kTIsOther
||
kUIsOther
||
(
internal
::
LosslessArithmeticConvertible
<
RawT
,
RawU
>::
value
),
conversion_of_arithmetic_types_must_be_lossless
);
return
MatcherCast
<
T
>
(
matcher
);
}
// A<T>() returns a matcher that matches any value of type T.
...
...
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