diff options
author | Abseil Team <absl-team@google.com> | 2018-11-15 20:43:19 (GMT) |
---|---|---|
committer | Gennadiy Civil <misterg@google.com> | 2018-11-20 18:29:12 (GMT) |
commit | aac18185ebb4c88d6df5dd4a40d553abf6b9792d (patch) | |
tree | 54be8bf5405dfdaddf29db24821bbbf205ed10d1 /googlemock/include/gmock/gmock-actions.h | |
parent | e46e87bb1f76b17fb50fc98065aa45e2207b94dc (diff) | |
download | googletest-aac18185ebb4c88d6df5dd4a40d553abf6b9792d.zip googletest-aac18185ebb4c88d6df5dd4a40d553abf6b9792d.tar.gz googletest-aac18185ebb4c88d6df5dd4a40d553abf6b9792d.tar.bz2 |
Googletest export
Upgrade WithArgs family of actions to C++11.
PiperOrigin-RevId: 221671690
Diffstat (limited to 'googlemock/include/gmock/gmock-actions.h')
-rw-r--r-- | googlemock/include/gmock/gmock-actions.h | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/googlemock/include/gmock/gmock-actions.h b/googlemock/include/gmock/gmock-actions.h index e4af9d2..37d0d53 100644 --- a/googlemock/include/gmock/gmock-actions.h +++ b/googlemock/include/gmock/gmock-actions.h @@ -1061,6 +1061,24 @@ class DoBothAction { GTEST_DISALLOW_ASSIGN_(DoBothAction); }; +template <typename InnerAction, size_t... I> +struct WithArgsAction { + InnerAction action; + + // The inner action could be anything convertible to Action<X>. + // We use the conversion operator to detect the signature of the inner Action. + template <typename R, typename... Args> + operator Action<R(Args...)>() const { // NOLINT + Action<R(typename std::tuple_element<I, std::tuple<Args...>>::type...)> + converted(action); + + return [converted](Args... args) -> R { + return converted.Perform(std::forward_as_tuple( + std::get<I>(std::forward_as_tuple(std::forward<Args>(args)...))...)); + }; + } +}; + } // namespace internal // An Unused object can be implicitly constructed from ANY value. @@ -1111,6 +1129,37 @@ Action<To>::Action(const Action<From>& from) : new internal::ActionAdaptor<To, From>(from)) { } +// WithArg<k>(an_action) creates an action that passes the k-th +// (0-based) argument of the mock function to an_action and performs +// it. It adapts an action accepting one argument to one that accepts +// multiple arguments. For convenience, we also provide +// WithArgs<k>(an_action) (defined below) as a synonym. +template <size_t k, typename InnerAction> +internal::WithArgsAction<typename std::decay<InnerAction>::type, k> +WithArg(InnerAction&& action) { + return {std::forward<InnerAction>(action)}; +} + +// WithArgs<N1, N2, ..., Nk>(an_action) creates an action that passes +// the selected arguments of the mock function to an_action and +// performs it. It serves as an adaptor between actions with +// different argument lists. +template <size_t k, size_t... ks, typename InnerAction> +internal::WithArgsAction<typename std::decay<InnerAction>::type, k, ks...> +WithArgs(InnerAction&& action) { + return {std::forward<InnerAction>(action)}; +} + +// 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 +// argument to one that accepts (and ignores) arguments. +template <typename InnerAction> +internal::WithArgsAction<typename std::decay<InnerAction>::type> +WithoutArgs(InnerAction&& action) { + return {std::forward<InnerAction>(action)}; +} + // Creates an action that returns 'value'. 'value' is passed by value // instead of const reference - otherwise Return("string literal") // will trigger a compiler error about using array as initializer. |