Commit 258585ef authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook Github Bot

Fixes for Try::withException

Summary:
[Folly] Fixes for `Try::withException`.

* Fix the overload with the exception type specified so that the specified exception type is checked. A mismatch between the specified exception type and the parameter type of the passed invokable will result in the expected compiler error.
* Add an overload where the exception type is deduced intentionally, as opposed to accidentally.

Of course, these simply forward to their corresponding `exception_wrapper::withException` overloads.

Reviewed By: ericniebler

Differential Revision: D5216691

fbshipit-source-id: 7e85c906c3aa17dfede6e0980c6ac8bf75034073
parent b3ab0cc4
......@@ -248,9 +248,32 @@ class Try {
if (!hasException()) {
return false;
}
return e_.with_exception(std::move(func));
return e_.with_exception<Ex>(std::move(func));
}
template <class Ex, class F>
bool withException(F func) const {
if (!hasException()) {
return false;
}
return e_.with_exception<Ex>(std::move(func));
}
/*
* If the Try contains an exception and it is of type compatible with Ex as
* deduced from the first parameter of func, execute func(Ex)
*
* @param func a function that takes a single parameter of type const Ex&
*
* @returns True if the Try held an Ex and func was executed, false otherwise
*/
template <class F>
bool withException(F func) {
if (!hasException()) {
return false;
}
return e_.with_exception(std::move(func));
}
template <class F>
bool withException(F func) const {
if (!hasException()) {
return false;
......@@ -401,9 +424,32 @@ class Try<void> {
if (!hasException()) {
return false;
}
return e_.with_exception(std::move(func));
return e_.with_exception<Ex>(std::move(func));
}
template <class Ex, class F>
bool withException(F func) const {
if (!hasException()) {
return false;
}
return e_.with_exception<Ex>(std::move(func));
}
/*
* If the Try contains an exception and it is of type compatible with Ex as
* deduced from the first parameter of func, execute func(Ex)
*
* @param func a function that takes a single parameter of type const Ex&
*
* @returns True if the Try held an Ex and func was executed, false otherwise
*/
template <class F>
bool withException(F func) {
if (!hasException()) {
return false;
}
return e_.with_exception(std::move(func));
}
template <class F>
bool withException(F func) const {
if (!hasException()) {
return false;
......
......@@ -195,3 +195,71 @@ TEST(Try, tryGetExceptionObject) {
EXPECT_EQ(num, t.tryGetExceptionObject<int>());
}
}
TEST(Try, withException) {
auto ew = make_exception_wrapper<std::range_error>("oops");
{
auto t = Try<bool>(true);
EXPECT_FALSE(t.withException<std::runtime_error>([](auto&) {}));
EXPECT_FALSE(t.withException<std::logic_error>([](auto&) {}));
EXPECT_FALSE(t.withException([](std::runtime_error&) {}));
EXPECT_FALSE(t.withException([](std::logic_error&) {}));
}
{
auto t = Try<bool>(ew);
EXPECT_TRUE(t.withException<std::runtime_error>([](auto&) {}));
EXPECT_FALSE(t.withException<std::logic_error>([](auto&) {}));
EXPECT_TRUE(t.withException([](std::runtime_error&) {}));
EXPECT_FALSE(t.withException([](std::logic_error&) {}));
}
{
auto t = Try<void>();
EXPECT_FALSE(t.withException<std::runtime_error>([](auto&) {}));
EXPECT_FALSE(t.withException<std::logic_error>([](auto&) {}));
EXPECT_FALSE(t.withException([](std::runtime_error&) {}));
EXPECT_FALSE(t.withException([](std::logic_error&) {}));
}
{
auto t = Try<void>(ew);
EXPECT_TRUE(t.withException<std::runtime_error>([](auto&) {}));
EXPECT_FALSE(t.withException<std::logic_error>([](auto&) {}));
EXPECT_TRUE(t.withException([](std::runtime_error&) {}));
EXPECT_FALSE(t.withException([](std::logic_error&) {}));
}
{
auto const t = Try<bool>(true);
EXPECT_FALSE(t.withException<std::runtime_error>([](auto&) {}));
EXPECT_FALSE(t.withException<std::logic_error>([](auto&) {}));
EXPECT_FALSE(t.withException([](std::runtime_error const&) {}));
EXPECT_FALSE(t.withException([](std::logic_error const&) {}));
}
{
auto const t = Try<bool>(ew);
EXPECT_TRUE(t.withException<std::runtime_error>([](auto&) {}));
EXPECT_FALSE(t.withException<std::logic_error>([](auto&) {}));
EXPECT_TRUE(t.withException([](std::runtime_error const&) {}));
EXPECT_FALSE(t.withException([](std::logic_error const&) {}));
}
{
auto const t = Try<void>();
EXPECT_FALSE(t.withException<std::runtime_error>([](auto&) {}));
EXPECT_FALSE(t.withException<std::logic_error>([](auto&) {}));
EXPECT_FALSE(t.withException([](std::runtime_error const&) {}));
EXPECT_FALSE(t.withException([](std::logic_error const&) {}));
}
{
auto const t = Try<void>(ew);
EXPECT_TRUE(t.withException<std::runtime_error>([](auto&) {}));
EXPECT_FALSE(t.withException<std::logic_error>([](auto&) {}));
EXPECT_TRUE(t.withException([](std::runtime_error const&) {}));
EXPECT_FALSE(t.withException([](std::logic_error const&) {}));
}
}
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