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

Make exception_wrapper be noexcept-copyable

Summary:
[Folly] Make `exception_wrapper` be `noexcept`-copyable.

This works across the storage types:
* InSitu - only store `noexcept`-copyable objects in-situ.
* OnHeap - `std::shared_ptr` is `noexcept`-copyable.
* Thrown - `std::exception_ptr` is in practice `noexcept`-copyable since it is a smart-ptr for thrown objects.

Reviewed By: marshallcline

Differential Revision: D8109991

fbshipit-source-id: e637c72466b22ab3076f52b4654a7538dcb1d30f
parent b3e7e89c
...@@ -308,8 +308,8 @@ inline exception_wrapper::exception_wrapper(exception_wrapper&& that) noexcept ...@@ -308,8 +308,8 @@ inline exception_wrapper::exception_wrapper(exception_wrapper&& that) noexcept
} }
inline exception_wrapper::exception_wrapper( inline exception_wrapper::exception_wrapper(
exception_wrapper const& that) : exception_wrapper{} { exception_wrapper const& that) noexcept : exception_wrapper{} {
that.vptr_->copy_(&that, this); // could throw that.vptr_->copy_(&that, this); // Copy into *this, won't throw
vptr_ = that.vptr_; vptr_ = that.vptr_;
} }
...@@ -323,7 +323,7 @@ inline exception_wrapper& exception_wrapper::operator=( ...@@ -323,7 +323,7 @@ inline exception_wrapper& exception_wrapper::operator=(
} }
inline exception_wrapper& exception_wrapper::operator=( inline exception_wrapper& exception_wrapper::operator=(
exception_wrapper const& that) { exception_wrapper const& that) noexcept {
exception_wrapper(that).swap(*this); exception_wrapper(that).swap(*this);
return *this; return *this;
} }
......
...@@ -246,7 +246,8 @@ class exception_wrapper final { ...@@ -246,7 +246,8 @@ class exception_wrapper final {
_t<std::conditional< _t<std::conditional<
sizeof(T) <= sizeof(Buffer::Storage) && sizeof(T) <= sizeof(Buffer::Storage) &&
alignof(T) <= alignof(Buffer::Storage) && alignof(T) <= alignof(Buffer::Storage) &&
noexcept(T(std::declval<T&&>())), noexcept(T(std::declval<T&&>())) &&
noexcept(T(std::declval<T const&>())),
InSituTag, InSituTag,
OnHeapTag>>>>; OnHeapTag>>>>;
...@@ -390,7 +391,7 @@ class exception_wrapper final { ...@@ -390,7 +391,7 @@ class exception_wrapper final {
//! Copy-constructs an `exception_wrapper` //! Copy-constructs an `exception_wrapper`
//! \post `*this` contains a copy of `that`, and `that` is unmodified //! \post `*this` contains a copy of `that`, and `that` is unmodified
//! \post `type() == that.type()` //! \post `type() == that.type()`
exception_wrapper(exception_wrapper const& that); exception_wrapper(exception_wrapper const& that) noexcept;
//! Move-assigns an `exception_wrapper` //! Move-assigns an `exception_wrapper`
//! \pre `this != &that` //! \pre `this != &that`
...@@ -401,7 +402,7 @@ class exception_wrapper final { ...@@ -401,7 +402,7 @@ class exception_wrapper final {
//! Copy-assigns an `exception_wrapper` //! Copy-assigns an `exception_wrapper`
//! \post `*this` contains a copy of `that`, and `that` is unmodified //! \post `*this` contains a copy of `that`, and `that` is unmodified
//! \post `type() == that.type()` //! \post `type() == that.type()`
exception_wrapper& operator=(exception_wrapper const& that); exception_wrapper& operator=(exception_wrapper const& that) noexcept;
~exception_wrapper(); ~exception_wrapper();
......
...@@ -60,6 +60,14 @@ T& from_eptr(std::exception_ptr& eptr) { ...@@ -60,6 +60,14 @@ T& from_eptr(std::exception_ptr& eptr) {
} }
} }
TEST(ExceptionWrapper, nothrow) {
EXPECT_TRUE(std::is_nothrow_default_constructible<exception_wrapper>::value);
EXPECT_TRUE(std::is_nothrow_move_constructible<exception_wrapper>::value);
EXPECT_TRUE(std::is_nothrow_move_assignable<exception_wrapper>::value);
EXPECT_TRUE(std::is_nothrow_copy_constructible<exception_wrapper>::value);
EXPECT_TRUE(std::is_nothrow_copy_assignable<exception_wrapper>::value);
}
// Tests that when we call throw_exception, the proper type is thrown (derived) // Tests that when we call throw_exception, the proper type is thrown (derived)
TEST(ExceptionWrapper, throw_test) { TEST(ExceptionWrapper, throw_test) {
std::runtime_error e("payload"); std::runtime_error e("payload");
......
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