parent
c5342c3e97
commit
4e6c6ef24d
@ -0,0 +1,41 @@
|
||||
diff -up chromium-65.0.3325.146/base/optional.h.noncopyable chromium-65.0.3325.146/base/optional.h
|
||||
--- chromium-65.0.3325.146/base/optional.h.noncopyable 2018-03-13 16:52:15.953729689 -0400
|
||||
+++ chromium-65.0.3325.146/base/optional.h 2018-03-13 16:53:55.365792522 -0400
|
||||
@@ -45,6 +45,15 @@ struct OptionalStorageBase {
|
||||
|
||||
// When T is not trivially destructible we must call its
|
||||
// destructor before deallocating its memory.
|
||||
+ // Note that this hides the (implicitly declared) move constructor, which
|
||||
+ // would be used for constexpr move constructor in OptionalStorage<T>.
|
||||
+ // It is needed iff T is trivially move constructible. However, the current
|
||||
+ // is_trivially_{copy,move}_constructible implementation requires
|
||||
+ // is_trivially_destructible (which looks a bug, cf:
|
||||
+ // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51452 and
|
||||
+ // http://cplusplus.github.io/LWG/lwg-active.html#2116), so it is not
|
||||
+ // necessary for this case at the moment. Please see also the destructor
|
||||
+ // comment in "is_trivially_destructible = true" specialization below.
|
||||
~OptionalStorageBase() {
|
||||
if (!is_null_)
|
||||
value_.~T();
|
||||
@@ -78,9 +87,18 @@ struct OptionalStorageBase<T, true /* tr
|
||||
: is_null_(false), value_(std::forward<Args>(args)...) {}
|
||||
|
||||
// When T is trivially destructible (i.e. its destructor does nothing) there
|
||||
- // is no need to call it. Explicitly defaulting the destructor means it's not
|
||||
- // user-provided. Those two together make this destructor trivial.
|
||||
- ~OptionalStorageBase() = default;
|
||||
+ // is no need to call it. Implicitly defined destructor is trivial, because
|
||||
+ // both members (bool and union containing only variants which are trivially
|
||||
+ // destructible) are trivially destructible.
|
||||
+ // Explicitly-defaulted destructor is also trivial, but do not use it here,
|
||||
+ // because it hides the implicit move constructor. It is needed to implement
|
||||
+ // constexpr move constructor in OptionalStorage iff T is trivially move
|
||||
+ // constructible. Note that, if T is trivially move constructible, the move
|
||||
+ // constructor of OptionalStorageBase<T> is also implicitly defined and it is
|
||||
+ // trivially move constructor. If T is not trivially move constructible,
|
||||
+ // "not declaring move constructor without destructor declaration" here means
|
||||
+ // "delete move constructor", which works because any move constructor of
|
||||
+ // OptionalStorage will not refer to it in that case.
|
||||
|
||||
template <class... Args>
|
||||
void Init(Args&&... args) {
|
@ -0,0 +1,108 @@
|
||||
diff -up chromium-65.0.3325.146/third_party/WebKit/Source/bindings/modules/v8/V8BindingForModules.cpp.GetString chromium-65.0.3325.146/third_party/WebKit/Source/bindings/modules/v8/V8BindingForModules.cpp
|
||||
--- chromium-65.0.3325.146/third_party/WebKit/Source/bindings/modules/v8/V8BindingForModules.cpp.GetString 2018-03-13 22:54:27.262671113 -0400
|
||||
+++ chromium-65.0.3325.146/third_party/WebKit/Source/bindings/modules/v8/V8BindingForModules.cpp 2018-03-13 22:55:47.722113713 -0400
|
||||
@@ -68,7 +68,7 @@ v8::Local<v8::Value> ToV8(const IDBKeyPa
|
||||
case IDBKeyPath::kNullType:
|
||||
return v8::Null(isolate);
|
||||
case IDBKeyPath::kStringType:
|
||||
- return V8String(isolate, value.String());
|
||||
+ return V8String(isolate, value.GetString());
|
||||
case IDBKeyPath::kArrayType:
|
||||
return ToV8(value.Array(), creation_context, isolate);
|
||||
}
|
||||
@@ -97,7 +97,7 @@ v8::Local<v8::Value> ToV8(const IDBKey*
|
||||
case IDBKey::kNumberType:
|
||||
return v8::Number::New(isolate, key->Number());
|
||||
case IDBKey::kStringType:
|
||||
- return V8String(isolate, key->String());
|
||||
+ return V8String(isolate, key->GetString());
|
||||
case IDBKey::kBinaryType:
|
||||
// https://w3c.github.io/IndexedDB/#convert-a-value-to-a-key
|
||||
return ToV8(DOMArrayBuffer::Create(key->Binary()), creation_context,
|
||||
@@ -379,7 +379,7 @@ static std::unique_ptr<IDBKey> CreateIDB
|
||||
}
|
||||
|
||||
DCHECK_EQ(key_path.GetType(), IDBKeyPath::kStringType);
|
||||
- return CreateIDBKeyFromValueAndKeyPath(isolate, value, key_path.String(),
|
||||
+ return CreateIDBKeyFromValueAndKeyPath(isolate, value, key_path.GetString(),
|
||||
exception_state);
|
||||
}
|
||||
|
||||
@@ -483,7 +483,7 @@ bool InjectV8KeyIntoV8Value(v8::Isolate*
|
||||
DCHECK(isolate->InContext());
|
||||
|
||||
DCHECK_EQ(key_path.GetType(), IDBKeyPath::kStringType);
|
||||
- Vector<String> key_path_elements = ParseKeyPath(key_path.String());
|
||||
+ Vector<String> key_path_elements = ParseKeyPath(key_path.GetString());
|
||||
|
||||
// The conbination of a key generator and an empty key path is forbidden by
|
||||
// spec.
|
||||
@@ -569,7 +569,7 @@ bool CanInjectIDBKeyIntoScriptValue(v8::
|
||||
const IDBKeyPath& key_path) {
|
||||
IDB_TRACE("canInjectIDBKeyIntoScriptValue");
|
||||
DCHECK_EQ(key_path.GetType(), IDBKeyPath::kStringType);
|
||||
- Vector<String> key_path_elements = ParseKeyPath(key_path.String());
|
||||
+ Vector<String> key_path_elements = ParseKeyPath(key_path.GetString());
|
||||
|
||||
if (!key_path_elements.size())
|
||||
return false;
|
||||
diff -up chromium-65.0.3325.146/third_party/WebKit/Source/modules/exported/WebIDBKey.cpp.GetString chromium-65.0.3325.146/third_party/WebKit/Source/modules/exported/WebIDBKey.cpp
|
||||
--- chromium-65.0.3325.146/third_party/WebKit/Source/modules/exported/WebIDBKey.cpp.GetString 2018-03-13 22:56:04.041798217 -0400
|
||||
+++ chromium-65.0.3325.146/third_party/WebKit/Source/modules/exported/WebIDBKey.cpp 2018-03-13 22:56:22.481440993 -0400
|
||||
@@ -56,7 +56,7 @@ WebData WebIDBKeyView::Binary() const {
|
||||
}
|
||||
|
||||
WebString WebIDBKeyView::String() const {
|
||||
- return private_->String();
|
||||
+ return private_->GetString();
|
||||
}
|
||||
|
||||
double WebIDBKeyView::Date() const {
|
||||
diff -up chromium-65.0.3325.146/third_party/WebKit/Source/modules/indexeddb/IDBDatabase.cpp.GetString chromium-65.0.3325.146/third_party/WebKit/Source/modules/indexeddb/IDBDatabase.cpp
|
||||
--- chromium-65.0.3325.146/third_party/WebKit/Source/modules/indexeddb/IDBDatabase.cpp.GetString 2018-03-13 22:56:36.028178758 -0400
|
||||
+++ chromium-65.0.3325.146/third_party/WebKit/Source/modules/indexeddb/IDBDatabase.cpp 2018-03-13 22:56:58.846736831 -0400
|
||||
@@ -297,7 +297,7 @@ IDBObjectStore* IDBDatabase::createObjec
|
||||
}
|
||||
|
||||
if (auto_increment && ((key_path.GetType() == IDBKeyPath::kStringType &&
|
||||
- key_path.String().IsEmpty()) ||
|
||||
+ key_path.GetString().IsEmpty()) ||
|
||||
key_path.GetType() == IDBKeyPath::kArrayType)) {
|
||||
exception_state.ThrowDOMException(
|
||||
kInvalidAccessError,
|
||||
diff -up chromium-65.0.3325.146/third_party/WebKit/Source/modules/indexeddb/IDBKey.h.GetString chromium-65.0.3325.146/third_party/WebKit/Source/modules/indexeddb/IDBKey.h
|
||||
--- chromium-65.0.3325.146/third_party/WebKit/Source/modules/indexeddb/IDBKey.h.GetString 2018-03-13 22:57:13.229458842 -0400
|
||||
+++ chromium-65.0.3325.146/third_party/WebKit/Source/modules/indexeddb/IDBKey.h 2018-03-13 22:57:38.633966776 -0400
|
||||
@@ -106,7 +106,7 @@ class MODULES_EXPORT IDBKey {
|
||||
return binary_;
|
||||
}
|
||||
|
||||
- const String& String() const {
|
||||
+ const String& GetString() const {
|
||||
DCHECK_EQ(type_, kStringType);
|
||||
return string_;
|
||||
}
|
||||
diff -up chromium-65.0.3325.146/third_party/WebKit/Source/modules/indexeddb/IDBKeyPath.h.GetString chromium-65.0.3325.146/third_party/WebKit/Source/modules/indexeddb/IDBKeyPath.h
|
||||
--- chromium-65.0.3325.146/third_party/WebKit/Source/modules/indexeddb/IDBKeyPath.h.GetString 2018-03-13 22:57:51.104725428 -0400
|
||||
+++ chromium-65.0.3325.146/third_party/WebKit/Source/modules/indexeddb/IDBKeyPath.h 2018-03-13 22:58:09.459369906 -0400
|
||||
@@ -65,7 +65,7 @@ class MODULES_EXPORT IDBKeyPath {
|
||||
return array_;
|
||||
}
|
||||
|
||||
- const String& String() const {
|
||||
+ const String& GetString() const {
|
||||
DCHECK_EQ(type_, kStringType);
|
||||
return string_;
|
||||
}
|
||||
diff -up chromium-65.0.3325.146/third_party/WebKit/Source/modules/indexeddb/InspectorIndexedDBAgent.cpp.GetString chromium-65.0.3325.146/third_party/WebKit/Source/modules/indexeddb/InspectorIndexedDBAgent.cpp
|
||||
--- chromium-65.0.3325.146/third_party/WebKit/Source/modules/indexeddb/InspectorIndexedDBAgent.cpp.GetString 2018-03-13 22:58:28.778995834 -0400
|
||||
+++ chromium-65.0.3325.146/third_party/WebKit/Source/modules/indexeddb/InspectorIndexedDBAgent.cpp 2018-03-13 22:58:45.044681364 -0400
|
||||
@@ -399,7 +399,7 @@ static std::unique_ptr<KeyPath> KeyPathF
|
||||
case IDBKeyPath::kStringType:
|
||||
key_path = KeyPath::create()
|
||||
.setType(KeyPath::TypeEnum::String)
|
||||
- .setString(idb_key_path.String())
|
||||
+ .setString(idb_key_path.GetString())
|
||||
.build();
|
||||
break;
|
||||
case IDBKeyPath::kArrayType: {
|
@ -0,0 +1,22 @@
|
||||
diff -up chromium-65.0.3325.146/cc/raster/playback_image_provider.cc.pipcc chromium-65.0.3325.146/cc/raster/playback_image_provider.cc
|
||||
--- chromium-65.0.3325.146/cc/raster/playback_image_provider.cc.pipcc 2018-03-13 22:47:00.271322726 -0400
|
||||
+++ chromium-65.0.3325.146/cc/raster/playback_image_provider.cc 2018-03-13 22:47:53.127300060 -0400
|
||||
@@ -92,7 +92,6 @@ PlaybackImageProvider::GetDecodedDrawIma
|
||||
}
|
||||
|
||||
PlaybackImageProvider::Settings::Settings() = default;
|
||||
-PlaybackImageProvider::Settings::Settings(const Settings& other) = default;
|
||||
PlaybackImageProvider::Settings::~Settings() = default;
|
||||
|
||||
} // namespace cc
|
||||
diff -up chromium-65.0.3325.146/cc/raster/playback_image_provider.h.pipcc chromium-65.0.3325.146/cc/raster/playback_image_provider.h
|
||||
--- chromium-65.0.3325.146/cc/raster/playback_image_provider.h.pipcc 2018-03-13 22:48:00.673153629 -0400
|
||||
+++ chromium-65.0.3325.146/cc/raster/playback_image_provider.h 2018-03-13 22:48:12.726920597 -0400
|
||||
@@ -20,7 +20,6 @@ class CC_EXPORT PlaybackImageProvider :
|
||||
public:
|
||||
struct CC_EXPORT Settings {
|
||||
Settings();
|
||||
- Settings(const Settings& other);
|
||||
~Settings();
|
||||
|
||||
// The set of image ids to skip during raster.
|
@ -0,0 +1,33 @@
|
||||
diff -up chromium-65.0.3325.146/services/preferences/tracked/pref_hash_filter.h.fulldecl chromium-65.0.3325.146/services/preferences/tracked/pref_hash_filter.h
|
||||
--- chromium-65.0.3325.146/services/preferences/tracked/pref_hash_filter.h.fulldecl 2018-03-13 16:38:38.870652491 -0400
|
||||
+++ chromium-65.0.3325.146/services/preferences/tracked/pref_hash_filter.h 2018-03-13 16:39:02.691186647 -0400
|
||||
@@ -21,9 +21,9 @@
|
||||
#include "services/preferences/public/interfaces/preferences.mojom.h"
|
||||
#include "services/preferences/tracked/hash_store_contents.h"
|
||||
#include "services/preferences/tracked/interceptable_pref_filter.h"
|
||||
+#include "services/preferences/tracked/pref_hash_store.h"
|
||||
#include "services/preferences/tracked/tracked_preference.h"
|
||||
|
||||
-class PrefHashStore;
|
||||
class PrefService;
|
||||
|
||||
namespace base {
|
||||
diff -up chromium-65.0.3325.146/third_party/WebKit/Source/modules/webdatabase/SQLTransactionBackend.h.fulldecl chromium-65.0.3325.146/third_party/WebKit/Source/modules/webdatabase/SQLTransactionBackend.h
|
||||
--- chromium-65.0.3325.146/third_party/WebKit/Source/modules/webdatabase/SQLTransactionBackend.h.fulldecl 2018-03-13 16:39:13.787970233 -0400
|
||||
+++ chromium-65.0.3325.146/third_party/WebKit/Source/modules/webdatabase/SQLTransactionBackend.h 2018-03-13 16:39:42.614407235 -0400
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
#include <memory>
|
||||
#include "modules/webdatabase/DatabaseBasicTypes.h"
|
||||
+#include "modules/webdatabase/SQLError.h"
|
||||
#include "modules/webdatabase/SQLStatement.h"
|
||||
#include "modules/webdatabase/SQLStatementBackend.h"
|
||||
#include "modules/webdatabase/SQLTransactionStateMachine.h"
|
||||
@@ -41,7 +42,6 @@
|
||||
namespace blink {
|
||||
|
||||
class Database;
|
||||
-class SQLErrorData;
|
||||
class SQLiteTransaction;
|
||||
class SQLTransaction;
|
||||
class SQLTransactionBackend;
|
@ -0,0 +1,24 @@
|
||||
diff -up chromium-65.0.3325.146/content/browser/appcache/appcache_request_handler.cc.explicit-std-move chromium-65.0.3325.146/content/browser/appcache/appcache_request_handler.cc
|
||||
--- chromium-65.0.3325.146/content/browser/appcache/appcache_request_handler.cc.explicit-std-move 2018-03-13 22:50:41.346043716 -0400
|
||||
+++ chromium-65.0.3325.146/content/browser/appcache/appcache_request_handler.cc 2018-03-13 22:51:21.428267583 -0400
|
||||
@@ -639,7 +639,7 @@ AppCacheRequestHandler::MaybeCreateSubre
|
||||
|
||||
SubresourceLoaderParams params;
|
||||
params.loader_factory_info = factory_ptr.PassInterface();
|
||||
- return params;
|
||||
+ return base::Optional<SubresourceLoaderParams>(std::move(params));
|
||||
}
|
||||
|
||||
void AppCacheRequestHandler::MaybeCreateSubresourceLoader(
|
||||
diff -up chromium-65.0.3325.146/content/browser/service_worker/service_worker_controllee_request_handler.cc.explicit-std-move chromium-65.0.3325.146/content/browser/service_worker/service_worker_controllee_request_handler.cc
|
||||
--- chromium-65.0.3325.146/content/browser/service_worker/service_worker_controllee_request_handler.cc.explicit-std-move 2018-03-13 22:51:38.133943776 -0400
|
||||
+++ chromium-65.0.3325.146/content/browser/service_worker/service_worker_controllee_request_handler.cc 2018-03-13 22:51:57.658566347 -0400
|
||||
@@ -271,7 +271,7 @@ ServiceWorkerControlleeRequestHandler::M
|
||||
controller_info->object_info = provider_host_->GetOrCreateServiceWorkerHandle(
|
||||
provider_host_->controller());
|
||||
params.controller_service_worker_info = std::move(controller_info);
|
||||
- return params;
|
||||
+ return base::Optional<SubresourceLoaderParams>(std::move(params));
|
||||
}
|
||||
|
||||
void ServiceWorkerControlleeRequestHandler::PrepareForMainResource(
|
@ -0,0 +1,18 @@
|
||||
diff -up chromium-65.0.3325.146/components/policy/core/browser/browser_policy_connector_base.h.fully-declare chromium-65.0.3325.146/components/policy/core/browser/browser_policy_connector_base.h
|
||||
--- chromium-65.0.3325.146/components/policy/core/browser/browser_policy_connector_base.h.fully-declare 2018-03-13 23:02:13.989635567 -0400
|
||||
+++ chromium-65.0.3325.146/components/policy/core/browser/browser_policy_connector_base.h 2018-03-13 23:02:44.318048625 -0400
|
||||
@@ -12,13 +12,13 @@
|
||||
#include "base/macros.h"
|
||||
#include "base/optional.h"
|
||||
#include "components/policy/core/browser/configuration_policy_handler_list.h"
|
||||
+#include "components/policy/core/common/configuration_policy_provider.h"
|
||||
#include "components/policy/core/common/schema.h"
|
||||
#include "components/policy/core/common/schema_registry.h"
|
||||
#include "components/policy/policy_export.h"
|
||||
|
||||
namespace policy {
|
||||
|
||||
-class ConfigurationPolicyProvider;
|
||||
class PolicyService;
|
||||
class PolicyServiceImpl;
|
||||
|
@ -0,0 +1,91 @@
|
||||
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<T> 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<T>'s move constructor should not
|
||||
+// participate in overload resolution. This inheritance trick implements that.
|
||||
+template <bool is_copy_constructible>
|
||||
+struct CopyConstructible {};
|
||||
+
|
||||
+template <>
|
||||
+struct CopyConstructible<false> {
|
||||
+ constexpr CopyConstructible() = default;
|
||||
+ constexpr CopyConstructible(const CopyConstructible&) = delete;
|
||||
+ constexpr CopyConstructible(CopyConstructible&&) = default;
|
||||
+ CopyConstructible& operator=(const CopyConstructible&) = default;
|
||||
+ CopyConstructible& operator=(CopyConstructible&&) = default;
|
||||
+};
|
||||
+
|
||||
+template <bool is_move_constructible>
|
||||
+struct MoveConstructible {};
|
||||
+
|
||||
+template <>
|
||||
+struct MoveConstructible<false> {
|
||||
+ constexpr MoveConstructible() = default;
|
||||
+ constexpr MoveConstructible(const MoveConstructible&) = default;
|
||||
+ constexpr MoveConstructible(MoveConstructible&&) = delete;
|
||||
+ MoveConstructible& operator=(const MoveConstructible&) = default;
|
||||
+ MoveConstructible& operator=(MoveConstructible&&) = default;
|
||||
+};
|
||||
+
|
||||
+template <bool is_copy_assignable>
|
||||
+struct CopyAssignable {};
|
||||
+
|
||||
+template <>
|
||||
+struct CopyAssignable<false> {
|
||||
+ constexpr CopyAssignable() = default;
|
||||
+ constexpr CopyAssignable(const CopyAssignable&) = default;
|
||||
+ constexpr CopyAssignable(CopyAssignable&&) = default;
|
||||
+ CopyAssignable& operator=(const CopyAssignable&) = delete;
|
||||
+ CopyAssignable& operator=(CopyAssignable&&) = default;
|
||||
+};
|
||||
+
|
||||
+template <bool is_move_assignable>
|
||||
+struct MoveAssignable {};
|
||||
+
|
||||
+template <>
|
||||
+struct MoveAssignable<false> {
|
||||
+ 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 <typename T>
|
||||
-class Optional : public internal::OptionalBase<T> {
|
||||
+class Optional
|
||||
+ : public internal::OptionalBase<T>,
|
||||
+ public internal::CopyConstructible<std::is_copy_constructible<T>::value>,
|
||||
+ public internal::MoveConstructible<std::is_move_constructible<T>::value>,
|
||||
+ public internal::CopyAssignable<std::is_copy_constructible<T>::value &&
|
||||
+ std::is_copy_assignable<T>::value>,
|
||||
+ public internal::MoveAssignable<std::is_move_constructible<T>::value &&
|
||||
+ std::is_move_assignable<T>::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;
|
||||
|
@ -0,0 +1,116 @@
|
||||
diff -up chromium-65.0.3325.146/base/optional.h.converting chromium-65.0.3325.146/base/optional.h
|
||||
--- chromium-65.0.3325.146/base/optional.h.converting 2018-03-13 22:31:05.248797490 -0400
|
||||
+++ chromium-65.0.3325.146/base/optional.h 2018-03-13 22:33:10.826368771 -0400
|
||||
@@ -31,6 +31,10 @@ constexpr in_place_t in_place = {};
|
||||
// http://en.cppreference.com/w/cpp/utility/optional/nullopt
|
||||
constexpr nullopt_t nullopt(0);
|
||||
|
||||
+// Forward declaration, which is refered by following helpers.
|
||||
+template <typename T>
|
||||
+class Optional;
|
||||
+
|
||||
namespace internal {
|
||||
|
||||
template <typename T, bool = std::is_trivially_destructible<T>::value>
|
||||
@@ -220,6 +224,19 @@ class OptionalBase {
|
||||
constexpr explicit OptionalBase(in_place_t, Args&&... args)
|
||||
: storage_(in_place, std::forward<Args>(args)...) {}
|
||||
|
||||
+ // Implementation of converting constructors.
|
||||
+ template <typename U>
|
||||
+ explicit OptionalBase(const OptionalBase<U>& other) {
|
||||
+ if (other.storage_.is_populated_)
|
||||
+ storage_.Init(other.storage_.value_);
|
||||
+ }
|
||||
+
|
||||
+ template <typename U>
|
||||
+ explicit OptionalBase(OptionalBase<U>&& other) {
|
||||
+ if (other.storage_.is_populated_)
|
||||
+ storage_.Init(std::move(other.storage_.value_));
|
||||
+ }
|
||||
+
|
||||
~OptionalBase() = default;
|
||||
|
||||
OptionalBase& operator=(const OptionalBase& other) {
|
||||
@@ -263,6 +280,11 @@ class OptionalBase {
|
||||
storage_.is_populated_ = false;
|
||||
}
|
||||
|
||||
+ // For implementing conversion, allow access to other typed OptionalBase
|
||||
+ // class.
|
||||
+ template <typename U>
|
||||
+ friend class OptionalBase;
|
||||
+
|
||||
OptionalStorage<T> storage_;
|
||||
};
|
||||
|
||||
@@ -318,6 +340,20 @@ struct MoveAssignable<false> {
|
||||
MoveAssignable& operator=(MoveAssignable&&) = delete;
|
||||
};
|
||||
|
||||
+// Helper to conditionally enable converting constructors.
|
||||
+template <typename T, typename U>
|
||||
+struct IsConvertibleFromOptional
|
||||
+ : std::integral_constant<
|
||||
+ bool,
|
||||
+ std::is_constructible<T, Optional<U>&>::value ||
|
||||
+ std::is_constructible<T, const Optional<U>&>::value ||
|
||||
+ std::is_constructible<T, Optional<U>&&>::value ||
|
||||
+ std::is_constructible<T, const Optional<U>&&>::value ||
|
||||
+ std::is_convertible<Optional<U>&, T>::value ||
|
||||
+ std::is_convertible<const Optional<U>&, T>::value ||
|
||||
+ std::is_convertible<Optional<U>&&, T>::value ||
|
||||
+ std::is_convertible<const Optional<U>&&, T>::value> {};
|
||||
+
|
||||
} // namespace internal
|
||||
|
||||
// base::Optional is a Chromium version of the C++17 optional class:
|
||||
@@ -348,7 +384,47 @@ class Optional
|
||||
constexpr Optional(const Optional& other) = default;
|
||||
constexpr Optional(Optional&& other) = default;
|
||||
|
||||
- constexpr Optional(nullopt_t) {}
|
||||
+ constexpr Optional(nullopt_t) {} // NOLINT(runtime/explicit)
|
||||
+
|
||||
+ // Converting copy constructor. "explicit" only if
|
||||
+ // std::is_convertible<const U&, T>::value is false. It is implemented by
|
||||
+ // declaring two almost same constructors, but that condition in enable_if_t
|
||||
+ // is different, so that either one is chosen, thanks to SFINAE.
|
||||
+ template <
|
||||
+ typename U,
|
||||
+ std::enable_if_t<std::is_constructible<T, const U&>::value &&
|
||||
+ !internal::IsConvertibleFromOptional<T, U>::value &&
|
||||
+ std::is_convertible<const U&, T>::value,
|
||||
+ bool> = false>
|
||||
+ Optional(const Optional<U>& other) : internal::OptionalBase<T>(other) {}
|
||||
+
|
||||
+ template <
|
||||
+ typename U,
|
||||
+ std::enable_if_t<std::is_constructible<T, const U&>::value &&
|
||||
+ !internal::IsConvertibleFromOptional<T, U>::value &&
|
||||
+ !std::is_convertible<const U&, T>::value,
|
||||
+ bool> = false>
|
||||
+ explicit Optional(const Optional<U>& other)
|
||||
+ : internal::OptionalBase<T>(other) {}
|
||||
+
|
||||
+ // Converting move constructor. Similar to converting copy constructor,
|
||||
+ // declaring two (explicit and non-explicit) constructors.
|
||||
+ template <
|
||||
+ typename U,
|
||||
+ std::enable_if_t<std::is_constructible<T, U&&>::value &&
|
||||
+ !internal::IsConvertibleFromOptional<T, U>::value &&
|
||||
+ std::is_convertible<U&&, T>::value,
|
||||
+ bool> = false>
|
||||
+ Optional(Optional<U>&& other) : internal::OptionalBase<T>(std::move(other)) {}
|
||||
+
|
||||
+ template <
|
||||
+ typename U,
|
||||
+ std::enable_if_t<std::is_constructible<T, U&&>::value &&
|
||||
+ !internal::IsConvertibleFromOptional<T, U>::value &&
|
||||
+ !std::is_convertible<U&&, T>::value,
|
||||
+ bool> = false>
|
||||
+ explicit Optional(Optional<U>&& other)
|
||||
+ : internal::OptionalBase<T>(std::move(other)) {}
|
||||
|
||||
constexpr Optional(const T& value)
|
||||
: internal::OptionalBase<T>(in_place, value) {}
|
@ -0,0 +1,72 @@
|
||||
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<Optional<U>&&, T>::value ||
|
||||
std::is_convertible<const Optional<U>&&, T>::value> {};
|
||||
|
||||
+// Forward compatibility for C++20.
|
||||
+template <typename T>
|
||||
+using RemoveCvRefT = std::remove_cv_t<std::remove_reference_t<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<T>) etc. Optional<T> checks
|
||||
+// T's constructor (specifically via IsConvertibleFromOptional), and in the
|
||||
+// check whether T can be constructible from Optional<T>, 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 <typename T>
|
||||
class Optional
|
||||
: public internal::OptionalBase<T>,
|
||||
@@ -426,12 +437,6 @@ class Optional
|
||||
explicit Optional(Optional<U>&& other)
|
||||
: internal::OptionalBase<T>(std::move(other)) {}
|
||||
|
||||
- constexpr Optional(const T& value)
|
||||
- : internal::OptionalBase<T>(in_place, value) {}
|
||||
-
|
||||
- constexpr Optional(T&& value)
|
||||
- : internal::OptionalBase<T>(in_place, std::move(value)) {}
|
||||
-
|
||||
template <class... Args>
|
||||
constexpr explicit Optional(in_place_t, Args&&... args)
|
||||
: internal::OptionalBase<T>(in_place, std::forward<Args>(args)...) {}
|
||||
@@ -447,6 +452,30 @@ class Optional
|
||||
Args&&... args)
|
||||
: internal::OptionalBase<T>(in_place, il, std::forward<Args>(args)...) {}
|
||||
|
||||
+ // Forward value constructor. Similar to converting constructors,
|
||||
+ // conditionally explicit.
|
||||
+ template <
|
||||
+ typename U = value_type,
|
||||
+ std::enable_if_t<
|
||||
+ std::is_constructible<T, U&&>::value &&
|
||||
+ !std::is_same<internal::RemoveCvRefT<U>, in_place_t>::value &&
|
||||
+ !std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value &&
|
||||
+ std::is_convertible<U&&, T>::value,
|
||||
+ bool> = false>
|
||||
+ constexpr Optional(U&& value)
|
||||
+ : internal::OptionalBase<T>(in_place, std::forward<U>(value)) {}
|
||||
+
|
||||
+ template <
|
||||
+ typename U = value_type,
|
||||
+ std::enable_if_t<
|
||||
+ std::is_constructible<T, U&&>::value &&
|
||||
+ !std::is_same<internal::RemoveCvRefT<U>, in_place_t>::value &&
|
||||
+ !std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value &&
|
||||
+ !std::is_convertible<U&&, T>::value,
|
||||
+ bool> = false>
|
||||
+ constexpr explicit Optional(U&& value)
|
||||
+ : internal::OptionalBase<T>(in_place, std::forward<U>(value)) {}
|
||||
+
|
||||
~Optional() = default;
|
||||
|
||||
// Defer copy-/move- assign operator implementation to OptionalBase.
|
@ -0,0 +1,144 @@
|
||||
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_;
|
||||
};
|
||||
|
@ -0,0 +1,265 @@
|
||||
diff -up chromium-65.0.3325.146/base/optional.h.affirmative chromium-65.0.3325.146/base/optional.h
|
||||
--- chromium-65.0.3325.146/base/optional.h.affirmative 2018-03-13 22:27:29.451969704 -0400
|
||||
+++ chromium-65.0.3325.146/base/optional.h 2018-03-13 22:27:57.031436045 -0400
|
||||
@@ -41,7 +41,7 @@ struct OptionalStorageBase {
|
||||
|
||||
template <class... Args>
|
||||
constexpr explicit OptionalStorageBase(in_place_t, Args&&... args)
|
||||
- : is_null_(false), value_(std::forward<Args>(args)...) {}
|
||||
+ : is_populated_(true), value_(std::forward<Args>(args)...) {}
|
||||
|
||||
// When T is not trivially destructible we must call its
|
||||
// destructor before deallocating its memory.
|
||||
@@ -55,18 +55,18 @@ struct OptionalStorageBase {
|
||||
// necessary for this case at the moment. Please see also the destructor
|
||||
// comment in "is_trivially_destructible = true" specialization below.
|
||||
~OptionalStorageBase() {
|
||||
- if (!is_null_)
|
||||
+ if (is_populated_)
|
||||
value_.~T();
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
void Init(Args&&... args) {
|
||||
- DCHECK(is_null_);
|
||||
+ DCHECK(!is_populated_);
|
||||
::new (&value_) T(std::forward<Args>(args)...);
|
||||
- is_null_ = false;
|
||||
+ is_populated_ = true;
|
||||
}
|
||||
|
||||
- bool is_null_ = true;
|
||||
+ bool is_populated_ = false;
|
||||
union {
|
||||
// |empty_| exists so that the union will always be initialized, even when
|
||||
// it doesn't contain a value. Union members must be initialized for the
|
||||
@@ -84,7 +84,7 @@ struct OptionalStorageBase<T, true /* tr
|
||||
|
||||
template <class... Args>
|
||||
constexpr explicit OptionalStorageBase(in_place_t, Args&&... args)
|
||||
- : is_null_(false), value_(std::forward<Args>(args)...) {}
|
||||
+ : is_populated_(true), value_(std::forward<Args>(args)...) {}
|
||||
|
||||
// When T is trivially destructible (i.e. its destructor does nothing) there
|
||||
// is no need to call it. Implicitly defined destructor is trivial, because
|
||||
@@ -102,12 +102,12 @@ struct OptionalStorageBase<T, true /* tr
|
||||
|
||||
template <class... Args>
|
||||
void Init(Args&&... args) {
|
||||
- DCHECK(is_null_);
|
||||
+ DCHECK(!is_populated_);
|
||||
::new (&value_) T(std::forward<Args>(args)...);
|
||||
- is_null_ = false;
|
||||
+ is_populated_ = true;
|
||||
}
|
||||
|
||||
- bool is_null_ = true;
|
||||
+ bool is_populated_ = false;
|
||||
union {
|
||||
// |empty_| exists so that the union will always be initialized, even when
|
||||
// it doesn't contain a value. Union members must be initialized for the
|
||||
@@ -133,7 +133,7 @@ struct OptionalStorage : OptionalStorage
|
||||
|
||||
// Accessing the members of template base class requires explicit
|
||||
// declaration.
|
||||
- using OptionalStorageBase<T>::is_null_;
|
||||
+ using OptionalStorageBase<T>::is_populated_;
|
||||
using OptionalStorageBase<T>::value_;
|
||||
using OptionalStorageBase<T>::Init;
|
||||
|
||||
@@ -145,12 +145,12 @@ struct OptionalStorage : OptionalStorage
|
||||
OptionalStorage() = default;
|
||||
|
||||
OptionalStorage(const OptionalStorage& other) {
|
||||
- if (!other.is_null_)
|
||||
+ if (other.is_populated_)
|
||||
Init(other.value_);
|
||||
}
|
||||
|
||||
OptionalStorage(OptionalStorage&& other) {
|
||||
- if (!other.is_null_)
|
||||
+ if (other.is_populated_)
|
||||
Init(std::move(other.value_));
|
||||
}
|
||||
};
|
||||
@@ -160,7 +160,7 @@ struct OptionalStorage<T,
|
||||
true /* trivially copy constructible */,
|
||||
false /* trivially move constructible */>
|
||||
: OptionalStorageBase<T> {
|
||||
- using OptionalStorageBase<T>::is_null_;
|
||||
+ using OptionalStorageBase<T>::is_populated_;
|
||||
using OptionalStorageBase<T>::value_;
|
||||
using OptionalStorageBase<T>::Init;
|
||||
using OptionalStorageBase<T>::OptionalStorageBase;
|
||||
@@ -169,7 +169,7 @@ struct OptionalStorage<T,
|
||||
OptionalStorage(const OptionalStorage& other) = default;
|
||||
|
||||
OptionalStorage(OptionalStorage&& other) {
|
||||
- if (!other.is_null_)
|
||||
+ if (other.is_populated_)
|
||||
Init(std::move(other.value_));
|
||||
}
|
||||
};
|
||||
@@ -179,7 +179,7 @@ struct OptionalStorage<T,
|
||||
false /* trivially copy constructible */,
|
||||
true /* trivially move constructible */>
|
||||
: OptionalStorageBase<T> {
|
||||
- using OptionalStorageBase<T>::is_null_;
|
||||
+ using OptionalStorageBase<T>::is_populated_;
|
||||
using OptionalStorageBase<T>::value_;
|
||||
using OptionalStorageBase<T>::Init;
|
||||
using OptionalStorageBase<T>::OptionalStorageBase;
|
||||
@@ -188,7 +188,7 @@ struct OptionalStorage<T,
|
||||
OptionalStorage(OptionalStorage&& other) = default;
|
||||
|
||||
OptionalStorage(const OptionalStorage& other) {
|
||||
- if (!other.is_null_)
|
||||
+ if (other.is_populated_)
|
||||
Init(other.value_);
|
||||
}
|
||||
};
|
||||
@@ -223,7 +223,7 @@ class OptionalBase {
|
||||
~OptionalBase() = default;
|
||||
|
||||
OptionalBase& operator=(const OptionalBase& other) {
|
||||
- if (other.storage_.is_null_) {
|
||||
+ if (!other.storage_.is_populated_) {
|
||||
FreeIfNeeded();
|
||||
return *this;
|
||||
}
|
||||
@@ -233,7 +233,7 @@ class OptionalBase {
|
||||
}
|
||||
|
||||
OptionalBase& operator=(OptionalBase&& other) {
|
||||
- if (other.storage_.is_null_) {
|
||||
+ if (!other.storage_.is_populated_) {
|
||||
FreeIfNeeded();
|
||||
return *this;
|
||||
}
|
||||
@@ -243,24 +243,24 @@ class OptionalBase {
|
||||
}
|
||||
|
||||
void InitOrAssign(const T& value) {
|
||||
- if (storage_.is_null_)
|
||||
+ if (!storage_.is_populated_)
|
||||
storage_.Init(value);
|
||||
else
|
||||
storage_.value_ = value;
|
||||
}
|
||||
|
||||
void InitOrAssign(T&& value) {
|
||||
- if (storage_.is_null_)
|
||||
+ if (!storage_.is_populated_)
|
||||
storage_.Init(std::move(value));
|
||||
else
|
||||
storage_.value_ = std::move(value);
|
||||
}
|
||||
|
||||
void FreeIfNeeded() {
|
||||
- if (storage_.is_null_)
|
||||
+ if (!storage_.is_populated_)
|
||||
return;
|
||||
storage_.value_.~T();
|
||||
- storage_.is_null_ = true;
|
||||
+ storage_.is_populated_ = false;
|
||||
}
|
||||
|
||||
OptionalStorage<T> storage_;
|
||||
@@ -334,12 +334,12 @@ class Optional : public internal::Option
|
||||
}
|
||||
|
||||
constexpr const T* operator->() const {
|
||||
- DCHECK(!storage_.is_null_);
|
||||
+ DCHECK(storage_.is_populated_);
|
||||
return &value();
|
||||
}
|
||||
|
||||
constexpr T* operator->() {
|
||||
- DCHECK(!storage_.is_null_);
|
||||
+ DCHECK(storage_.is_populated_);
|
||||
return &value();
|
||||
}
|
||||
|
||||
@@ -351,27 +351,27 @@ class Optional : public internal::Option
|
||||
|
||||
constexpr T&& operator*() && { return std::move(value()); }
|
||||
|
||||
- constexpr explicit operator bool() const { return !storage_.is_null_; }
|
||||
+ constexpr explicit operator bool() const { return storage_.is_populated_; }
|
||||
|
||||
- constexpr bool has_value() const { return !storage_.is_null_; }
|
||||
+ constexpr bool has_value() const { return storage_.is_populated_; }
|
||||
|
||||
constexpr T& value() & {
|
||||
- DCHECK(!storage_.is_null_);
|
||||
+ DCHECK(storage_.is_populated_);
|
||||
return storage_.value_;
|
||||
}
|
||||
|
||||
constexpr const T& value() const & {
|
||||
- DCHECK(!storage_.is_null_);
|
||||
+ DCHECK(storage_.is_populated_);
|
||||
return storage_.value_;
|
||||
}
|
||||
|
||||
constexpr T&& value() && {
|
||||
- DCHECK(!storage_.is_null_);
|
||||
+ DCHECK(storage_.is_populated_);
|
||||
return std::move(storage_.value_);
|
||||
}
|
||||
|
||||
constexpr const T&& value() const && {
|
||||
- DCHECK(!storage_.is_null_);
|
||||
+ DCHECK(storage_.is_populated_);
|
||||
return std::move(storage_.value_);
|
||||
}
|
||||
|
||||
@@ -382,8 +382,9 @@ class Optional : public internal::Option
|
||||
// "T must be copy constructible");
|
||||
static_assert(std::is_convertible<U, T>::value,
|
||||
"U must be convertible to T");
|
||||
- return storage_.is_null_ ? static_cast<T>(std::forward<U>(default_value))
|
||||
- : value();
|
||||
+ return storage_.is_populated_
|
||||
+ ? value()
|
||||
+ : static_cast<T>(std::forward<U>(default_value));
|
||||
}
|
||||
|
||||
template <class U>
|
||||
@@ -393,26 +394,27 @@ class Optional : public internal::Option
|
||||
// "T must be move constructible");
|
||||
static_assert(std::is_convertible<U, T>::value,
|
||||
"U must be convertible to T");
|
||||
- return storage_.is_null_ ? static_cast<T>(std::forward<U>(default_value))
|
||||
- : std::move(value());
|
||||
+ return storage_.is_populated_
|
||||
+ ? std::move(value())
|
||||
+ : static_cast<T>(std::forward<U>(default_value));
|
||||
}
|
||||
|
||||
void swap(Optional& other) {
|
||||
- if (storage_.is_null_ && other.storage_.is_null_)
|
||||
+ if (!storage_.is_populated_ && !other.storage_.is_populated_)
|
||||
return;
|
||||
|
||||
- if (storage_.is_null_ != other.storage_.is_null_) {
|
||||
- if (storage_.is_null_) {
|
||||
- storage_.Init(std::move(other.storage_.value_));
|
||||
- other.FreeIfNeeded();
|
||||
- } else {
|
||||
+ if (storage_.is_populated_ != other.storage_.is_populated_) {
|
||||
+ if (storage_.is_populated_) {
|
||||
other.storage_.Init(std::move(storage_.value_));
|
||||
FreeIfNeeded();
|
||||
+ } else {
|
||||
+ storage_.Init(std::move(other.storage_.value_));
|
||||
+ other.FreeIfNeeded();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
- DCHECK(!storage_.is_null_ && !other.storage_.is_null_);
|
||||
+ DCHECK(storage_.is_populated_ && other.storage_.is_populated_);
|
||||
using std::swap;
|
||||
swap(**this, *other);
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
diff -up chromium-65.0.3325.146/base/optional.h.784732 chromium-65.0.3325.146/base/optional.h
|
||||
--- chromium-65.0.3325.146/base/optional.h.784732 2018-03-07 13:40:00.103579631 -0500
|
||||
+++ chromium-65.0.3325.146/base/optional.h 2018-03-07 13:41:08.950323996 -0500
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <utility>
|
||||
|
||||
#include "base/logging.h"
|
||||
+#include "base/template_util.h"
|
||||
|
||||
namespace base {
|
||||
|
||||
@@ -106,7 +107,7 @@ struct OptionalStorageBase<T, true /* tr
|
||||
// compiler generated constexpr {copy,move} constructors). Note that
|
||||
// placement-new is prohibited in constexpr.
|
||||
template <typename T,
|
||||
- bool = std::is_trivially_copy_constructible<T>::value,
|
||||
+ bool = is_trivially_copy_constructible<T>::value,
|
||||
bool = std::is_trivially_move_constructible<T>::value>
|
||||
struct OptionalStorage : OptionalStorageBase<T> {
|
||||
// This is no trivially {copy,move} constructible case. Other cases are
|
||||
diff -up chromium-65.0.3325.146/base/template_util.h.784732 chromium-65.0.3325.146/base/template_util.h
|
||||
--- chromium-65.0.3325.146/base/template_util.h.784732 2018-03-07 13:41:19.479131969 -0500
|
||||
+++ chromium-65.0.3325.146/base/template_util.h 2018-03-07 13:42:41.308639551 -0500
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
+#include <vector>
|
||||
|
||||
#include "build/build_config.h"
|
||||
|
||||
@@ -127,6 +128,23 @@ template <class T>
|
||||
using is_trivially_copyable = std::is_trivially_copyable<T>;
|
||||
#endif
|
||||
|
||||
+#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ <= 7
|
||||
+// Workaround for g++7 and earlier family.
|
||||
+// Due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80654, without this
|
||||
+// Optional<std::vector<T>> where T is non-copyable causes a compile error.
|
||||
+// As we know it is not trivially copy constructible, explicitly declare so.
|
||||
+template <typename T>
|
||||
+struct is_trivially_copy_constructible
|
||||
+ : std::is_trivially_copy_constructible<T> {};
|
||||
+
|
||||
+template <typename... T>
|
||||
+struct is_trivially_copy_constructible<std::vector<T...>> : std::false_type {};
|
||||
+#else
|
||||
+// Otherwise use std::is_trivially_copy_constructible as is.
|
||||
+template <typename T>
|
||||
+using is_trivially_copy_constructible = std::is_trivially_copy_constructible<T>;
|
||||
+#endif
|
||||
+
|
||||
} // namespace base
|
||||
|
||||
#undef CR_USE_FALLBACKS_FOR_GCC_WITH_LIBCXX
|
@ -0,0 +1,61 @@
|
||||
diff -up chromium-65.0.3325.146/third_party/WebKit/Source/platform/heap/TraceTraits.h.oilpan chromium-65.0.3325.146/third_party/WebKit/Source/platform/heap/TraceTraits.h
|
||||
--- chromium-65.0.3325.146/third_party/WebKit/Source/platform/heap/TraceTraits.h.oilpan 2018-03-13 16:45:40.613426445 -0400
|
||||
+++ chromium-65.0.3325.146/third_party/WebKit/Source/platform/heap/TraceTraits.h 2018-03-13 16:45:49.946244905 -0400
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "platform/wtf/HashTable.h"
|
||||
#include "platform/wtf/LinkedHashSet.h"
|
||||
#include "platform/wtf/ListHashSet.h"
|
||||
+#include "platform/wtf/Optional.h"
|
||||
#include "platform/wtf/TypeTraits.h"
|
||||
|
||||
namespace blink {
|
||||
@@ -325,6 +326,23 @@ class TraceTrait<std::pair<T, U>> {
|
||||
}
|
||||
};
|
||||
|
||||
+// While using Optional<T> with garbage-collected types is generally disallowed
|
||||
+// by the OptionalGarbageCollected check in blink_gc_plugin, garbage-collected
|
||||
+// containers such as HeapVector are allowed and need to be traced.
|
||||
+template <typename T>
|
||||
+class TraceTrait<WTF::Optional<T>> {
|
||||
+ STATIC_ONLY(TraceTrait);
|
||||
+
|
||||
+ public:
|
||||
+ template <typename VisitorDispatcher>
|
||||
+ static void Trace(VisitorDispatcher visitor, WTF::Optional<T>* optional) {
|
||||
+ if (*optional != WTF::nullopt) {
|
||||
+ TraceIfEnabled<T, WTF::IsTraceable<T>::value>::Trace(visitor,
|
||||
+ optional->value());
|
||||
+ }
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
// If eager tracing leads to excessively deep |trace()| call chains (and
|
||||
// the system stack usage that this brings), the marker implementation will
|
||||
// switch to using an explicit mark stack. Recursive and deep object graphs
|
||||
diff -up chromium-65.0.3325.146/third_party/WebKit/Source/platform/wtf/Optional.h.oilpan chromium-65.0.3325.146/third_party/WebKit/Source/platform/wtf/Optional.h
|
||||
--- chromium-65.0.3325.146/third_party/WebKit/Source/platform/wtf/Optional.h.oilpan 2018-03-13 16:46:01.683015951 -0400
|
||||
+++ chromium-65.0.3325.146/third_party/WebKit/Source/platform/wtf/Optional.h 2018-03-13 16:46:51.632043375 -0400
|
||||
@@ -7,20 +7,15 @@
|
||||
|
||||
#include "base/optional.h"
|
||||
#include "platform/wtf/TemplateUtil.h"
|
||||
-#include "platform/wtf/TypeTraits.h"
|
||||
|
||||
namespace WTF {
|
||||
|
||||
// WTF::Optional is base::Optional. See base/optional.h for documentation.
|
||||
//
|
||||
// A clang plugin enforces that garbage collected types are not allocated
|
||||
-// outside of the heap, similarly we enforce that one doesn't create garbage
|
||||
-// collected types nested inside an Optional.
|
||||
+// outside of the heap. GC containers such as HeapVector are allowed though.
|
||||
template <typename T>
|
||||
-using Optional =
|
||||
- typename std::enable_if<!IsGarbageCollectedType<T>::value ||
|
||||
- IsPersistentReferenceType<T>::value,
|
||||
- base::Optional<T>>::type;
|
||||
+using Optional = base::Optional<T>;
|
||||
|
||||
constexpr base::nullopt_t nullopt = base::nullopt;
|
||||
constexpr base::in_place_t in_place = base::in_place;
|
@ -0,0 +1,54 @@
|
||||
diff -up chromium-65.0.3325.146/third_party/WebKit/Source/platform/wtf/DEPS.jdp chromium-65.0.3325.146/third_party/WebKit/Source/platform/wtf/DEPS
|
||||
--- chromium-65.0.3325.146/third_party/WebKit/Source/platform/wtf/DEPS.jdp 2018-03-07 13:54:42.653286576 -0500
|
||||
+++ chromium-65.0.3325.146/third_party/WebKit/Source/platform/wtf/DEPS 2018-03-07 13:55:00.973903591 -0500
|
||||
@@ -16,6 +16,7 @@ include_rules = [
|
||||
"+base/process/process_metrics.h",
|
||||
"+base/rand_util.h",
|
||||
"+base/strings",
|
||||
+ "+base/template_util.h",
|
||||
"+base/threading/thread_checker.h",
|
||||
"+base/time/time.h",
|
||||
"+base/tuple.h",
|
||||
diff -up chromium-65.0.3325.146/third_party/WebKit/Source/platform/wtf/Optional.h.jdp chromium-65.0.3325.146/third_party/WebKit/Source/platform/wtf/Optional.h
|
||||
--- chromium-65.0.3325.146/third_party/WebKit/Source/platform/wtf/Optional.h.jdp 2018-03-07 13:56:29.053062331 -0500
|
||||
+++ chromium-65.0.3325.146/third_party/WebKit/Source/platform/wtf/Optional.h 2018-03-07 13:56:36.595904651 -0500
|
||||
@@ -6,6 +6,7 @@
|
||||
#define Optional_h
|
||||
|
||||
#include "base/optional.h"
|
||||
+#include "platform/wtf/TemplateUtil.h"
|
||||
#include "platform/wtf/TypeTraits.h"
|
||||
|
||||
namespace WTF {
|
||||
diff -up chromium-65.0.3325.146/third_party/WebKit/Source/platform/wtf/TemplateUtil.h.jdp chromium-65.0.3325.146/third_party/WebKit/Source/platform/wtf/TemplateUtil.h
|
||||
--- chromium-65.0.3325.146/third_party/WebKit/Source/platform/wtf/TemplateUtil.h.jdp 2018-03-07 13:56:47.356679702 -0500
|
||||
+++ chromium-65.0.3325.146/third_party/WebKit/Source/platform/wtf/TemplateUtil.h 2018-03-07 13:57:41.769542223 -0500
|
||||
@@ -0,0 +1,28 @@
|
||||
+// Copyright 2018 The Chromium Authors. All rights reserved.
|
||||
+// Use of this source code is governed by a BSD-style license that can be
|
||||
+// found in the LICENSE file.
|
||||
+
|
||||
+#ifndef TemplateUtil_h
|
||||
+#define TemplateUtil_h
|
||||
+
|
||||
+#include "base/template_util.h"
|
||||
+#include "platform/wtf/Vector.h"
|
||||
+
|
||||
+namespace base {
|
||||
+
|
||||
+#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ <= 7
|
||||
+// Workaround for g++7 and earlier family.
|
||||
+// Due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80654, without this
|
||||
+// Optional<WTF::Vector<T>> where T is non-copyable causes a compile error.
|
||||
+// As we know it is not trivially copy constructible, explicitly declare so.
|
||||
+//
|
||||
+// It completes the declaration in base/template_util.h that was provided
|
||||
+// for std::vector
|
||||
+template <typename T>
|
||||
+struct is_trivially_copy_constructible<WTF::Vector<T>> : std::false_type {};
|
||||
+#endif
|
||||
+
|
||||
+} // namespace base
|
||||
+
|
||||
+#endif // TemplateUtil_h
|
||||
+
|
@ -1,2 +1,3 @@
|
||||
SHA512 (depot_tools.git-master.tar.gz) = d3d6a1873b2b0296a8cd99e0d8d2e629a17b1808934b4972556168f8b4ccea60577ebaeab4445baf15afb1b04080808db59a832a5b61d247bd48da14fa6acf03
|
||||
SHA512 (chromium-65.0.3325.146-clean.tar.xz) = 18a45e41eb706fa87a707c89ee419b6a408132d763318c06cffca9e453f09a0e52a76089002ec1c25224d77a54eecc17013a6087dd4acdbd15df073fd7eff937
|
||||
SHA512 (chromium-65.0.3325.162-clean.tar.xz) = 6f8d2267ca27027a87515e0dfc4aafeb89b2344b994b48c0b7302dd56868e47df46f270c403f7311a2bbacaf5e1eb8b96b31141e9a99080e12321a0d38a618f5
|
||||
|
Loading…
Reference in new issue