From: Yedidya Feldblum Date: Thu, 24 Aug 2017 07:42:16 +0000 (-0700) Subject: Try::exception overload for Try&& X-Git-Tag: v2017.08.28.00~11 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=4d4a549d8b38418b395516d68dbf679efefe2e00;p=folly.git Try::exception overload for Try&& Summary: [Folly] `Try::exception` overload for `Try&&`. For consistency with `Try::value`. Reviewed By: WillerZ Differential Revision: D5691758 fbshipit-source-id: 9904b2a5c90f4575a3c09dc012658d359d11fdd9 --- diff --git a/folly/Try.h b/folly/Try.h index fb783b01..6d219a73 100644 --- a/folly/Try.h +++ b/folly/Try.h @@ -201,20 +201,34 @@ class Try { return hasException() && e_.is_compatible_with(); } - exception_wrapper& exception() { + exception_wrapper& exception() & { if (!hasException()) { try_detail::throwTryDoesNotContainException(); } return e_; } - const exception_wrapper& exception() const { + exception_wrapper&& exception() && { + if (!hasException()) { + try_detail::throwTryDoesNotContainException(); + } + return std::move(e_); + } + + const exception_wrapper& exception() const & { if (!hasException()) { try_detail::throwTryDoesNotContainException(); } return e_; } + const exception_wrapper&& exception() const && { + if (!hasException()) { + try_detail::throwTryDoesNotContainException(); + } + return std::move(e_); + } + /* * @returns a pointer to the `std::exception` held by `*this`, if one is held; * otherwise, returns `nullptr`. @@ -370,20 +384,34 @@ class Try { * * @returns mutable reference to the exception contained by this Try */ - exception_wrapper& exception() { + exception_wrapper& exception() & { if (!hasException()) { try_detail::throwTryDoesNotContainException(); } return e_; } - const exception_wrapper& exception() const { + exception_wrapper&& exception() && { + if (!hasException()) { + try_detail::throwTryDoesNotContainException(); + } + return std::move(e_); + } + + const exception_wrapper& exception() const & { if (!hasException()) { try_detail::throwTryDoesNotContainException(); } return e_; } + const exception_wrapper&& exception() const && { + if (!hasException()) { + try_detail::throwTryDoesNotContainException(); + } + return std::move(e_); + } + /* * @returns a pointer to the `std::exception` held by `*this`, if one is held; * otherwise, returns `nullptr`. diff --git a/folly/test/TryTest.cpp b/folly/test/TryTest.cpp index ae9e301f..5fdd231d 100644 --- a/folly/test/TryTest.cpp +++ b/folly/test/TryTest.cpp @@ -109,6 +109,69 @@ TEST(Try, makeTryWithVoidThrow) { EXPECT_TRUE(result.hasException()); } +TEST(Try, exception) { + using ML = exception_wrapper&; + using MR = exception_wrapper&&; + using CL = exception_wrapper const&; + using CR = exception_wrapper const&&; + + { + auto obj = Try(); + using ActualML = decltype(obj.exception()); + using ActualMR = decltype(std::move(obj).exception()); + using ActualCL = decltype(as_const(obj).exception()); + using ActualCR = decltype(std::move(as_const(obj)).exception()); + EXPECT_TRUE((std::is_same::value)); + EXPECT_TRUE((std::is_same::value)); + EXPECT_TRUE((std::is_same::value)); + EXPECT_TRUE((std::is_same::value)); + } + + { + auto obj = Try(3); + EXPECT_THROW(obj.exception(), TryException); + EXPECT_THROW(std::move(obj).exception(), TryException); + EXPECT_THROW(as_const(obj).exception(), TryException); + EXPECT_THROW(std::move(as_const(obj)).exception(), TryException); + } + + { + auto obj = Try(make_exception_wrapper(-3)); + EXPECT_EQ(-3, *obj.exception().get_exception()); + EXPECT_EQ(-3, *std::move(obj).exception().get_exception()); + EXPECT_EQ(-3, *as_const(obj).exception().get_exception()); + EXPECT_EQ(-3, *std::move(as_const(obj)).exception().get_exception()); + } + + { + auto obj = Try(); + using ActualML = decltype(obj.exception()); + using ActualMR = decltype(std::move(obj).exception()); + using ActualCL = decltype(as_const(obj).exception()); + using ActualCR = decltype(std::move(as_const(obj)).exception()); + EXPECT_TRUE((std::is_same::value)); + EXPECT_TRUE((std::is_same::value)); + EXPECT_TRUE((std::is_same::value)); + EXPECT_TRUE((std::is_same::value)); + } + + { + auto obj = Try(); + EXPECT_THROW(obj.exception(), TryException); + EXPECT_THROW(std::move(obj).exception(), TryException); + EXPECT_THROW(as_const(obj).exception(), TryException); + EXPECT_THROW(std::move(as_const(obj)).exception(), TryException); + } + + { + auto obj = Try(make_exception_wrapper(-3)); + EXPECT_EQ(-3, *obj.exception().get_exception()); + EXPECT_EQ(-3, *std::move(obj).exception().get_exception()); + EXPECT_EQ(-3, *as_const(obj).exception().get_exception()); + EXPECT_EQ(-3, *std::move(as_const(obj)).exception().get_exception()); + } +} + template static E* get_exception(std::exception_ptr eptr) { try {