Commit 79a367eb authored by jgm's avatar jgm
Browse files

Reduced template instantiation depth for the AllOf and AnyOf matchers. Also...

Reduced template instantiation depth for the AllOf and AnyOf matchers. Also some formatting changes.
parent 9bcb5f91
...@@ -36,13 +36,13 @@ ...@@ -36,13 +36,13 @@
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ #define GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
#include <algorithm>
#include <string>
#ifndef _WIN32_WCE #ifndef _WIN32_WCE
# include <errno.h> # include <errno.h>
#endif #endif
#include <algorithm>
#include <string>
#include "gmock/internal/gmock-internal-utils.h" #include "gmock/internal/gmock-internal-utils.h"
#include "gmock/internal/gmock-port.h" #include "gmock/internal/gmock-port.h"
...@@ -189,6 +189,7 @@ class DefaultValue { ...@@ -189,6 +189,7 @@ class DefaultValue {
return value_ == NULL ? return value_ == NULL ?
internal::BuiltInDefaultValue<T>::Get() : *value_; internal::BuiltInDefaultValue<T>::Get() : *value_;
} }
private: private:
static const T* value_; static const T* value_;
}; };
...@@ -224,6 +225,7 @@ class DefaultValue<T&> { ...@@ -224,6 +225,7 @@ class DefaultValue<T&> {
return address_ == NULL ? return address_ == NULL ?
internal::BuiltInDefaultValue<T&>::Get() : *address_; internal::BuiltInDefaultValue<T&>::Get() : *address_;
} }
private: private:
static T* address_; static T* address_;
}; };
......
...@@ -117,6 +117,7 @@ class GTEST_API_ Cardinality { ...@@ -117,6 +117,7 @@ class GTEST_API_ Cardinality {
// Describes the given actual call count to an ostream. // Describes the given actual call count to an ostream.
static void DescribeActualCallCountTo(int actual_call_count, static void DescribeActualCallCountTo(int actual_call_count,
::std::ostream* os); ::std::ostream* os);
private: private:
internal::linked_ptr<const CardinalityInterface> impl_; internal::linked_ptr<const CardinalityInterface> impl_;
}; };
......
...@@ -381,7 +381,6 @@ class CallableHelper { ...@@ -381,7 +381,6 @@ class CallableHelper {
A7 a7, A8 a8, A9 a9, A10 a10) { A7 a7, A8 a8, A9 a9, A10 a10) {
return function(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); return function(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
} }
}; // class CallableHelper }; // class CallableHelper
// An INTERNAL macro for extracting the type of a tuple field. It's // An INTERNAL macro for extracting the type of a tuple field. It's
...@@ -1018,16 +1017,16 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, ...@@ -1018,16 +1017,16 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
// An internal macro needed for implementing ACTION*(). // An internal macro needed for implementing ACTION*().
#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\ #define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\
const args_type& args GTEST_ATTRIBUTE_UNUSED_,\ const args_type& args GTEST_ATTRIBUTE_UNUSED_, \
arg0_type arg0 GTEST_ATTRIBUTE_UNUSED_,\ arg0_type arg0 GTEST_ATTRIBUTE_UNUSED_, \
arg1_type arg1 GTEST_ATTRIBUTE_UNUSED_,\ arg1_type arg1 GTEST_ATTRIBUTE_UNUSED_, \
arg2_type arg2 GTEST_ATTRIBUTE_UNUSED_,\ arg2_type arg2 GTEST_ATTRIBUTE_UNUSED_, \
arg3_type arg3 GTEST_ATTRIBUTE_UNUSED_,\ arg3_type arg3 GTEST_ATTRIBUTE_UNUSED_, \
arg4_type arg4 GTEST_ATTRIBUTE_UNUSED_,\ arg4_type arg4 GTEST_ATTRIBUTE_UNUSED_, \
arg5_type arg5 GTEST_ATTRIBUTE_UNUSED_,\ arg5_type arg5 GTEST_ATTRIBUTE_UNUSED_, \
arg6_type arg6 GTEST_ATTRIBUTE_UNUSED_,\ arg6_type arg6 GTEST_ATTRIBUTE_UNUSED_, \
arg7_type arg7 GTEST_ATTRIBUTE_UNUSED_,\ arg7_type arg7 GTEST_ATTRIBUTE_UNUSED_, \
arg8_type arg8 GTEST_ATTRIBUTE_UNUSED_,\ arg8_type arg8 GTEST_ATTRIBUTE_UNUSED_, \
arg9_type arg9 GTEST_ATTRIBUTE_UNUSED_ arg9_type arg9 GTEST_ATTRIBUTE_UNUSED_
// Sometimes you want to give an action explicit template parameters // Sometimes you want to give an action explicit template parameters
...@@ -1433,9 +1432,9 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, ...@@ -1433,9 +1432,9 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
template <GMOCK_INTERNAL_DECL_##template_params\ template <GMOCK_INTERNAL_DECL_##template_params\
GMOCK_INTERNAL_DECL_TYPE_##value_params>\ GMOCK_INTERNAL_DECL_TYPE_##value_params>\
template <typename F>\ template <typename F>\
template <typename arg0_type, typename arg1_type, typename arg2_type,\ template <typename arg0_type, typename arg1_type, typename arg2_type, \
typename arg3_type, typename arg4_type, typename arg5_type,\ typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type,\ typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\ typename arg9_type>\
typename ::testing::internal::Function<F>::Result\ typename ::testing::internal::Function<F>::Result\
GMOCK_ACTION_CLASS_(name, value_params)<\ GMOCK_ACTION_CLASS_(name, value_params)<\
......
...@@ -136,7 +136,6 @@ $var Ts = [[$for j, [[T$j]]]] ...@@ -136,7 +136,6 @@ $var Ts = [[$for j, [[T$j]]]]
} }
]] ]]
}; // class CallableHelper }; // class CallableHelper
// An INTERNAL macro for extracting the type of a tuple field. It's // An INTERNAL macro for extracting the type of a tuple field. It's
...@@ -427,7 +426,7 @@ $range k 0..n-1 ...@@ -427,7 +426,7 @@ $range k 0..n-1
// An internal macro needed for implementing ACTION*(). // An internal macro needed for implementing ACTION*().
#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\ #define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\
const args_type& args GTEST_ATTRIBUTE_UNUSED_ const args_type& args GTEST_ATTRIBUTE_UNUSED_
$for k [[,\ $for k [[, \
arg$k[[]]_type arg$k GTEST_ATTRIBUTE_UNUSED_]] arg$k[[]]_type arg$k GTEST_ATTRIBUTE_UNUSED_]]
...@@ -657,9 +656,9 @@ $for k [[, arg$k[[]]_type arg$k]]) const;\ ...@@ -657,9 +656,9 @@ $for k [[, arg$k[[]]_type arg$k]]) const;\
template <GMOCK_INTERNAL_DECL_##template_params\ template <GMOCK_INTERNAL_DECL_##template_params\
GMOCK_INTERNAL_DECL_TYPE_##value_params>\ GMOCK_INTERNAL_DECL_TYPE_##value_params>\
template <typename F>\ template <typename F>\
template <typename arg0_type, typename arg1_type, typename arg2_type,\ template <typename arg0_type, typename arg1_type, typename arg2_type, \
typename arg3_type, typename arg4_type, typename arg5_type,\ typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type,\ typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\ typename arg9_type>\
typename ::testing::internal::Function<F>::Result\ typename ::testing::internal::Function<F>::Result\
GMOCK_ACTION_CLASS_(name, value_params)<\ GMOCK_ACTION_CLASS_(name, value_params)<\
......
This diff is collapsed.
...@@ -242,6 +242,66 @@ $for j [[ ...@@ -242,6 +242,66 @@ $for j [[
]] ]]
// A set of metafunctions for computing the result type of AllOf.
// AllOf(m1, ..., mN) returns
// AllOfResultN<decltype(m1), ..., decltype(mN)>::type.
// Although AllOf isn't defined for one argument, AllOfResult1 is defined
// to simplify the implementation.
template <typename M1>
struct AllOfResult1 {
typedef M1 type;
};
$range i 1..n
$range i 2..n
$for i [[
$range j 2..i
$var m = i/2
$range k 1..m
$range t m+1..i
template <typename M1$for j [[, typename M$j]]>
struct AllOfResult$i {
typedef BothOfMatcher<
typename AllOfResult$m<$for k, [[M$k]]>::type,
typename AllOfResult$(i-m)<$for t, [[M$t]]>::type
> type;
};
]]
// A set of metafunctions for computing the result type of AnyOf.
// AnyOf(m1, ..., mN) returns
// AnyOfResultN<decltype(m1), ..., decltype(mN)>::type.
// Although AnyOf isn't defined for one argument, AnyOfResult1 is defined
// to simplify the implementation.
template <typename M1>
struct AnyOfResult1 {
typedef M1 type;
};
$range i 1..n
$range i 2..n
$for i [[
$range j 2..i
$var m = i/2
$range k 1..m
$range t m+1..i
template <typename M1$for j [[, typename M$j]]>
struct AnyOfResult$i {
typedef EitherOfMatcher<
typename AnyOfResult$m<$for k, [[M$k]]>::type,
typename AnyOfResult$(i-m)<$for t, [[M$t]]>::type
> type;
};
]]
} // namespace internal } // namespace internal
// Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected // Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected
...@@ -308,19 +368,16 @@ ElementsAreArray(const T (&array)[N]) { ...@@ -308,19 +368,16 @@ ElementsAreArray(const T (&array)[N]) {
$range i 2..n $range i 2..n
$for i [[ $for i [[
$range j 1..i $range j 1..i
$range k 1..i-1 $var m = i/2
$range k 1..m
template <$for j, [[typename Matcher$j]]> $range t m+1..i
inline $for k[[internal::BothOfMatcher<Matcher$k, ]]Matcher$i[[]]$for k [[> ]]
template <$for j, [[typename M$j]]>
AllOf($for j, [[Matcher$j m$j]]) { inline typename internal::AllOfResult$i<$for j, [[M$j]]>::type
AllOf($for j, [[M$j m$j]]) {
$if i == 2 [[ return typename internal::AllOfResult$i<$for j, [[M$j]]>::type(
return internal::BothOfMatcher<Matcher1, Matcher2>(m1, m2); $if m == 1 [[m1]] $else [[::testing::AllOf($for k, [[m$k]])]],
]] $else [[ $if m+1 == i [[m$i]] $else [[::testing::AllOf($for t, [[m$t]])]]);
return ::testing::AllOf(m1, ::testing::AllOf($for k, [[m$(k + 1)]]));
]]
} }
]] ]]
...@@ -331,19 +388,16 @@ $if i == 2 [[ ...@@ -331,19 +388,16 @@ $if i == 2 [[
$range i 2..n $range i 2..n
$for i [[ $for i [[
$range j 1..i $range j 1..i
$range k 1..i-1 $var m = i/2
$range k 1..m
template <$for j, [[typename Matcher$j]]> $range t m+1..i
inline $for k[[internal::EitherOfMatcher<Matcher$k, ]]Matcher$i[[]]$for k [[> ]]
template <$for j, [[typename M$j]]>
AnyOf($for j, [[Matcher$j m$j]]) { inline typename internal::AnyOfResult$i<$for j, [[M$j]]>::type
AnyOf($for j, [[M$j m$j]]) {
$if i == 2 [[ return typename internal::AnyOfResult$i<$for j, [[M$j]]>::type(
return internal::EitherOfMatcher<Matcher1, Matcher2>(m1, m2); $if m == 1 [[m1]] $else [[::testing::AnyOf($for k, [[m$k]])]],
]] $else [[ $if m+1 == i [[m$i]] $else [[::testing::AnyOf($for t, [[m$t]])]]);
return ::testing::AnyOf(m1, ::testing::AnyOf($for k, [[m$(k + 1)]]));
]]
} }
]] ]]
...@@ -621,7 +675,7 @@ $var param_field_decls2 = [[$for j ...@@ -621,7 +675,7 @@ $var param_field_decls2 = [[$for j
if (!gmock_description.empty())\ if (!gmock_description.empty())\
return gmock_description;\ return gmock_description;\
return ::testing::internal::FormatMatcherDescription(\ return ::testing::internal::FormatMatcherDescription(\
negation, #name,\ negation, #name, \
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
::std::tr1::tuple<$for j, [[p$j##_type]]>($for j, [[p$j]])));\ ::std::tr1::tuple<$for j, [[p$j##_type]]>($for j, [[p$j]])));\
}\ }\
...@@ -642,7 +696,7 @@ $var param_field_decls2 = [[$for j ...@@ -642,7 +696,7 @@ $var param_field_decls2 = [[$for j
}\$template }\$template
template <typename arg_type>\ template <typename arg_type>\
bool $class_name$param_types::gmock_Impl<arg_type>::MatchAndExplain(\ bool $class_name$param_types::gmock_Impl<arg_type>::MatchAndExplain(\
arg_type arg,\ arg_type arg, \
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
const const
]] ]]
......
...@@ -384,12 +384,119 @@ inline PolymorphicMatcher<Impl> MakePolymorphicMatcher(const Impl& impl) { ...@@ -384,12 +384,119 @@ inline PolymorphicMatcher<Impl> MakePolymorphicMatcher(const Impl& impl) {
return PolymorphicMatcher<Impl>(impl); return PolymorphicMatcher<Impl>(impl);
} }
// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION
// and MUST NOT BE USED IN USER CODE!!!
namespace internal {
// The MatcherCastImpl class template is a helper for implementing
// MatcherCast(). We need this helper in order to partially
// specialize the implementation of MatcherCast() (C++ allows
// class/struct templates to be partially specialized, but not
// function templates.).
// This general version is used when MatcherCast()'s argument is a
// polymorphic matcher (i.e. something that can be converted to a
// Matcher but is not one yet; for example, Eq(value)) or a value (for
// example, "hello").
template <typename T, typename M>
class MatcherCastImpl {
public:
static Matcher<T> Cast(M polymorphic_matcher_or_value) {
// M can be a polymorhic matcher, in which case we want to use
// its conversion operator to create Matcher<T>. Or it can be a value
// that should be passed to the Matcher<T>'s constructor.
//
// We can't call Matcher<T>(polymorphic_matcher_or_value) when M is a
// polymorphic matcher because it'll be ambiguous if T has an implicit
// constructor from M (this usually happens when T has an implicit
// constructor from any type).
//
// It won't work to unconditionally implict_cast
// polymorphic_matcher_or_value to Matcher<T> because it won't trigger
// a user-defined conversion from M to T if one exists (assuming M is
// a value).
return CastImpl(
polymorphic_matcher_or_value,
BooleanConstant<
internal::ImplicitlyConvertible<M, Matcher<T> >::value>());
}
private:
static Matcher<T> CastImpl(M value, BooleanConstant<false>) {
// M can't be implicitly converted to Matcher<T>, so M isn't a polymorphic
// matcher. It must be a value then. Use direct initialization to create
// a matcher.
return Matcher<T>(ImplicitCast_<T>(value));
}
static Matcher<T> CastImpl(M polymorphic_matcher_or_value,
BooleanConstant<true>) {
// M is implicitly convertible to Matcher<T>, which means that either
// M is a polymorhpic matcher or Matcher<T> has an implicit constructor
// from M. In both cases using the implicit conversion will produce a
// matcher.
//
// Even if T has an implicit constructor from M, it won't be called because
// creating Matcher<T> would require a chain of two user-defined conversions
// (first to create T from M and then to create Matcher<T> from T).
return polymorphic_matcher_or_value;
}
};
// This more specialized version is used when MatcherCast()'s argument
// is already a Matcher. This only compiles when type T can be
// statically converted to type U.
template <typename T, typename U>
class MatcherCastImpl<T, Matcher<U> > {
public:
static Matcher<T> Cast(const Matcher<U>& source_matcher) {
return Matcher<T>(new Impl(source_matcher));
}
private:
class Impl : public MatcherInterface<T> {
public:
explicit Impl(const Matcher<U>& source_matcher)
: source_matcher_(source_matcher) {}
// We delegate the matching logic to the source matcher.
virtual bool MatchAndExplain(T x, MatchResultListener* listener) const {
return source_matcher_.MatchAndExplain(static_cast<U>(x), listener);
}
virtual void DescribeTo(::std::ostream* os) const {
source_matcher_.DescribeTo(os);
}
virtual void DescribeNegationTo(::std::ostream* os) const {
source_matcher_.DescribeNegationTo(os);
}
private:
const Matcher<U> source_matcher_;
GTEST_DISALLOW_ASSIGN_(Impl);
};
};
// This even more specialized version is used for efficiently casting
// a matcher to its own type.
template <typename T>
class MatcherCastImpl<T, Matcher<T> > {
public:
static Matcher<T> Cast(const Matcher<T>& matcher) { return matcher; }
};
} // namespace internal
// In order to be safe and clear, casting between different matcher // In order to be safe and clear, casting between different matcher
// types is done explicitly via MatcherCast<T>(m), which takes a // types is done explicitly via MatcherCast<T>(m), which takes a
// matcher m and returns a Matcher<T>. It compiles only when T can be // matcher m and returns a Matcher<T>. It compiles only when T can be
// statically converted to the argument type of m. // statically converted to the argument type of m.
template <typename T, typename M> template <typename T, typename M>
Matcher<T> MatcherCast(M m); inline Matcher<T> MatcherCast(M matcher) {
return internal::MatcherCastImpl<T, M>::Cast(matcher);
}
// Implements SafeMatcherCast(). // Implements SafeMatcherCast().
// //
...@@ -401,11 +508,11 @@ Matcher<T> MatcherCast(M m); ...@@ -401,11 +508,11 @@ Matcher<T> MatcherCast(M m);
template <typename T> template <typename T>
class SafeMatcherCastImpl { class SafeMatcherCastImpl {
public: public:
// This overload handles polymorphic matchers only since monomorphic // This overload handles polymorphic matchers and values only since
// matchers are handled by the next one. // monomorphic matchers are handled by the next one.
template <typename M> template <typename M>
static inline Matcher<T> Cast(M polymorphic_matcher) { static inline Matcher<T> Cast(M polymorphic_matcher_or_value) {
return Matcher<T>(polymorphic_matcher); return internal::MatcherCastImpl<T, M>::Cast(polymorphic_matcher_or_value);
} }
// This overload handles monomorphic matchers. // This overload handles monomorphic matchers.
...@@ -600,67 +707,6 @@ void ExplainMatchFailureTupleTo(const MatcherTuple& matchers, ...@@ -600,67 +707,6 @@ void ExplainMatchFailureTupleTo(const MatcherTuple& matchers,
matchers, values, os); matchers, values, os);
} }
// The MatcherCastImpl class template is a helper for implementing
// MatcherCast(). We need this helper in order to partially
// specialize the implementation of MatcherCast() (C++ allows
// class/struct templates to be partially specialized, but not
// function templates.).
// This general version is used when MatcherCast()'s argument is a
// polymorphic matcher (i.e. something that can be converted to a
// Matcher but is not one yet; for example, Eq(value)).
template <typename T, typename M>
class MatcherCastImpl {
public:
static Matcher<T> Cast(M polymorphic_matcher) {
return Matcher<T>(polymorphic_matcher);
}
};
// This more specialized version is used when MatcherCast()'s argument
// is already a Matcher. This only compiles when type T can be
// statically converted to type U.
template <typename T, typename U>
class MatcherCastImpl<T, Matcher<U> > {
public:
static Matcher<T> Cast(const Matcher<U>& source_matcher) {
return Matcher<T>(new Impl(source_matcher));
}
private:
class Impl : public MatcherInterface<T> {
public:
explicit Impl(const Matcher<U>& source_matcher)
: source_matcher_(source_matcher) {}
// We delegate the matching logic to the source matcher.
virtual bool MatchAndExplain(T x, MatchResultListener* listener) const {
return source_matcher_.MatchAndExplain(static_cast<U>(x), listener);
}
virtual void DescribeTo(::std::ostream* os) const {
source_matcher_.DescribeTo(os);
}
virtual void DescribeNegationTo(::std::ostream* os) const {
source_matcher_.DescribeNegationTo(os);
}
private:
const Matcher<U> source_matcher_;
GTEST_DISALLOW_ASSIGN_(Impl);
};
};
// This even more specialized version is used for efficiently casting
// a matcher to its own type.
template <typename T>
class MatcherCastImpl<T, Matcher<T> > {
public:
static Matcher<T> Cast(const Matcher<T>& matcher) { return matcher; }
};
// Implements A<T>(). // Implements A<T>().
template <typename T> template <typename T>
class AnyMatcherImpl : public MatcherInterface<T> { class AnyMatcherImpl : public MatcherInterface<T> {
...@@ -1596,6 +1642,7 @@ class FloatingEqMatcher { ...@@ -1596,6 +1642,7 @@ class FloatingEqMatcher {
operator Matcher<FloatType&>() const { operator Matcher<FloatType&>() const {
return MakeMatcher(new Impl<FloatType&>(rhs_, nan_eq_nan_)); return MakeMatcher(new Impl<FloatType&>(rhs_, nan_eq_nan_));
} }
private: private:
const FloatType rhs_; const FloatType rhs_;
const bool nan_eq_nan_; const bool nan_eq_nan_;
...@@ -2633,12 +2680,6 @@ GTEST_API_ string FormatMatcherDescription(bool negation, ...@@ -2633,12 +2680,6 @@ GTEST_API_ string FormatMatcherDescription(bool negation,
} // namespace internal } // namespace internal
// Implements MatcherCast().
template <typename T, typename M>
inline Matcher<T> MatcherCast(M matcher) {
return internal::MatcherCastImpl<T, M>::Cast(matcher);
}
// _ is a matcher that matches anything of any type. // _ is a matcher that matches anything of any type.
// //
// This definition is fine as: // This definition is fine as:
......
...@@ -384,6 +384,7 @@ class GTEST_API_ Mock { ...@@ -384,6 +384,7 @@ class GTEST_API_ Mock {
// verification was successful. // verification was successful.
static bool VerifyAndClear(void* mock_obj) static bool VerifyAndClear(void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
private: private:
friend class internal::UntypedFunctionMockerBase; friend class internal::UntypedFunctionMockerBase;
......
// This file was GENERATED by a script. DO NOT EDIT BY HAND!!! // This file was GENERATED by command:
// pump.py gmock-generated-internal-utils.h.pump
// DO NOT EDIT BY HAND!!!
// Copyright 2007, Google Inc. // Copyright 2007, Google Inc.
// All rights reserved. // All rights reserved.
...@@ -58,7 +60,7 @@ class IgnoredValue { ...@@ -58,7 +60,7 @@ class IgnoredValue {
// deliberately omit the 'explicit' keyword in order to allow the // deliberately omit the 'explicit' keyword in order to allow the
// conversion to be implicit. // conversion to be implicit.
template <typename T> template <typename T>
IgnoredValue(const T&) {} IgnoredValue(const T& /* ignored */) {} // NOLINT(runtime/explicit)
}; };
// MatcherTuple<T>::type is a tuple type where each field is a Matcher // MatcherTuple<T>::type is a tuple type where each field is a Matcher
......
...@@ -61,7 +61,7 @@ class IgnoredValue { ...@@ -61,7 +61,7 @@ class IgnoredValue {
// deliberately omit the 'explicit' keyword in order to allow the // deliberately omit the 'explicit' keyword in order to allow the
// conversion to be implicit. // conversion to be implicit.
template <typename T> template <typename T>
IgnoredValue(const T&) {} IgnoredValue(const T& /* ignored */) {} // NOLINT(runtime/explicit)
}; };
// MatcherTuple<T>::type is a tuple type where each field is a Matcher // MatcherTuple<T>::type is a tuple type where each field is a Matcher
......
...@@ -354,7 +354,8 @@ template <typename T> struct remove_reference<T&> { typedef T type; }; // NOLINT ...@@ -354,7 +354,8 @@ template <typename T> struct remove_reference<T&> { typedef T type; }; // NOLINT
// crashes). // crashes).
template <typename T> template <typename T>
inline T Invalid() { inline T Invalid() {
return *static_cast<typename remove_reference<T>::type*>(NULL); return const_cast<typename remove_reference<T>::type&>(
*static_cast<volatile typename remove_reference<T>::type*>(NULL));
} }
template <> template <>
inline void Invalid<void>() {} inline void Invalid<void>() {}
...@@ -459,6 +460,11 @@ class StlContainerView< ::std::tr1::tuple<ElementPointer, Size> > { ...@@ -459,6 +460,11 @@ class StlContainerView< ::std::tr1::tuple<ElementPointer, Size> > {
// StlContainer with a reference type. // StlContainer with a reference type.
template <typename T> class StlContainerView<T&>; template <typename T> class StlContainerView<T&>;
// Mapping from booleans to types. Similar to boost::bool_<kValue> and
// std::integral_constant<bool, kValue>.
template <bool kValue>
struct BooleanConstant {};
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
......
...@@ -416,7 +416,7 @@ def _NeedToUseReturnNullDiagnoser(msg): ...@@ -416,7 +416,7 @@ def _NeedToUseReturnNullDiagnoser(msg):
'::operator testing::Action<Func>\(\) const.*\n' + '::operator testing::Action<Func>\(\) const.*\n' +
_GCC_FILE_LINE_RE + r'instantiated from here\n' _GCC_FILE_LINE_RE + r'instantiated from here\n'
r'.*error: no matching function for call to \'ImplicitCast_\(' r'.*error: no matching function for call to \'ImplicitCast_\('
r'long int&\)') r'(:?long )?int&\)')
clang_regex = (r'\bgmock-actions.h:.* error: no matching function for ' clang_regex = (r'\bgmock-actions.h:.* error: no matching function for '
r'call to \'ImplicitCast_\'\r?\n' r'call to \'ImplicitCast_\'\r?\n'
r'(.*\n)*?' + r'(.*\n)*?' +
......
...@@ -75,7 +75,7 @@ class BetweenCardinalityImpl : public CardinalityInterface { ...@@ -75,7 +75,7 @@ class BetweenCardinalityImpl : public CardinalityInterface {
virtual int ConservativeUpperBound() const { return max_; } virtual int ConservativeUpperBound() const { return max_; }
virtual bool IsSatisfiedByCallCount(int call_count) const { virtual bool IsSatisfiedByCallCount(int call_count) const {
return min_ <= call_count && call_count <= max_ ; return min_ <= call_count && call_count <= max_;
} }
virtual bool IsSaturatedByCallCount(int call_count) const { virtual bool IsSaturatedByCallCount(int call_count) const {
...@@ -83,6 +83,7 @@ class BetweenCardinalityImpl : public CardinalityInterface { ...@@ -83,6 +83,7 @@ class BetweenCardinalityImpl : public CardinalityInterface {
} }
virtual void DescribeTo(::std::ostream* os) const; virtual void DescribeTo(::std::ostream* os) const;
private: private:
const int min_; const int min_;
const int max_; const int max_;
......
...@@ -579,6 +579,7 @@ class MockObjectRegistry { ...@@ -579,6 +579,7 @@ class MockObjectRegistry {
} }
StateMap& states() { return states_; } StateMap& states() { return states_; }
private: private:
StateMap states_; StateMap states_;
}; };
......
...@@ -518,7 +518,7 @@ TEST(ReturnTest, IsCovariant) { ...@@ -518,7 +518,7 @@ TEST(ReturnTest, IsCovariant) {
// gmock-actions.h for more information. // gmock-actions.h for more information.
class FromType { class FromType {
public: public:
FromType(bool* is_converted) : converted_(is_converted) {} explicit FromType(bool* is_converted) : converted_(is_converted) {}
bool* converted() const { return converted_; } bool* converted() const { return converted_; }
private: private:
...@@ -529,7 +529,8 @@ class FromType { ...@@ -529,7 +529,8 @@ class FromType {
class ToType { class ToType {
public: public:
ToType(const FromType& x) { *x.converted() = true; } // Must allow implicit conversion due to use in ImplicitCast_<T>.
ToType(const FromType& x) { *x.converted() = true; } // NOLINT
}; };
TEST(ReturnTest, ConvertsArgumentWhenConverted) { TEST(ReturnTest, ConvertsArgumentWhenConverted) {
...@@ -541,7 +542,7 @@ TEST(ReturnTest, ConvertsArgumentWhenConverted) { ...@@ -541,7 +542,7 @@ TEST(ReturnTest, ConvertsArgumentWhenConverted) {
converted = false; converted = false;
action.Perform(tuple<>()); action.Perform(tuple<>());
EXPECT_FALSE(converted) << "Action must NOT convert its argument " EXPECT_FALSE(converted) << "Action must NOT convert its argument "
<< "when performed." ; << "when performed.";
} }
class DestinationType {}; class DestinationType {};
...@@ -1226,7 +1227,8 @@ TEST(ByRefTest, IsCopyable) { ...@@ -1226,7 +1227,8 @@ TEST(ByRefTest, IsCopyable) {
const std::string s1 = "Hi"; const std::string s1 = "Hi";
const std::string s2 = "Hello"; const std::string s2 = "Hello";
::testing::internal::ReferenceWrapper<const std::string> ref_wrapper = ByRef(s1); ::testing::internal::ReferenceWrapper<const std::string> ref_wrapper =
ByRef(s1);
const std::string& r1 = ref_wrapper; const std::string& r1 = ref_wrapper;
EXPECT_EQ(&s1, &r1); EXPECT_EQ(&s1, &r1);
...@@ -1235,7 +1237,8 @@ TEST(ByRefTest, IsCopyable) { ...@@ -1235,7 +1237,8 @@ TEST(ByRefTest, IsCopyable) {
const std::string& r2 = ref_wrapper; const std::string& r2 = ref_wrapper;
EXPECT_EQ(&s2, &r2); EXPECT_EQ(&s2, &r2);
::testing::internal::ReferenceWrapper<const std::string> ref_wrapper1 = ByRef(s1); ::testing::internal::ReferenceWrapper<const std::string> ref_wrapper1 =
ByRef(s1);
// Copies ref_wrapper1 to ref_wrapper. // Copies ref_wrapper1 to ref_wrapper.
ref_wrapper = ref_wrapper1; ref_wrapper = ref_wrapper1;
const std::string& r3 = ref_wrapper; const std::string& r3 = ref_wrapper;
......
...@@ -35,11 +35,6 @@ ...@@ -35,11 +35,6 @@
#include "gmock/gmock-generated-function-mockers.h" #include "gmock/gmock-generated-function-mockers.h"
#include <map>
#include <string>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#if GTEST_OS_WINDOWS #if GTEST_OS_WINDOWS
// MSDN says the header file to be included for STDMETHOD is BaseTyps.h but // MSDN says the header file to be included for STDMETHOD is BaseTyps.h but
// we are getting compiler errors if we use basetyps.h, hence including // we are getting compiler errors if we use basetyps.h, hence including
...@@ -47,6 +42,11 @@ ...@@ -47,6 +42,11 @@
# include <objbase.h> # include <objbase.h>
#endif // GTEST_OS_WINDOWS #endif // GTEST_OS_WINDOWS
#include <map>
#include <string>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
// There is a bug in MSVC (fixed in VS 2008) that prevents creating a // There is a bug in MSVC (fixed in VS 2008) that prevents creating a
// mock for a function with const arguments, so we don't test such // mock for a function with const arguments, so we don't test such
// cases for MSVC versions older than 2008. // cases for MSVC versions older than 2008.
......
...@@ -1091,6 +1091,20 @@ TEST(ContainsTest, WorksForTwoDimensionalNativeArray) { ...@@ -1091,6 +1091,20 @@ TEST(ContainsTest, WorksForTwoDimensionalNativeArray) {
EXPECT_THAT(a, Contains(Not(Contains(5)))); EXPECT_THAT(a, Contains(Not(Contains(5))));
} }
TEST(AllOfTest, HugeMatcher) {
// Verify that using AllOf with many arguments doesn't cause
// the compiler to exceed template instantiation depth limit.
EXPECT_THAT(0, testing::AllOf(_, _, _, _, _, _, _, _, _,
testing::AllOf(_, _, _, _, _, _, _, _, _, _)));
}
TEST(AnyOfTest, HugeMatcher) {
// Verify that using AnyOf with many arguments doesn't cause
// the compiler to exceed template instantiation depth limit.
EXPECT_THAT(0, testing::AnyOf(_, _, _, _, _, _, _, _, _,
testing::AnyOf(_, _, _, _, _, _, _, _, _, _)));
}
namespace adl_test { namespace adl_test {
// Verifies that the implementation of ::testing::AllOf and ::testing::AnyOf // Verifies that the implementation of ::testing::AllOf and ::testing::AnyOf
......
...@@ -545,6 +545,37 @@ TEST(MatcherCastTest, FromSameType) { ...@@ -545,6 +545,37 @@ TEST(MatcherCastTest, FromSameType) {
EXPECT_FALSE(m2.Matches(1)); EXPECT_FALSE(m2.Matches(1));
} }
// Implicitly convertible form any type.
struct ConvertibleFromAny {
ConvertibleFromAny(int a_value) : value(a_value) {}
template <typename T>
ConvertibleFromAny(const T& a_value) : value(-1) {
ADD_FAILURE() << "Conversion constructor called";
}
int value;
};
bool operator==(const ConvertibleFromAny& a, const ConvertibleFromAny& b) {
return a.value == b.value;
}
ostream& operator<<(ostream& os, const ConvertibleFromAny& a) {
return os << a.value;
}
TEST(MatcherCastTest, ConversionConstructorIsUsed) {
Matcher<ConvertibleFromAny> m = MatcherCast<ConvertibleFromAny>(1);
EXPECT_TRUE(m.Matches(ConvertibleFromAny(1)));
EXPECT_FALSE(m.Matches(ConvertibleFromAny(2)));
}
TEST(MatcherCastTest, FromConvertibleFromAny) {
Matcher<ConvertibleFromAny> m =
MatcherCast<ConvertibleFromAny>(Eq(ConvertibleFromAny(1)));
EXPECT_TRUE(m.Matches(ConvertibleFromAny(1)));
EXPECT_FALSE(m.Matches(ConvertibleFromAny(2)));
}
class Base {}; class Base {};
class Derived : public Base {}; class Derived : public Base {};
...@@ -620,6 +651,19 @@ TEST(SafeMatcherCastTest, FromSameType) { ...@@ -620,6 +651,19 @@ TEST(SafeMatcherCastTest, FromSameType) {
EXPECT_FALSE(m2.Matches(1)); EXPECT_FALSE(m2.Matches(1));
} }
TEST(SafeMatcherCastTest, ConversionConstructorIsUsed) {
Matcher<ConvertibleFromAny> m = SafeMatcherCast<ConvertibleFromAny>(1);
EXPECT_TRUE(m.Matches(ConvertibleFromAny(1)));
EXPECT_FALSE(m.Matches(ConvertibleFromAny(2)));
}
TEST(SafeMatcherCastTest, FromConvertibleFromAny) {
Matcher<ConvertibleFromAny> m =
SafeMatcherCast<ConvertibleFromAny>(Eq(ConvertibleFromAny(1)));
EXPECT_TRUE(m.Matches(ConvertibleFromAny(1)));
EXPECT_FALSE(m.Matches(ConvertibleFromAny(2)));
}
// Tests that A<T>() matches any value of type T. // Tests that A<T>() matches any value of type T.
TEST(ATest, MatchesAnyValue) { TEST(ATest, MatchesAnyValue) {
// Tests a matcher for a value type. // Tests a matcher for a value type.
...@@ -1940,19 +1984,19 @@ TEST(AllOfTest, CanDescribeSelf) { ...@@ -1940,19 +1984,19 @@ TEST(AllOfTest, CanDescribeSelf) {
m = AllOf(Gt(0), Ne(1), Ne(2), Ne(3)); m = AllOf(Gt(0), Ne(1), Ne(2), Ne(3));
EXPECT_EQ("(is > 0) and " EXPECT_EQ("((is > 0) and "
"((isn't equal to 1) and " "(isn't equal to 1)) and "
"((isn't equal to 2) and " "((isn't equal to 2) and "
"(isn't equal to 3)))", "(isn't equal to 3))",
Describe(m)); Describe(m));
m = AllOf(Ge(0), Lt(10), Ne(3), Ne(5), Ne(7)); m = AllOf(Ge(0), Lt(10), Ne(3), Ne(5), Ne(7));
EXPECT_EQ("(is >= 0) and " EXPECT_EQ("((is >= 0) and "
"((is < 10) and " "(is < 10)) and "
"((isn't equal to 3) and " "((isn't equal to 3) and "
"((isn't equal to 5) and " "((isn't equal to 5) and "
"(isn't equal to 7))))", "(isn't equal to 7)))",
Describe(m)); Describe(m));
} }
...@@ -1972,19 +2016,19 @@ TEST(AllOfTest, CanDescribeNegation) { ...@@ -1972,19 +2016,19 @@ TEST(AllOfTest, CanDescribeNegation) {
m = AllOf(Gt(0), Ne(1), Ne(2), Ne(3)); m = AllOf(Gt(0), Ne(1), Ne(2), Ne(3));
EXPECT_EQ("(isn't > 0) or " EXPECT_EQ("((isn't > 0) or "
"((is equal to 1) or " "(is equal to 1)) or "
"((is equal to 2) or " "((is equal to 2) or "
"(is equal to 3)))", "(is equal to 3))",
DescribeNegation(m)); DescribeNegation(m));
m = AllOf(Ge(0), Lt(10), Ne(3), Ne(5), Ne(7)); m = AllOf(Ge(0), Lt(10), Ne(3), Ne(5), Ne(7));
EXPECT_EQ("(isn't >= 0) or " EXPECT_EQ("((isn't >= 0) or "
"((isn't < 10) or " "(isn't < 10)) or "
"((is equal to 3) or " "((is equal to 3) or "
"((is equal to 5) or " "((is equal to 5) or "
"(is equal to 7))))", "(is equal to 7)))",
DescribeNegation(m)); DescribeNegation(m));
} }
...@@ -2112,18 +2156,18 @@ TEST(AnyOfTest, CanDescribeSelf) { ...@@ -2112,18 +2156,18 @@ TEST(AnyOfTest, CanDescribeSelf) {
Describe(m)); Describe(m));
m = AnyOf(Lt(0), Eq(1), Eq(2), Eq(3)); m = AnyOf(Lt(0), Eq(1), Eq(2), Eq(3));
EXPECT_EQ("(is < 0) or " EXPECT_EQ("((is < 0) or "
"((is equal to 1) or " "(is equal to 1)) or "
"((is equal to 2) or " "((is equal to 2) or "
"(is equal to 3)))", "(is equal to 3))",
Describe(m)); Describe(m));
m = AnyOf(Le(0), Gt(10), 3, 5, 7); m = AnyOf(Le(0), Gt(10), 3, 5, 7);
EXPECT_EQ("(is <= 0) or " EXPECT_EQ("((is <= 0) or "
"((is > 10) or " "(is > 10)) or "
"((is equal to 3) or " "((is equal to 3) or "
"((is equal to 5) or " "((is equal to 5) or "
"(is equal to 7))))", "(is equal to 7)))",
Describe(m)); Describe(m));
} }
...@@ -2140,18 +2184,18 @@ TEST(AnyOfTest, CanDescribeNegation) { ...@@ -2140,18 +2184,18 @@ TEST(AnyOfTest, CanDescribeNegation) {
DescribeNegation(m)); DescribeNegation(m));
m = AnyOf(Lt(0), Eq(1), Eq(2), Eq(3)); m = AnyOf(Lt(0), Eq(1), Eq(2), Eq(3));
EXPECT_EQ("(isn't < 0) and " EXPECT_EQ("((isn't < 0) and "
"((isn't equal to 1) and " "(isn't equal to 1)) and "
"((isn't equal to 2) and " "((isn't equal to 2) and "
"(isn't equal to 3)))", "(isn't equal to 3))",
DescribeNegation(m)); DescribeNegation(m));
m = AnyOf(Le(0), Gt(10), 3, 5, 7); m = AnyOf(Le(0), Gt(10), 3, 5, 7);
EXPECT_EQ("(isn't <= 0) and " EXPECT_EQ("((isn't <= 0) and "
"((isn't > 10) and " "(isn't > 10)) and "
"((isn't equal to 3) and " "((isn't equal to 3) and "
"((isn't equal to 5) and " "((isn't equal to 5) and "
"(isn't equal to 7))))", "(isn't equal to 7)))",
DescribeNegation(m)); DescribeNegation(m));
} }
......
...@@ -225,6 +225,7 @@ class Foo { ...@@ -225,6 +225,7 @@ class Foo {
const char* s10) { const char* s10) {
return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10; return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;
} }
private: private:
int value_; int value_;
}; };
......
...@@ -195,8 +195,8 @@ class Interface { ...@@ -195,8 +195,8 @@ class Interface {
virtual char* StringFromString(char* str) = 0; virtual char* StringFromString(char* str) = 0;
virtual int IntFromString(char* str) = 0; virtual int IntFromString(char* str) = 0;
virtual int& IntRefFromString(char* str) = 0; virtual int& IntRefFromString(char* str) = 0;
virtual void VoidFromFunc(void(*)(char*)) = 0; virtual void VoidFromFunc(void(*func)(char* str)) = 0;
virtual void VoidFromIntRef(int& n) = 0; virtual void VoidFromIntRef(int& n) = 0; // NOLINT
virtual void VoidFromFloat(float n) = 0; virtual void VoidFromFloat(float n) = 0;
virtual void VoidFromDouble(double n) = 0; virtual void VoidFromDouble(double n) = 0;
virtual void VoidFromVector(const std::vector<int>& v) = 0; virtual void VoidFromVector(const std::vector<int>& v) = 0;
...@@ -211,7 +211,7 @@ class Mock: public Interface { ...@@ -211,7 +211,7 @@ class Mock: public Interface {
MOCK_METHOD1(IntFromString, int(char* str)); MOCK_METHOD1(IntFromString, int(char* str));
MOCK_METHOD1(IntRefFromString, int&(char* str)); MOCK_METHOD1(IntRefFromString, int&(char* str));
MOCK_METHOD1(VoidFromFunc, void(void(*func)(char* str))); MOCK_METHOD1(VoidFromFunc, void(void(*func)(char* str)));
MOCK_METHOD1(VoidFromIntRef, void(int& n)); MOCK_METHOD1(VoidFromIntRef, void(int& n)); // NOLINT
MOCK_METHOD1(VoidFromFloat, void(float n)); MOCK_METHOD1(VoidFromFloat, void(float n));
MOCK_METHOD1(VoidFromDouble, void(double n)); MOCK_METHOD1(VoidFromDouble, void(double n));
MOCK_METHOD1(VoidFromVector, void(const std::vector<int>& v)); MOCK_METHOD1(VoidFromVector, void(const std::vector<int>& v));
...@@ -224,15 +224,15 @@ class InvokeHelper { ...@@ -224,15 +224,15 @@ class InvokeHelper {
public: public:
static void StaticVoidFromVoid() {} static void StaticVoidFromVoid() {}
void VoidFromVoid() {} void VoidFromVoid() {}
static void StaticVoidFromString(char*) {} static void StaticVoidFromString(char* /* str */) {}
void VoidFromString(char*) {} void VoidFromString(char* /* str */) {}
static int StaticIntFromString(char*) { return 1; } static int StaticIntFromString(char* /* str */) { return 1; }
static bool StaticBoolFromString(const char*) { return true; } static bool StaticBoolFromString(const char* /* str */) { return true; }
}; };
class FieldHelper { class FieldHelper {
public: public:
FieldHelper(int a_field) : field_(a_field) {} explicit FieldHelper(int a_field) : field_(a_field) {}
int field() const { return field_; } int field() const { return field_; }
int field_; // NOLINT -- need external access to field_ to test int field_; // NOLINT -- need external access to field_ to test
// the Field matcher. // the Field matcher.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment