diff options
Diffstat (limited to 'googlemock/include/gmock/gmock-actions.h')
-rw-r--r-- | googlemock/include/gmock/gmock-actions.h | 82 |
1 files changed, 67 insertions, 15 deletions
diff --git a/googlemock/include/gmock/gmock-actions.h b/googlemock/include/gmock/gmock-actions.h index e921cf4a..b040004a 100644 --- a/googlemock/include/gmock/gmock-actions.h +++ b/googlemock/include/gmock/gmock-actions.h @@ -99,7 +99,8 @@ struct BuiltInDefaultValueGetter<T, false> { template <typename T> class BuiltInDefaultValue { public: - // This function returns true if type T has a built-in default value. + // This function returns true if and only if type T has a built-in default + // value. static bool Exists() { return ::std::is_default_constructible<T>::value; } @@ -208,7 +209,7 @@ class DefaultValue { producer_ = nullptr; } - // Returns true if the user has set the default value for type T. + // Returns true if and only if the user has set the default value for type T. static bool IsSet() { return producer_ != nullptr; } // Returns true if T has a default return value set by the user or there @@ -269,7 +270,7 @@ class DefaultValue<T&> { // Unsets the default value for type T&. static void Clear() { address_ = nullptr; } - // Returns true if the user has set the default value for type T&. + // Returns true if and only if the user has set the default value for type T&. static bool IsSet() { return address_ != nullptr; } // Returns true if T has a default return value set by the user or there @@ -375,7 +376,7 @@ class Action { template <typename Func> explicit Action(const Action<Func>& action) : fun_(action.fun_) {} - // Returns true if this is the DoDefault() action. + // Returns true if and only if this is the DoDefault() action. bool IsDoDefault() const { return fun_ == nullptr; } // Performs the action. Note that this method is const even though @@ -395,7 +396,7 @@ class Action { template <typename G> friend class Action; - // fun_ is an empty function if this is the DoDefault() action. + // fun_ is an empty function if and only if this is the DoDefault() action. ::std::function<F> fun_; }; @@ -532,7 +533,7 @@ class ReturnAction { // in the Impl class. But both definitions must be the same. typedef typename Function<F>::Result Result; GTEST_COMPILE_ASSERT_( - !is_reference<Result>::value, + !std::is_reference<Result>::value, use_ReturnRef_instead_of_Return_to_return_a_reference); static_assert(!std::is_void<Result>::value, "Can't use Return() on an action expected to return `void`."); @@ -561,7 +562,7 @@ class ReturnAction { Result Perform(const ArgumentTuple&) override { return value_; } private: - GTEST_COMPILE_ASSERT_(!is_reference<Result>::value, + GTEST_COMPILE_ASSERT_(!std::is_reference<Result>::value, Result_cannot_be_a_reference_type); // We save the value before casting just in case it is being cast to a // wrapper type. @@ -619,7 +620,7 @@ class ReturnVoidAction { // Allows Return() to be used in any void-returning function. template <typename Result, typename ArgumentTuple> static void Perform(const ArgumentTuple&) { - CompileAssertTypesEqual<void, Result>(); + static_assert(std::is_void<Result>::value, "Result should be void."); } }; @@ -640,7 +641,7 @@ class ReturnRefAction { // Asserts that the function return type is a reference. This // catches the user error of using ReturnRef(x) when Return(x) // should be used, and generates some helpful error message. - GTEST_COMPILE_ASSERT_(internal::is_reference<Result>::value, + GTEST_COMPILE_ASSERT_(std::is_reference<Result>::value, use_Return_instead_of_ReturnRef_to_return_a_value); return Action<F>(new Impl<F>(ref_)); } @@ -687,7 +688,7 @@ class ReturnRefOfCopyAction { // catches the user error of using ReturnRefOfCopy(x) when Return(x) // should be used, and generates some helpful error message. GTEST_COMPILE_ASSERT_( - internal::is_reference<Result>::value, + std::is_reference<Result>::value, use_Return_instead_of_ReturnRefOfCopy_to_return_a_value); return Action<F>(new Impl<F>(value_)); } @@ -715,6 +716,36 @@ class ReturnRefOfCopyAction { GTEST_DISALLOW_ASSIGN_(ReturnRefOfCopyAction); }; +// Implements the polymorphic ReturnRoundRobin(v) action, which can be +// used in any function that returns the element_type of v. +template <typename T> +class ReturnRoundRobinAction { + public: + explicit ReturnRoundRobinAction(std::vector<T> values) { + GTEST_CHECK_(!values.empty()) + << "ReturnRoundRobin requires at least one element."; + state_->values = std::move(values); + } + + template <typename... Args> + T operator()(Args&&...) const { + return state_->Next(); + } + + private: + struct State { + T Next() { + T ret_val = values[i++]; + if (i == values.size()) i = 0; + return ret_val; + } + + std::vector<T> values; + size_t i = 0; + }; + std::shared_ptr<State> state_ = std::make_shared<State>(); +}; + // Implements the polymorphic DoDefault() action. class DoDefaultAction { public: @@ -842,7 +873,7 @@ class IgnoreResultAction { typedef typename internal::Function<F>::Result Result; // Asserts at compile time that F returns void. - CompileAssertTypesEqual<void, Result>(); + static_assert(std::is_void<Result>::value, "Result type should be void."); return Action<F>(new Impl<F>(action_)); } @@ -1021,6 +1052,10 @@ inline internal::ReturnRefAction<R> ReturnRef(R& x) { // NOLINT return internal::ReturnRefAction<R>(x); } +// Prevent using ReturnRef on reference to temporary. +template <typename R, R* = nullptr> +internal::ReturnRefAction<R> ReturnRef(R&&) = delete; + // Creates an action that returns the reference to a copy of the // argument. The copy is created when the action is constructed and // lives as long as the action. @@ -1038,6 +1073,23 @@ internal::ByMoveWrapper<R> ByMove(R x) { return internal::ByMoveWrapper<R>(std::move(x)); } +// Creates an action that returns an element of `vals`. Calling this action will +// repeatedly return the next value from `vals` until it reaches the end and +// will restart from the beginning. +template <typename T> +internal::ReturnRoundRobinAction<T> ReturnRoundRobin(std::vector<T> vals) { + return internal::ReturnRoundRobinAction<T>(std::move(vals)); +} + +// Creates an action that returns an element of `vals`. Calling this action will +// repeatedly return the next value from `vals` until it reaches the end and +// will restart from the beginning. +template <typename T> +internal::ReturnRoundRobinAction<T> ReturnRoundRobin( + std::initializer_list<T> vals) { + return internal::ReturnRoundRobinAction<T>(std::vector<T>(vals)); +} + // Creates an action that does the default action for the give mock function. inline internal::DoDefaultAction DoDefault() { return internal::DoDefaultAction(); @@ -1046,14 +1098,14 @@ inline internal::DoDefaultAction DoDefault() { // Creates an action that sets the variable pointed by the N-th // (0-based) function argument to 'value'. template <size_t N, typename T> -internal::SetArgumentPointeeAction<N, T> SetArgPointee(T x) { - return {std::move(x)}; +internal::SetArgumentPointeeAction<N, T> SetArgPointee(T value) { + return {std::move(value)}; } // The following version is DEPRECATED. template <size_t N, typename T> -internal::SetArgumentPointeeAction<N, T> SetArgumentPointee(T x) { - return {std::move(x)}; +internal::SetArgumentPointeeAction<N, T> SetArgumentPointee(T value) { + return {std::move(value)}; } // Creates an action that sets a pointer referent to a given value. |