util/Exception: add FindNested()
This commit is contained in:
parent
80172e17ac
commit
0091c4e12b
@ -83,6 +83,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
|
* Find an instance of #T in the nested exception chain, and rethrow
|
||||||
* it. Does nothing if no such instance was found.
|
* 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");
|
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>
|
template<typename T>
|
||||||
static bool
|
static bool
|
||||||
CheckFindRetrowNested(std::exception_ptr e) noexcept
|
CheckFindRetrowNested(std::exception_ptr e) noexcept
|
||||||
|
Loading…
Reference in New Issue
Block a user