Commit 477a4c23 authored by Eric Niebler's avatar Eric Niebler Committed by Facebook GitHub Bot

exception_wrapper::handle should accommodate noexcept lambdas in C++17

Summary: `exception_wrapper::handle` uses the signature of `Fn::operator()` to pick apart the function type and deduce the exception type for the handler. We use specializations of an `arg_type_` class template to do this. In C++17, `noexcept` is a part of the type system, but there were no specializations of `arg_type_` to handle `noexcept`-qualified callables.

Reviewed By: ispeters

Differential Revision: D24733871

fbshipit-source-id: 344e735e653296c9344b6c09662fccd94953e8a7
parent 11440055
...@@ -59,6 +59,41 @@ struct exception_wrapper::arg_type_<Ret (*)(...)> { ...@@ -59,6 +59,41 @@ struct exception_wrapper::arg_type_<Ret (*)(...)> {
using type = AnyException; using type = AnyException;
}; };
#ifdef FOLLY_HAVE_NOEXCEPT_FUNCTION_TYPE
template <class Ret, class Class, class Arg>
struct exception_wrapper::arg_type_<Ret (Class::*)(Arg) noexcept> {
using type = Arg;
};
template <class Ret, class Class, class Arg>
struct exception_wrapper::arg_type_<Ret (Class::*)(Arg) const noexcept> {
using type = Arg;
};
template <class Ret, class Arg>
struct exception_wrapper::arg_type_<Ret(Arg) noexcept> {
using type = Arg;
};
template <class Ret, class Arg>
struct exception_wrapper::arg_type_<Ret (*)(Arg) noexcept> {
using type = Arg;
};
template <class Ret, class Class>
struct exception_wrapper::arg_type_<Ret (Class::*)(...) noexcept> {
using type = AnyException;
};
template <class Ret, class Class>
struct exception_wrapper::arg_type_<Ret (Class::*)(...) const noexcept> {
using type = AnyException;
};
template <class Ret>
struct exception_wrapper::arg_type_<Ret(...) noexcept> {
using type = AnyException;
};
template <class Ret>
struct exception_wrapper::arg_type_<Ret (*)(...) noexcept> {
using type = AnyException;
};
#endif
template <class Ret, class... Args> template <class Ret, class... Args>
inline Ret exception_wrapper::noop_(Args...) { inline Ret exception_wrapper::noop_(Args...) {
return Ret(); return Ret();
......
...@@ -589,7 +589,7 @@ TEST(ExceptionWrapper, handle_std_exception) { ...@@ -589,7 +589,7 @@ TEST(ExceptionWrapper, handle_std_exception) {
auto expect_runtime_error_yes_catch_all = [&](const exception_wrapper& ew) { auto expect_runtime_error_yes_catch_all = [&](const exception_wrapper& ew) {
ew.handle( ew.handle(
[](const std::logic_error&) { ADD_FAILURE(); }, [](const std::logic_error&) { ADD_FAILURE(); },
[&](const std::runtime_error&) { handled = true; }, [&](const std::runtime_error&) noexcept { handled = true; },
[](const std::exception&) { ADD_FAILURE(); }, [](const std::exception&) { ADD_FAILURE(); },
[](...) { ADD_FAILURE(); }); [](...) { ADD_FAILURE(); });
}; };
...@@ -606,7 +606,7 @@ TEST(ExceptionWrapper, handle_std_exception) { ...@@ -606,7 +606,7 @@ TEST(ExceptionWrapper, handle_std_exception) {
auto expect_runtime_error_no_catch_all = [&](const exception_wrapper& ew) { auto expect_runtime_error_no_catch_all = [&](const exception_wrapper& ew) {
ew.handle( ew.handle(
[](const std::logic_error&) { ADD_FAILURE(); }, [](const std::logic_error&) noexcept { ADD_FAILURE(); },
[&](const std::runtime_error&) { handled = true; }, [&](const std::runtime_error&) { handled = true; },
[](const std::exception&) { ADD_FAILURE(); }); [](const std::exception&) { ADD_FAILURE(); });
}; };
......
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