diff options
author | Abseil Team <absl-team@google.com> | 2023-11-27 21:31:59 (GMT) |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2023-11-27 21:32:49 (GMT) |
commit | 76bb2afb8b522d24496ad1c757a49784fbfa2e42 (patch) | |
tree | dfc624e5c005a86b9a7680926625b1aaf881cd43 /googlemock/include/gmock | |
parent | b10fad38c4026a29ea6561ab15fc4818170d1c10 (diff) | |
download | googletest-76bb2afb8b522d24496ad1c757a49784fbfa2e42.zip googletest-76bb2afb8b522d24496ad1c757a49784fbfa2e42.tar.gz googletest-76bb2afb8b522d24496ad1c757a49784fbfa2e42.tar.bz2 |
Implement `testing::Rethrow` to throw exceptions more easily via `std::exception_ptr`
We avoid overloading or specializing `testing::Throw` as this is fundamentally a different operation than throwing the object.
However, we disable the corresponding overload of `testing::Throw` to prevent likely mistakes in the usage.
Fixes: #4412
PiperOrigin-RevId: 585745469
Change-Id: I03bb585427ce51983d914e88f2bf65a13545c920
Diffstat (limited to 'googlemock/include/gmock')
-rw-r--r-- | googlemock/include/gmock/gmock-actions.h | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/googlemock/include/gmock/gmock-actions.h b/googlemock/include/gmock/gmock-actions.h index f20258b..fab9993 100644 --- a/googlemock/include/gmock/gmock-actions.h +++ b/googlemock/include/gmock/gmock-actions.h @@ -135,6 +135,7 @@ #endif #include <algorithm> +#include <exception> #include <functional> #include <memory> #include <string> @@ -1746,6 +1747,13 @@ struct ThrowAction { return [copy](Args...) -> R { throw copy; }; } }; +struct RethrowAction { + std::exception_ptr exception; + template <typename R, typename... Args> + operator Action<R(Args...)>() const { // NOLINT + return [ex = exception](Args...) -> R { std::rethrow_exception(ex); }; + } +}; #endif // GTEST_HAS_EXCEPTIONS } // namespace internal @@ -2062,13 +2070,23 @@ internal::ReturnPointeeAction<Ptr> ReturnPointee(Ptr pointer) { return {pointer}; } -// Action Throw(exception) can be used in a mock function of any type -// to throw the given exception. Any copyable value can be thrown. #if GTEST_HAS_EXCEPTIONS +// Action Throw(exception) can be used in a mock function of any type +// to throw the given exception. Any copyable value can be thrown, +// except for std::exception_ptr, which is likely a mistake if +// thrown directly. template <typename T> -internal::ThrowAction<typename std::decay<T>::type> Throw(T&& exception) { +typename std::enable_if< + !std::is_base_of<std::exception_ptr, typename std::decay<T>::type>::value, + internal::ThrowAction<typename std::decay<T>::type>>::type +Throw(T&& exception) { return {std::forward<T>(exception)}; } +// Action Rethrow(exception_ptr) can be used in a mock function of any type +// to rethrow any exception_ptr. Note that the same object is thrown each time. +inline internal::RethrowAction Rethrow(std::exception_ptr exception) { + return {std::move(exception)}; +} #endif // GTEST_HAS_EXCEPTIONS namespace internal { |