X-Git-Url: http://plrg.eecs.uci.edu/git/?p=folly.git;a=blobdiff_plain;f=folly%2FExceptionWrapper.h;h=fc0cac77529b58165c6029137d5aa7c0bc9bf012;hp=958a3d317a06b8f3f65096b691e90fa5d2430c86;hb=3579ddb46bf91312e7c1d24389ad60fd96fad776;hpb=c9afb47c5c08bd25b819d90cebf9cb639005918d diff --git a/folly/ExceptionWrapper.h b/folly/ExceptionWrapper.h index 958a3d31..fc0cac77 100644 --- a/folly/ExceptionWrapper.h +++ b/folly/ExceptionWrapper.h @@ -29,12 +29,14 @@ #include #include -#include #include #include #include #include +#include #include +#include +#include #ifdef __GNUC__ #pragma GCC diagnostic push @@ -42,8 +44,7 @@ #pragma GCC diagnostic ignored "-Wpotentially-evaluated-expression" // GCC gets confused about lambda scopes and issues shadow-local warnings for // parameters in totally different functions. -#pragma GCC diagnostic ignored "-Wshadow-local" -#pragma GCC diagnostic ignored "-Wshadow-compatible-local" +FOLLY_GCC_DISABLE_NEW_SHADOW_WARNINGS #endif #define FOLLY_EXCEPTION_WRAPPER_H_INCLUDED @@ -161,7 +162,7 @@ auto fold(Fn&& fn, A&& a, B&& b, Bs&&... bs) { //! \endcode class exception_wrapper final { private: - struct AnyException : std::exception { + struct FOLLY_EXPORT AnyException : std::exception { std::type_info const* typeinfo_; template /* implicit */ AnyException(T&& t) noexcept : typeinfo_(&typeid(t)) {} @@ -196,7 +197,7 @@ class exception_wrapper final { exception_wrapper (*get_exception_ptr_)(exception_wrapper const*); }; - [[noreturn]] static void onNoExceptionError(); + [[noreturn]] static void onNoExceptionError(char const* name); template static Ret noop_(Args...); @@ -234,18 +235,20 @@ class exception_wrapper final { Ex const& as() const noexcept; }; - enum class Placement { kInSitu, kOnHeap }; + struct ThrownTag {}; + struct InSituTag {}; + struct OnHeapTag {}; + template - using PlacementOf = std::integral_constant< - Placement, - sizeof(T) <= sizeof(Buffer::Storage) && + using PlacementOf = _t::value, + ThrownTag, + _t())) - ? Placement::kInSitu - : Placement::kOnHeap>; - - using InSituTag = std::integral_constant; - using OnHeapTag = std::integral_constant; + noexcept(T(std::declval())), + InSituTag, + OnHeapTag>>>>; static std::exception const* as_exception_or_null_(std::exception const& ex); static std::exception const* as_exception_or_null_(AnyException); @@ -279,6 +282,7 @@ class exception_wrapper final { template struct InPlace { + static_assert(IsStdException::value, "only deriving std::exception"); static void copy_(exception_wrapper const* from, exception_wrapper* to); static void move_(exception_wrapper* from, exception_wrapper* to); static void delete_(exception_wrapper* that); @@ -307,6 +311,7 @@ class exception_wrapper final { }; template struct Impl final : public Base { + static_assert(IsStdException::value, "only deriving std::exception"); Ex ex_; Impl() = default; template @@ -335,6 +340,9 @@ class exception_wrapper final { }; VTable const* vptr_{&uninit_}; + template + exception_wrapper(ThrownTag, in_place_type_t, As&&... as); + template exception_wrapper(OnHeapTag, in_place_type_t, As&&... as); @@ -367,6 +375,9 @@ class exception_wrapper final { static bool with_exception_(This& this_, Fn fn_); public: + static exception_wrapper from_exception_ptr( + std::exception_ptr const& eptr) noexcept; + //! Default-constructs an empty `exception_wrapper` //! \post `type() == none()` exception_wrapper() noexcept {} @@ -443,7 +454,7 @@ class exception_wrapper final { //! Swaps the value of `*this` with the value of `that` void swap(exception_wrapper& that) noexcept; - //! \return `true` if `*this` is not holding an exception. + //! \return `true` if `*this` is holding an exception. explicit operator bool() const noexcept; //! \return `!bool(*this)` @@ -604,7 +615,7 @@ constexpr exception_wrapper::VTable exception_wrapper::InPlace::ops_; */ template exception_wrapper make_exception_wrapper(As&&... as) { - return exception_wrapper{in_place, std::forward(as)...}; + return exception_wrapper{in_place_type, std::forward(as)...}; } /** @@ -642,7 +653,7 @@ inline exception_wrapper try_and_catch_(F&& f) { return exception_wrapper(std::current_exception(), ex); } } -} // detail +} // namespace detail //! `try_and_catch` is a simple replacement for `try {} catch(){}`` that allows //! you to specify which derived exceptions you would like to catch and store in @@ -683,7 +694,7 @@ template exception_wrapper try_and_catch(F&& fn) { return detail::try_and_catch_(std::forward(fn)); } -} // folly +} // namespace folly #include