ExceptionWrapper: use std::decay in implicit constructor
authorTudor Bosman <tudorb@fb.com>
Fri, 12 Jun 2015 23:57:02 +0000 (16:57 -0700)
committerSara Golemon <sgolemon@fb.com>
Mon, 15 Jun 2015 20:34:36 +0000 (13:34 -0700)
Summary: Because Ex resolves to SomeException&, and then all the tests in optimize<>
fail.

Reviewed By: @yfeldblum

Differential Revision: D2152893

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

index a99e84d95a8f35e9deb95665275efe28130fa47a..bfe19a03791e8bb5db99175e77ee41460c98f52a 100644 (file)
@@ -112,10 +112,12 @@ class exception_wrapper {
   // Implicitly construct an exception_wrapper from a qualifying exception.
   // See the optimize struct for details.
   template <typename Ex, typename =
-    typename std::enable_if<optimize<Ex>::value>::type>
+    typename std::enable_if<optimize<typename std::decay<Ex>::type>::value>
+    ::type>
   /* implicit */ exception_wrapper(Ex&& exn) {
-    item_ = std::make_shared<Ex>(std::forward<Ex>(exn));
-    throwfn_ = folly::detail::Thrower<Ex>::doThrow;
+    typedef typename std::decay<Ex>::type DEx;
+    item_ = std::make_shared<DEx>(std::forward<Ex>(exn));
+    throwfn_ = folly::detail::Thrower<DEx>::doThrow;
   }
 
   // The following two constructors are meant to emulate the behavior of
index a12445adb514fab2e6c9cba6a8b3ab35cc592460..47b18d2ef5fbc200c01d2be0cce91cd2af1c3cc7 100644 (file)
@@ -227,3 +227,17 @@ TEST(ExceptionWrapper, exceptionStr) {
   auto ew = make_exception_wrapper<std::runtime_error>("argh");
   EXPECT_EQ("std::runtime_error: argh", exceptionStr(ew));
 }
+
+namespace {
+class TestException : public std::exception { };
+void testEW(const exception_wrapper& ew) {
+  EXPECT_THROW(ew.throwException(), TestException);
+}
+}  // namespace
+
+TEST(ExceptionWrapper, implicitConstruction) {
+  // Try with both lvalue and rvalue references
+  TestException e;
+  testEW(e);
+  testEW(TestException());
+}