futures/SharedPromise-inl.h \
futures/ThreadWheelTimekeeper.h \
futures/Timekeeper.h \
- futures/Try-inl.h \
- futures/Try.h \
futures/detail/Core.h \
futures/detail/FSM.h \
futures/detail/Types.h \
ThreadName.h \
TimeoutQueue.h \
Traits.h \
+ Try-inl.h \
+ Try.h \
Unicode.h \
Function.h \
Unit.h \
--- /dev/null
+/*
+ * Copyright 2016 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.
+ */
+
+#pragma once
+
+#include <stdexcept>
+
+namespace folly {
+
+template <class T>
+Try<T>::Try(Try<T>&& t) noexcept : contains_(t.contains_) {
+ if (contains_ == Contains::VALUE) {
+ new (&value_)T(std::move(t.value_));
+ } else if (contains_ == Contains::EXCEPTION) {
+ new (&e_)std::unique_ptr<exception_wrapper>(std::move(t.e_));
+ }
+}
+
+template <class T>
+template <class T2>
+Try<T>::Try(typename std::enable_if<std::is_same<Unit, T2>::value,
+ Try<void> const&>::type t)
+ : contains_(Contains::NOTHING) {
+ if (t.hasValue()) {
+ contains_ = Contains::VALUE;
+ new (&value_) T();
+ } else if (t.hasException()) {
+ contains_ = Contains::EXCEPTION;
+ new (&e_) std::unique_ptr<exception_wrapper>(
+ folly::make_unique<exception_wrapper>(t.exception()));
+ }
+}
+
+template <class T>
+Try<T>& Try<T>::operator=(Try<T>&& t) noexcept {
+ if (this == &t) {
+ return *this;
+ }
+
+ this->~Try();
+ contains_ = t.contains_;
+ if (contains_ == Contains::VALUE) {
+ new (&value_)T(std::move(t.value_));
+ } else if (contains_ == Contains::EXCEPTION) {
+ new (&e_)std::unique_ptr<exception_wrapper>(std::move(t.e_));
+ }
+ return *this;
+}
+
+template <class T>
+Try<T>::Try(const Try<T>& t) {
+ static_assert(
+ std::is_copy_constructible<T>::value,
+ "T must be copyable for Try<T> to be copyable");
+ contains_ = t.contains_;
+ if (contains_ == Contains::VALUE) {
+ new (&value_)T(t.value_);
+ } else if (contains_ == Contains::EXCEPTION) {
+ new (&e_)std::unique_ptr<exception_wrapper>();
+ e_ = folly::make_unique<exception_wrapper>(*(t.e_));
+ }
+}
+
+template <class T>
+Try<T>& Try<T>::operator=(const Try<T>& t) {
+ static_assert(
+ std::is_copy_constructible<T>::value,
+ "T must be copyable for Try<T> to be copyable");
+ this->~Try();
+ contains_ = t.contains_;
+ if (contains_ == Contains::VALUE) {
+ new (&value_)T(t.value_);
+ } else if (contains_ == Contains::EXCEPTION) {
+ new (&e_)std::unique_ptr<exception_wrapper>();
+ e_ = folly::make_unique<exception_wrapper>(*(t.e_));
+ }
+ return *this;
+}
+
+template <class T>
+Try<T>::~Try() {
+ if (LIKELY(contains_ == Contains::VALUE)) {
+ value_.~T();
+ } else if (UNLIKELY(contains_ == Contains::EXCEPTION)) {
+ e_.~unique_ptr<exception_wrapper>();
+ }
+}
+
+template <class T>
+T& Try<T>::value() & {
+ throwIfFailed();
+ return value_;
+}
+
+template <class T>
+T&& Try<T>::value() && {
+ throwIfFailed();
+ return std::move(value_);
+}
+
+template <class T>
+const T& Try<T>::value() const & {
+ throwIfFailed();
+ return value_;
+}
+
+template <class T>
+void Try<T>::throwIfFailed() const {
+ if (contains_ != Contains::VALUE) {
+ if (contains_ == Contains::EXCEPTION) {
+ e_->throwException();
+ } else {
+ throw UsingUninitializedTry();
+ }
+ }
+}
+
+void Try<void>::throwIfFailed() const {
+ if (!hasValue_) {
+ e_->throwException();
+ }
+}
+
+template <typename T>
+inline T moveFromTry(Try<T>& t) {
+ return std::move(t.value());
+}
+
+inline void moveFromTry(Try<void>& t) {
+ 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
+makeTryWith(F&& f) {
+ typedef typename std::result_of<F()>::type ResultType;
+ try {
+ return Try<ResultType>(f());
+ } catch (std::exception& e) {
+ return Try<ResultType>(exception_wrapper(std::current_exception(), e));
+ } catch (...) {
+ return Try<ResultType>(exception_wrapper(std::current_exception()));
+ }
+}
+
+template <typename F>
+typename std::enable_if<
+ std::is_same<typename std::result_of<F()>::type, void>::value,
+ Try<void>>::type
+makeTryWith(F&& f) {
+ try {
+ f();
+ return Try<void>();
+ } catch (std::exception& e) {
+ return Try<void>(exception_wrapper(std::current_exception(), e));
+ } catch (...) {
+ return Try<void>(exception_wrapper(std::current_exception()));
+ }
+}
+
+} // folly
--- /dev/null
+/*
+ * Copyright 2016 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.
+ */
+
+#pragma once
+
+#include <type_traits>
+#include <exception>
+#include <algorithm>
+#include <folly/ExceptionWrapper.h>
+#include <folly/Likely.h>
+#include <folly/Memory.h>
+#include <folly/Portability.h>
+#include <folly/Unit.h>
+
+namespace folly {
+
+class TryException : public std::exception {
+ public:
+ explicit TryException(std::string message_arg) noexcept
+ : message(std::move(message_arg)) {}
+
+ const char* what() const noexcept override {
+ return message.c_str();
+ }
+
+ bool operator==(const TryException& other) const noexcept {
+ return other.message == this->message;
+ }
+
+ bool operator!=(const TryException& other) const noexcept {
+ return !(*this == other);
+ }
+
+ protected:
+ std::string message;
+};
+
+class UsingUninitializedTry : public TryException {
+ public:
+ UsingUninitializedTry() noexcept : TryException("Using unitialized try") {}
+};
+
+/*
+ * Try<T> is a wrapper that contains either an instance of T, an exception, or
+ * nothing. Exceptions are stored as exception_wrappers so that the user can
+ * minimize rethrows if so desired.
+ *
+ * To represent success or a captured exception, use Try<Unit>.
+ */
+template <class T>
+class Try {
+ static_assert(!std::is_reference<T>::value,
+ "Try may not be used with reference types");
+
+ enum class Contains {
+ VALUE,
+ EXCEPTION,
+ NOTHING,
+ };
+
+ public:
+ /*
+ * The value type for the Try
+ */
+ typedef T element_type;
+
+ /*
+ * Construct an empty Try
+ */
+ Try() : contains_(Contains::NOTHING) {}
+
+ /*
+ * Construct a Try with a value by copy
+ *
+ * @param v The value to copy in
+ */
+ explicit Try(const T& v) : contains_(Contains::VALUE), value_(v) {}
+
+ /*
+ * Construct a Try with a value by move
+ *
+ * @param v The value to move in
+ */
+ explicit Try(T&& v) : contains_(Contains::VALUE), value_(std::move(v)) {}
+
+ /// Implicit conversion from Try<void> to Try<Unit>
+ template <class T2 = T>
+ /* implicit */
+ Try(typename std::enable_if<std::is_same<Unit, T2>::value,
+ Try<void> const&>::type t);
+
+ /*
+ * Construct a Try with an exception_wrapper
+ *
+ * @param e The exception_wrapper
+ */
+ explicit Try(exception_wrapper e)
+ : contains_(Contains::EXCEPTION),
+ e_(folly::make_unique<exception_wrapper>(std::move(e))) {}
+
+ /*
+ * DEPRECATED
+ * Construct a Try with an exception_pointer
+ *
+ * @param ep The exception_pointer. Will be rethrown.
+ */
+ FOLLY_DEPRECATED("use Try(exception_wrapper)")
+ explicit Try(std::exception_ptr ep)
+ : contains_(Contains::EXCEPTION) {
+ try {
+ std::rethrow_exception(ep);
+ } catch (const std::exception& e) {
+ e_ = folly::make_unique<exception_wrapper>(std::current_exception(), e);
+ } catch (...) {
+ e_ = folly::make_unique<exception_wrapper>(std::current_exception());
+ }
+ }
+
+ // Move constructor
+ Try(Try<T>&& t) noexcept;
+ // Move assigner
+ Try& operator=(Try<T>&& t) noexcept;
+
+ // Copy constructor
+ Try(const Try& t);
+ // Copy assigner
+ Try& operator=(const Try& t);
+
+ ~Try();
+
+ /*
+ * Get a mutable reference to the contained value. If the Try contains an
+ * exception it will be rethrown.
+ *
+ * @returns mutable reference to the contained value
+ */
+ T& value()&;
+ /*
+ * Get a rvalue reference to the contained value. If the Try contains an
+ * exception it will be rethrown.
+ *
+ * @returns rvalue reference to the contained value
+ */
+ T&& value()&&;
+ /*
+ * Get a const reference to the contained value. If the Try contains an
+ * exception it will be rethrown.
+ *
+ * @returns const reference to the contained value
+ */
+ const T& value() const&;
+
+ /*
+ * If the Try contains an exception, rethrow it. Otherwise do nothing.
+ */
+ void throwIfFailed() const;
+
+ /*
+ * Const dereference operator. If the Try contains an exception it will be
+ * rethrown.
+ *
+ * @returns const reference to the contained value
+ */
+ const T& operator*() const { return value(); }
+ /*
+ * Dereference operator. If the Try contains an exception it will be rethrown.
+ *
+ * @returns mutable reference to the contained value
+ */
+ T& operator*() { return value(); }
+
+ /*
+ * Const arrow operator. If the Try contains an exception it will be
+ * rethrown.
+ *
+ * @returns const reference to the contained value
+ */
+ const T* operator->() const { return &value(); }
+ /*
+ * Arrow operator. If the Try contains an exception it will be rethrown.
+ *
+ * @returns mutable reference to the contained value
+ */
+ T* operator->() { return &value(); }
+
+ /*
+ * @returns True if the Try contains a value, false otherwise
+ */
+ bool hasValue() const { return contains_ == Contains::VALUE; }
+ /*
+ * @returns True if the Try contains an exception, false otherwise
+ */
+ bool hasException() const { return contains_ == Contains::EXCEPTION; }
+
+ /*
+ * @returns True if the Try contains an exception of type Ex, false otherwise
+ */
+ template <class Ex>
+ bool hasException() const {
+ return hasException() && e_->is_compatible_with<Ex>();
+ }
+
+ exception_wrapper& exception() {
+ if (UNLIKELY(!hasException())) {
+ throw TryException("exception(): Try does not contain an exception");
+ }
+ return *e_;
+ }
+
+ const exception_wrapper& exception() const {
+ if (UNLIKELY(!hasException())) {
+ throw TryException("exception(): Try does not contain an exception");
+ }
+ return *e_;
+ }
+
+ /*
+ * If the Try contains an exception and it is of type Ex, execute func(Ex)
+ *
+ * @param func a function that takes a single parameter of type const Ex&
+ *
+ * @returns True if the Try held an Ex and func was executed, false otherwise
+ */
+ template <class Ex, class F>
+ bool withException(F func) const {
+ if (!hasException()) {
+ return false;
+ }
+ return e_->with_exception(std::move(func));
+ }
+
+ template <bool isTry, typename R>
+ typename std::enable_if<isTry, R>::type get() {
+ return std::forward<R>(*this);
+ }
+
+ template <bool isTry, typename R>
+ typename std::enable_if<!isTry, R>::type get() {
+ return std::forward<R>(value());
+ }
+
+ private:
+ Contains contains_;
+ union {
+ T value_;
+ std::unique_ptr<exception_wrapper> e_;
+ };
+};
+
+/*
+ * Specialization of Try for void value type. Encapsulates either success or an
+ * exception.
+ */
+template <>
+class Try<void> {
+ public:
+ /*
+ * The value type for the Try
+ */
+ typedef void element_type;
+
+ // Construct a Try holding a successful and void result
+ Try() : hasValue_(true) {}
+
+ /*
+ * Construct a Try with an exception_wrapper
+ *
+ * @param e The exception_wrapper
+ */
+ explicit Try(exception_wrapper e)
+ : hasValue_(false),
+ e_(folly::make_unique<exception_wrapper>(std::move(e))) {}
+
+ /*
+ * DEPRECATED
+ * Construct a Try with an exception_pointer
+ *
+ * @param ep The exception_pointer. Will be rethrown.
+ */
+ FOLLY_DEPRECATED("use Try(exception_wrapper)")
+ explicit Try(std::exception_ptr ep) : hasValue_(false) {
+ try {
+ std::rethrow_exception(ep);
+ } catch (const std::exception& e) {
+ e_ = folly::make_unique<exception_wrapper>(std::current_exception(), e);
+ } catch (...) {
+ e_ = folly::make_unique<exception_wrapper>(std::current_exception());
+ }
+ }
+
+ // Copy assigner
+ Try& operator=(const Try<void>& t) {
+ hasValue_ = t.hasValue_;
+ if (t.e_) {
+ e_ = folly::make_unique<exception_wrapper>(*t.e_);
+ }
+ return *this;
+ }
+ // Copy constructor
+ Try(const Try<void>& t) {
+ *this = t;
+ }
+
+ // If the Try contains an exception, throws it
+ void value() const { throwIfFailed(); }
+ // Dereference operator. If the Try contains an exception, throws it
+ void operator*() const { return value(); }
+
+ // If the Try contains an exception, throws it
+ inline void throwIfFailed() const;
+
+ // @returns False if the Try contains an exception, true otherwise
+ bool hasValue() const { return hasValue_; }
+ // @returns True if the Try contains an exception, false otherwise
+ bool hasException() const { return !hasValue_; }
+
+ // @returns True if the Try contains an exception of type Ex, false otherwise
+ template <class Ex>
+ bool hasException() const {
+ return hasException() && e_->is_compatible_with<Ex>();
+ }
+
+ /*
+ * @throws TryException if the Try doesn't contain an exception
+ *
+ * @returns mutable reference to the exception contained by this Try
+ */
+ exception_wrapper& exception() {
+ if (UNLIKELY(!hasException())) {
+ throw TryException("exception(): Try does not contain an exception");
+ }
+ return *e_;
+ }
+
+ const exception_wrapper& exception() const {
+ if (UNLIKELY(!hasException())) {
+ throw TryException("exception(): Try does not contain an exception");
+ }
+ return *e_;
+ }
+
+ /*
+ * If the Try contains an exception and it is of type Ex, execute func(Ex)
+ *
+ * @param func a function that takes a single parameter of type const Ex&
+ *
+ * @returns True if the Try held an Ex and func was executed, false otherwise
+ */
+ template <class Ex, class F>
+ bool withException(F func) const {
+ if (!hasException()) {
+ return false;
+ }
+ return e_->with_exception(std::move(func));
+ }
+
+ template <bool, typename R>
+ R get() {
+ return std::forward<R>(*this);
+ }
+
+ private:
+ bool hasValue_;
+ std::unique_ptr<exception_wrapper> e_{nullptr};
+};
+
+/*
+ * Extracts value from try and returns it. Throws if try contained an exception.
+ *
+ * @param t Try to extract value from
+ *
+ * @returns value contained in t
+ */
+template <typename T>
+T moveFromTry(Try<T>& t);
+
+/*
+ * Throws if try contained an exception.
+ *
+ * @param t Try to move from
+ */
+void moveFromTry(Try<void>& t);
+
+/*
+ * @param f a function to execute and capture the result of (value or exception)
+ *
+ * @returns Try holding the result of f
+ */
+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
+makeTryWith(F&& f);
+
+/*
+ * Specialization of makeTryWith for void return
+ *
+ * @param f a function to execute and capture the result of
+ *
+ * @returns Try<void> holding the result of f
+ */
+template <typename F>
+typename std::enable_if<
+ std::is_same<typename std::result_of<F()>::type, void>::value,
+ Try<void>>::type
+makeTryWith(F&& f);
+
+} // folly
+
+#include <folly/Try-inl.h>
#include <folly/Optional.h>
#include <folly/fibers/FiberManager.h>
#include <folly/fibers/Promise.h>
-#include <folly/futures/Try.h>
+#include <folly/Try.h>
namespace folly {
namespace fibers {
#include <folly/fibers/LoopController.h>
#include <folly/fibers/Promise.h>
#include <folly/futures/Promise.h>
-#include <folly/futures/Try.h>
+#include <folly/Try.h>
namespace folly {
namespace fibers {
#include <folly/Executor.h>
#include <folly/IntrusiveList.h>
#include <folly/Likely.h>
-#include <folly/futures/Try.h>
+#include <folly/Try.h>
#include <folly/io/async/Request.h>
#include <folly/experimental/ExecutionObserver.h>
#pragma once
#include <folly/fibers/traits.h>
-#include <folly/futures/Try.h>
+#include <folly/Try.h>
namespace folly {
namespace fibers {
#include <folly/Portability.h>
#include <folly/futures/DrivableExecutor.h>
#include <folly/futures/Promise.h>
-#include <folly/futures/Try.h>
+#include <folly/Try.h>
#include <folly/futures/FutureException.h>
#include <folly/futures/detail/Types.h>
#pragma once
#include <folly/Portability.h>
-#include <folly/futures/Try.h>
+#include <folly/Try.h>
#include <functional>
namespace folly {
<p>That <tt>then()</tt> method on futures is the real bread and butter of Futures code. It allows you to provide a callback which will be executed when that <tt>Future</tt> is complete. Note that while we fulfill the promise after setting the callback here, those operations could be swapped. Setting a callback on an already completed future executes the callback immediately.</p>
-<p>In this case, the callback takes a value directly. If the Future contained an exception, the callback will be passed over and the exception will be propagated to the resultant Future - more on that in a second. Your callback may also take a <a href="https://github.com/facebook/folly/blob/master/folly/futures/Try.h" target="_blank">Try</a>, which encapsulates either an exception or a value of its templated type.</p>
+<p>In this case, the callback takes a value directly. If the Future contained an exception, the callback will be passed over and the exception will be propagated to the resultant Future - more on that in a second. Your callback may also take a <a href="https://github.com/facebook/folly/blob/master/folly/Try.h" target="_blank">Try</a>, which encapsulates either an exception or a value of its templated type.</p>
<div class="remarkup-code-block" data-code-lang="cpp"><pre class="remarkup-code"><span class=""></span><span class="n">f</span><span class="p">.</span><span class="n">then</span><span class="p">(</span><span class="p">[</span><span class="p">]</span><span class="p">(</span><span class="n">Try</span><span class="o"><</span><span class="kt">int</span><span class="o">></span><span class=""> </span><span class="k">const</span><span class="o">&</span><span class=""> </span><span class="n">t</span><span class="p">)</span><span class="p">{</span><span class="">
</span><span class=""> </span><span class="n">cout</span><span class=""> </span><span class="o"><</span><span class="o"><</span><span class=""> </span><span class="n">t</span><span class="p">.</span><span class="n">value</span><span class="p">(</span><span class="p">)</span><span class="p">;</span><span class="">
+++ /dev/null
-/*
- * Copyright 2016 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.
- */
-
-#pragma once
-
-#include <stdexcept>
-
-namespace folly {
-
-template <class T>
-Try<T>::Try(Try<T>&& t) noexcept : contains_(t.contains_) {
- if (contains_ == Contains::VALUE) {
- new (&value_)T(std::move(t.value_));
- } else if (contains_ == Contains::EXCEPTION) {
- new (&e_)std::unique_ptr<exception_wrapper>(std::move(t.e_));
- }
-}
-
-template <class T>
-template <class T2>
-Try<T>::Try(typename std::enable_if<std::is_same<Unit, T2>::value,
- Try<void> const&>::type t)
- : contains_(Contains::NOTHING) {
- if (t.hasValue()) {
- contains_ = Contains::VALUE;
- new (&value_) T();
- } else if (t.hasException()) {
- contains_ = Contains::EXCEPTION;
- new (&e_) std::unique_ptr<exception_wrapper>(
- folly::make_unique<exception_wrapper>(t.exception()));
- }
-}
-
-template <class T>
-Try<T>& Try<T>::operator=(Try<T>&& t) noexcept {
- if (this == &t) {
- return *this;
- }
-
- this->~Try();
- contains_ = t.contains_;
- if (contains_ == Contains::VALUE) {
- new (&value_)T(std::move(t.value_));
- } else if (contains_ == Contains::EXCEPTION) {
- new (&e_)std::unique_ptr<exception_wrapper>(std::move(t.e_));
- }
- return *this;
-}
-
-template <class T>
-Try<T>::Try(const Try<T>& t) {
- static_assert(
- std::is_copy_constructible<T>::value,
- "T must be copyable for Try<T> to be copyable");
- contains_ = t.contains_;
- if (contains_ == Contains::VALUE) {
- new (&value_)T(t.value_);
- } else if (contains_ == Contains::EXCEPTION) {
- new (&e_)std::unique_ptr<exception_wrapper>();
- e_ = folly::make_unique<exception_wrapper>(*(t.e_));
- }
-}
-
-template <class T>
-Try<T>& Try<T>::operator=(const Try<T>& t) {
- static_assert(
- std::is_copy_constructible<T>::value,
- "T must be copyable for Try<T> to be copyable");
- this->~Try();
- contains_ = t.contains_;
- if (contains_ == Contains::VALUE) {
- new (&value_)T(t.value_);
- } else if (contains_ == Contains::EXCEPTION) {
- new (&e_)std::unique_ptr<exception_wrapper>();
- e_ = folly::make_unique<exception_wrapper>(*(t.e_));
- }
- return *this;
-}
-
-template <class T>
-Try<T>::~Try() {
- if (LIKELY(contains_ == Contains::VALUE)) {
- value_.~T();
- } else if (UNLIKELY(contains_ == Contains::EXCEPTION)) {
- e_.~unique_ptr<exception_wrapper>();
- }
-}
-
-template <class T>
-T& Try<T>::value() & {
- throwIfFailed();
- return value_;
-}
-
-template <class T>
-T&& Try<T>::value() && {
- throwIfFailed();
- return std::move(value_);
-}
-
-template <class T>
-const T& Try<T>::value() const & {
- throwIfFailed();
- return value_;
-}
-
-template <class T>
-void Try<T>::throwIfFailed() const {
- if (contains_ != Contains::VALUE) {
- if (contains_ == Contains::EXCEPTION) {
- e_->throwException();
- } else {
- throw UsingUninitializedTry();
- }
- }
-}
-
-void Try<void>::throwIfFailed() const {
- if (!hasValue_) {
- e_->throwException();
- }
-}
-
-template <typename T>
-inline T moveFromTry(Try<T>& t) {
- return std::move(t.value());
-}
-
-inline void moveFromTry(Try<void>& t) {
- 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
-makeTryWith(F&& f) {
- typedef typename std::result_of<F()>::type ResultType;
- try {
- return Try<ResultType>(f());
- } catch (std::exception& e) {
- return Try<ResultType>(exception_wrapper(std::current_exception(), e));
- } catch (...) {
- return Try<ResultType>(exception_wrapper(std::current_exception()));
- }
-}
-
-template <typename F>
-typename std::enable_if<
- std::is_same<typename std::result_of<F()>::type, void>::value,
- Try<void>>::type
-makeTryWith(F&& f) {
- try {
- f();
- return Try<void>();
- } catch (std::exception& e) {
- return Try<void>(exception_wrapper(std::current_exception(), e));
- } catch (...) {
- return Try<void>(exception_wrapper(std::current_exception()));
- }
-}
-
-} // folly
+++ /dev/null
-/*
- * Copyright 2016 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.
- */
-
-#pragma once
-
-#include <type_traits>
-#include <exception>
-#include <algorithm>
-#include <folly/ExceptionWrapper.h>
-#include <folly/Likely.h>
-#include <folly/Memory.h>
-#include <folly/Portability.h>
-#include <folly/Unit.h>
-
-namespace folly {
-
-class TryException : public std::exception {
- public:
- explicit TryException(std::string message_arg) noexcept
- : message(std::move(message_arg)) {}
-
- const char* what() const noexcept override {
- return message.c_str();
- }
-
- bool operator==(const TryException& other) const noexcept {
- return other.message == this->message;
- }
-
- bool operator!=(const TryException& other) const noexcept {
- return !(*this == other);
- }
-
- protected:
- std::string message;
-};
-
-class UsingUninitializedTry : public TryException {
- public:
- UsingUninitializedTry() noexcept : TryException("Using unitialized try") {}
-};
-
-/*
- * Try<T> is a wrapper that contains either an instance of T, an exception, or
- * nothing. Exceptions are stored as exception_wrappers so that the user can
- * minimize rethrows if so desired.
- *
- * To represent success or a captured exception, use Try<Unit>.
- */
-template <class T>
-class Try {
- static_assert(!std::is_reference<T>::value,
- "Try may not be used with reference types");
-
- enum class Contains {
- VALUE,
- EXCEPTION,
- NOTHING,
- };
-
- public:
- /*
- * The value type for the Try
- */
- typedef T element_type;
-
- /*
- * Construct an empty Try
- */
- Try() : contains_(Contains::NOTHING) {}
-
- /*
- * Construct a Try with a value by copy
- *
- * @param v The value to copy in
- */
- explicit Try(const T& v) : contains_(Contains::VALUE), value_(v) {}
-
- /*
- * Construct a Try with a value by move
- *
- * @param v The value to move in
- */
- explicit Try(T&& v) : contains_(Contains::VALUE), value_(std::move(v)) {}
-
- /// Implicit conversion from Try<void> to Try<Unit>
- template <class T2 = T>
- /* implicit */
- Try(typename std::enable_if<std::is_same<Unit, T2>::value,
- Try<void> const&>::type t);
-
- /*
- * Construct a Try with an exception_wrapper
- *
- * @param e The exception_wrapper
- */
- explicit Try(exception_wrapper e)
- : contains_(Contains::EXCEPTION),
- e_(folly::make_unique<exception_wrapper>(std::move(e))) {}
-
- /*
- * DEPRECATED
- * Construct a Try with an exception_pointer
- *
- * @param ep The exception_pointer. Will be rethrown.
- */
- FOLLY_DEPRECATED("use Try(exception_wrapper)")
- explicit Try(std::exception_ptr ep)
- : contains_(Contains::EXCEPTION) {
- try {
- std::rethrow_exception(ep);
- } catch (const std::exception& e) {
- e_ = folly::make_unique<exception_wrapper>(std::current_exception(), e);
- } catch (...) {
- e_ = folly::make_unique<exception_wrapper>(std::current_exception());
- }
- }
-
- // Move constructor
- Try(Try<T>&& t) noexcept;
- // Move assigner
- Try& operator=(Try<T>&& t) noexcept;
-
- // Copy constructor
- Try(const Try& t);
- // Copy assigner
- Try& operator=(const Try& t);
-
- ~Try();
-
- /*
- * Get a mutable reference to the contained value. If the Try contains an
- * exception it will be rethrown.
- *
- * @returns mutable reference to the contained value
- */
- T& value()&;
- /*
- * Get a rvalue reference to the contained value. If the Try contains an
- * exception it will be rethrown.
- *
- * @returns rvalue reference to the contained value
- */
- T&& value()&&;
- /*
- * Get a const reference to the contained value. If the Try contains an
- * exception it will be rethrown.
- *
- * @returns const reference to the contained value
- */
- const T& value() const&;
-
- /*
- * If the Try contains an exception, rethrow it. Otherwise do nothing.
- */
- void throwIfFailed() const;
-
- /*
- * Const dereference operator. If the Try contains an exception it will be
- * rethrown.
- *
- * @returns const reference to the contained value
- */
- const T& operator*() const { return value(); }
- /*
- * Dereference operator. If the Try contains an exception it will be rethrown.
- *
- * @returns mutable reference to the contained value
- */
- T& operator*() { return value(); }
-
- /*
- * Const arrow operator. If the Try contains an exception it will be
- * rethrown.
- *
- * @returns const reference to the contained value
- */
- const T* operator->() const { return &value(); }
- /*
- * Arrow operator. If the Try contains an exception it will be rethrown.
- *
- * @returns mutable reference to the contained value
- */
- T* operator->() { return &value(); }
-
- /*
- * @returns True if the Try contains a value, false otherwise
- */
- bool hasValue() const { return contains_ == Contains::VALUE; }
- /*
- * @returns True if the Try contains an exception, false otherwise
- */
- bool hasException() const { return contains_ == Contains::EXCEPTION; }
-
- /*
- * @returns True if the Try contains an exception of type Ex, false otherwise
- */
- template <class Ex>
- bool hasException() const {
- return hasException() && e_->is_compatible_with<Ex>();
- }
-
- exception_wrapper& exception() {
- if (UNLIKELY(!hasException())) {
- throw TryException("exception(): Try does not contain an exception");
- }
- return *e_;
- }
-
- const exception_wrapper& exception() const {
- if (UNLIKELY(!hasException())) {
- throw TryException("exception(): Try does not contain an exception");
- }
- return *e_;
- }
-
- /*
- * If the Try contains an exception and it is of type Ex, execute func(Ex)
- *
- * @param func a function that takes a single parameter of type const Ex&
- *
- * @returns True if the Try held an Ex and func was executed, false otherwise
- */
- template <class Ex, class F>
- bool withException(F func) const {
- if (!hasException()) {
- return false;
- }
- return e_->with_exception(std::move(func));
- }
-
- template <bool isTry, typename R>
- typename std::enable_if<isTry, R>::type get() {
- return std::forward<R>(*this);
- }
-
- template <bool isTry, typename R>
- typename std::enable_if<!isTry, R>::type get() {
- return std::forward<R>(value());
- }
-
- private:
- Contains contains_;
- union {
- T value_;
- std::unique_ptr<exception_wrapper> e_;
- };
-};
-
-/*
- * Specialization of Try for void value type. Encapsulates either success or an
- * exception.
- */
-template <>
-class Try<void> {
- public:
- /*
- * The value type for the Try
- */
- typedef void element_type;
-
- // Construct a Try holding a successful and void result
- Try() : hasValue_(true) {}
-
- /*
- * Construct a Try with an exception_wrapper
- *
- * @param e The exception_wrapper
- */
- explicit Try(exception_wrapper e)
- : hasValue_(false),
- e_(folly::make_unique<exception_wrapper>(std::move(e))) {}
-
- /*
- * DEPRECATED
- * Construct a Try with an exception_pointer
- *
- * @param ep The exception_pointer. Will be rethrown.
- */
- FOLLY_DEPRECATED("use Try(exception_wrapper)")
- explicit Try(std::exception_ptr ep) : hasValue_(false) {
- try {
- std::rethrow_exception(ep);
- } catch (const std::exception& e) {
- e_ = folly::make_unique<exception_wrapper>(std::current_exception(), e);
- } catch (...) {
- e_ = folly::make_unique<exception_wrapper>(std::current_exception());
- }
- }
-
- // Copy assigner
- Try& operator=(const Try<void>& t) {
- hasValue_ = t.hasValue_;
- if (t.e_) {
- e_ = folly::make_unique<exception_wrapper>(*t.e_);
- }
- return *this;
- }
- // Copy constructor
- Try(const Try<void>& t) {
- *this = t;
- }
-
- // If the Try contains an exception, throws it
- void value() const { throwIfFailed(); }
- // Dereference operator. If the Try contains an exception, throws it
- void operator*() const { return value(); }
-
- // If the Try contains an exception, throws it
- inline void throwIfFailed() const;
-
- // @returns False if the Try contains an exception, true otherwise
- bool hasValue() const { return hasValue_; }
- // @returns True if the Try contains an exception, false otherwise
- bool hasException() const { return !hasValue_; }
-
- // @returns True if the Try contains an exception of type Ex, false otherwise
- template <class Ex>
- bool hasException() const {
- return hasException() && e_->is_compatible_with<Ex>();
- }
-
- /*
- * @throws TryException if the Try doesn't contain an exception
- *
- * @returns mutable reference to the exception contained by this Try
- */
- exception_wrapper& exception() {
- if (UNLIKELY(!hasException())) {
- throw TryException("exception(): Try does not contain an exception");
- }
- return *e_;
- }
-
- const exception_wrapper& exception() const {
- if (UNLIKELY(!hasException())) {
- throw TryException("exception(): Try does not contain an exception");
- }
- return *e_;
- }
-
- /*
- * If the Try contains an exception and it is of type Ex, execute func(Ex)
- *
- * @param func a function that takes a single parameter of type const Ex&
- *
- * @returns True if the Try held an Ex and func was executed, false otherwise
- */
- template <class Ex, class F>
- bool withException(F func) const {
- if (!hasException()) {
- return false;
- }
- return e_->with_exception(std::move(func));
- }
-
- template <bool, typename R>
- R get() {
- return std::forward<R>(*this);
- }
-
- private:
- bool hasValue_;
- std::unique_ptr<exception_wrapper> e_{nullptr};
-};
-
-/*
- * Extracts value from try and returns it. Throws if try contained an exception.
- *
- * @param t Try to extract value from
- *
- * @returns value contained in t
- */
-template <typename T>
-T moveFromTry(Try<T>& t);
-
-/*
- * Throws if try contained an exception.
- *
- * @param t Try to move from
- */
-void moveFromTry(Try<void>& t);
-
-/*
- * @param f a function to execute and capture the result of (value or exception)
- *
- * @returns Try holding the result of f
- */
-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
-makeTryWith(F&& f);
-
-/*
- * Specialization of makeTryWith for void return
- *
- * @param f a function to execute and capture the result of
- *
- * @returns Try<void> holding the result of f
- */
-template <typename F>
-typename std::enable_if<
- std::is_same<typename std::result_of<F()>::type, void>::value,
- Try<void>>::type
-makeTryWith(F&& f);
-
-} // folly
-
-#include <folly/futures/Try-inl.h>
#include <folly/Optional.h>
#include <folly/futures/Future.h>
#include <folly/futures/Promise.h>
-#include <folly/futures/Try.h>
+#include <folly/Try.h>
#include <folly/futures/detail/FSM.h>
#include <folly/io/async/Request.h>
// amazing what things can go wrong if you include things in an unexpected
// order.
-#include <folly/futures/Try.h>
+#include <folly/Try.h>
#include <folly/futures/Promise.h>
#include <folly/futures/Future.h>
+++ /dev/null
-/*
- * Copyright 2016 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/futures/Try.h>
-
-using namespace folly;
-
-TEST(Try, basic) {
- class A {
- public:
- A(int x) : x_(x) {}
-
- int x() const {
- return x_;
- }
- private:
- int x_;
- };
-
- A a(5);
- Try<A> t_a(std::move(a));
-
- Try<Unit> t_void;
-
- EXPECT_EQ(5, t_a.value().x());
-}
-
-// Make sure we can copy Trys for copyable types
-TEST(Try, copy) {
- Try<int> t;
- auto t2 = t;
-}
-
-// But don't choke on move-only types
-TEST(Try, moveOnly) {
- Try<std::unique_ptr<int>> t;
- std::vector<Try<std::unique_ptr<int>>> v;
- v.reserve(10);
-}
-
-TEST(Try, makeTryWith) {
- auto func = []() {
- return folly::make_unique<int>(1);
- };
-
- auto result = makeTryWith(func);
- EXPECT_TRUE(result.hasValue());
- EXPECT_EQ(*result.value(), 1);
-}
-
-TEST(Try, makeTryWithThrow) {
- auto func = []() {
- throw std::runtime_error("Runtime");
- return folly::make_unique<int>(1);
- };
-
- auto result = makeTryWith(func);
- EXPECT_TRUE(result.hasException<std::runtime_error>());
-}
-
-TEST(Try, makeTryWithVoid) {
- auto func = []() {
- return;
- };
-
- auto result = makeTryWith(func);
- EXPECT_TRUE(result.hasValue());
-}
-
-TEST(Try, makeTryWithVoidThrow) {
- auto func = []() {
- throw std::runtime_error("Runtime");
- return;
- };
-
- auto result = makeTryWith(func);
- EXPECT_TRUE(result.hasException<std::runtime_error>());
-}
indestructible_test_LDADD = libfollytestmain.la
TESTS += indestructible_test
+try_test_SOURCES = TryTest.cpp
+try_test_LDADD = libfollytestmain.la
+TESTS += try_test
+
unit_test_SOURCES = UnitTest.cpp
unit_test_LDADD = libfollytestmain.la
TESTS += unit_test
../futures/test/ThenTest.cpp \
../futures/test/TimekeeperTest.cpp \
../futures/test/TimesTest.cpp \
- ../futures/test/TryTest.cpp \
../futures/test/UnwrapTest.cpp \
../futures/test/ViaTest.cpp \
../futures/test/WaitTest.cpp \
--- /dev/null
+/*
+ * Copyright 2016 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/Try.h>
+
+using namespace folly;
+
+TEST(Try, basic) {
+ class A {
+ public:
+ A(int x) : x_(x) {}
+
+ int x() const {
+ return x_;
+ }
+ private:
+ int x_;
+ };
+
+ A a(5);
+ Try<A> t_a(std::move(a));
+
+ Try<Unit> t_void;
+
+ EXPECT_EQ(5, t_a.value().x());
+}
+
+// Make sure we can copy Trys for copyable types
+TEST(Try, copy) {
+ Try<int> t;
+ auto t2 = t;
+}
+
+// But don't choke on move-only types
+TEST(Try, moveOnly) {
+ Try<std::unique_ptr<int>> t;
+ std::vector<Try<std::unique_ptr<int>>> v;
+ v.reserve(10);
+}
+
+TEST(Try, makeTryWith) {
+ auto func = []() {
+ return folly::make_unique<int>(1);
+ };
+
+ auto result = makeTryWith(func);
+ EXPECT_TRUE(result.hasValue());
+ EXPECT_EQ(*result.value(), 1);
+}
+
+TEST(Try, makeTryWithThrow) {
+ auto func = []() {
+ throw std::runtime_error("Runtime");
+ return folly::make_unique<int>(1);
+ };
+
+ auto result = makeTryWith(func);
+ EXPECT_TRUE(result.hasException<std::runtime_error>());
+}
+
+TEST(Try, makeTryWithVoid) {
+ auto func = []() {
+ return;
+ };
+
+ auto result = makeTryWith(func);
+ EXPECT_TRUE(result.hasValue());
+}
+
+TEST(Try, makeTryWithVoidThrow) {
+ auto func = []() {
+ throw std::runtime_error("Runtime");
+ return;
+ };
+
+ auto result = makeTryWith(func);
+ EXPECT_TRUE(result.hasException<std::runtime_error>());
+}