#if __cpp_lib_exception_ptr_cast >= 202506L
template<typename _Ex>
- const _Ex* exception_ptr_cast(const exception_ptr&) noexcept;
+ constexpr const _Ex* exception_ptr_cast(const exception_ptr&) noexcept;
template<typename _Ex>
void exception_ptr_cast(const exception_ptr&&) = delete;
#endif
_GLIBCXX_USE_NOEXCEPT;
#if __cpp_lib_exception_ptr_cast >= 202506L
template<typename _Ex>
- friend const _Ex* std::exception_ptr_cast(const exception_ptr&) noexcept;
+ friend constexpr const _Ex* std::exception_ptr_cast(const exception_ptr&)
+ noexcept;
#endif
const void* _M_exception_ptr_cast(const type_info&) const
#if __cpp_lib_exception_ptr_cast >= 202506L
template<typename _Ex>
[[__gnu__::__always_inline__]]
- inline const _Ex* exception_ptr_cast(const exception_ptr& __p) noexcept
+ constexpr const _Ex* exception_ptr_cast(const exception_ptr& __p) noexcept
{
+ static_assert(!std::is_const_v<_Ex>);
+ static_assert(!std::is_reference_v<_Ex>);
+ static_assert(std::is_object_v<_Ex>);
+ static_assert(!std::is_array_v<_Ex>);
+ static_assert(!std::is_pointer_v<_Ex>);
+ static_assert(!std::is_member_pointer_v<_Ex>);
#ifdef __cpp_rtti
- const type_info &__id = typeid(const _Ex&);
- return static_cast<const _Ex*>(__p._M_exception_ptr_cast(__id));
+ if consteval {
+ if (__p._M_exception_object)
+ try
+ {
+ std::rethrow_exception(__p);
+ }
+ catch (const _Ex& __exc)
+ {
+ return &__exc;
+ }
+ catch (...)
+ {
+ }
+ return nullptr;
+ } else {
+ const type_info &__id = typeid(const _Ex&);
+ return static_cast<const _Ex*>(__p._M_exception_ptr_cast(__id));
+ }
#else
return nullptr;
#endif
struct B : A {};
struct C : B {};
struct D {};
-struct E : virtual C { int e; virtual ~E () {} };
+struct E : virtual C { int e; constexpr virtual ~E () {} };
struct F : virtual E, virtual C { int f; };
struct G : virtual F, virtual C, virtual E {
- G () : g (4) { a = 1; e = 2; f = 3; } int g;
+ constexpr G () : g (4) { a = 1; e = 2; f = 3; } int g;
};
-void test01()
+constexpr bool test01(bool x)
{
auto a = std::make_exception_ptr(C{ 42 });
auto b = std::exception_ptr_cast<C>(a);
auto n = std::exception_ptr_cast<G>(a);
VERIFY( n == nullptr );
}
+ if (x)
+ throw 1;
+ return true;
}
+static_assert(test01(false));
+
int main()
{
- test01();
+ try
+ {
+ test01(true);
+ }
+ catch (...)
+ {
+ }
}