Commit f0a9aafc authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by facebook-github-bot-0

Fix ExceptionWrapper::with_exception to support lvalue ref functors

Summary: [Folly] Fix `ExceptionWrapper::with_exception` to support lvalue ref functors.

Ex:

    auto handler = [&](const std::runtime_error& e) { handle_runtime_error(e); };
    exception_wrapper wrap = get_some_exception_wrapper_from_context();
    wrap.with_exception(handler); // broken before this diff, fixed after

Reviewed By: markisaa

Differential Revision: D2698680

fb-gh-sync-id: 4976ba08e3601e22891d00d79a5dae5118887b71
parent 596aa895
...@@ -330,7 +330,9 @@ private: ...@@ -330,7 +330,9 @@ private:
struct impl<R(C::*)(A)> { using arg_type = A; }; struct impl<R(C::*)(A)> { using arg_type = A; };
template <typename C, typename R, typename A> template <typename C, typename R, typename A>
struct impl<R(C::*)(A) const> { using arg_type = A; }; struct impl<R(C::*)(A) const> { using arg_type = A; };
using arg_type = typename impl<decltype(&F::operator())>::arg_type; using functor_decayed = typename std::decay<F>::type;
using functor_op = decltype(&functor_decayed::operator());
using arg_type = typename impl<functor_op>::arg_type;
using arg_type_decayed = typename std::decay<arg_type>::type; using arg_type_decayed = typename std::decay<arg_type>::type;
}; };
......
...@@ -210,14 +210,14 @@ TEST(ExceptionWrapper, with_exception_deduction) { ...@@ -210,14 +210,14 @@ TEST(ExceptionWrapper, with_exception_deduction) {
EXPECT_FALSE(ew.with_exception([](std::logic_error&) {})); EXPECT_FALSE(ew.with_exception([](std::logic_error&) {}));
} }
TEST(ExceptionWrapper, with_exception_deduction_const) { TEST(ExceptionWrapper, with_exception_deduction_exn_const) {
auto ew = make_exception_wrapper<std::runtime_error>("hi"); auto ew = make_exception_wrapper<std::runtime_error>("hi");
EXPECT_TRUE(ew.with_exception([](const std::runtime_error&) {})); EXPECT_TRUE(ew.with_exception([](const std::runtime_error&) {}));
EXPECT_TRUE(ew.with_exception([](const std::exception&) {})); EXPECT_TRUE(ew.with_exception([](const std::exception&) {}));
EXPECT_FALSE(ew.with_exception([](const std::logic_error&) {})); EXPECT_FALSE(ew.with_exception([](const std::logic_error&) {}));
} }
TEST(ExceptionWrapper, with_exception_deduction_const_const) { TEST(ExceptionWrapper, with_exception_deduction_wrap_const_exn_const) {
const auto cew = make_exception_wrapper<std::runtime_error>("hi"); const auto cew = make_exception_wrapper<std::runtime_error>("hi");
EXPECT_TRUE(cew.with_exception([](const std::runtime_error&) {})); EXPECT_TRUE(cew.with_exception([](const std::runtime_error&) {}));
EXPECT_TRUE(cew.with_exception([](const std::exception&) {})); EXPECT_TRUE(cew.with_exception([](const std::exception&) {}));
...@@ -231,6 +231,18 @@ TEST(ExceptionWrapper, with_exception_deduction_returning) { ...@@ -231,6 +231,18 @@ TEST(ExceptionWrapper, with_exception_deduction_returning) {
EXPECT_FALSE(ew.with_exception([](std::logic_error&) { return nullptr; })); EXPECT_FALSE(ew.with_exception([](std::logic_error&) { return nullptr; }));
} }
namespace {
template <typename T>
T& r_to_l(T v) { return std::ref(v); }
}
TEST(ExceptionWrapper, with_exception_deduction_functor_lvalue) {
auto ew = make_exception_wrapper<std::runtime_error>("hi");
EXPECT_TRUE(ew.with_exception(r_to_l([](std::runtime_error&) {})));
EXPECT_TRUE(ew.with_exception(r_to_l([](std::exception&) {})));
EXPECT_FALSE(ew.with_exception(r_to_l([](std::logic_error&) {})));
}
TEST(ExceptionWrapper, non_std_exception_test) { TEST(ExceptionWrapper, non_std_exception_test) {
int expected = 17; int expected = 17;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment