diff -up chromium-65.0.3325.146/base/optional.h.vforward chromium-65.0.3325.146/base/optional.h --- chromium-65.0.3325.146/base/optional.h.vforward 2018-03-13 22:35:46.383359966 -0400 +++ chromium-65.0.3325.146/base/optional.h 2018-03-13 22:37:48.724992995 -0400 @@ -354,6 +354,10 @@ struct IsConvertibleFromOptional std::is_convertible&&, T>::value || std::is_convertible&&, T>::value> {}; +// Forward compatibility for C++20. +template +using RemoveCvRefT = std::remove_cv_t>; + } // namespace internal // base::Optional is a Chromium version of the C++17 optional class: @@ -367,6 +371,13 @@ struct IsConvertibleFromOptional // - 'constexpr' might be missing in some places for reasons specified locally. // - No exceptions are thrown, because they are banned from Chromium. // - All the non-members are in the 'base' namespace instead of 'std'. +// +// Note that T cannot have a constructor T(Optional) etc. Optional checks +// T's constructor (specifically via IsConvertibleFromOptional), and in the +// check whether T can be constructible from Optional, which is recursive +// so it does not work. As of Feb 2018, std::optional C++17 implementation in +// both clang and gcc has same limitation. MSVC SFINAE looks to have different +// behavior, but anyway it reports an error, too. template class Optional : public internal::OptionalBase, @@ -426,12 +437,6 @@ class Optional explicit Optional(Optional&& other) : internal::OptionalBase(std::move(other)) {} - constexpr Optional(const T& value) - : internal::OptionalBase(in_place, value) {} - - constexpr Optional(T&& value) - : internal::OptionalBase(in_place, std::move(value)) {} - template constexpr explicit Optional(in_place_t, Args&&... args) : internal::OptionalBase(in_place, std::forward(args)...) {} @@ -447,6 +452,30 @@ class Optional Args&&... args) : internal::OptionalBase(in_place, il, std::forward(args)...) {} + // Forward value constructor. Similar to converting constructors, + // conditionally explicit. + template < + typename U = value_type, + std::enable_if_t< + std::is_constructible::value && + !std::is_same, in_place_t>::value && + !std::is_same, Optional>::value && + std::is_convertible::value, + bool> = false> + constexpr Optional(U&& value) + : internal::OptionalBase(in_place, std::forward(value)) {} + + template < + typename U = value_type, + std::enable_if_t< + std::is_constructible::value && + !std::is_same, in_place_t>::value && + !std::is_same, Optional>::value && + !std::is_convertible::value, + bool> = false> + constexpr explicit Optional(U&& value) + : internal::OptionalBase(in_place, std::forward(value)) {} + ~Optional() = default; // Defer copy-/move- assign operator implementation to OptionalBase.