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
}
inline exception_wrapper::exception_wrapper(
exception_wrapper const& that) : exception_wrapper{} {
that.vptr_->copy_(&that, this); // could throw
exception_wrapper const& that) noexcept : exception_wrapper{} {
that.vptr_->copy_(&that, this); // Copy into *this, won't throw
vptr_ = that.vptr_;
}
......@@ -323,7 +323,7 @@ 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);
return *this;
}
......
......@@ -246,7 +246,8 @@ class exception_wrapper final {
_t<std::conditional<
sizeof(T) <= sizeof(Buffer::Storage) &&
alignof(T) <= alignof(Buffer::Storage) &&
noexcept(T(std::declval<T&&>())),
noexcept(T(std::declval<T&&>())) &&
noexcept(T(std::declval<T const&>())),
InSituTag,
OnHeapTag>>>>;
......@@ -390,7 +391,7 @@ class exception_wrapper final {
//! Copy-constructs an `exception_wrapper`
//! \post `*this` contains a copy of `that`, and `that` is unmodified
//! \post `type() == that.type()`
exception_wrapper(exception_wrapper const& that);
exception_wrapper(exception_wrapper const& that) noexcept;
//! Move-assigns an `exception_wrapper`
//! \pre `this != &that`
......@@ -401,7 +402,7 @@ class exception_wrapper final {
//! Copy-assigns an `exception_wrapper`
//! \post `*this` contains a copy of `that`, and `that` is unmodified
//! \post `type() == that.type()`
exception_wrapper& operator=(exception_wrapper const& that);
exception_wrapper& operator=(exception_wrapper const& that) noexcept;
~exception_wrapper();
......
......@@ -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)
TEST(ExceptionWrapper, throw_test) {
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