diff -up chromium-65.0.3325.146/base/optional.h.conditional chromium-65.0.3325.146/base/optional.h --- chromium-65.0.3325.146/base/optional.h.conditional 2018-03-13 22:11:02.328058249 -0400 +++ chromium-65.0.3325.146/base/optional.h 2018-03-13 22:12:43.622098296 -0400 @@ -266,6 +266,58 @@ class OptionalBase { OptionalStorage storage_; }; +// The following {Copy,Move}{Constructible,Assignable} structs are helpers to +// implement constructor/assign-operator overloading. Specifically, if T is +// is not movable but copyable, Optional's move constructor should not +// participate in overload resolution. This inheritance trick implements that. +template +struct CopyConstructible {}; + +template <> +struct CopyConstructible { + constexpr CopyConstructible() = default; + constexpr CopyConstructible(const CopyConstructible&) = delete; + constexpr CopyConstructible(CopyConstructible&&) = default; + CopyConstructible& operator=(const CopyConstructible&) = default; + CopyConstructible& operator=(CopyConstructible&&) = default; +}; + +template +struct MoveConstructible {}; + +template <> +struct MoveConstructible { + constexpr MoveConstructible() = default; + constexpr MoveConstructible(const MoveConstructible&) = default; + constexpr MoveConstructible(MoveConstructible&&) = delete; + MoveConstructible& operator=(const MoveConstructible&) = default; + MoveConstructible& operator=(MoveConstructible&&) = default; +}; + +template +struct CopyAssignable {}; + +template <> +struct CopyAssignable { + constexpr CopyAssignable() = default; + constexpr CopyAssignable(const CopyAssignable&) = default; + constexpr CopyAssignable(CopyAssignable&&) = default; + CopyAssignable& operator=(const CopyAssignable&) = delete; + CopyAssignable& operator=(CopyAssignable&&) = default; +}; + +template +struct MoveAssignable {}; + +template <> +struct MoveAssignable { + constexpr MoveAssignable() = default; + constexpr MoveAssignable(const MoveAssignable&) = default; + constexpr MoveAssignable(MoveAssignable&&) = default; + MoveAssignable& operator=(const MoveAssignable&) = default; + MoveAssignable& operator=(MoveAssignable&&) = delete; +}; + } // namespace internal // base::Optional is a Chromium version of the C++17 optional class: @@ -280,12 +332,18 @@ class OptionalBase { // - No exceptions are thrown, because they are banned from Chromium. // - All the non-members are in the 'base' namespace instead of 'std'. template -class Optional : public internal::OptionalBase { +class Optional + : public internal::OptionalBase, + public internal::CopyConstructible::value>, + public internal::MoveConstructible::value>, + public internal::CopyAssignable::value && + std::is_copy_assignable::value>, + public internal::MoveAssignable::value && + std::is_move_assignable::value> { public: using value_type = T; // Defer default/copy/move constructor implementation to OptionalBase. - // TODO(hidehiko): Implement conditional enabling. constexpr Optional() = default; constexpr Optional(const Optional& other) = default; constexpr Optional(Optional&& other) = default; @@ -316,7 +374,6 @@ class Optional : public internal::Option ~Optional() = default; // Defer copy-/move- assign operator implementation to OptionalBase. - // TOOD(hidehiko): Implement conditional enabling. Optional& operator=(const Optional& other) = default; Optional& operator=(Optional&& other) = default;