proxygen
Try-inl.h
Go to the documentation of this file.
1 /*
2  * Copyright 2014-present Facebook, Inc.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 
17 #pragma once
18 
19 #include <folly/Utility.h>
21 
22 #include <stdexcept>
23 #include <tuple>
24 
25 namespace folly {
26 
27 template <class T>
28 Try<T>::Try(Try<T>&& t) noexcept(std::is_nothrow_move_constructible<T>::value)
29  : contains_(t.contains_) {
30  if (contains_ == Contains::VALUE) {
31  new (&value_) T(std::move(t.value_));
32  } else if (contains_ == Contains::EXCEPTION) {
33  new (&e_) exception_wrapper(std::move(t.e_));
34  }
35 }
36 
37 template <class T>
38 template <class T2>
39 Try<T>::Try(typename std::enable_if<
41  Try<void> const&>::type t) noexcept
42  : contains_(Contains::NOTHING) {
43  if (t.hasValue()) {
44  contains_ = Contains::VALUE;
45  new (&value_) T();
46  } else if (t.hasException()) {
47  contains_ = Contains::EXCEPTION;
48  new (&e_) exception_wrapper(t.exception());
49  }
50 }
51 
52 template <class T>
54  std::is_nothrow_move_constructible<T>::value) {
55  if (this == &t) {
56  return *this;
57  }
58 
59  destroy();
60 
61  if (t.contains_ == Contains::VALUE) {
62  new (&value_) T(std::move(t.value_));
63  } else if (t.contains_ == Contains::EXCEPTION) {
64  new (&e_) exception_wrapper(std::move(t.e_));
65  }
66 
67  contains_ = t.contains_;
68 
69  return *this;
70 }
71 
72 template <class T>
75  static_assert(
77  "T must be copyable for Try<T> to be copyable");
78  contains_ = t.contains_;
79  if (contains_ == Contains::VALUE) {
80  new (&value_) T(t.value_);
81  } else if (contains_ == Contains::EXCEPTION) {
82  new (&e_) exception_wrapper(t.e_);
83  }
84 }
85 
86 template <class T>
89  static_assert(
91  "T must be copyable for Try<T> to be copyable");
92 
93  if (this == &t) {
94  return *this;
95  }
96 
97  destroy();
98 
99  if (t.contains_ == Contains::VALUE) {
100  new (&value_) T(t.value_);
101  } else if (t.contains_ == Contains::EXCEPTION) {
102  new (&e_) exception_wrapper(t.e_);
103  }
104 
105  contains_ = t.contains_;
106 
107  return *this;
108 }
109 
110 template <class T>
112  if (LIKELY(contains_ == Contains::VALUE)) {
113  value_.~T();
114  } else if (UNLIKELY(contains_ == Contains::EXCEPTION)) {
115  e_.~exception_wrapper();
116  }
117 }
118 
119 template <typename T>
120 template <typename... Args>
122  std::is_nothrow_constructible<T, Args&&...>::value) {
123  this->destroy();
124  new (&value_) T(static_cast<Args&&>(args)...);
125  contains_ = Contains::VALUE;
126  return value_;
127 }
128 
129 template <typename T>
130 template <typename... Args>
132  std::is_nothrow_constructible<exception_wrapper, Args&&...>::value) {
133  this->destroy();
134  new (&e_) exception_wrapper(static_cast<Args&&>(args)...);
135  contains_ = Contains::EXCEPTION;
136  return e_;
137 }
138 
139 template <class T>
141  throwIfFailed();
142  return value_;
143 }
144 
145 template <class T>
146 T&& Try<T>::value() && {
147  throwIfFailed();
148  return std::move(value_);
149 }
150 
151 template <class T>
152 const T& Try<T>::value() const& {
153  throwIfFailed();
154  return value_;
155 }
156 
157 template <class T>
158 const T&& Try<T>::value() const&& {
159  throwIfFailed();
160  return std::move(value_);
161 }
162 
163 template <class T>
164 void Try<T>::throwIfFailed() const {
165  switch (contains_) {
166  case Contains::VALUE:
167  return;
168  case Contains::EXCEPTION:
169  e_.throw_exception();
170  default:
171  throw_exception<UsingUninitializedTry>();
172  }
173 }
174 
175 template <class T>
177  auto oldContains = folly::exchange(contains_, Contains::NOTHING);
178  if (LIKELY(oldContains == Contains::VALUE)) {
179  value_.~T();
180  } else if (UNLIKELY(oldContains == Contains::EXCEPTION)) {
181  e_.~exception_wrapper();
182  }
183 }
184 
186  if (t.hasException()) {
187  if (hasException()) {
188  e_ = t.e_;
189  } else {
190  new (&e_) exception_wrapper(t.e_);
191  hasValue_ = false;
192  }
193  } else {
194  if (hasException()) {
195  e_.~exception_wrapper();
196  hasValue_ = true;
197  }
198  }
199  return *this;
200 }
201 
202 template <typename... Args>
204  std::is_nothrow_constructible<exception_wrapper, Args&&...>::value) {
205  if (hasException()) {
207  }
208  new (&e_) exception_wrapper(static_cast<Args&&>(args)...);
209  hasValue_ = false;
210  return e_;
211 }
212 
214  if (hasException()) {
216  }
217 }
218 
219 template <typename F>
220 typename std::enable_if<
221  !std::is_same<invoke_result_t<F>, void>::value,
224  using ResultType = invoke_result_t<F>;
225  try {
226  return Try<ResultType>(f());
227  } catch (std::exception& e) {
228  return Try<ResultType>(exception_wrapper(std::current_exception(), e));
229  } catch (...) {
230  return Try<ResultType>(exception_wrapper(std::current_exception()));
231  }
232 }
233 
234 template <typename F>
235 typename std::
236  enable_if<std::is_same<invoke_result_t<F>, void>::value, Try<void>>::type
237  makeTryWith(F&& f) {
238  try {
239  f();
240  return Try<void>();
241  } catch (std::exception& e) {
242  return Try<void>(exception_wrapper(std::current_exception(), e));
243  } catch (...) {
244  return Try<void>(exception_wrapper(std::current_exception()));
245  }
246 }
247 
248 template <typename T, typename... Args>
249 T* tryEmplace(Try<T>& t, Args&&... args) noexcept {
250  try {
251  return std::addressof(t.emplace(static_cast<Args&&>(args)...));
252  } catch (const std::exception& ex) {
253  t.emplaceException(std::current_exception(), ex);
254  return nullptr;
255  } catch (...) {
256  t.emplaceException(std::current_exception());
257  return nullptr;
258  }
259 }
260 
262  t.emplace();
263 }
264 
265 template <typename T, typename Func>
267  static_assert(
268  std::is_constructible<T, folly::invoke_result_t<Func>>::value,
269  "Unable to initialise a value of type T with the result of 'func'");
270  try {
271  return std::addressof(t.emplace(static_cast<Func&&>(func)()));
272  } catch (const std::exception& ex) {
273  t.emplaceException(std::current_exception(), ex);
274  return nullptr;
275  } catch (...) {
276  t.emplaceException(std::current_exception());
277  return nullptr;
278  }
279 }
280 
281 template <typename Func>
283  static_assert(
284  std::is_void<folly::invoke_result_t<Func>>::value,
285  "Func returns non-void. Cannot be used to emplace Try<void>");
286  try {
287  static_cast<Func&&>(func)();
288  t.emplace();
289  return true;
290  } catch (const std::exception& ex) {
291  t.emplaceException(std::current_exception(), ex);
292  return false;
293  } catch (...) {
294  t.emplaceException(std::current_exception());
295  return false;
296  }
297 }
298 
299 namespace try_detail {
300 
304 template <typename Type>
305 struct RemoveTry;
306 template <template <typename...> class TupleType, typename... Types>
307 struct RemoveTry<TupleType<folly::Try<Types>...>> {
308  using type = TupleType<Types...>;
309 };
310 
311 template <std::size_t... Indices, typename Tuple>
313  using std::get;
314  using ReturnType = typename RemoveTry<typename std::decay<Tuple>::type>::type;
315  return ReturnType{(get<Indices>(std::forward<Tuple>(instance)).value())...};
316 }
317 } // namespace try_detail
318 
319 template <typename Tuple>
320 auto unwrapTryTuple(Tuple&& instance) {
321  using TupleDecayed = typename std::decay<Tuple>::type;
323  return try_detail::unwrapTryTupleImpl(Seq{}, std::forward<Tuple>(instance));
324 }
325 
326 } // namespace folly
T * tryEmplace(Try< T > &t, Args &&...args) noexcept
Definition: Try-inl.h:249
auto f
void destroy() noexcept
Definition: Try-inl.h:176
typename invoke_result< F, Args... >::type invoke_result_t
Definition: Invoke.h:142
Try & operator=(Try< T > &&t) noexcept(std::is_nothrow_move_constructible< T >::value)
Definition: Try-inl.h:53
T & emplace(Args &&...args) noexcept(std::is_nothrow_constructible< T, Args &&... >::value)
Definition: Try-inl.h:121
PskType type
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
#define LIKELY(x)
Definition: Likely.h:47
exception_wrapper e_
Definition: Try.h:374
STL namespace.
folly::std T
internal::ArgsMatcher< InnerMatcher > Args(const InnerMatcher &matcher)
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
requires E e noexcept(noexcept(s.error(std::move(e))))
T * tryEmplaceWith(Try< T > &t, Func &&func) noexcept
Definition: Try-inl.h:266
static void destroy()
bool hasException() const
Definition: Try.h:248
void emplace() noexcept
Definition: Try.h:423
make_integer_sequence< std::size_t, Size > make_index_sequence
Definition: Utility.h:209
exception_wrapper & emplaceException(Args &&...args) noexcept(std::is_nothrow_constructible< exception_wrapper, Args &&... >::value)
Definition: Try-inl.h:203
static const char *const value
Definition: Conv.cpp:50
Try() noexcept
Definition: Try.h:71
Definition: Try.h:51
T exchange(T &obj, U &&new_value)
Definition: Utility.h:120
auto unwrapTryTupleImpl(folly::index_sequence< Indices... >, Tuple &&instance)
Definition: Try-inl.h:312
void throwIfFailed() const
Definition: Try-inl.h:164
std::enable_if< !std::is_same< invoke_result_t< F >, void >::value, Try< invoke_result_t< F > > >::type makeTryWith(F &&f)
Definition: Try-inl.h:223
const
Definition: upload.py:398
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
exception_wrapper & emplaceException(Args &&...args) noexcept(std::is_nothrow_constructible< exception_wrapper, Args &&... >::value)
Definition: Try-inl.h:131
T & value()&
Definition: Try-inl.h:140
#define UNLIKELY(x)
Definition: Likely.h:48
PUSHMI_INLINE_VAR constexpr detail::get_fn< T > get
Definition: submit.h:391
auto unwrapTryTuple(Tuple &&instance)
Definition: Try-inl.h:320