From: Victor Loh Date: Fri, 12 Sep 2014 22:03:39 +0000 (-0700) Subject: equality for exception_wrapper X-Git-Tag: v0.22.0~364 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=6b82bb37845de2c5f4885fd2527e9a4a77bb0129;p=folly.git equality for exception_wrapper Summary: std::exception_ptr expose methods to compare equality and it will be great to do so for folly::exception_wrapper (it helps in gmock testing). Test Plan: added some unit tests to test this new functionality Reviewed By: mhorowitz@fb.com Subscribers: njormrod FB internal diff: D1546597 --- diff --git a/folly/ExceptionWrapper.h b/folly/ExceptionWrapper.h index 08082232..c0619727 100644 --- a/folly/ExceptionWrapper.h +++ b/folly/ExceptionWrapper.h @@ -117,6 +117,23 @@ class exception_wrapper { return item_ || eptr_; } + // This implementation is similar to std::exception_ptr's implementation + // where two exception_wrappers are equal when the address in the underlying + // reference field both point to the same exception object. The reference + // field remains the same when the exception_wrapper is copied or when + // the exception_wrapper is "rethrown". + bool operator==(const exception_wrapper& a) const { + if (item_) { + return a.item_ && item_.get() == a.item_.get(); + } else { + return eptr_ == a.eptr_; + } + } + + bool operator!=(const exception_wrapper& a) const { + return !(*this == a); + } + // This will return a non-nullptr only if the exception is held as a // copy. It is the only interface which will distinguish between an // exception held this way, and by exception_ptr. You probably diff --git a/folly/test/ExceptionWrapperTest.cpp b/folly/test/ExceptionWrapperTest.cpp index e04b9f47..ad8c43ce 100644 --- a/folly/test/ExceptionWrapperTest.cpp +++ b/folly/test/ExceptionWrapperTest.cpp @@ -45,6 +45,41 @@ TEST(ExceptionWrapper, boolean) { EXPECT_TRUE(bool(ew)); } +TEST(ExceptionWrapper, equals) { + std::runtime_error e("payload"); + auto ew1 = make_exception_wrapper(e); + auto ew2 = ew1; + EXPECT_EQ(ew1, ew2); + + auto ew3 = try_and_catch([&]() { + throw std::runtime_error("payload"); + }); + auto ew4 = try_and_catch([&]() { + ew3.throwException(); + }); + EXPECT_EQ(ew3, ew4); +} + +TEST(ExceptionWrapper, not_equals) { + std::runtime_error e1("payload"); + std::runtime_error e2("payload"); + auto ew1 = make_exception_wrapper(e1); + auto ew2 = make_exception_wrapper(e2); + EXPECT_NE(ew1, ew2); + + auto ew3 = make_exception_wrapper(e1); + auto ew4 = make_exception_wrapper(e1); + EXPECT_NE(ew3, ew4); + + auto ew5 = try_and_catch([&]() { + throw e1; + }); + auto ew6 = try_and_catch([&]() { + throw e1; + }); + EXPECT_NE(ew5, ew6); +} + TEST(ExceptionWrapper, try_and_catch_test) { std::string expected = "payload";