return that->sptr_.ptr_->get_exception_ptr_();
}
+template <class Ex, typename... As>
+inline exception_wrapper::exception_wrapper(
+ ThrownTag,
+ in_place_type_t<Ex>,
+ As&&... as)
+ : eptr_{std::make_exception_ptr(Ex(std::forward<As>(as)...)),
+ reinterpret_cast<std::uintptr_t>(std::addressof(typeid(Ex))) + 1u},
+ vptr_(&ExceptionPtr::ops_) {}
+
template <class Ex, typename... As>
inline exception_wrapper::exception_wrapper(
OnHeapTag,
Ex const& as() const noexcept;
};
+ struct ThrownTag {};
struct InSituTag {};
struct OnHeapTag {};
template <class T>
using PlacementOf = _t<std::conditional<
- sizeof(T) <= sizeof(Buffer::Storage) &&
- alignof(T) <= alignof(Buffer::Storage) &&
- noexcept(T(std::declval<T&&>())),
- InSituTag,
- OnHeapTag>>;
+ !IsStdException<T>::value,
+ ThrownTag,
+ _t<std::conditional<
+ sizeof(T) <= sizeof(Buffer::Storage) &&
+ alignof(T) <= alignof(Buffer::Storage) &&
+ noexcept(T(std::declval<T&&>())),
+ InSituTag,
+ OnHeapTag>>>>;
static std::exception const* as_exception_or_null_(std::exception const& ex);
static std::exception const* as_exception_or_null_(AnyException);
template <class Ex>
struct InPlace {
+ static_assert(IsStdException<Ex>::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);
};
template <class Ex>
struct Impl final : public Base {
+ static_assert(IsStdException<Ex>::value, "only deriving std::exception");
Ex ex_;
Impl() = default;
template <typename... As>
};
VTable const* vptr_{&uninit_};
+ template <class Ex, typename... As>
+ exception_wrapper(ThrownTag, in_place_type_t<Ex>, As&&... as);
+
template <class Ex, typename... As>
exception_wrapper(OnHeapTag, in_place_type_t<Ex>, As&&... as);
EXPECT_EQ(typeid(std::runtime_error), ew.type());
EXPECT_NE(nullptr, ew.get_exception());
EXPECT_NE(nullptr, ew.get_exception<std::exception>());
+ EXPECT_STREQ("foo", ew.get_exception<std::exception>()->what());
EXPECT_EQ(nullptr, ew.get_exception<int>());
EXPECT_FALSE(ew.has_exception_ptr());
EXPECT_NE(nullptr, ew.to_exception_ptr());
EXPECT_EQ(typeid(std::runtime_error), ew.type());
EXPECT_NE(nullptr, ew.get_exception());
EXPECT_NE(nullptr, ew.get_exception<std::exception>());
+ EXPECT_STREQ("foo", ew.get_exception<std::exception>()->what());
EXPECT_EQ(nullptr, ew.get_exception<int>());
EXPECT_TRUE(ew.has_exception_ptr());
EXPECT_EQ(ep, ew.to_exception_ptr());
EXPECT_EQ(nullptr, ew.get_exception());
EXPECT_EQ(nullptr, ew.get_exception<std::exception>());
EXPECT_NE(nullptr, ew.get_exception<int>());
+ EXPECT_EQ(12, *ew.get_exception<int>());
EXPECT_TRUE(ew.has_exception_ptr());
EXPECT_EQ(ep, ew.to_exception_ptr());
EXPECT_TRUE(ew.has_exception_ptr());
EXPECT_EQ(nullptr, ew.get_exception());
EXPECT_EQ(nullptr, ew.get_exception<std::exception>());
EXPECT_NE(nullptr, ew.get_exception<int>());
- EXPECT_FALSE(ew.has_exception_ptr());
+ EXPECT_EQ(42, *ew.get_exception<int>());
+ EXPECT_TRUE(ew.has_exception_ptr());
EXPECT_EQ("int", ew.class_name());
EXPECT_EQ("int", ew.what());
EXPECT_NE(nullptr, ew.to_exception_ptr());
EXPECT_EQ(nullptr, ew.get_exception());
EXPECT_EQ(nullptr, ew.get_exception<std::exception>());
EXPECT_NE(nullptr, ew.get_exception<int>());
+ EXPECT_EQ(12, *ew.get_exception<int>());
EXPECT_EQ(ep, ew.to_exception_ptr());
EXPECT_EQ("<unknown exception>", ew.class_name()); // because concrete type is
// erased