equality for exception_wrapper
authorVictor Loh <vloh@fb.com>
Fri, 12 Sep 2014 22:03:39 +0000 (15:03 -0700)
committerDave Watson <davejwatson@fb.com>
Mon, 15 Sep 2014 21:30:19 +0000 (14:30 -0700)
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

folly/ExceptionWrapper.h
folly/test/ExceptionWrapperTest.cpp

index 080822323b19003d73260d8632d122abb551491c..c06197273f9c76f708428048f29af9ff6d984abf 100644 (file)
@@ -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
index e04b9f47d649e39cda355d2b0e083b2b37ca6d1a..ad8c43cef0c6c54faea6ce6b8e085cea4be184a8 100644 (file)
@@ -45,6 +45,41 @@ TEST(ExceptionWrapper, boolean) {
   EXPECT_TRUE(bool(ew));
 }
 
+TEST(ExceptionWrapper, equals) {
+  std::runtime_error e("payload");
+  auto ew1 = make_exception_wrapper<std::runtime_error>(e);
+  auto ew2 = ew1;
+  EXPECT_EQ(ew1, ew2);
+
+  auto ew3 = try_and_catch<std::exception>([&]() {
+    throw std::runtime_error("payload");
+  });
+  auto ew4 = try_and_catch<std::exception>([&]() {
+    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<std::runtime_error>(e1);
+  auto ew2 = make_exception_wrapper<std::runtime_error>(e2);
+  EXPECT_NE(ew1, ew2);
+
+  auto ew3 = make_exception_wrapper<std::runtime_error>(e1);
+  auto ew4 = make_exception_wrapper<std::runtime_error>(e1);
+  EXPECT_NE(ew3, ew4);
+
+  auto ew5 = try_and_catch<std::exception>([&]() {
+    throw e1;
+  });
+  auto ew6 = try_and_catch<std::exception>([&]() {
+    throw e1;
+  });
+  EXPECT_NE(ew5, ew6);
+}
+
 TEST(ExceptionWrapper, try_and_catch_test) {
   std::string expected = "payload";