2 * Copyright 2014 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <type_traits>
22 #include <folly/ExceptionWrapper.h>
23 #include <folly/Likely.h>
24 #include <folly/Memory.h>
25 #include <folly/wangle/futures/Deprecated.h>
26 #include <folly/wangle/futures/WangleException.h>
28 namespace folly { namespace wangle {
32 static_assert(!std::is_reference<T>::value,
33 "Try may not be used with reference types");
42 typedef T element_type;
44 Try() : contains_(Contains::NOTHING) {}
45 explicit Try(const T& v) : contains_(Contains::VALUE), value_(v) {}
46 explicit Try(T&& v) : contains_(Contains::VALUE), value_(std::move(v)) {}
47 explicit Try(exception_wrapper e)
48 : contains_(Contains::EXCEPTION),
49 e_(folly::make_unique<exception_wrapper>(std::move(e))) {}
50 explicit Try(std::exception_ptr ep) DEPRECATED
51 : contains_(Contains::EXCEPTION) {
53 std::rethrow_exception(ep);
54 } catch (const std::exception& e) {
55 e_ = folly::make_unique<exception_wrapper>(std::current_exception(), e);
57 e_ = folly::make_unique<exception_wrapper>(std::current_exception());
63 Try& operator=(Try<T>&& t);
66 Try(const Try<T>& t) = delete;
67 Try& operator=(const Try<T>& t) = delete;
72 const T& value() const;
74 void throwIfFailed() const;
76 const T& operator*() const { return value(); }
77 T& operator*() { return value(); }
79 const T* operator->() const { return &value(); }
80 T* operator->() { return &value(); }
82 bool hasValue() const { return contains_ == Contains::VALUE; }
83 bool hasException() const { return contains_ == Contains::EXCEPTION; }
86 bool hasException() const {
87 return hasException() && e_->is_compatible_with<Ex>();
90 exception_wrapper& exception() {
91 if (UNLIKELY(!hasException())) {
92 throw WangleException("exception(): Try does not contain an exception");
97 template <class Ex, class F>
98 bool withException(F func) const {
99 if (!hasException()) {
102 return e_->with_exception<Ex>(std::move(func));
109 std::unique_ptr<exception_wrapper> e_;
116 Try() : hasValue_(true) {}
117 explicit Try(exception_wrapper e)
119 e_(folly::make_unique<exception_wrapper>(std::move(e))) {}
120 explicit Try(std::exception_ptr ep) DEPRECATED : hasValue_(false) {
122 std::rethrow_exception(ep);
123 } catch (const std::exception& e) {
124 e_ = folly::make_unique<exception_wrapper>(std::current_exception(), e);
126 e_ = folly::make_unique<exception_wrapper>(std::current_exception());
130 Try& operator=(const Try<void>& t) {
131 hasValue_ = t.hasValue_;
133 e_ = folly::make_unique<exception_wrapper>(*t.e_);
137 Try(const Try<void>& t) {
141 void value() const { throwIfFailed(); }
142 void operator*() const { return value(); }
144 inline void throwIfFailed() const;
146 bool hasValue() const { return hasValue_; }
147 bool hasException() const { return !hasValue_; }
150 bool hasException() const {
151 return hasException() && e_->is_compatible_with<Ex>();
154 exception_wrapper& exception() {
155 if (UNLIKELY(!hasException())) {
156 throw WangleException("exception(): Try does not contain an exception");
161 template <class Ex, class F>
162 bool withException(F func) const {
163 if (!hasException()) {
166 return e_->with_exception<Ex>(std::move(func));
171 std::unique_ptr<exception_wrapper> e_{nullptr};
175 * Extracts value from try and returns it. Throws if try contained an exception.
177 template <typename T>
178 T moveFromTry(wangle::Try<T>&& t);
181 * Throws if try contained an exception.
183 void moveFromTry(wangle::Try<void>&& t);
186 * Constructs Try based on the result of execution of function f (e.g. result
189 template <typename F>
190 typename std::enable_if<
191 !std::is_same<typename std::result_of<F()>::type, void>::value,
192 Try<typename std::result_of<F()>::type>>::type
193 makeTryFunction(F&& f);
196 * makeTryFunction specialization for void functions.
198 template <typename F>
199 typename std::enable_if<
200 std::is_same<typename std::result_of<F()>::type, void>::value,
202 makeTryFunction(F&& f);
207 #include <folly/wangle/futures/Try-inl.h>