diff options
| author | zhanyong.wan <zhanyong.wan@8415998a-534a-0410-bf83-d39667b30386> | 2009-05-14 20:55:30 +0000 | 
|---|---|---|
| committer | zhanyong.wan <zhanyong.wan@8415998a-534a-0410-bf83-d39667b30386> | 2009-05-14 20:55:30 +0000 | 
| commit | 16cf473930c01cd7a1a51dff65f22c541fbad5b8 (patch) | |
| tree | 5d286c8a70d91a0f100523f64ad17d316e8f25f7 /include | |
| parent | c6a412397bc98f120d5e79d4a64e3972854b5af3 (diff) | |
| download | googletest-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.h | 890 | ||||
| -rw-r--r-- | include/gmock/gmock-generated-actions.h.pump | 290 | ||||
| -rw-r--r-- | include/gmock/gmock-matchers.h | 17 | ||||
| -rw-r--r-- | include/gmock/gmock-printers.h | 11 | ||||
| -rw-r--r-- | include/gmock/gmock-spec-builders.h | 14 | ||||
| -rw-r--r-- | include/gmock/internal/gmock-internal-utils.h | 157 | 
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 | 
