X-Git-Url: http://plrg.eecs.uci.edu/git/?p=folly.git;a=blobdiff_plain;f=folly%2FTry.h;h=d145806a058cbd0387451e4c68593e40d19f469c;hp=f38362b803c580ea0062a8616ae69dabf73a4b57;hb=717229ecf385ee10a91d6c2af859e8550df84531;hpb=d4aacd244f21e76dce685365acc281a9015897c1 diff --git a/folly/Try.h b/folly/Try.h index f38362b8..d145806a 100644 --- a/folly/Try.h +++ b/folly/Try.h @@ -1,5 +1,5 @@ /* - * Copyright 2017 Facebook, Inc. + * Copyright 2014-present Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #pragma once #include @@ -29,12 +28,12 @@ namespace folly { -class TryException : public std::logic_error { +class FOLLY_EXPORT TryException : public std::logic_error { public: using std::logic_error::logic_error; }; -class UsingUninitializedTry : public TryException { +class FOLLY_EXPORT UsingUninitializedTry : public TryException { public: UsingUninitializedTry() : TryException("Using uninitialized try") {} }; @@ -114,15 +113,8 @@ class Try { */ FOLLY_DEPRECATED("use Try(exception_wrapper)") explicit Try(std::exception_ptr ep) - : contains_(Contains::EXCEPTION) { - try { - std::rethrow_exception(ep); - } catch (std::exception& e) { - e_ = exception_wrapper(std::current_exception(), e); - } catch (...) { - e_ = exception_wrapper(std::current_exception()); - } - } + : contains_(Contains::EXCEPTION), + e_(exception_wrapper::from_exception_ptr(ep)) {} // Move constructor Try(Try&& t) noexcept; @@ -142,21 +134,28 @@ class Try { * * @returns mutable reference to the contained value */ - T& 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()&&; + 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&; + const T& value() const &; + /* + * Get a const rvalue reference to the contained value. If the Try contains an + * exception it will be rethrown. + * + * @returns const rvalue reference to the contained value + */ + const T&& value() const &&; /* * If the Try contains an exception, rethrow it. Otherwise do nothing. @@ -169,13 +168,35 @@ class Try { * * @returns const reference to the contained value */ - const T& operator*() const { return 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(); } + T& operator*() & { + return value(); + } + /* + * Mutable rvalue dereference operator. If the Try contains an exception it + * will be rethrown. + * + * @returns rvalue reference to the contained value + */ + T&& operator*() && { + return std::move(value()); + } + /* + * Const rvalue dereference operator. If the Try contains an exception it + * will be rethrown. + * + * @returns rvalue reference to the contained value + */ + const T&& operator*() const && { + return std::move(value()); + } /* * Const arrow operator. If the Try contains an exception it will be @@ -208,20 +229,34 @@ class Try { return hasException() && e_.is_compatible_with(); } - exception_wrapper& exception() { + exception_wrapper& exception() & { if (!hasException()) { try_detail::throwTryDoesNotContainException(); } return e_; } - const exception_wrapper& exception() const { + exception_wrapper&& exception() && { + if (!hasException()) { + try_detail::throwTryDoesNotContainException(); + } + return std::move(e_); + } + + const exception_wrapper& exception() const & { if (!hasException()) { try_detail::throwTryDoesNotContainException(); } return e_; } + const exception_wrapper&& exception() const && { + if (!hasException()) { + try_detail::throwTryDoesNotContainException(); + } + return std::move(e_); + } + /* * @returns a pointer to the `std::exception` held by `*this`, if one is held; * otherwise, returns `nullptr`. @@ -339,15 +374,8 @@ class Try { * @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_ = exception_wrapper(std::current_exception(), e); - } catch (...) { - e_ = exception_wrapper(std::current_exception()); - } - } + explicit Try(std::exception_ptr ep) + : hasValue_(false), e_(exception_wrapper::from_exception_ptr(ep)) {} // Copy assigner Try& operator=(const Try& t) { @@ -384,20 +412,34 @@ class Try { * * @returns mutable reference to the exception contained by this Try */ - exception_wrapper& exception() { + exception_wrapper& exception() & { if (!hasException()) { try_detail::throwTryDoesNotContainException(); } return e_; } - const exception_wrapper& exception() const { + exception_wrapper&& exception() && { + if (!hasException()) { + try_detail::throwTryDoesNotContainException(); + } + return std::move(e_); + } + + const exception_wrapper& exception() const & { if (!hasException()) { try_detail::throwTryDoesNotContainException(); } return e_; } + const exception_wrapper&& exception() const && { + if (!hasException()) { + try_detail::throwTryDoesNotContainException(); + } + return std::move(e_); + } + /* * @returns a pointer to the `std::exception` held by `*this`, if one is held; * otherwise, returns `nullptr`. @@ -502,8 +544,14 @@ typename std::enable_if< Try>::type makeTryWith(F&& f); -template -std::tuple unwrapTryTuple(std::tuple...>&& ts); +/** + * Tuple...> -> std::tuple + * + * Unwraps a tuple-like type containing a sequence of Try instances to + * std::tuple + */ +template +auto unwrapTryTuple(Tuple&&); } // namespace folly