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

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
parent 6cf4cd30
......@@ -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 {
......
......@@ -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)...};
}
/**
......
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