145 lines
4.7 KiB
Diff
145 lines
4.7 KiB
Diff
|
diff -up chromium-65.0.3325.146/base/optional.h.ncnm chromium-65.0.3325.146/base/optional.h
|
||
|
--- chromium-65.0.3325.146/base/optional.h.ncnm 2018-03-13 22:40:11.743226276 -0400
|
||
|
+++ chromium-65.0.3325.146/base/optional.h 2018-03-13 22:44:30.948211358 -0400
|
||
|
@@ -240,37 +240,37 @@ class OptionalBase {
|
||
|
~OptionalBase() = default;
|
||
|
|
||
|
OptionalBase& operator=(const OptionalBase& other) {
|
||
|
- if (!other.storage_.is_populated_) {
|
||
|
- FreeIfNeeded();
|
||
|
- return *this;
|
||
|
- }
|
||
|
-
|
||
|
- InitOrAssign(other.storage_.value_);
|
||
|
+ CopyAssign(other);
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
OptionalBase& operator=(OptionalBase&& other) {
|
||
|
- if (!other.storage_.is_populated_) {
|
||
|
- FreeIfNeeded();
|
||
|
- return *this;
|
||
|
- }
|
||
|
-
|
||
|
- InitOrAssign(std::move(other.storage_.value_));
|
||
|
+ MoveAssign(std::move(other));
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
- void InitOrAssign(const T& value) {
|
||
|
- if (!storage_.is_populated_)
|
||
|
- storage_.Init(value);
|
||
|
+ template <typename U>
|
||
|
+ void CopyAssign(const OptionalBase<U>& other) {
|
||
|
+ if (other.storage_.is_populated_)
|
||
|
+ InitOrAssign(other.storage_.value_);
|
||
|
else
|
||
|
- storage_.value_ = value;
|
||
|
+ FreeIfNeeded();
|
||
|
}
|
||
|
|
||
|
- void InitOrAssign(T&& value) {
|
||
|
- if (!storage_.is_populated_)
|
||
|
- storage_.Init(std::move(value));
|
||
|
+ template <typename U>
|
||
|
+ void MoveAssign(OptionalBase<U>&& other) {
|
||
|
+ if (other.storage_.is_populated_)
|
||
|
+ InitOrAssign(std::move(other.storage_.value_));
|
||
|
+ else
|
||
|
+ FreeIfNeeded();
|
||
|
+ }
|
||
|
+
|
||
|
+ template <typename U>
|
||
|
+ void InitOrAssign(U&& value) {
|
||
|
+ if (storage_.is_populated_)
|
||
|
+ storage_.value_ = std::forward<U>(value);
|
||
|
else
|
||
|
- storage_.value_ = std::move(value);
|
||
|
+ storage_.Init(std::forward<U>(value));
|
||
|
}
|
||
|
|
||
|
void FreeIfNeeded() {
|
||
|
@@ -340,7 +340,7 @@ struct MoveAssignable<false> {
|
||
|
MoveAssignable& operator=(MoveAssignable&&) = delete;
|
||
|
};
|
||
|
|
||
|
-// Helper to conditionally enable converting constructors.
|
||
|
+// Helper to conditionally enable converting constructors and assign operators.
|
||
|
template <typename T, typename U>
|
||
|
struct IsConvertibleFromOptional
|
||
|
: std::integral_constant<
|
||
|
@@ -354,6 +354,16 @@ struct IsConvertibleFromOptional
|
||
|
std::is_convertible<Optional<U>&&, T>::value ||
|
||
|
std::is_convertible<const Optional<U>&&, T>::value> {};
|
||
|
|
||
|
+template <typename T, typename U>
|
||
|
+struct IsAssignableFromOptional
|
||
|
+ : std::integral_constant<
|
||
|
+ bool,
|
||
|
+ IsConvertibleFromOptional<T, U>::value ||
|
||
|
+ std::is_assignable<T&, Optional<U>&>::value ||
|
||
|
+ std::is_assignable<T&, const Optional<U>&>::value ||
|
||
|
+ std::is_assignable<T&, Optional<U>&&>::value ||
|
||
|
+ std::is_assignable<T&, const Optional<U>&&>::value> {};
|
||
|
+
|
||
|
// Forward compatibility for C++20.
|
||
|
template <typename T>
|
||
|
using RemoveCvRefT = std::remove_cv_t<std::remove_reference_t<T>>;
|
||
|
@@ -487,14 +497,42 @@ class Optional
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
- template <class U>
|
||
|
- typename std::enable_if<std::is_same<std::decay_t<U>, T>::value,
|
||
|
- Optional&>::type
|
||
|
+ // Perfect-forwarded assignment.
|
||
|
+ template <typename U>
|
||
|
+ std::enable_if_t<
|
||
|
+ !std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value &&
|
||
|
+ std::is_constructible<T, U>::value &&
|
||
|
+ std::is_assignable<T&, U>::value &&
|
||
|
+ (!std::is_scalar<T>::value ||
|
||
|
+ !std::is_same<std::decay_t<U>, T>::value),
|
||
|
+ Optional&>
|
||
|
operator=(U&& value) {
|
||
|
InitOrAssign(std::forward<U>(value));
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
+// Copy assign the state of other.
|
||
|
+ template <typename U>
|
||
|
+ std::enable_if_t<!internal::IsAssignableFromOptional<T, U>::value &&
|
||
|
+ std::is_constructible<T, const U&>::value &&
|
||
|
+ std::is_assignable<T&, const U&>::value,
|
||
|
+ Optional&>
|
||
|
+ operator=(const Optional<U>& other) {
|
||
|
+ CopyAssign(other);
|
||
|
+ return *this;
|
||
|
+ }
|
||
|
+
|
||
|
+ // Move assign the state of other.
|
||
|
+ template <typename U>
|
||
|
+ std::enable_if_t<!internal::IsAssignableFromOptional<T, U>::value &&
|
||
|
+ std::is_constructible<T, U>::value &&
|
||
|
+ std::is_assignable<T&, U>::value,
|
||
|
+ Optional&>
|
||
|
+ operator=(Optional<U>&& other) {
|
||
|
+ MoveAssign(std::move(other));
|
||
|
+ return *this;
|
||
|
+ }
|
||
|
+
|
||
|
constexpr const T* operator->() const {
|
||
|
DCHECK(storage_.is_populated_);
|
||
|
return &value();
|
||
|
@@ -606,8 +644,10 @@ class Optional
|
||
|
private:
|
||
|
// Accessing template base class's protected member needs explicit
|
||
|
// declaration to do so.
|
||
|
+ using internal::OptionalBase<T>::CopyAssign;
|
||
|
using internal::OptionalBase<T>::FreeIfNeeded;
|
||
|
using internal::OptionalBase<T>::InitOrAssign;
|
||
|
+ using internal::OptionalBase<T>::MoveAssign;
|
||
|
using internal::OptionalBase<T>::storage_;
|
||
|
};
|
||
|
|