Commit 0091c4e1 authored by Max Kellermann's avatar Max Kellermann Committed by Max Kellermann

util/Exception: add FindNested()

parent 80172e17
......@@ -84,6 +84,27 @@ NestException(std::exception_ptr ep, T &&t) noexcept
}
/**
* Find an instance of #T in the nested exception chain, and return a
* pointer. Returns nullptr if no such instance was found.
*/
template<typename T>
[[gnu::pure]]
inline const T *
FindNested(std::exception_ptr ep) noexcept
{
try {
std::rethrow_exception(ep);
} catch (const T &t) {
return &t;
} catch (const std::nested_exception &ne) {
return FindNested<T>(ne.nested_ptr());
} catch (...) {
}
return nullptr;
}
/**
* Find an instance of #T in the nested exception chain, and rethrow
* it. Does nothing if no such instance was found.
*/
......
......@@ -50,6 +50,75 @@ TEST(ExceptionTest, DerivedError)
ASSERT_EQ(GetFullMessage(std::make_exception_ptr(DerivedError("Foo"))), "Foo");
}
TEST(ExceptionTest, FindNestedDirect)
{
struct Foo {};
struct Bar {};
struct Derived : Foo {};
try {
throw Foo{};
} catch (...) {
EXPECT_NE(FindNested<Foo>(std::current_exception()),
nullptr);
}
try {
throw Bar{};
} catch (...) {
EXPECT_EQ(FindNested<Foo>(std::current_exception()),
nullptr);
}
try {
throw Derived{};
} catch (...) {
EXPECT_NE(FindNested<Foo>(std::current_exception()),
nullptr);
}
}
TEST(ExceptionTest, FindNestedIndirect)
{
struct Foo {};
struct Bar {};
struct Derived : Foo {};
struct Outer {};
try {
throw Foo{};
} catch (...) {
try {
std::throw_with_nested(Outer{});
} catch (...) {
EXPECT_NE(FindNested<Foo>(std::current_exception()),
nullptr);
}
}
try {
throw Bar{};
} catch (...) {
try {
std::throw_with_nested(Outer{});
} catch (...) {
EXPECT_EQ(FindNested<Foo>(std::current_exception()),
nullptr);
}
}
try {
throw Derived{};
} catch (...) {
try {
std::throw_with_nested(Outer{});
} catch (...) {
EXPECT_NE(FindNested<Foo>(std::current_exception()),
nullptr);
}
}
}
template<typename T>
static bool
CheckFindRetrowNested(std::exception_ptr e) noexcept
......
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