namespace folly {
template <class Fn>
-struct exception_wrapper::arg_type2_ {};
+struct exception_wrapper::arg_type_
+ : public arg_type_<decltype(&Fn::operator())> {
+};
template <class Ret, class Class, class Arg>
-struct exception_wrapper::arg_type2_<Ret (Class::*)(Arg)> {
+struct exception_wrapper::arg_type_<Ret (Class::*)(Arg)> {
using type = Arg;
};
template <class Ret, class Class, class Arg>
-struct exception_wrapper::arg_type2_<Ret (Class::*)(Arg) const> {
+struct exception_wrapper::arg_type_<Ret (Class::*)(Arg) const> {
+ using type = Arg;
+};
+template <class Ret, class Arg>
+struct exception_wrapper::arg_type_<Ret (Arg)> {
+ using type = Arg;
+};
+template <class Ret, class Arg>
+struct exception_wrapper::arg_type_<Ret (*)(Arg)> {
using type = Arg;
};
template <class Ret, class Class>
-struct exception_wrapper::arg_type2_<Ret (Class::*)(...)> {
+struct exception_wrapper::arg_type_<Ret (Class::*)(...)> {
using type = AnyException;
};
template <class Ret, class Class>
-struct exception_wrapper::arg_type2_<Ret (Class::*)(...) const> {
+struct exception_wrapper::arg_type_<Ret (Class::*)(...) const> {
using type = AnyException;
};
-
-template <class Fn, class>
-struct exception_wrapper::arg_type_ {};
-template <class Fn>
-struct exception_wrapper::arg_type_<Fn, void_t<decltype(&Fn::operator())>>
- : public arg_type2_<decltype(&Fn::operator())> {};
-template <class Ret, class Arg>
-struct exception_wrapper::arg_type_<Ret (*)(Arg)> {
- using type = Arg;
+template <class Ret>
+struct exception_wrapper::arg_type_<Ret (...)> {
+ using type = AnyException;
};
template <class Ret>
struct exception_wrapper::arg_type_<Ret (*)(...)> {
assert(eptr_.ptr_);
}
+namespace exception_wrapper_detail {
+template <class Ex>
+Ex&& dont_slice(Ex&& ex) {
+ assert(typeid(ex) == typeid(_t<std::decay<Ex>>) ||
+ !"Dynamic and static exception types don't match. Exception would "
+ "be sliced when storing in exception_wrapper.");
+ return std::forward<Ex>(ex);
+}
+}
+
template <
class Ex,
class Ex_,
FOLLY_REQUIRES_DEF(
Conjunction<
exception_wrapper::IsStdException<Ex_>,
- exception_wrapper::IsRegularExceptionType<Ex_>>())>
+ exception_wrapper::IsRegularExceptionType<Ex_>>::value)>
inline exception_wrapper::exception_wrapper(Ex&& ex)
- : exception_wrapper{std::forward<Ex>(ex), PlacementOf<Ex_>{}} {
- // Don't slice!!!
- assert(typeid(ex) == typeid(Ex_) ||
- !"Dynamic and static exception types don't match. Exception would "
- "be sliced when storing in exception_wrapper.");
+ : exception_wrapper{
+ exception_wrapper_detail::dont_slice(std::forward<Ex>(ex)),
+ PlacementOf<Ex_>{}} {
}
template <
class Ex,
class Ex_,
FOLLY_REQUIRES_DEF(
- exception_wrapper::IsRegularExceptionType<Ex_>())>
+ exception_wrapper::IsRegularExceptionType<Ex_>::value)>
inline exception_wrapper::exception_wrapper(in_place_t, Ex&& ex)
- : exception_wrapper{std::forward<Ex>(ex), PlacementOf<Ex_>{}} {
- // Don't slice!!!
- assert(typeid(ex) == typeid(Ex_) ||
- !"Dynamic and static exception types don't match. Exception would "
- "be sliced when storing in exception_wrapper.");
+ : exception_wrapper{
+ exception_wrapper_detail::dont_slice(std::forward<Ex>(ex)),
+ PlacementOf<Ex_>{}} {
}
inline void exception_wrapper::swap(exception_wrapper& that) noexcept {
return vptr_->get_exception_(this);
}
+template <typename Ex>
+inline Ex* exception_wrapper::get_object() noexcept {
+ Ex* object{nullptr};
+ with_exception([&](Ex& ex) { object = &ex; });
+ return object;
+}
+
+template <typename Ex>
+inline Ex const* exception_wrapper::get_object() const noexcept {
+ Ex const* object{nullptr};
+ with_exception([&](Ex const& ex) { object = &ex; });
+ return object;
+}
+
inline std::exception_ptr const& exception_wrapper::to_exception_ptr()
noexcept {
// Computing an exception_ptr is expensive so cache the result.
return with_exception([](Ex const&) {});
}
-[[noreturn]] inline void exception_wrapper::throwException() const {
+[[noreturn]] inline void exception_wrapper::throw_exception() const {
vptr_->throw_(this);
onNoExceptionError();
}
bool handled = false;
auto impl = exception_wrapper_detail::fold(
HandleReduce<std::is_const<This>::value>{&handled},
- [&] { this_.throwException(); },
+ [&] { this_.throw_exception(); },
fns...);
impl();
}