From: Yedidya Feldblum <yfeldblum@fb.com> Date: Mon, 26 Jun 2017 20:22:19 +0000 (-0700) Subject: Let make_exception_wrapper construct on-heap objects in-place X-Git-Tag: v2017.07.03.00~32 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=c9afb47c5c08bd25b819d90cebf9cb639005918d;p=folly.git Let make_exception_wrapper construct on-heap objects in-place Summary: [Folly] Let `make_exception_wrapper` construct on-heap objects in-place. Currently, it constructs on-heap objects on the stack and then move-constructs them into on-heap storage. Reviewed By: ericniebler Differential Revision: D5315104 fbshipit-source-id: cc0493e7d98aacadd342eb56601028ced4a19bb3 --- diff --git a/folly/ExceptionWrapper-inl.h b/folly/ExceptionWrapper-inl.h index 2845c2e3..c1e83785 100644 --- a/folly/ExceptionWrapper-inl.h +++ b/folly/ExceptionWrapper-inl.h @@ -69,9 +69,9 @@ inline std::type_info const* exception_wrapper::uninit_type_( return &typeid(void); } -template <class Ex, class DEx> -inline exception_wrapper::Buffer::Buffer(in_place_t, Ex&& ex) { - ::new (static_cast<void*>(&buff_)) DEx(std::forward<Ex>(ex)); +template <class Ex, typename... As> +inline exception_wrapper::Buffer::Buffer(in_place_type_t<Ex>, As&&... as_) { + ::new (static_cast<void*>(&buff_)) Ex(std::forward<As>(as_)...); } template <class Ex> @@ -280,14 +280,15 @@ inline exception_wrapper exception_wrapper::SharedPtr::get_exception_ptr_( return that->sptr_.ptr_->get_exception_ptr_(); } -template <class Ex, class DEx> -inline exception_wrapper::exception_wrapper(Ex&& ex, OnHeapTag) - : sptr_{std::make_shared<SharedPtr::Impl<DEx>>(std::forward<Ex>(ex))}, +template <class Ex, typename... As> +inline exception_wrapper::exception_wrapper(OnHeapTag, in_place_type_t<Ex>, As&&... as) + : sptr_{std::make_shared<SharedPtr::Impl<Ex>>(std::forward<As>(as)...)}, vptr_(&SharedPtr::ops_) {} -template <class Ex, class DEx> -inline exception_wrapper::exception_wrapper(Ex&& ex, InSituTag) - : buff_{in_place, std::forward<Ex>(ex)}, vptr_(&InPlace<DEx>::ops_) {} +template <class Ex, typename... As> +inline exception_wrapper::exception_wrapper(InSituTag, in_place_type_t<Ex>, As&&... as) + : buff_{in_place<Ex>, std::forward<As>(as)...}, + vptr_(&InPlace<Ex>::ops_) {} inline exception_wrapper::exception_wrapper(exception_wrapper&& that) noexcept : exception_wrapper{} { @@ -345,8 +346,9 @@ template < exception_wrapper::IsRegularExceptionType<Ex_>>::value)> inline exception_wrapper::exception_wrapper(Ex&& ex) : exception_wrapper{ - exception_wrapper_detail::dont_slice(std::forward<Ex>(ex)), - PlacementOf<Ex_>{}} { + PlacementOf<Ex_>{}, + in_place<Ex_>, + exception_wrapper_detail::dont_slice(std::forward<Ex>(ex))} { } template < @@ -356,8 +358,21 @@ template < exception_wrapper::IsRegularExceptionType<Ex_>::value)> inline exception_wrapper::exception_wrapper(in_place_t, Ex&& ex) : exception_wrapper{ - exception_wrapper_detail::dont_slice(std::forward<Ex>(ex)), - PlacementOf<Ex_>{}} { + PlacementOf<Ex_>{}, + in_place<Ex_>, + exception_wrapper_detail::dont_slice(std::forward<Ex>(ex))} { +} + +template < + class Ex, + typename... As, + FOLLY_REQUIRES_DEF( + exception_wrapper::IsRegularExceptionType<Ex>::value)> +inline exception_wrapper::exception_wrapper(in_place_type_t<Ex>, As&&... as) + : exception_wrapper{ + PlacementOf<Ex>{}, + in_place<Ex>, + std::forward<As>(as)...} { } inline void exception_wrapper::swap(exception_wrapper& that) noexcept { diff --git a/folly/ExceptionWrapper.h b/folly/ExceptionWrapper.h index 449080d7..958a3d31 100644 --- a/folly/ExceptionWrapper.h +++ b/folly/ExceptionWrapper.h @@ -226,8 +226,8 @@ class exception_wrapper final { Buffer() : buff_{} {} - template <class Ex, class DEx = _t<std::decay<Ex>>> - Buffer(in_place_t, Ex&& ex); + template <class Ex, typename... As> + Buffer(in_place_type_t<Ex>, As&&... as_); template <class Ex> Ex& as() noexcept; template <class Ex> @@ -309,10 +309,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 <typename... As> + explicit Impl(As&&... as) + : Base{typeid(Ex)}, ex_(std::forward<As>(as)...) {} + [[noreturn]] void throw_() const override; std::exception const* get_exception_() const noexcept override; exception_wrapper get_exception_ptr_() const noexcept override; }; @@ -335,11 +335,11 @@ class exception_wrapper final { }; VTable const* vptr_{&uninit_}; - template <class Ex, class DEx = _t<std::decay<Ex>>> - exception_wrapper(Ex&& ex, OnHeapTag); + template <class Ex, typename... As> + exception_wrapper(OnHeapTag, in_place_type_t<Ex>, As&&... as); - template <class Ex, class DEx = _t<std::decay<Ex>>> - exception_wrapper(Ex&& ex, InSituTag); + template <class Ex, typename... As> + exception_wrapper(InSituTag, in_place_type_t<Ex>, As&&... as); template <class T> struct IsRegularExceptionType @@ -434,6 +434,12 @@ class exception_wrapper final { FOLLY_REQUIRES(IsRegularExceptionType<Ex_>::value)> exception_wrapper(in_place_t, Ex&& ex); + template < + class Ex, + typename... As, + FOLLY_REQUIRES(IsRegularExceptionType<Ex>::value)> + exception_wrapper(in_place_type_t<Ex>, As&&... as); + //! Swaps the value of `*this` with the value of `that` void swap(exception_wrapper& that) noexcept; @@ -598,7 +604,7 @@ constexpr exception_wrapper::VTable exception_wrapper::InPlace<Ex>::ops_; */ template <class Ex, typename... As> exception_wrapper make_exception_wrapper(As&&... as) { - return exception_wrapper{Ex{std::forward<As>(as)...}}; + return exception_wrapper{in_place<Ex>, std::forward<As>(as)...}; } /**