X-Git-Url: http://plrg.eecs.uci.edu/git/?p=folly.git;a=blobdiff_plain;f=folly%2FExceptionWrapper.h;h=2d70538e1ae0700e28b4f499f030273a59a4e232;hp=b00dc77d213a8e6e5efcf5d0187a4ccd3ca199a6;hb=e52b296424c9441b5595906674045e04c6ccf24a;hpb=3c7ee0d0b0174c3d5cbe22581201c8fbef666bdf diff --git a/folly/ExceptionWrapper.h b/folly/ExceptionWrapper.h index b00dc77d..2d70538e 100644 --- a/folly/ExceptionWrapper.h +++ b/folly/ExceptionWrapper.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-present Facebook, Inc. + * Copyright 2014-present Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -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...); @@ -226,26 +227,28 @@ 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 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); @@ -258,8 +261,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; @@ -275,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); @@ -303,12 +311,13 @@ class exception_wrapper final { }; template struct Impl final : public Base { + static_assert(IsStdException::value, "only deriving std::exception"); 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 +340,14 @@ class exception_wrapper final { }; VTable const* vptr_{&uninit_}; - template >> - exception_wrapper(Ex&& ex, OnHeapTag); + template + exception_wrapper(ThrownTag, in_place_type_t, As&&... as); - template >> - exception_wrapper(Ex&& ex, InSituTag); + template + exception_wrapper(OnHeapTag, in_place_type_t, As&&... as); + + template + exception_wrapper(InSituTag, in_place_type_t, As&&... as); template struct IsRegularExceptionType @@ -363,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 {} @@ -430,10 +445,16 @@ class exception_wrapper final { 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)` @@ -594,7 +615,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)...}; } /** @@ -632,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 @@ -673,7 +694,7 @@ template exception_wrapper try_and_catch(F&& fn) { return detail::try_and_catch_(std::forward(fn)); } -} // folly +} // namespace folly #include