Commit a610249b authored by Eric Niebler's avatar Eric Niebler Committed by Facebook Github Bot 2

work around LLVM#30305 in folly::Expected, use unified initialization syntax for extra goodness

Summary: The behavior of inheriting constructors changed in clang 3.9 (see https://llvm.org/bugs/show_bug.cgi?id=30305), and folly::Expected needs to change accordingly. As a drive-by improvement, change all invocations of default constructors to use unified initialization syntax.

Reviewed By: igorsugak

Differential Revision: D3872994

fbshipit-source-id: fdaea8b35980df21b8522e2c3d5a8c3be1d84efa
parent 101b2ad7
...@@ -181,11 +181,11 @@ struct ExpectedStorage { ...@@ -181,11 +181,11 @@ struct ExpectedStorage {
}; };
Which which_; Which which_;
template <class E = Error, class = decltype(E())> template <class E = Error, class = decltype(E{})>
constexpr ExpectedStorage() noexcept(noexcept(E())) constexpr ExpectedStorage() noexcept(noexcept(E{}))
: error_(), which_(Which::eError) {} : error_{}, which_(Which::eError) {}
explicit constexpr ExpectedStorage(EmptyTag) noexcept explicit constexpr ExpectedStorage(EmptyTag) noexcept
: ch_(), which_(Which::eEmpty) {} : ch_{}, which_(Which::eEmpty) {}
template <class... Vs> template <class... Vs>
explicit constexpr ExpectedStorage(ValueTag, Vs&&... vs) noexcept( explicit constexpr ExpectedStorage(ValueTag, Vs&&... vs) noexcept(
noexcept(Value(static_cast<Vs&&>(vs)...))) noexcept(Value(static_cast<Vs&&>(vs)...)))
...@@ -253,8 +253,8 @@ struct ExpectedUnion { ...@@ -253,8 +253,8 @@ struct ExpectedUnion {
}; };
Which which_; Which which_;
explicit constexpr ExpectedUnion(EmptyTag = {}) noexcept explicit constexpr ExpectedUnion(EmptyTag) noexcept
: ch_(), which_(Which::eEmpty) {} : ch_{}, which_(Which::eEmpty) {}
template <class... Vs> template <class... Vs>
explicit constexpr ExpectedUnion(ValueTag, Vs&&... vs) noexcept( explicit constexpr ExpectedUnion(ValueTag, Vs&&... vs) noexcept(
noexcept(Value(static_cast<Vs&&>(vs)...))) noexcept(Value(static_cast<Vs&&>(vs)...)))
...@@ -396,8 +396,8 @@ struct ExpectedStorage<Value, Error, StorageType::eUnion> ...@@ -396,8 +396,8 @@ struct ExpectedStorage<Value, Error, StorageType::eUnion>
using value_type = Value; using value_type = Value;
using error_type = Error; using error_type = Error;
using Base = ExpectedUnion<Value, Error>; using Base = ExpectedUnion<Value, Error>;
template <class E = Error, class = decltype(E())> template <class E = Error, class = decltype(E{})>
constexpr ExpectedStorage() noexcept(noexcept(E())) : Base{ErrorTag{}} {} constexpr ExpectedStorage() noexcept(noexcept(E{})) : Base{ErrorTag{}} {}
ExpectedStorage(const ExpectedStorage&) = default; ExpectedStorage(const ExpectedStorage&) = default;
ExpectedStorage(ExpectedStorage&&) = default; ExpectedStorage(ExpectedStorage&&) = default;
ExpectedStorage& operator=(const ExpectedStorage&) = default; ExpectedStorage& operator=(const ExpectedStorage&) = default;
...@@ -480,17 +480,17 @@ struct ExpectedStorage<Value, Error, StorageType::ePODStruct> { ...@@ -480,17 +480,17 @@ struct ExpectedStorage<Value, Error, StorageType::ePODStruct> {
Value value_; Value value_;
constexpr ExpectedStorage() noexcept constexpr ExpectedStorage() noexcept
: which_(Which::eError), error_(), value_() {} : which_(Which::eError), error_{}, value_{} {}
explicit constexpr ExpectedStorage(EmptyTag) noexcept explicit constexpr ExpectedStorage(EmptyTag) noexcept
: which_(Which::eEmpty), error_(), value_() {} : which_(Which::eEmpty), error_{}, value_{} {}
template <class... Vs> template <class... Vs>
explicit constexpr ExpectedStorage(ValueTag, Vs&&... vs) noexcept( explicit constexpr ExpectedStorage(ValueTag, Vs&&... vs) noexcept(
noexcept(Value(static_cast<Vs&&>(vs)...))) noexcept(Value(static_cast<Vs&&>(vs)...)))
: which_(Which::eValue), error_(), value_(static_cast<Vs&&>(vs)...) {} : which_(Which::eValue), error_{}, value_(static_cast<Vs&&>(vs)...) {}
template <class... Es> template <class... Es>
explicit constexpr ExpectedStorage(ErrorTag, Es&&... es) noexcept( explicit constexpr ExpectedStorage(ErrorTag, Es&&... es) noexcept(
noexcept(Error(static_cast<Es&&>(es)...))) noexcept(Error(static_cast<Es&&>(es)...)))
: which_(Which::eError), error_(static_cast<Es&&>(es)...), value_() {} : which_(Which::eError), error_(static_cast<Es&&>(es)...), value_{} {}
void clear() noexcept {} void clear() noexcept {}
constexpr static bool uninitializedByException() noexcept { constexpr static bool uninitializedByException() noexcept {
return false; return false;
...@@ -661,7 +661,7 @@ class Unexpected final { ...@@ -661,7 +661,7 @@ class Unexpected final {
class BadExpectedAccess : public folly::BadExpectedAccess { class BadExpectedAccess : public folly::BadExpectedAccess {
public: public:
explicit BadExpectedAccess(Error err) explicit BadExpectedAccess(Error err)
: folly::BadExpectedAccess(), error_(std::move(err)) {} : folly::BadExpectedAccess{}, error_(std::move(err)) {}
/** /**
* The error code that was held by the Expected object when the user * The error code that was held by the Expected object when the user
* erroneously requested the value. * erroneously requested the value.
...@@ -892,7 +892,7 @@ class Expected final : expected_detail::ExpectedStorage<Value, Error> { ...@@ -892,7 +892,7 @@ class Expected final : expected_detail::ExpectedStorage<Value, Error> {
* Constructors * Constructors
*/ */
template <class B = Base, class = decltype(B{})> template <class B = Base, class = decltype(B{})>
Expected() noexcept(noexcept(B{})) : Base() {} Expected() noexcept(noexcept(B{})) : Base{} {}
Expected(const Expected& that) = default; Expected(const Expected& that) = default;
Expected(Expected&& that) = default; Expected(Expected&& that) = default;
...@@ -1198,7 +1198,7 @@ class Expected final : expected_detail::ExpectedStorage<Value, Error> { ...@@ -1198,7 +1198,7 @@ class Expected final : expected_detail::ExpectedStorage<Value, Error> {
* thenOrThrow * thenOrThrow
*/ */
template <class Yes, class No = MakeBadExpectedAccess> template <class Yes, class No = MakeBadExpectedAccess>
auto thenOrThrow(Yes&& yes, No&& no = No()) const& -> decltype( auto thenOrThrow(Yes&& yes, No&& no = No{}) const& -> decltype(
std::declval<Yes>()(std::declval<const Value&>())) { std::declval<Yes>()(std::declval<const Value&>())) {
using Ret = decltype(std::declval<Yes>()(std::declval<const Value&>())); using Ret = decltype(std::declval<Yes>()(std::declval<const Value&>()));
if (this->uninitializedByException()) if (this->uninitializedByException())
...@@ -1208,7 +1208,7 @@ class Expected final : expected_detail::ExpectedStorage<Value, Error> { ...@@ -1208,7 +1208,7 @@ class Expected final : expected_detail::ExpectedStorage<Value, Error> {
} }
template <class Yes, class No = MakeBadExpectedAccess> template <class Yes, class No = MakeBadExpectedAccess>
auto thenOrThrow(Yes&& yes, No&& no = No()) & -> decltype( auto thenOrThrow(Yes&& yes, No&& no = No{}) & -> decltype(
std::declval<Yes>()(std::declval<Value&>())) { std::declval<Yes>()(std::declval<Value&>())) {
using Ret = decltype(std::declval<Yes>()(std::declval<Value&>())); using Ret = decltype(std::declval<Yes>()(std::declval<Value&>()));
if (this->uninitializedByException()) if (this->uninitializedByException())
...@@ -1218,7 +1218,7 @@ class Expected final : expected_detail::ExpectedStorage<Value, Error> { ...@@ -1218,7 +1218,7 @@ class Expected final : expected_detail::ExpectedStorage<Value, Error> {
} }
template <class Yes, class No = MakeBadExpectedAccess> template <class Yes, class No = MakeBadExpectedAccess>
auto thenOrThrow(Yes&& yes, No&& no = No()) && -> decltype( auto thenOrThrow(Yes&& yes, No&& no = No{}) && -> decltype(
std::declval<Yes>()(std::declval<Value&&>())) { std::declval<Yes>()(std::declval<Value&&>())) {
using Ret = decltype(std::declval<Yes>()(std::declval<Value&&>())); using Ret = decltype(std::declval<Yes>()(std::declval<Value&&>()));
if (this->uninitializedByException()) if (this->uninitializedByException())
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment