From: Yedidya Feldblum Date: Tue, 27 Jun 2017 21:27:31 +0000 (-0700) Subject: Fixes for Try::withException X-Git-Tag: v2017.07.03.00~25 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=258585eff14817914814310573cde2166fcc068f;p=folly.git 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 --- diff --git a/folly/Try.h b/folly/Try.h index e5af11fa..f115a34a 100644 --- a/folly/Try.h +++ b/folly/Try.h @@ -248,9 +248,32 @@ class Try { if (!hasException()) { return false; } - return e_.with_exception(std::move(func)); + return e_.with_exception(std::move(func)); } template + bool withException(F func) const { + if (!hasException()) { + return false; + } + return e_.with_exception(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 + bool withException(F func) { + if (!hasException()) { + return false; + } + return e_.with_exception(std::move(func)); + } + template bool withException(F func) const { if (!hasException()) { return false; @@ -401,9 +424,32 @@ class Try { if (!hasException()) { return false; } - return e_.with_exception(std::move(func)); + return e_.with_exception(std::move(func)); } template + bool withException(F func) const { + if (!hasException()) { + return false; + } + return e_.with_exception(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 + bool withException(F func) { + if (!hasException()) { + return false; + } + return e_.with_exception(std::move(func)); + } + template bool withException(F func) const { if (!hasException()) { return false; diff --git a/folly/test/TryTest.cpp b/folly/test/TryTest.cpp index e67761b1..49517bf5 100644 --- a/folly/test/TryTest.cpp +++ b/folly/test/TryTest.cpp @@ -195,3 +195,71 @@ TEST(Try, tryGetExceptionObject) { EXPECT_EQ(num, t.tryGetExceptionObject()); } } + +TEST(Try, withException) { + auto ew = make_exception_wrapper("oops"); + + { + auto t = Try(true); + EXPECT_FALSE(t.withException([](auto&) {})); + EXPECT_FALSE(t.withException([](auto&) {})); + EXPECT_FALSE(t.withException([](std::runtime_error&) {})); + EXPECT_FALSE(t.withException([](std::logic_error&) {})); + } + + { + auto t = Try(ew); + EXPECT_TRUE(t.withException([](auto&) {})); + EXPECT_FALSE(t.withException([](auto&) {})); + EXPECT_TRUE(t.withException([](std::runtime_error&) {})); + EXPECT_FALSE(t.withException([](std::logic_error&) {})); + } + + { + auto t = Try(); + EXPECT_FALSE(t.withException([](auto&) {})); + EXPECT_FALSE(t.withException([](auto&) {})); + EXPECT_FALSE(t.withException([](std::runtime_error&) {})); + EXPECT_FALSE(t.withException([](std::logic_error&) {})); + } + + { + auto t = Try(ew); + EXPECT_TRUE(t.withException([](auto&) {})); + EXPECT_FALSE(t.withException([](auto&) {})); + EXPECT_TRUE(t.withException([](std::runtime_error&) {})); + EXPECT_FALSE(t.withException([](std::logic_error&) {})); + } + + { + auto const t = Try(true); + EXPECT_FALSE(t.withException([](auto&) {})); + EXPECT_FALSE(t.withException([](auto&) {})); + EXPECT_FALSE(t.withException([](std::runtime_error const&) {})); + EXPECT_FALSE(t.withException([](std::logic_error const&) {})); + } + + { + auto const t = Try(ew); + EXPECT_TRUE(t.withException([](auto&) {})); + EXPECT_FALSE(t.withException([](auto&) {})); + EXPECT_TRUE(t.withException([](std::runtime_error const&) {})); + EXPECT_FALSE(t.withException([](std::logic_error const&) {})); + } + + { + auto const t = Try(); + EXPECT_FALSE(t.withException([](auto&) {})); + EXPECT_FALSE(t.withException([](auto&) {})); + EXPECT_FALSE(t.withException([](std::runtime_error const&) {})); + EXPECT_FALSE(t.withException([](std::logic_error const&) {})); + } + + { + auto const t = Try(ew); + EXPECT_TRUE(t.withException([](auto&) {})); + EXPECT_FALSE(t.withException([](auto&) {})); + EXPECT_TRUE(t.withException([](std::runtime_error const&) {})); + EXPECT_FALSE(t.withException([](std::logic_error const&) {})); + } +}