Commit f4dd104c authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook Github Bot

A smaller implementation of try_and_catch

Summary:
[Folly] A smaller implementation of `try_and_catch`.

No longer done as a derived class. This lets us make the protected members of `exception_wrapper` into private members.

Reviewed By: ericniebler

Differential Revision: D4366065

fbshipit-source-id: ae4763b55e431ac08260f74f6a23a257581247c9
parent 1e039743
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <exception> #include <exception>
#include <memory> #include <memory>
#include <string> #include <string>
#include <tuple>
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
...@@ -105,7 +106,7 @@ namespace folly { ...@@ -105,7 +106,7 @@ namespace folly {
* *
*/ */
class exception_wrapper { class exception_wrapper {
protected: private:
template <typename Ex> template <typename Ex>
struct optimize; struct optimize;
...@@ -269,7 +270,7 @@ class exception_wrapper { ...@@ -269,7 +270,7 @@ class exception_wrapper {
return std::exception_ptr(); return std::exception_ptr();
} }
protected: private:
template <typename Ex> template <typename Ex>
struct optimize { struct optimize {
static const bool value = static const bool value =
...@@ -408,67 +409,43 @@ fbstring exceptionStr(const exception_wrapper& ew); ...@@ -408,67 +409,43 @@ fbstring exceptionStr(const exception_wrapper& ew);
* }); * });
*/ */
namespace detail { namespace try_and_catch_detail {
template <typename... Exceptions>
class try_and_catch;
template <typename LastException, typename... Exceptions>
class try_and_catch<LastException, Exceptions...> :
public try_and_catch<Exceptions...> {
public:
template <typename F>
explicit try_and_catch(F&& fn) : Base() {
call_fn(fn);
}
protected: template <bool V, typename T = void>
typedef try_and_catch<Exceptions...> Base; using enable_if_t_ = typename std::enable_if<V, T>::type;
try_and_catch() : Base() {} template <typename... Args>
using is_wrap_ctor = std::is_constructible<exception_wrapper, Args...>;
template <typename Ex> template <typename Ex>
typename std::enable_if<!exception_wrapper::optimize<Ex>::value>::type inline enable_if_t_<!is_wrap_ctor<Ex&>::value, exception_wrapper> make(Ex& ex) {
assign_exception(Ex& e, std::exception_ptr eptr) { return exception_wrapper(std::current_exception(), ex);
exception_wrapper::assign_eptr(eptr, e); }
}
template <typename Ex>
typename std::enable_if<exception_wrapper::optimize<Ex>::value>::type
assign_exception(Ex& e, std::exception_ptr /*eptr*/) {
exception_wrapper::assign_sptr(std::make_shared<Ex>(e));
}
template <typename F> template <typename Ex>
void call_fn(F&& fn) { inline enable_if_t_<is_wrap_ctor<Ex&>::value, exception_wrapper> make(Ex& ex) {
try { return typeid(Ex&) == typeid(ex)
Base::call_fn(std::move(fn)); ? exception_wrapper(ex)
} catch (LastException& e) { : exception_wrapper(std::current_exception(), ex);
if (typeid(e) == typeid(LastException&)) { }
assign_exception(e, std::current_exception());
} else {
exception_wrapper::assign_eptr(std::current_exception(), e);
}
}
}
};
template<> template <typename F>
class try_and_catch<> : public exception_wrapper { inline exception_wrapper impl(F&& f) {
public: return (f(), exception_wrapper());
try_and_catch() = default; }
protected: template <typename F, typename Ex, typename... Exs>
template <typename F> inline exception_wrapper impl(F&& f) {
void call_fn(F&& fn) { try {
fn(); return impl<F, Exs...>(std::forward<F>(f));
} catch (Ex& ex) {
return make(ex);
} }
};
} }
} // try_and_catch_detail
template <typename... Exceptions, typename F> template <typename... Exceptions, typename F>
exception_wrapper try_and_catch(F&& fn) { exception_wrapper try_and_catch(F&& fn) {
return detail::try_and_catch<Exceptions...>(std::forward<F>(fn)); return try_and_catch_detail::impl<F, Exceptions...>(std::forward<F>(fn));
} // detail }
} // folly } // folly
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