2 * Copyright 2016 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.
24 Try<T>::Try(Try<T>&& t) noexcept : contains_(t.contains_) {
25 if (contains_ == Contains::VALUE) {
26 new (&value_)T(std::move(t.value_));
27 } else if (contains_ == Contains::EXCEPTION) {
28 new (&e_)std::unique_ptr<exception_wrapper>(std::move(t.e_));
34 Try<T>::Try(typename std::enable_if<std::is_same<Unit, T2>::value,
35 Try<void> const&>::type t)
36 : contains_(Contains::NOTHING) {
38 contains_ = Contains::VALUE;
40 } else if (t.hasException()) {
41 contains_ = Contains::EXCEPTION;
42 new (&e_) std::unique_ptr<exception_wrapper>(
43 folly::make_unique<exception_wrapper>(t.exception()));
48 Try<T>& Try<T>::operator=(Try<T>&& t) noexcept {
54 contains_ = t.contains_;
55 if (contains_ == Contains::VALUE) {
56 new (&value_)T(std::move(t.value_));
57 } else if (contains_ == Contains::EXCEPTION) {
58 new (&e_)std::unique_ptr<exception_wrapper>(std::move(t.e_));
64 Try<T>::Try(const Try<T>& t) {
66 std::is_copy_constructible<T>::value,
67 "T must be copyable for Try<T> to be copyable");
68 contains_ = t.contains_;
69 if (contains_ == Contains::VALUE) {
70 new (&value_)T(t.value_);
71 } else if (contains_ == Contains::EXCEPTION) {
72 new (&e_)std::unique_ptr<exception_wrapper>();
73 e_ = folly::make_unique<exception_wrapper>(*(t.e_));
78 Try<T>& Try<T>::operator=(const Try<T>& t) {
80 std::is_copy_constructible<T>::value,
81 "T must be copyable for Try<T> to be copyable");
83 contains_ = t.contains_;
84 if (contains_ == Contains::VALUE) {
85 new (&value_)T(t.value_);
86 } else if (contains_ == Contains::EXCEPTION) {
87 new (&e_)std::unique_ptr<exception_wrapper>();
88 e_ = folly::make_unique<exception_wrapper>(*(t.e_));
95 if (LIKELY(contains_ == Contains::VALUE)) {
97 } else if (UNLIKELY(contains_ == Contains::EXCEPTION)) {
98 e_.~unique_ptr<exception_wrapper>();
103 T& Try<T>::value() & {
109 T&& Try<T>::value() && {
111 return std::move(value_);
115 const T& Try<T>::value() const & {
121 void Try<T>::throwIfFailed() const {
122 if (contains_ != Contains::VALUE) {
123 if (contains_ == Contains::EXCEPTION) {
124 e_->throwException();
126 throw UsingUninitializedTry();
131 void Try<void>::throwIfFailed() const {
133 e_->throwException();
137 template <typename T>
138 inline T moveFromTry(Try<T>& t) {
139 return std::move(t.value());
142 inline void moveFromTry(Try<void>& t) {
146 template <typename F>
147 typename std::enable_if<
148 !std::is_same<typename std::result_of<F()>::type, void>::value,
149 Try<typename std::result_of<F()>::type>>::type
151 typedef typename std::result_of<F()>::type ResultType;
153 return Try<ResultType>(f());
154 } catch (std::exception& e) {
155 return Try<ResultType>(exception_wrapper(std::current_exception(), e));
157 return Try<ResultType>(exception_wrapper(std::current_exception()));
161 template <typename F>
162 typename std::enable_if<
163 std::is_same<typename std::result_of<F()>::type, void>::value,
169 } catch (std::exception& e) {
170 return Try<void>(exception_wrapper(std::current_exception(), e));
172 return Try<void>(exception_wrapper(std::current_exception()));