X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FExceptionWrapper.h;h=eb493fc68c10429428515a8f6459429e24d01162;hb=2ca10eeefdc1231a20fb1cb75dc3e8d2c5fa70ba;hp=c305e688d79fa750b9e61bae02c0026750d2f07d;hpb=d2efd8104d4191f67140ecdbd5343ba05552f083;p=folly.git diff --git a/folly/ExceptionWrapper.h b/folly/ExceptionWrapper.h index c305e688..eb493fc6 100644 --- a/folly/ExceptionWrapper.h +++ b/folly/ExceptionWrapper.h @@ -34,7 +34,9 @@ #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 @@ -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...); @@ -226,8 +227,8 @@ class exception_wrapper final { Buffer() : buff_{} {} - template >> - Buffer(in_place_t, Ex&& ex); + template + Buffer(in_place_type_t, As&&... as_); template Ex& as() noexcept; template @@ -258,8 +259,12 @@ class exception_wrapper final { "Surprise! std::exception and std::type_info don't have alignment " "greater than one. as_int_ below will not work!"); - static std::uintptr_t as_int_(std::exception const& e); - static std::uintptr_t as_int_(AnyException e); + static std::uintptr_t as_int_( + std::exception_ptr const& ptr, + std::exception const& e); + static std::uintptr_t as_int_( + std::exception_ptr const& ptr, + AnyException e); bool has_exception_() const; std::exception const* as_exception_() const; std::type_info const* as_type_() const; @@ -305,10 +310,10 @@ class exception_wrapper final { struct Impl final : public Base { Ex ex_; Impl() = default; - explicit Impl(Ex const& ex) : Base{typeid(ex)}, ex_(ex) {} - explicit Impl(Ex&& ex) - : Base{typeid(ex)}, - ex_(std::move(ex)){}[[noreturn]] void throw_() const override; + template + explicit Impl(As&&... as) + : Base{typeid(Ex)}, ex_(std::forward(as)...) {} + [[noreturn]] void throw_() const override; std::exception const* get_exception_() const noexcept override; exception_wrapper get_exception_ptr_() const noexcept override; }; @@ -331,11 +336,11 @@ class exception_wrapper final { }; VTable const* vptr_{&uninit_}; - template >> - exception_wrapper(Ex&& ex, OnHeapTag); + template + exception_wrapper(OnHeapTag, in_place_type_t, As&&... as); - template >> - exception_wrapper(Ex&& ex, InSituTag); + template + exception_wrapper(InSituTag, in_place_type_t, As&&... as); template struct IsRegularExceptionType @@ -363,6 +368,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 {} @@ -414,7 +422,7 @@ class exception_wrapper final { class Ex, class Ex_ = _t>, FOLLY_REQUIRES( - Conjunction, IsRegularExceptionType>())> + Conjunction, IsRegularExceptionType>::value)> /* implicit */ exception_wrapper(Ex&& ex); //! \pre `typeid(ex) == typeid(typename decay::type)` @@ -427,13 +435,19 @@ class exception_wrapper final { template < class Ex, class Ex_ = _t>, - FOLLY_REQUIRES(IsRegularExceptionType())> + FOLLY_REQUIRES(IsRegularExceptionType::value)> exception_wrapper(in_place_t, Ex&& ex); + template < + class Ex, + typename... As, + FOLLY_REQUIRES(IsRegularExceptionType::value)> + exception_wrapper(in_place_type_t, As&&... as); + //! 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)` @@ -457,6 +471,18 @@ class exception_wrapper final { //! \overload std::exception const* get_exception() const noexcept; + //! \returns a pointer to the `Ex` held by `*this`, if it holds an object + //! whose type `From` permits `std::is_convertible`; + //! otherwise, returns `nullptr`. + //! \note This function does not mutate the `exception_wrapper` object. + //! \note This function may cause an exception to be thrown and immediately + //! caught internally, affecting runtime performance. + template + Ex* get_exception() noexcept; + //! \overload + template + Ex const* get_exception() const noexcept; + //! \return A `std::exception_ptr` that references either the exception held //! by `*this`, or a copy of same. //! \note This function may need to throw an exception to complete the action. @@ -501,11 +527,6 @@ class exception_wrapper final { //! Throws the wrapped expression. [[noreturn]] void throw_exception() const; - [[noreturn]] FOLLY_DEPRECATED( - "use throw_exception") void throwException() const { - throw_exception(); - } - //! Call `fn` with the wrapped exception (if any), if `fn` can accept it. //! \par Example //! \code @@ -587,7 +608,7 @@ constexpr exception_wrapper::VTable exception_wrapper::InPlace::ops_; */ template exception_wrapper make_exception_wrapper(As&&... as) { - return exception_wrapper{Ex{std::forward(as)...}}; + return exception_wrapper{in_place_type, std::forward(as)...}; } /** @@ -625,7 +646,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 @@ -666,7 +687,7 @@ template exception_wrapper try_and_catch(F&& fn) { return detail::try_and_catch_(std::forward(fn)); } -} // folly +} // namespace folly #include