Add method, that constructs Try<T> based on the result of functor.
authorStepan Palamarchuk <stepan@fb.com>
Tue, 25 Feb 2014 22:42:55 +0000 (14:42 -0800)
committerDave Watson <davejwatson@fb.com>
Fri, 28 Feb 2014 22:02:58 +0000 (14:02 -0800)
Summary:
Usually we construct Try<T> as a result of execution of some functor.
And we need to treat void and non-void functors in similar way, but that requires different, yet similar pieces of code.

This diff simplifies future usage of Try.

Test Plan: compile only

Reviewed By: andrii@fb.com

FB internal diff: D1190296

folly/wangle/Try-inl.h
folly/wangle/Try.h
folly/wangle/test/Try.cpp [new file with mode: 0644]

index 68b412120dca0e985fa760d105743341aab25939..760ad55193f1ed5e9e95d362936d1281e5c02645 100644 (file)
@@ -90,4 +90,31 @@ inline void moveFromTry(wangle::Try<void>&& t) {
   return t.value();
 }
 
   return t.value();
 }
 
+template <typename F>
+typename std::enable_if<
+  !std::is_same<typename std::result_of<F()>::type, void>::value,
+  Try<typename std::result_of<F()>::type>>::type
+makeTryFunction(F&& f) {
+  typedef typename std::result_of<F()>::type ResultType;
+  try {
+    auto value = f();
+    return Try<ResultType>(std::move(value));
+  } catch (...) {
+    return Try<ResultType>(std::current_exception());
+  }
+}
+
+template <typename F>
+typename std::enable_if<
+  std::is_same<typename std::result_of<F()>::type, void>::value,
+  Try<void>>::type
+makeTryFunction(F&& f) {
+  try {
+    f();
+    return Try<void>();
+  } catch (...) {
+    return Try<void>(std::current_exception());
+  }
+}
+
 }}
 }}
index 1e1df07d73c8ef575a2c7d3e34b2d6e4ba110da8..2e740c20f475918c07c20ee37442510e45bb240e 100644 (file)
@@ -99,6 +99,26 @@ T moveFromTry(wangle::Try<T>&& t);
  */
 void moveFromTry(wangle::Try<void>&& t);
 
  */
 void moveFromTry(wangle::Try<void>&& t);
 
+/**
+ * Constructs Try based on the result of execution of function f (e.g. result
+ * or exception).
+ */
+template <typename F>
+typename std::enable_if<
+  !std::is_same<typename std::result_of<F()>::type, void>::value,
+  Try<typename std::result_of<F()>::type>>::type
+makeTryFunction(F&& f);
+
+/**
+ * makeTryFunction specialization for void functions.
+ */
+template <typename F>
+typename std::enable_if<
+  std::is_same<typename std::result_of<F()>::type, void>::value,
+  Try<void>>::type
+makeTryFunction(F&& f);
+
+
 }}
 
 #include "Try-inl.h"
 }}
 
 #include "Try-inl.h"
diff --git a/folly/wangle/test/Try.cpp b/folly/wangle/test/Try.cpp
new file mode 100644 (file)
index 0000000..f8affab
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include "folly/Memory.h"
+#include "folly/wangle/Try.h"
+
+using namespace folly::wangle;
+
+TEST(Try, makeTryFunction) {
+  auto func = []() {
+    return folly::make_unique<int>(1);
+  };
+
+  auto result = makeTryFunction(func);
+  EXPECT_TRUE(result.hasValue());
+  EXPECT_EQ(*result.value(), 1);
+}
+
+TEST(Try, makeTryFunctionThrow) {
+  auto func = []() {
+    throw std::runtime_error("Runtime");
+    return folly::make_unique<int>(1);
+  };
+
+  auto result = makeTryFunction(func);
+  EXPECT_TRUE(result.hasException());
+}
+
+TEST(Try, makeTryFunctionVoid) {
+  auto func = []() {
+    return;
+  };
+
+  auto result = makeTryFunction(func);
+  EXPECT_TRUE(result.hasValue());
+}
+
+TEST(Try, makeTryFunctionVoidThrow) {
+  auto func = []() {
+    throw std::runtime_error("Runtime");
+    return;
+  };
+
+  auto result = makeTryFunction(func);
+  EXPECT_TRUE(result.hasException());
+}