aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorzhanyong.wan <zhanyong.wan@8415998a-534a-0410-bf83-d39667b30386>2009-05-14 20:55:30 +0000
committerzhanyong.wan <zhanyong.wan@8415998a-534a-0410-bf83-d39667b30386>2009-05-14 20:55:30 +0000
commit16cf473930c01cd7a1a51dff65f22c541fbad5b8 (patch)
tree5d286c8a70d91a0f100523f64ad17d316e8f25f7 /include
parentc6a412397bc98f120d5e79d4a64e3972854b5af3 (diff)
downloadgoogletest-16cf473930c01cd7a1a51dff65f22c541fbad5b8.tar.gz
googletest-16cf473930c01cd7a1a51dff65f22c541fbad5b8.tar.bz2
googletest-16cf473930c01cd7a1a51dff65f22c541fbad5b8.zip
Finishes SafeMatcherCast by catching lossy arithmetic conversions at compile-time; uses ACTION_TEMPLATE to simplify the definition of many actions; makes mock object uncopyable; teaches gmock doctor about wrong MOCK_METHODn.
Diffstat (limited to 'include')
-rw-r--r--include/gmock/gmock-generated-actions.h890
-rw-r--r--include/gmock/gmock-generated-actions.h.pump290
-rw-r--r--include/gmock/gmock-matchers.h17
-rw-r--r--include/gmock/gmock-printers.h11
-rw-r--r--include/gmock/gmock-spec-builders.h14
-rw-r--r--include/gmock/internal/gmock-internal-utils.h157
6 files changed, 437 insertions, 942 deletions
diff --git a/include/gmock/gmock-generated-actions.h b/include/gmock/gmock-generated-actions.h
index 6d49c600..fa02faaa 100644
--- a/include/gmock/gmock-generated-actions.h
+++ b/include/gmock/gmock-generated-actions.h
@@ -443,264 +443,6 @@ class CallableHelper {
}; // class CallableHelper
-// Invokes a nullary callable argument.
-template <size_t N>
-class InvokeArgumentAction0 {
- public:
- template <typename Result, typename ArgumentTuple>
- static Result Perform(const ArgumentTuple& args) {
- return CallableHelper<Result>::Call(::std::tr1::get<N>(args));
- }
-};
-
-// Invokes a unary callable argument with the given argument.
-template <size_t N, typename A1>
-class InvokeArgumentAction1 {
- public:
- // We deliberately pass a1 by value instead of const reference here
- // in case it is a C-string literal.
- //
- // Since this function is defined inline, the compiler can get rid
- // of the copying of the arguments. Therefore the performance won't
- // be hurt.
- explicit InvokeArgumentAction1(A1 a1) : arg1_(a1) {}
-
- template <typename Result, typename ArgumentTuple>
- Result Perform(const ArgumentTuple& args) {
- return CallableHelper<Result>::Call(::std::tr1::get<N>(args), arg1_);
- }
- private:
- const A1 arg1_;
-};
-
-// Invokes a binary callable argument with the given arguments.
-template <size_t N, typename A1, typename A2>
-class InvokeArgumentAction2 {
- public:
- InvokeArgumentAction2(A1 a1, A2 a2) :
- arg1_(a1), arg2_(a2) {}
-
- template <typename Result, typename ArgumentTuple>
- Result Perform(const ArgumentTuple& args) {
- return CallableHelper<Result>::Call(::std::tr1::get<N>(args), arg1_, arg2_);
- }
- private:
- const A1 arg1_;
- const A2 arg2_;
-};
-
-// Invokes a ternary callable argument with the given arguments.
-template <size_t N, typename A1, typename A2, typename A3>
-class InvokeArgumentAction3 {
- public:
- InvokeArgumentAction3(A1 a1, A2 a2, A3 a3) :
- arg1_(a1), arg2_(a2), arg3_(a3) {}
-
- template <typename Result, typename ArgumentTuple>
- Result Perform(const ArgumentTuple& args) {
- return CallableHelper<Result>::Call(::std::tr1::get<N>(args), arg1_, arg2_,
- arg3_);
- }
- private:
- const A1 arg1_;
- const A2 arg2_;
- const A3 arg3_;
-};
-
-// Invokes a 4-ary callable argument with the given arguments.
-template <size_t N, typename A1, typename A2, typename A3, typename A4>
-class InvokeArgumentAction4 {
- public:
- InvokeArgumentAction4(A1 a1, A2 a2, A3 a3, A4 a4) :
- arg1_(a1), arg2_(a2), arg3_(a3), arg4_(a4) {}
-
- template <typename Result, typename ArgumentTuple>
- Result Perform(const ArgumentTuple& args) {
- return CallableHelper<Result>::Call(::std::tr1::get<N>(args), arg1_, arg2_,
- arg3_, arg4_);
- }
- private:
- const A1 arg1_;
- const A2 arg2_;
- const A3 arg3_;
- const A4 arg4_;
-};
-
-// Invokes a 5-ary callable argument with the given arguments.
-template <size_t N, typename A1, typename A2, typename A3, typename A4,
- typename A5>
-class InvokeArgumentAction5 {
- public:
- InvokeArgumentAction5(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) :
- arg1_(a1), arg2_(a2), arg3_(a3), arg4_(a4), arg5_(a5) {}
-
- template <typename Result, typename ArgumentTuple>
- Result Perform(const ArgumentTuple& args) {
- // We extract the callable to a variable before invoking it, in
- // case it is a functor passed by value and its operator() is not
- // const.
- typename ::std::tr1::tuple_element<N, ArgumentTuple>::type function =
- ::std::tr1::get<N>(args);
- return function(arg1_, arg2_, arg3_, arg4_, arg5_);
- }
- private:
- const A1 arg1_;
- const A2 arg2_;
- const A3 arg3_;
- const A4 arg4_;
- const A5 arg5_;
-};
-
-// Invokes a 6-ary callable argument with the given arguments.
-template <size_t N, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6>
-class InvokeArgumentAction6 {
- public:
- InvokeArgumentAction6(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) :
- arg1_(a1), arg2_(a2), arg3_(a3), arg4_(a4), arg5_(a5), arg6_(a6) {}
-
- template <typename Result, typename ArgumentTuple>
- Result Perform(const ArgumentTuple& args) {
- // We extract the callable to a variable before invoking it, in
- // case it is a functor passed by value and its operator() is not
- // const.
- typename ::std::tr1::tuple_element<N, ArgumentTuple>::type function =
- ::std::tr1::get<N>(args);
- return function(arg1_, arg2_, arg3_, arg4_, arg5_, arg6_);
- }
- private:
- const A1 arg1_;
- const A2 arg2_;
- const A3 arg3_;
- const A4 arg4_;
- const A5 arg5_;
- const A6 arg6_;
-};
-
-// Invokes a 7-ary callable argument with the given arguments.
-template <size_t N, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6, typename A7>
-class InvokeArgumentAction7 {
- public:
- InvokeArgumentAction7(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) :
- arg1_(a1), arg2_(a2), arg3_(a3), arg4_(a4), arg5_(a5), arg6_(a6),
- arg7_(a7) {}
-
- template <typename Result, typename ArgumentTuple>
- Result Perform(const ArgumentTuple& args) {
- // We extract the callable to a variable before invoking it, in
- // case it is a functor passed by value and its operator() is not
- // const.
- typename ::std::tr1::tuple_element<N, ArgumentTuple>::type function =
- ::std::tr1::get<N>(args);
- return function(arg1_, arg2_, arg3_, arg4_, arg5_, arg6_, arg7_);
- }
- private:
- const A1 arg1_;
- const A2 arg2_;
- const A3 arg3_;
- const A4 arg4_;
- const A5 arg5_;
- const A6 arg6_;
- const A7 arg7_;
-};
-
-// Invokes a 8-ary callable argument with the given arguments.
-template <size_t N, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6, typename A7, typename A8>
-class InvokeArgumentAction8 {
- public:
- InvokeArgumentAction8(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7,
- A8 a8) :
- arg1_(a1), arg2_(a2), arg3_(a3), arg4_(a4), arg5_(a5), arg6_(a6),
- arg7_(a7), arg8_(a8) {}
-
- template <typename Result, typename ArgumentTuple>
- Result Perform(const ArgumentTuple& args) {
- // We extract the callable to a variable before invoking it, in
- // case it is a functor passed by value and its operator() is not
- // const.
- typename ::std::tr1::tuple_element<N, ArgumentTuple>::type function =
- ::std::tr1::get<N>(args);
- return function(arg1_, arg2_, arg3_, arg4_, arg5_, arg6_, arg7_, arg8_);
- }
- private:
- const A1 arg1_;
- const A2 arg2_;
- const A3 arg3_;
- const A4 arg4_;
- const A5 arg5_;
- const A6 arg6_;
- const A7 arg7_;
- const A8 arg8_;
-};
-
-// Invokes a 9-ary callable argument with the given arguments.
-template <size_t N, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6, typename A7, typename A8, typename A9>
-class InvokeArgumentAction9 {
- public:
- InvokeArgumentAction9(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8,
- A9 a9) :
- arg1_(a1), arg2_(a2), arg3_(a3), arg4_(a4), arg5_(a5), arg6_(a6),
- arg7_(a7), arg8_(a8), arg9_(a9) {}
-
- template <typename Result, typename ArgumentTuple>
- Result Perform(const ArgumentTuple& args) {
- // We extract the callable to a variable before invoking it, in
- // case it is a functor passed by value and its operator() is not
- // const.
- typename ::std::tr1::tuple_element<N, ArgumentTuple>::type function =
- ::std::tr1::get<N>(args);
- return function(arg1_, arg2_, arg3_, arg4_, arg5_, arg6_, arg7_, arg8_,
- arg9_);
- }
- private:
- const A1 arg1_;
- const A2 arg2_;
- const A3 arg3_;
- const A4 arg4_;
- const A5 arg5_;
- const A6 arg6_;
- const A7 arg7_;
- const A8 arg8_;
- const A9 arg9_;
-};
-
-// Invokes a 10-ary callable argument with the given arguments.
-template <size_t N, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6, typename A7, typename A8, typename A9,
- typename A10>
-class InvokeArgumentAction10 {
- public:
- InvokeArgumentAction10(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7,
- A8 a8, A9 a9, A10 a10) :
- arg1_(a1), arg2_(a2), arg3_(a3), arg4_(a4), arg5_(a5), arg6_(a6),
- arg7_(a7), arg8_(a8), arg9_(a9), arg10_(a10) {}
-
- template <typename Result, typename ArgumentTuple>
- Result Perform(const ArgumentTuple& args) {
- // We extract the callable to a variable before invoking it, in
- // case it is a functor passed by value and its operator() is not
- // const.
- typename ::std::tr1::tuple_element<N, ArgumentTuple>::type function =
- ::std::tr1::get<N>(args);
- return function(arg1_, arg2_, arg3_, arg4_, arg5_, arg6_, arg7_, arg8_,
- arg9_, arg10_);
- }
- private:
- const A1 arg1_;
- const A2 arg2_;
- const A3 arg3_;
- const A4 arg4_;
- const A5 arg5_;
- const A6 arg6_;
- const A7 arg7_;
- const A8 arg8_;
- const A9 arg9_;
- const A10 arg10_;
-};
-
// An INTERNAL macro for extracting the type of a tuple field. It's
// subject to change without notice - DO NOT USE IN USER CODE!
#define GMOCK_FIELD_(Tuple, N) \
@@ -1140,140 +882,6 @@ inline internal::ReferenceWrapper<T> ByRef(T& l_value) { // NOLINT
return internal::ReferenceWrapper<T>(l_value);
}
-// Various overloads for InvokeArgument<N>().
-//
-// The InvokeArgument<N>(a1, a2, ..., a_k) action invokes the N-th
-// (0-based) argument, which must be a k-ary callable, of the mock
-// function, with arguments a1, a2, ..., a_k.
-//
-// Notes:
-//
-// 1. The arguments are passed by value by default. If you need to
-// pass an argument by reference, wrap it inside ByRef(). For
-// example,
-//
-// InvokeArgument<1>(5, string("Hello"), ByRef(foo))
-//
-// passes 5 and string("Hello") by value, and passes foo by
-// reference.
-//
-// 2. If the callable takes an argument by reference but ByRef() is
-// not used, it will receive the reference to a copy of the value,
-// instead of the original value. For example, when the 0-th
-// argument of the mock function takes a const string&, the action
-//
-// InvokeArgument<0>(string("Hello"))
-//
-// makes a copy of the temporary string("Hello") object and passes a
-// reference of the copy, instead of the original temporary object,
-// to the callable. This makes it easy for a user to define an
-// InvokeArgument action from temporary values and have it performed
-// later.
-template <size_t N>
-inline PolymorphicAction<internal::InvokeArgumentAction0<N> > InvokeArgument() {
- return MakePolymorphicAction(internal::InvokeArgumentAction0<N>());
-}
-
-// We deliberately pass a1 by value instead of const reference here in
-// case it is a C-string literal. If we had declared the parameter as
-// 'const A1& a1' and write InvokeArgument<0>("Hi"), the compiler
-// would've thought A1 is 'char[3]', which causes trouble as the
-// implementation needs to copy a value of type A1. By declaring the
-// parameter as 'A1 a1', the compiler will correctly infer that A1 is
-// 'const char*' when it sees InvokeArgument<0>("Hi").
-//
-// Since this function is defined inline, the compiler can get rid of
-// the copying of the arguments. Therefore the performance won't be
-// hurt.
-template <size_t N, typename A1>
-inline PolymorphicAction<internal::InvokeArgumentAction1<N, A1> >
-InvokeArgument(A1 a1) {
- return MakePolymorphicAction(internal::InvokeArgumentAction1<N, A1>(a1));
-}
-
-template <size_t N, typename A1, typename A2>
-inline PolymorphicAction<internal::InvokeArgumentAction2<N, A1, A2> >
-InvokeArgument(A1 a1, A2 a2) {
- return MakePolymorphicAction(
- internal::InvokeArgumentAction2<N, A1, A2>(a1, a2));
-}
-
-template <size_t N, typename A1, typename A2, typename A3>
-inline PolymorphicAction<internal::InvokeArgumentAction3<N, A1, A2, A3> >
-InvokeArgument(A1 a1, A2 a2, A3 a3) {
- return MakePolymorphicAction(
- internal::InvokeArgumentAction3<N, A1, A2, A3>(a1, a2, a3));
-}
-
-template <size_t N, typename A1, typename A2, typename A3, typename A4>
-inline PolymorphicAction<internal::InvokeArgumentAction4<N, A1, A2, A3, A4> >
-InvokeArgument(A1 a1, A2 a2, A3 a3, A4 a4) {
- return MakePolymorphicAction(
- internal::InvokeArgumentAction4<N, A1, A2, A3, A4>(a1, a2, a3, a4));
-}
-
-template <size_t N, typename A1, typename A2, typename A3, typename A4,
- typename A5>
-inline PolymorphicAction<internal::InvokeArgumentAction5<N, A1, A2, A3, A4,
- A5> >
-InvokeArgument(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {
- return MakePolymorphicAction(
- internal::InvokeArgumentAction5<N, A1, A2, A3, A4, A5>(a1, a2, a3, a4,
- a5));
-}
-
-template <size_t N, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6>
-inline PolymorphicAction<internal::InvokeArgumentAction6<N, A1, A2, A3, A4, A5,
- A6> >
-InvokeArgument(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) {
- return MakePolymorphicAction(
- internal::InvokeArgumentAction6<N, A1, A2, A3, A4, A5, A6>(a1, a2, a3,
- a4, a5, a6));
-}
-
-template <size_t N, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6, typename A7>
-inline PolymorphicAction<internal::InvokeArgumentAction7<N, A1, A2, A3, A4, A5,
- A6, A7> >
-InvokeArgument(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) {
- return MakePolymorphicAction(
- internal::InvokeArgumentAction7<N, A1, A2, A3, A4, A5, A6, A7>(a1, a2,
- a3, a4, a5, a6, a7));
-}
-
-template <size_t N, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6, typename A7, typename A8>
-inline PolymorphicAction<internal::InvokeArgumentAction8<N, A1, A2, A3, A4, A5,
- A6, A7, A8> >
-InvokeArgument(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) {
- return MakePolymorphicAction(
- internal::InvokeArgumentAction8<N, A1, A2, A3, A4, A5, A6, A7, A8>(a1,
- a2, a3, a4, a5, a6, a7, a8));
-}
-
-template <size_t N, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6, typename A7, typename A8, typename A9>
-inline PolymorphicAction<internal::InvokeArgumentAction9<N, A1, A2, A3, A4, A5,
- A6, A7, A8, A9> >
-InvokeArgument(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) {
- return MakePolymorphicAction(
- internal::InvokeArgumentAction9<N, A1, A2, A3, A4, A5, A6, A7, A8,
- A9>(a1, a2, a3, a4, a5, a6, a7, a8, a9));
-}
-
-template <size_t N, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6, typename A7, typename A8, typename A9,
- typename A10>
-inline PolymorphicAction<internal::InvokeArgumentAction10<N, A1, A2, A3, A4,
- A5, A6, A7, A8, A9, A10> >
-InvokeArgument(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9,
- A10 a10) {
- return MakePolymorphicAction(
- internal::InvokeArgumentAction10<N, A1, A2, A3, A4, A5, A6, A7, A8, A9,
- A10>(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10));
-}
-
// WithoutArgs(inner_action) can be used in a mock function with a
// non-empty argument list to perform inner_action, which takes no
// argument. In other words, it adapts an action accepting no
@@ -2715,271 +2323,153 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
// updated.
namespace testing {
-namespace internal {
-
-// Saves argument #0 to where the pointer points.
-ACTION_P(SaveArg0, pointer) { *pointer = arg0; }
+// Various overloads for InvokeArgument<N>().
+//
+// The InvokeArgument<N>(a1, a2, ..., a_k) action invokes the N-th
+// (0-based) argument, which must be a k-ary callable, of the mock
+// function, with arguments a1, a2, ..., a_k.
+//
+// Notes:
+//
+// 1. The arguments are passed by value by default. If you need to
+// pass an argument by reference, wrap it inside ByRef(). For
+// example,
+//
+// InvokeArgument<1>(5, string("Hello"), ByRef(foo))
+//
+// passes 5 and string("Hello") by value, and passes foo by
+// reference.
+//
+// 2. If the callable takes an argument by reference but ByRef() is
+// not used, it will receive the reference to a copy of the value,
+// instead of the original value. For example, when the 0-th
+// argument of the mock function takes a const string&, the action
+//
+// InvokeArgument<0>(string("Hello"))
+//
+// makes a copy of the temporary string("Hello") object and passes a
+// reference of the copy, instead of the original temporary object,
+// to the callable. This makes it easy for a user to define an
+// InvokeArgument action from temporary values and have it performed
+// later.
-// Assigns 'value' to the variable referenced by argument #0.
-ACTION_P(SetArg0Referee, value) {
- // Ensures that argument #0 is a reference. If you get a compiler
- // error on the next line, you are using SetArgReferee<k>(value) in
- // a mock function whose k-th (0-based) argument is not a reference.
- GMOCK_COMPILE_ASSERT_(internal::is_reference<arg0_type>::value,
- SetArgReferee_must_be_used_with_a_reference_argument);
- arg0 = value;
+ACTION_TEMPLATE(InvokeArgument,
+ HAS_1_TEMPLATE_PARAMS(int, k),
+ AND_0_VALUE_PARAMS()) {
+ return internal::CallableHelper<return_type>::Call(
+ ::std::tr1::get<k>(args));
}
-// ReturnNewAction<T> creates and returns a new instance of an object each time
-// it is performed. It is overloaded to work with constructors that take
-// different numbers of arguments.
-// Returns a new instance of T using a nullary constructor with the given
-// arguments.
-template <typename T>
-class ReturnNewAction0 {
- public:
- ReturnNewAction0() {}
-
- template <typename Result, typename ArgumentTuple>
- Result Perform(const ArgumentTuple& /* args */) {
- return new T();
- }
- private:
-};
-
-// Returns a new instance of T using a unary constructor with the given
-// arguments.
-template <typename T, typename A1>
-class ReturnNewAction1 {
- public:
- explicit ReturnNewAction1(A1 a1) : arg1_(a1) {}
-
- template <typename Result, typename ArgumentTuple>
- Result Perform(const ArgumentTuple& /* args */) {
- return new T(arg1_);
- }
- private:
- const A1 arg1_;
-};
-
-// Returns a new instance of T using a binary constructor with the given
-// arguments.
-template <typename T, typename A1, typename A2>
-class ReturnNewAction2 {
- public:
- ReturnNewAction2(A1 a1, A2 a2) : arg1_(a1), arg2_(a2) {}
-
- template <typename Result, typename ArgumentTuple>
- Result Perform(const ArgumentTuple& /* args */) {
- return new T(arg1_, arg2_);
- }
- private:
- const A1 arg1_;
- const A2 arg2_;
-};
-
-// Returns a new instance of T using a ternary constructor with the given
-// arguments.
-template <typename T, typename A1, typename A2, typename A3>
-class ReturnNewAction3 {
- public:
- ReturnNewAction3(A1 a1, A2 a2, A3 a3) : arg1_(a1), arg2_(a2), arg3_(a3) {}
-
- template <typename Result, typename ArgumentTuple>
- Result Perform(const ArgumentTuple& /* args */) {
- return new T(arg1_, arg2_, arg3_);
- }
- private:
- const A1 arg1_;
- const A2 arg2_;
- const A3 arg3_;
-};
-
-// Returns a new instance of T using a 4-ary constructor with the given
-// arguments.
-template <typename T, typename A1, typename A2, typename A3, typename A4>
-class ReturnNewAction4 {
- public:
- ReturnNewAction4(A1 a1, A2 a2, A3 a3, A4 a4) : arg1_(a1), arg2_(a2),
- arg3_(a3), arg4_(a4) {}
-
- template <typename Result, typename ArgumentTuple>
- Result Perform(const ArgumentTuple& /* args */) {
- return new T(arg1_, arg2_, arg3_, arg4_);
- }
- private:
- const A1 arg1_;
- const A2 arg2_;
- const A3 arg3_;
- const A4 arg4_;
-};
-
-// Returns a new instance of T using a 5-ary constructor with the given
-// arguments.
-template <typename T, typename A1, typename A2, typename A3, typename A4,
- typename A5>
-class ReturnNewAction5 {
- public:
- ReturnNewAction5(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : arg1_(a1), arg2_(a2),
- arg3_(a3), arg4_(a4), arg5_(a5) {}
-
- template <typename Result, typename ArgumentTuple>
- Result Perform(const ArgumentTuple& /* args */) {
- return new T(arg1_, arg2_, arg3_, arg4_, arg5_);
- }
- private:
- const A1 arg1_;
- const A2 arg2_;
- const A3 arg3_;
- const A4 arg4_;
- const A5 arg5_;
-};
-
-// Returns a new instance of T using a 6-ary constructor with the given
-// arguments.
-template <typename T, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6>
-class ReturnNewAction6 {
- public:
- ReturnNewAction6(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : arg1_(a1),
- arg2_(a2), arg3_(a3), arg4_(a4), arg5_(a5), arg6_(a6) {}
-
- template <typename Result, typename ArgumentTuple>
- Result Perform(const ArgumentTuple& /* args */) {
- return new T(arg1_, arg2_, arg3_, arg4_, arg5_, arg6_);
- }
- private:
- const A1 arg1_;
- const A2 arg2_;
- const A3 arg3_;
- const A4 arg4_;
- const A5 arg5_;
- const A6 arg6_;
-};
-
-// Returns a new instance of T using a 7-ary constructor with the given
-// arguments.
-template <typename T, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6, typename A7>
-class ReturnNewAction7 {
- public:
- ReturnNewAction7(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6,
- A7 a7) : arg1_(a1), arg2_(a2), arg3_(a3), arg4_(a4), arg5_(a5),
- arg6_(a6), arg7_(a7) {}
+ACTION_TEMPLATE(InvokeArgument,
+ HAS_1_TEMPLATE_PARAMS(int, k),
+ AND_1_VALUE_PARAMS(p0)) {
+ return internal::CallableHelper<return_type>::Call(
+ ::std::tr1::get<k>(args), p0);
+}
- template <typename Result, typename ArgumentTuple>
- Result Perform(const ArgumentTuple& /* args */) {
- return new T(arg1_, arg2_, arg3_, arg4_, arg5_, arg6_, arg7_);
- }
- private:
- const A1 arg1_;
- const A2 arg2_;
- const A3 arg3_;
- const A4 arg4_;
- const A5 arg5_;
- const A6 arg6_;
- const A7 arg7_;
-};
+ACTION_TEMPLATE(InvokeArgument,
+ HAS_1_TEMPLATE_PARAMS(int, k),
+ AND_2_VALUE_PARAMS(p0, p1)) {
+ return internal::CallableHelper<return_type>::Call(
+ ::std::tr1::get<k>(args), p0, p1);
+}
-// Returns a new instance of T using a 8-ary constructor with the given
-// arguments.
-template <typename T, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6, typename A7, typename A8>
-class ReturnNewAction8 {
- public:
- ReturnNewAction8(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7,
- A8 a8) : arg1_(a1), arg2_(a2), arg3_(a3), arg4_(a4), arg5_(a5),
- arg6_(a6), arg7_(a7), arg8_(a8) {}
+ACTION_TEMPLATE(InvokeArgument,
+ HAS_1_TEMPLATE_PARAMS(int, k),
+ AND_3_VALUE_PARAMS(p0, p1, p2)) {
+ return internal::CallableHelper<return_type>::Call(
+ ::std::tr1::get<k>(args), p0, p1, p2);
+}
- template <typename Result, typename ArgumentTuple>
- Result Perform(const ArgumentTuple& /* args */) {
- return new T(arg1_, arg2_, arg3_, arg4_, arg5_, arg6_, arg7_, arg8_);
- }
- private:
- const A1 arg1_;
- const A2 arg2_;
- const A3 arg3_;
- const A4 arg4_;
- const A5 arg5_;
- const A6 arg6_;
- const A7 arg7_;
- const A8 arg8_;
-};
+ACTION_TEMPLATE(InvokeArgument,
+ HAS_1_TEMPLATE_PARAMS(int, k),
+ AND_4_VALUE_PARAMS(p0, p1, p2, p3)) {
+ return internal::CallableHelper<return_type>::Call(
+ ::std::tr1::get<k>(args), p0, p1, p2, p3);
+}
-// Returns a new instance of T using a 9-ary constructor with the given
-// arguments.
-template <typename T, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6, typename A7, typename A8, typename A9>
-class ReturnNewAction9 {
- public:
- ReturnNewAction9(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8,
- A9 a9) : arg1_(a1), arg2_(a2), arg3_(a3), arg4_(a4), arg5_(a5),
- arg6_(a6), arg7_(a7), arg8_(a8), arg9_(a9) {}
+ACTION_TEMPLATE(InvokeArgument,
+ HAS_1_TEMPLATE_PARAMS(int, k),
+ AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)) {
+ return internal::CallableHelper<return_type>::Call(
+ ::std::tr1::get<k>(args), p0, p1, p2, p3, p4);
+}
- template <typename Result, typename ArgumentTuple>
- Result Perform(const ArgumentTuple& /* args */) {
- return new T(arg1_, arg2_, arg3_, arg4_, arg5_, arg6_, arg7_, arg8_, arg9_);
- }
- private:
- const A1 arg1_;
- const A2 arg2_;
- const A3 arg3_;
- const A4 arg4_;
- const A5 arg5_;
- const A6 arg6_;
- const A7 arg7_;
- const A8 arg8_;
- const A9 arg9_;
-};
+ACTION_TEMPLATE(InvokeArgument,
+ HAS_1_TEMPLATE_PARAMS(int, k),
+ AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)) {
+ return internal::CallableHelper<return_type>::Call(
+ ::std::tr1::get<k>(args), p0, p1, p2, p3, p4, p5);
+}
-// Returns a new instance of T using a 10-ary constructor with the given
-// arguments.
-template <typename T, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6, typename A7, typename A8, typename A9,
- typename A10>
-class ReturnNewAction10 {
- public:
- ReturnNewAction10(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8,
- A9 a9, A10 a10) : arg1_(a1), arg2_(a2), arg3_(a3), arg4_(a4), arg5_(a5),
- arg6_(a6), arg7_(a7), arg8_(a8), arg9_(a9), arg10_(a10) {}
+ACTION_TEMPLATE(InvokeArgument,
+ HAS_1_TEMPLATE_PARAMS(int, k),
+ AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)) {
+ return internal::CallableHelper<return_type>::Call(
+ ::std::tr1::get<k>(args), p0, p1, p2, p3, p4, p5, p6);
+}
- template <typename Result, typename ArgumentTuple>
- Result Perform(const ArgumentTuple& /* args */) {
- return new T(arg1_, arg2_, arg3_, arg4_, arg5_, arg6_, arg7_, arg8_, arg9_,
- arg10_);
- }
- private:
- const A1 arg1_;
- const A2 arg2_;
- const A3 arg3_;
- const A4 arg4_;
- const A5 arg5_;
- const A6 arg6_;
- const A7 arg7_;
- const A8 arg8_;
- const A9 arg9_;
- const A10 arg10_;
-};
+ACTION_TEMPLATE(InvokeArgument,
+ HAS_1_TEMPLATE_PARAMS(int, k),
+ AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7)) {
+ return internal::CallableHelper<return_type>::Call(
+ ::std::tr1::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7);
+}
-// Deletes the object pointed to by argument #0.
-ACTION(DeleteArg0) { delete arg0; }
+ACTION_TEMPLATE(InvokeArgument,
+ HAS_1_TEMPLATE_PARAMS(int, k),
+ AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, p8)) {
+ return internal::CallableHelper<return_type>::Call(
+ ::std::tr1::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7, p8);
+}
-} // namespace internal
+ACTION_TEMPLATE(InvokeArgument,
+ HAS_1_TEMPLATE_PARAMS(int, k),
+ AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)) {
+ return internal::CallableHelper<return_type>::Call(
+ ::std::tr1::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
+}
// Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the
// mock function to *pointer.
-template <int k, typename Pointer>
-inline internal::WithArgsAction<internal::SaveArg0ActionP<Pointer>, k>
-SaveArg(const Pointer& pointer) {
- return WithArg<k>(internal::SaveArg0(pointer));
+ACTION_TEMPLATE(SaveArg,
+ HAS_1_TEMPLATE_PARAMS(int, k),
+ AND_1_VALUE_PARAMS(pointer)) {
+ *pointer = ::std::tr1::get<k>(args);
}
// Action SetArgReferee<k>(value) assigns 'value' to the variable
// referenced by the k-th (0-based) argument of the mock function.
-template <int k, typename Value>
-inline internal::WithArgsAction<internal::SetArg0RefereeActionP<Value>, k>
-SetArgReferee(const Value& value) {
- return WithArg<k>(internal::SetArg0Referee(value));
+ACTION_TEMPLATE(SetArgReferee,
+ HAS_1_TEMPLATE_PARAMS(int, k),
+ AND_1_VALUE_PARAMS(value)) {
+ typedef typename ::std::tr1::tuple_element<k, args_type>::type argk_type;
+ // Ensures that argument #k is a reference. If you get a compiler
+ // error on the next line, you are using SetArgReferee<k>(value) in
+ // a mock function whose k-th (0-based) argument is not a reference.
+ GMOCK_COMPILE_ASSERT_(internal::is_reference<argk_type>::value,
+ SetArgReferee_must_be_used_with_a_reference_argument);
+ ::std::tr1::get<k>(args) = value;
+}
+
+// Action SetArrayArgument<k>(first, last) copies the elements in
+// source range [first, last) to the array pointed to by the k-th
+// (0-based) argument, which can be either a pointer or an
+// iterator. The action does not take ownership of the elements in the
+// source range.
+ACTION_TEMPLATE(SetArrayArgument,
+ HAS_1_TEMPLATE_PARAMS(int, k),
+ AND_2_VALUE_PARAMS(first, last)) {
+ // Microsoft compiler deprecates ::std::copy, so we want to suppress warning
+ // 4996 (Function call with parameters that may be unsafe) there.
+#ifdef _MSC_VER
+#pragma warning(push) // Saves the current warning state.
+#pragma warning(disable:4996) // Temporarily disables warning 4996.
+#endif
+ ::std::copy(first, last, ::std::tr1::get<k>(args));
+#ifdef _MSC_VER
+#pragma warning(pop) // Restores the warning state.
+#endif
}
// Various overloads for ReturnNew<T>().
@@ -2987,106 +2477,78 @@ SetArgReferee(const Value& value) {
// The ReturnNew<T>(a1, a2, ..., a_k) action returns a pointer to a new
// instance of type T, constructed on the heap with constructor arguments
// a1, a2, ..., and a_k. The caller assumes ownership of the returned value.
-template <typename T>
-inline PolymorphicAction<internal::ReturnNewAction0<T> >
-ReturnNew() {
- return MakePolymorphicAction(
- internal::ReturnNewAction0<T>());
+ACTION_TEMPLATE(ReturnNew,
+ HAS_1_TEMPLATE_PARAMS(typename, T),
+ AND_0_VALUE_PARAMS()) {
+ return new T();
}
-template <typename T, typename A1>
-inline PolymorphicAction<internal::ReturnNewAction1<T, A1> >
-ReturnNew(A1 a1) {
- return MakePolymorphicAction(
- internal::ReturnNewAction1<T, A1>(a1));
+ACTION_TEMPLATE(ReturnNew,
+ HAS_1_TEMPLATE_PARAMS(typename, T),
+ AND_1_VALUE_PARAMS(p0)) {
+ return new T(p0);
}
-template <typename T, typename A1, typename A2>
-inline PolymorphicAction<internal::ReturnNewAction2<T, A1, A2> >
-ReturnNew(A1 a1, A2 a2) {
- return MakePolymorphicAction(
- internal::ReturnNewAction2<T, A1, A2>(a1, a2));
+ACTION_TEMPLATE(ReturnNew,
+ HAS_1_TEMPLATE_PARAMS(typename, T),
+ AND_2_VALUE_PARAMS(p0, p1)) {
+ return new T(p0, p1);
}
-template <typename T, typename A1, typename A2, typename A3>
-inline PolymorphicAction<internal::ReturnNewAction3<T, A1, A2, A3> >
-ReturnNew(A1 a1, A2 a2, A3 a3) {
- return MakePolymorphicAction(
- internal::ReturnNewAction3<T, A1, A2, A3>(a1, a2, a3));
+ACTION_TEMPLATE(ReturnNew,
+ HAS_1_TEMPLATE_PARAMS(typename, T),
+ AND_3_VALUE_PARAMS(p0, p1, p2)) {
+ return new T(p0, p1, p2);
}
-template <typename T, typename A1, typename A2, typename A3, typename A4>
-inline PolymorphicAction<internal::ReturnNewAction4<T, A1, A2, A3, A4> >
-ReturnNew(A1 a1, A2 a2, A3 a3, A4 a4) {
- return MakePolymorphicAction(
- internal::ReturnNewAction4<T, A1, A2, A3, A4>(a1, a2, a3, a4));
+ACTION_TEMPLATE(ReturnNew,
+ HAS_1_TEMPLATE_PARAMS(typename, T),
+ AND_4_VALUE_PARAMS(p0, p1, p2, p3)) {
+ return new T(p0, p1, p2, p3);
}
-template <typename T, typename A1, typename A2, typename A3, typename A4,
- typename A5>
-inline PolymorphicAction<internal::ReturnNewAction5<T, A1, A2, A3, A4, A5> >
-ReturnNew(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {
- return MakePolymorphicAction(
- internal::ReturnNewAction5<T, A1, A2, A3, A4, A5>(a1, a2, a3, a4, a5));
+ACTION_TEMPLATE(ReturnNew,
+ HAS_1_TEMPLATE_PARAMS(typename, T),
+ AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)) {
+ return new T(p0, p1, p2, p3, p4);
}
-template <typename T, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6>
-inline PolymorphicAction<internal::ReturnNewAction6<T, A1, A2, A3, A4, A5, A6> >
-ReturnNew(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) {
- return MakePolymorphicAction(
- internal::ReturnNewAction6<T, A1, A2, A3, A4, A5, A6>(a1, a2, a3, a4, a5,
- a6));
+ACTION_TEMPLATE(ReturnNew,
+ HAS_1_TEMPLATE_PARAMS(typename, T),
+ AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)) {
+ return new T(p0, p1, p2, p3, p4, p5);
}
-template <typename T, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6, typename A7>
-inline PolymorphicAction<internal::ReturnNewAction7<T, A1, A2, A3, A4, A5, A6,
- A7> >
-ReturnNew(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) {
- return MakePolymorphicAction(
- internal::ReturnNewAction7<T, A1, A2, A3, A4, A5, A6, A7>(a1, a2, a3, a4,
- a5, a6, a7));
+ACTION_TEMPLATE(ReturnNew,
+ HAS_1_TEMPLATE_PARAMS(typename, T),
+ AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)) {
+ return new T(p0, p1, p2, p3, p4, p5, p6);
}
-template <typename T, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6, typename A7, typename A8>
-inline PolymorphicAction<internal::ReturnNewAction8<T, A1, A2, A3, A4, A5, A6,
- A7, A8> >
-ReturnNew(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) {
- return MakePolymorphicAction(
- internal::ReturnNewAction8<T, A1, A2, A3, A4, A5, A6, A7, A8>(a1, a2, a3,
- a4, a5, a6, a7, a8));
+ACTION_TEMPLATE(ReturnNew,
+ HAS_1_TEMPLATE_PARAMS(typename, T),
+ AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7)) {
+ return new T(p0, p1, p2, p3, p4, p5, p6, p7);
}
-template <typename T, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6, typename A7, typename A8, typename A9>
-inline PolymorphicAction<internal::ReturnNewAction9<T, A1, A2, A3, A4, A5, A6,
- A7, A8, A9> >
-ReturnNew(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) {
- return MakePolymorphicAction(
- internal::ReturnNewAction9<T, A1, A2, A3, A4, A5, A6, A7, A8, A9>(a1, a2,
- a3, a4, a5, a6, a7, a8, a9));
+ACTION_TEMPLATE(ReturnNew,
+ HAS_1_TEMPLATE_PARAMS(typename, T),
+ AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, p8)) {
+ return new T(p0, p1, p2, p3, p4, p5, p6, p7, p8);
}
-template <typename T, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6, typename A7, typename A8, typename A9,
- typename A10>
-inline PolymorphicAction<internal::ReturnNewAction10<T, A1, A2, A3, A4, A5, A6,
- A7, A8, A9, A10> >
-ReturnNew(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9,
- A10 a10) {
- return MakePolymorphicAction(
- internal::ReturnNewAction10<T, A1, A2, A3, A4, A5, A6, A7, A8, A9,
- A10>(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10));
+ACTION_TEMPLATE(ReturnNew,
+ HAS_1_TEMPLATE_PARAMS(typename, T),
+ AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)) {
+ return new T(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
}
// Action DeleteArg<k>() deletes the k-th (0-based) argument of the mock
// function.
-template <int k>
-inline internal::WithArgsAction<internal::DeleteArg0Action, k>
-DeleteArg() {
- return WithArg<k>(internal::DeleteArg0());
+ACTION_TEMPLATE(DeleteArg,
+ HAS_1_TEMPLATE_PARAMS(int, k),
+ AND_0_VALUE_PARAMS()) {
+ delete ::std::tr1::get<k>(args);
}
// Action Throw(exception) can be used in a mock function of any type
diff --git a/include/gmock/gmock-generated-actions.h.pump b/include/gmock/gmock-generated-actions.h.pump
index 39f80804..b5223a34 100644
--- a/include/gmock/gmock-generated-actions.h.pump
+++ b/include/gmock/gmock-generated-actions.h.pump
@@ -198,77 +198,6 @@ $var Ts = [[$for j, [[T$j]]]]
}; // class CallableHelper
-// Invokes a nullary callable argument.
-template <size_t N>
-class InvokeArgumentAction0 {
- public:
- template <typename Result, typename ArgumentTuple>
- static Result Perform(const ArgumentTuple& args) {
- return CallableHelper<Result>::Call(::std::tr1::get<N>(args));
- }
-};
-
-// Invokes a unary callable argument with the given argument.
-template <size_t N, typename A1>
-class InvokeArgumentAction1 {
- public:
- // We deliberately pass a1 by value instead of const reference here
- // in case it is a C-string literal.
- //
- // Since this function is defined inline, the compiler can get rid
- // of the copying of the arguments. Therefore the performance won't
- // be hurt.
- explicit InvokeArgumentAction1(A1 a1) : arg1_(a1) {}
-
- template <typename Result, typename ArgumentTuple>
- Result Perform(const ArgumentTuple& args) {
- return CallableHelper<Result>::Call(::std::tr1::get<N>(args), arg1_);
- }
- private:
- const A1 arg1_;
-};
-
-$range i 2..n
-$for i [[
-$var arity = [[$if i==2 [[binary]] $elif i==3 [[ternary]] $else [[$i-ary]]]]
-$range j 1..i
-$var typename_As = [[$for j, [[typename A$j]]]]
-$var args_ = [[$for j, [[arg$j[[]]_]]]]
-
-// Invokes a $arity callable argument with the given arguments.
-template <size_t N, $typename_As>
-class InvokeArgumentAction$i {
- public:
- InvokeArgumentAction$i($for j, [[A$j a$j]]) :
- $for j, [[arg$j[[]]_(a$j)]] {}
-
- template <typename Result, typename ArgumentTuple>
- Result Perform(const ArgumentTuple& args) {
-$if i <= 4 [[
-
- return CallableHelper<Result>::Call(::std::tr1::get<N>(args), $args_);
-
-]] $else [[
-
- // We extract the callable to a variable before invoking it, in
- // case it is a functor passed by value and its operator() is not
- // const.
- typename ::std::tr1::tuple_element<N, ArgumentTuple>::type function =
- ::std::tr1::get<N>(args);
- return function($args_);
-
-]]
- }
- private:
-$for j [[
-
- const A$j arg$j[[]]_;
-]]
-
-};
-
-]]
-
// An INTERNAL macro for extracting the type of a tuple field. It's
// subject to change without notice - DO NOT USE IN USER CODE!
#define GMOCK_FIELD_(Tuple, N) \
@@ -478,74 +407,6 @@ inline internal::ReferenceWrapper<T> ByRef(T& l_value) { // NOLINT
return internal::ReferenceWrapper<T>(l_value);
}
-// Various overloads for InvokeArgument<N>().
-//
-// The InvokeArgument<N>(a1, a2, ..., a_k) action invokes the N-th
-// (0-based) argument, which must be a k-ary callable, of the mock
-// function, with arguments a1, a2, ..., a_k.
-//
-// Notes:
-//
-// 1. The arguments are passed by value by default. If you need to
-// pass an argument by reference, wrap it inside ByRef(). For
-// example,
-//
-// InvokeArgument<1>(5, string("Hello"), ByRef(foo))
-//
-// passes 5 and string("Hello") by value, and passes foo by
-// reference.
-//
-// 2. If the callable takes an argument by reference but ByRef() is
-// not used, it will receive the reference to a copy of the value,
-// instead of the original value. For example, when the 0-th
-// argument of the mock function takes a const string&, the action
-//
-// InvokeArgument<0>(string("Hello"))
-//
-// makes a copy of the temporary string("Hello") object and passes a
-// reference of the copy, instead of the original temporary object,
-// to the callable. This makes it easy for a user to define an
-// InvokeArgument action from temporary values and have it performed
-// later.
-template <size_t N>
-inline PolymorphicAction<internal::InvokeArgumentAction0<N> > InvokeArgument() {
- return MakePolymorphicAction(internal::InvokeArgumentAction0<N>());
-}
-
-// We deliberately pass a1 by value instead of const reference here in
-// case it is a C-string literal. If we had declared the parameter as
-// 'const A1& a1' and write InvokeArgument<0>("Hi"), the compiler
-// would've thought A1 is 'char[3]', which causes trouble as the
-// implementation needs to copy a value of type A1. By declaring the
-// parameter as 'A1 a1', the compiler will correctly infer that A1 is
-// 'const char*' when it sees InvokeArgument<0>("Hi").
-//
-// Since this function is defined inline, the compiler can get rid of
-// the copying of the arguments. Therefore the performance won't be
-// hurt.
-template <size_t N, typename A1>
-inline PolymorphicAction<internal::InvokeArgumentAction1<N, A1> >
-InvokeArgument(A1 a1) {
- return MakePolymorphicAction(internal::InvokeArgumentAction1<N, A1>(a1));
-}
-
-$range i 2..n
-$for i [[
-$range j 1..i
-$var typename_As = [[$for j, [[typename A$j]]]]
-$var As = [[$for j, [[A$j]]]]
-$var Aas = [[$for j, [[A$j a$j]]]]
-$var as = [[$for j, [[a$j]]]]
-
-template <size_t N, $typename_As>
-inline PolymorphicAction<internal::InvokeArgumentAction$i<N, $As> >
-InvokeArgument($Aas) {
- return MakePolymorphicAction(
- internal::InvokeArgumentAction$i<N, $As>($as));
-}
-
-]]
-
// WithoutArgs(inner_action) can be used in a mock function with a
// non-empty argument list to perform inner_action, which takes no
// argument. In other words, it adapts an action accepting no
@@ -1025,76 +886,89 @@ $$ // show up in the generated code.
// updated.
namespace testing {
-namespace internal {
-
-// Saves argument #0 to where the pointer points.
-ACTION_P(SaveArg0, pointer) { *pointer = arg0; }
-
-// Assigns 'value' to the variable referenced by argument #0.
-ACTION_P(SetArg0Referee, value) {
- // Ensures that argument #0 is a reference. If you get a compiler
- // error on the next line, you are using SetArgReferee<k>(value) in
- // a mock function whose k-th (0-based) argument is not a reference.
- GMOCK_COMPILE_ASSERT_(internal::is_reference<arg0_type>::value,
- SetArgReferee_must_be_used_with_a_reference_argument);
- arg0 = value;
-}
+// Various overloads for InvokeArgument<N>().
+//
+// The InvokeArgument<N>(a1, a2, ..., a_k) action invokes the N-th
+// (0-based) argument, which must be a k-ary callable, of the mock
+// function, with arguments a1, a2, ..., a_k.
+//
+// Notes:
+//
+// 1. The arguments are passed by value by default. If you need to
+// pass an argument by reference, wrap it inside ByRef(). For
+// example,
+//
+// InvokeArgument<1>(5, string("Hello"), ByRef(foo))
+//
+// passes 5 and string("Hello") by value, and passes foo by
+// reference.
+//
+// 2. If the callable takes an argument by reference but ByRef() is
+// not used, it will receive the reference to a copy of the value,
+// instead of the original value. For example, when the 0-th
+// argument of the mock function takes a const string&, the action
+//
+// InvokeArgument<0>(string("Hello"))
+//
+// makes a copy of the temporary string("Hello") object and passes a
+// reference of the copy, instead of the original temporary object,
+// to the callable. This makes it easy for a user to define an
+// InvokeArgument action from temporary values and have it performed
+// later.
-// ReturnNewAction<T> creates and returns a new instance of an object each time
-// it is performed. It is overloaded to work with constructors that take
-// different numbers of arguments.
$range i 0..n
$for i [[
-$var arity = [[ $if i==0 [[nullary]]
- $elif i==1 [[unary]]
- $elif i==2 [[binary]]
- $elif i==3 [[ternary]]
- $else [[$i-ary]]]]
-$range j 1..i
-$var typename_As = [[$for j [[, typename A$j]]]]
-$var args_ = [[$for j, [[arg$j[[]]_]]]]
-
-// Returns a new instance of T using a $arity constructor with the given
-// arguments.
-template <typename T$typename_As>
-class ReturnNewAction$i {
- public:
- $if i==1 [[explicit ]]ReturnNewAction$i($for j, [[A$j a$j]])$if i>0 [[ : ]]
-$for j, [[arg$j[[]]_(a$j)]] {}
-
- template <typename Result, typename ArgumentTuple>
- Result Perform(const ArgumentTuple& /* args */) {
- return new T($args_);
- }
- private:
-$for j [[
-
- const A$j arg$j[[]]_;
-]]
+$range j 0..i-1
-};
+ACTION_TEMPLATE(InvokeArgument,
+ HAS_1_TEMPLATE_PARAMS(int, k),
+ AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])) {
+ return internal::CallableHelper<return_type>::Call(
+ ::std::tr1::get<k>(args)$for j [[, p$j]]);
+}
]]
-// Deletes the object pointed to by argument #0.
-ACTION(DeleteArg0) { delete arg0; }
-
-} // namespace internal
-
// Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the
// mock function to *pointer.
-template <int k, typename Pointer>
-inline internal::WithArgsAction<internal::SaveArg0ActionP<Pointer>, k>
-SaveArg(const Pointer& pointer) {
- return WithArg<k>(internal::SaveArg0(pointer));
+ACTION_TEMPLATE(SaveArg,
+ HAS_1_TEMPLATE_PARAMS(int, k),
+ AND_1_VALUE_PARAMS(pointer)) {
+ *pointer = ::std::tr1::get<k>(args);
}
// Action SetArgReferee<k>(value) assigns 'value' to the variable
// referenced by the k-th (0-based) argument of the mock function.
-template <int k, typename Value>
-inline internal::WithArgsAction<internal::SetArg0RefereeActionP<Value>, k>
-SetArgReferee(const Value& value) {
- return WithArg<k>(internal::SetArg0Referee(value));
+ACTION_TEMPLATE(SetArgReferee,
+ HAS_1_TEMPLATE_PARAMS(int, k),
+ AND_1_VALUE_PARAMS(value)) {
+ typedef typename ::std::tr1::tuple_element<k, args_type>::type argk_type;
+ // Ensures that argument #k is a reference. If you get a compiler
+ // error on the next line, you are using SetArgReferee<k>(value) in
+ // a mock function whose k-th (0-based) argument is not a reference.
+ GMOCK_COMPILE_ASSERT_(internal::is_reference<argk_type>::value,
+ SetArgReferee_must_be_used_with_a_reference_argument);
+ ::std::tr1::get<k>(args) = value;
+}
+
+// Action SetArrayArgument<k>(first, last) copies the elements in
+// source range [first, last) to the array pointed to by the k-th
+// (0-based) argument, which can be either a pointer or an
+// iterator. The action does not take ownership of the elements in the
+// source range.
+ACTION_TEMPLATE(SetArrayArgument,
+ HAS_1_TEMPLATE_PARAMS(int, k),
+ AND_2_VALUE_PARAMS(first, last)) {
+ // Microsoft compiler deprecates ::std::copy, so we want to suppress warning
+ // 4996 (Function call with parameters that may be unsafe) there.
+#ifdef _MSC_VER
+#pragma warning(push) // Saves the current warning state.
+#pragma warning(disable:4996) // Temporarily disables warning 4996.
+#endif
+ ::std::copy(first, last, ::std::tr1::get<k>(args));
+#ifdef _MSC_VER
+#pragma warning(pop) // Restores the warning state.
+#endif
}
// Various overloads for ReturnNew<T>().
@@ -1104,27 +978,23 @@ SetArgReferee(const Value& value) {
// a1, a2, ..., and a_k. The caller assumes ownership of the returned value.
$range i 0..n
$for i [[
-$range j 1..i
-$var typename_As = [[$for j [[, typename A$j]]]]
-$var As = [[$for j [[, A$j]]]]
-$var Aas = [[$for j, [[A$j a$j]]]]
-$var as = [[$for j, [[a$j]]]]
+$range j 0..i-1
+$var ps = [[$for j, [[p$j]]]]
-template <typename T$typename_As>
-inline PolymorphicAction<internal::ReturnNewAction$i<T$As> >
-ReturnNew($Aas) {
- return MakePolymorphicAction(
- internal::ReturnNewAction$i<T$As>($as));
+ACTION_TEMPLATE(ReturnNew,
+ HAS_1_TEMPLATE_PARAMS(typename, T),
+ AND_$i[[]]_VALUE_PARAMS($ps)) {
+ return new T($ps);
}
]]
// Action DeleteArg<k>() deletes the k-th (0-based) argument of the mock
// function.
-template <int k>
-inline internal::WithArgsAction<internal::DeleteArg0Action, k>
-DeleteArg() {
- return WithArg<k>(internal::DeleteArg0());
+ACTION_TEMPLATE(DeleteArg,
+ HAS_1_TEMPLATE_PARAMS(int, k),
+ AND_0_VALUE_PARAMS()) {
+ delete ::std::tr1::get<k>(args);
}
// Action Throw(exception) can be used in a mock function of any type
diff --git a/include/gmock/gmock-matchers.h b/include/gmock/gmock-matchers.h
index bf049d45..0497be27 100644
--- a/include/gmock/gmock-matchers.h
+++ b/include/gmock/gmock-matchers.h
@@ -39,6 +39,7 @@
#define GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
#include <algorithm>
+#include <limits>
#include <ostream> // NOLINT
#include <sstream>
#include <string>
@@ -340,6 +341,16 @@ Matcher<T> SafeMatcherCast(const Matcher<U>& matcher) {
GMOCK_COMPILE_ASSERT_(
internal::is_reference<T>::value || !internal::is_reference<U>::value,
cannot_convert_non_referentce_arg_to_reference);
+ // In case both T and U are arithmetic types, enforce that the
+ // conversion is not lossy.
+ typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(T)) RawT;
+ typedef GMOCK_REMOVE_CONST_(GMOCK_REMOVE_REFERENCE_(U)) RawU;
+ const bool kTIsOther = GMOCK_KIND_OF_(RawT) == internal::kOther;
+ const bool kUIsOther = GMOCK_KIND_OF_(RawU) == internal::kOther;
+ GMOCK_COMPILE_ASSERT_(
+ kTIsOther || kUIsOther ||
+ (internal::LosslessArithmeticConvertible<RawT, RawU>::value),
+ conversion_of_arithmetic_types_must_be_lossless);
return MatcherCast<T>(matcher);
}
@@ -1164,8 +1175,8 @@ class EitherOfMatcher {
// both Matcher1 and Matcher2 can match.
template <typename T>
operator Matcher<T>() const {
- return Matcher<T>(new EitherOfMatcherImpl<T>(SafeMatcherCast<T>(matcher1_),
- SafeMatcherCast<T>(matcher2_)));
+ return Matcher<T>(new EitherOfMatcherImpl<T>(
+ SafeMatcherCast<T>(matcher1_), SafeMatcherCast<T>(matcher2_)));
}
private:
Matcher1 matcher1_;
@@ -1184,7 +1195,7 @@ class TrulyMatcher {
// argument is passed by reference as the predicate may be
// interested in the address of the argument.
template <typename T>
- bool Matches(T& x) const {
+ bool Matches(T& x) const { // NOLINT
#if GTEST_OS_WINDOWS
// MSVC warns about converting a value into bool (warning 4800).
#pragma warning(push) // Saves the current warning state.
diff --git a/include/gmock/gmock-printers.h b/include/gmock/gmock-printers.h
index 6997a6c1..99002434 100644
--- a/include/gmock/gmock-printers.h
+++ b/include/gmock/gmock-printers.h
@@ -341,12 +341,11 @@ inline void PrintTo(char* s, ::std::ostream* os) {
PrintTo(implicit_cast<const char*>(s), os);
}
-// MSVC compiler can be configured to define whar_t as a typedef
-// of unsigned short. Defining an overload for const wchar_t* in that case
-// would cause pointers to unsigned shorts be printed as wide strings,
-// possibly accessing more memory than intended and causing invalid
-// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when
-// wchar_t is implemented as a native type.
+// MSVC can be configured to define wchar_t as a typedef of unsigned
+// short. It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native
+// type. When wchar_t is a typedef, defining an overload for const
+// wchar_t* would cause unsigned short* be printed as a wide string,
+// possibly causing invalid memory accesses.
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
// Overloads for wide C strings
void PrintTo(const wchar_t* s, ::std::ostream* os);
diff --git a/include/gmock/gmock-spec-builders.h b/include/gmock/gmock-spec-builders.h
index af2e8ad2..cc48bc0b 100644
--- a/include/gmock/gmock-spec-builders.h
+++ b/include/gmock/gmock-spec-builders.h
@@ -1359,6 +1359,20 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
std::vector<DefaultActionSpec<F> > default_actions_;
// All expectations for this function mocker.
Expectations expectations_;
+
+ // There is no generally useful and implementable semantics of
+ // copying a mock object, so copying a mock is usually a user error.
+ // Thus we disallow copying function mockers. If the user really
+ // wants to copy a mock object, he should implement his own copy
+ // operation, for example:
+ //
+ // class MockFoo : public Foo {
+ // public:
+ // // Defines a copy constructor explicitly.
+ // MockFoo(const MockFoo& src) {}
+ // ...
+ // };
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(FunctionMockerBase);
}; // class FunctionMockerBase
#ifdef _MSC_VER
diff --git a/include/gmock/internal/gmock-internal-utils.h b/include/gmock/internal/gmock-internal-utils.h
index b3d1a1d1..b02682f8 100644
--- a/include/gmock/internal/gmock-internal-utils.h
+++ b/include/gmock/internal/gmock-internal-utils.h
@@ -157,7 +157,7 @@ inline Element* GetRawPointer(Element* p) { return p; }
// This comparator allows linked_ptr to be stored in sets.
template <typename T>
struct LinkedPtrLessThan {
- bool operator()(const ::testing::internal::linked_ptr<T>& lhs,
+ bool operator()(const ::testing::internal::linked_ptr<T>& lhs,
const ::testing::internal::linked_ptr<T>& rhs) const {
return lhs.get() < rhs.get();
}
@@ -210,17 +210,154 @@ class ImplicitlyConvertible {
template <typename From, typename To>
const bool ImplicitlyConvertible<From, To>::value;
+// In what follows, we use the term "kind" to indicate whether a type
+// is bool, an integer type (excluding bool), a floating-point type,
+// or none of them. This categorization is useful for determining
+// when a matcher argument type can be safely converted to another
+// type in the implementation of SafeMatcherCast.
+enum TypeKind {
+ kBool, kInteger, kFloatingPoint, kOther
+};
+
+// KindOf<T>::value is the kind of type T.
+template <typename T> struct KindOf {
+ enum { value = kOther }; // The default kind.
+};
+
+// This macro declares that the kind of 'type' is 'kind'.
+#define GMOCK_DECLARE_KIND_(type, kind) \
+ template <> struct KindOf<type> { enum { value = kind }; }
+
+GMOCK_DECLARE_KIND_(bool, kBool);
+
+// All standard integer types.
+GMOCK_DECLARE_KIND_(char, kInteger);
+GMOCK_DECLARE_KIND_(signed char, kInteger);
+GMOCK_DECLARE_KIND_(unsigned char, kInteger);
+GMOCK_DECLARE_KIND_(short, kInteger); // NOLINT
+GMOCK_DECLARE_KIND_(unsigned short, kInteger); // NOLINT
+GMOCK_DECLARE_KIND_(int, kInteger);
+GMOCK_DECLARE_KIND_(unsigned int, kInteger);
+GMOCK_DECLARE_KIND_(long, kInteger); // NOLINT
+GMOCK_DECLARE_KIND_(unsigned long, kInteger); // NOLINT
+
+// MSVC can be configured to define wchar_t as a typedef of unsigned
+// short. It defines _NATIVE_WCHAR_T_DEFINED symbol when wchar_t is a
+// native type.
+#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
+GMOCK_DECLARE_KIND_(wchar_t, kInteger);
+#endif
+
+// Non-standard integer types.
+GMOCK_DECLARE_KIND_(Int64, kInteger);
+GMOCK_DECLARE_KIND_(UInt64, kInteger);
+
+// All standard floating-point types.
+GMOCK_DECLARE_KIND_(float, kFloatingPoint);
+GMOCK_DECLARE_KIND_(double, kFloatingPoint);
+GMOCK_DECLARE_KIND_(long double, kFloatingPoint);
+
+#undef GMOCK_DECLARE_KIND_
+
+// Evaluates to the kind of 'type'.
+#define GMOCK_KIND_OF_(type) \
+ static_cast< ::testing::internal::TypeKind>( \
+ ::testing::internal::KindOf<type>::value)
+
+// Evaluates to true iff integer type T is signed.
+#define GMOCK_IS_SIGNED_(T) (static_cast<T>(-1) < 0)
+
+// LosslessArithmeticConvertibleImpl<kFromKind, From, kToKind, To>::value
+// is true iff arithmetic type From can be losslessly converted to
+// arithmetic type To.
+//
+// It's the user's responsibility to ensure that both From and To are
+// raw (i.e. has no CV modifier, is not a pointer, and is not a
+// reference) built-in arithmetic types, kFromKind is the kind of
+// From, and kToKind is the kind of To; the value is
+// implementation-defined when the above pre-condition is violated.
+template <TypeKind kFromKind, typename From, TypeKind kToKind, typename To>
+struct LosslessArithmeticConvertibleImpl : public false_type {};
+
+// Converting bool to bool is lossless.
+template <>
+struct LosslessArithmeticConvertibleImpl<kBool, bool, kBool, bool>
+ : public true_type {}; // NOLINT
+
+// Converting bool to any integer type is lossless.
+template <typename To>
+struct LosslessArithmeticConvertibleImpl<kBool, bool, kInteger, To>
+ : public true_type {}; // NOLINT
+
+// Converting bool to any floating-point type is lossless.
+template <typename To>
+struct LosslessArithmeticConvertibleImpl<kBool, bool, kFloatingPoint, To>
+ : public true_type {}; // NOLINT
+
+// Converting an integer to bool is lossy.
+template <typename From>
+struct LosslessArithmeticConvertibleImpl<kInteger, From, kBool, bool>
+ : public false_type {}; // NOLINT
+
+// Converting an integer to another non-bool integer is lossless iff
+// the target type's range encloses the source type's range.
+template <typename From, typename To>
+struct LosslessArithmeticConvertibleImpl<kInteger, From, kInteger, To>
+ : public bool_constant<
+ // When converting from a smaller size to a larger size, we are
+ // fine as long as we are not converting from signed to unsigned.
+ ((sizeof(From) < sizeof(To)) &&
+ (!GMOCK_IS_SIGNED_(From) || GMOCK_IS_SIGNED_(To))) ||
+ // When converting between the same size, the signedness must match.
+ ((sizeof(From) == sizeof(To)) &&
+ (GMOCK_IS_SIGNED_(From) == GMOCK_IS_SIGNED_(To)))> {}; // NOLINT
+
+#undef GMOCK_IS_SIGNED_
+
+// Converting an integer to a floating-point type may be lossy, since
+// the format of a floating-point number is implementation-defined.
+template <typename From, typename To>
+struct LosslessArithmeticConvertibleImpl<kInteger, From, kFloatingPoint, To>
+ : public false_type {}; // NOLINT
+
+// Converting a floating-point to bool is lossy.
+template <typename From>
+struct LosslessArithmeticConvertibleImpl<kFloatingPoint, From, kBool, bool>
+ : public false_type {}; // NOLINT
+
+// Converting a floating-point to an integer is lossy.
+template <typename From, typename To>
+struct LosslessArithmeticConvertibleImpl<kFloatingPoint, From, kInteger, To>
+ : public false_type {}; // NOLINT
+
+// Converting a floating-point to another floating-point is lossless
+// iff the target type is at least as big as the source type.
+template <typename From, typename To>
+struct LosslessArithmeticConvertibleImpl<
+ kFloatingPoint, From, kFloatingPoint, To>
+ : public bool_constant<sizeof(From) <= sizeof(To)> {}; // NOLINT
+
+// LosslessArithmeticConvertible<From, To>::value is true iff arithmetic
+// type From can be losslessly converted to arithmetic type To.
+//
+// It's the user's responsibility to ensure that both From and To are
+// raw (i.e. has no CV modifier, is not a pointer, and is not a
+// reference) built-in arithmetic types; the value is
+// implementation-defined when the above pre-condition is violated.
+template <typename From, typename To>
+struct LosslessArithmeticConvertible
+ : public LosslessArithmeticConvertibleImpl<
+ GMOCK_KIND_OF_(From), From, GMOCK_KIND_OF_(To), To> {}; // NOLINT
+
// IsAProtocolMessage<T>::value is a compile-time bool constant that's
// true iff T is type ProtocolMessage, proto2::Message, or a subclass
// of those.
template <typename T>
-struct IsAProtocolMessage {
- static const bool value =
- ImplicitlyConvertible<const T*, const ::ProtocolMessage*>::value ||
- ImplicitlyConvertible<const T*, const ::proto2::Message*>::value;
+struct IsAProtocolMessage
+ : public bool_constant<
+ ImplicitlyConvertible<const T*, const ::ProtocolMessage*>::value ||
+ ImplicitlyConvertible<const T*, const ::proto2::Message*>::value> {
};
-template <typename T>
-const bool IsAProtocolMessage<T>::value;
// When the compiler sees expression IsContainerTest<C>(0), the first
// overload of IsContainerTest will be picked if C is an STL-style
@@ -314,6 +451,8 @@ void Log(LogSeverity severity, const string& message, int stack_frames_to_skip);
// to declare an unused << operator in the global namespace.
struct Unused {};
+// TODO(wan@google.com): group all type utilities together.
+
// Type traits.
// is_reference<T>::value is non-zero iff T is a reference type.
@@ -325,8 +464,8 @@ template <typename T1, typename T2> struct type_equals : public false_type {};
template <typename T> struct type_equals<T, T> : public true_type {};
// remove_reference<T>::type removes the reference from type T, if any.
-template <typename T> struct remove_reference { typedef T type; };
-template <typename T> struct remove_reference<T&> { typedef T type; };
+template <typename T> struct remove_reference { typedef T type; }; // NOLINT
+template <typename T> struct remove_reference<T&> { typedef T type; }; // NOLINT
// Invalid<T>() returns an invalid value of type T. This is useful
// when a value of type T is needed for compilation, but the statement