| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_STRUCT_PTR_H_ | 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_STRUCT_PTR_H_ |
| 6 #define MOJO_PUBLIC_CPP_BINDINGS_STRUCT_PTR_H_ | 6 #define MOJO_PUBLIC_CPP_BINDINGS_STRUCT_PTR_H_ |
| 7 | 7 |
| 8 #include <functional> | 8 #include <functional> |
| 9 #include <memory> |
| 9 #include <new> | 10 #include <new> |
| 10 | 11 |
| 11 #include "base/logging.h" | 12 #include "base/logging.h" |
| 12 #include "base/macros.h" | 13 #include "base/macros.h" |
| 14 #include "base/optional.h" |
| 13 #include "mojo/public/cpp/bindings/lib/hash_util.h" | 15 #include "mojo/public/cpp/bindings/lib/hash_util.h" |
| 14 #include "mojo/public/cpp/bindings/type_converter.h" | 16 #include "mojo/public/cpp/bindings/type_converter.h" |
| 15 | 17 |
| 16 namespace mojo { | 18 namespace mojo { |
| 17 namespace internal { | 19 namespace internal { |
| 18 | 20 |
| 19 constexpr size_t kHashSeed = 31; | 21 constexpr size_t kHashSeed = 31; |
| 20 | 22 |
| 21 template <typename Struct> | 23 template <typename Struct> |
| 22 class StructHelper { | |
| 23 public: | |
| 24 template <typename Ptr> | |
| 25 static void Initialize(Ptr* ptr) { | |
| 26 ptr->Initialize(); | |
| 27 } | |
| 28 }; | |
| 29 | |
| 30 template <typename Struct> | |
| 31 class StructPtrWTFHelper; | 24 class StructPtrWTFHelper; |
| 32 | 25 |
| 33 template <typename Struct> | 26 template <typename Struct> |
| 34 class InlinedStructPtrWTFHelper; | 27 class InlinedStructPtrWTFHelper; |
| 35 | 28 |
| 36 } // namespace internal | 29 } // namespace internal |
| 37 | 30 |
| 38 // Smart pointer wrapping a mojom structure with move-only semantics. | 31 // Smart pointer wrapping a mojom structure with move-only semantics. |
| 39 template <typename S> | 32 template <typename S> |
| 40 class StructPtr { | 33 class StructPtr { |
| 41 public: | 34 public: |
| 42 using Struct = S; | 35 using Struct = S; |
| 43 | 36 |
| 44 StructPtr() : ptr_(nullptr) {} | 37 StructPtr() = default; |
| 45 StructPtr(decltype(nullptr)) : ptr_(nullptr) {} | 38 StructPtr(decltype(nullptr)) {} |
| 46 | 39 |
| 47 ~StructPtr() { delete ptr_; } | 40 ~StructPtr() = default; |
| 48 | 41 |
| 49 StructPtr& operator=(decltype(nullptr)) { | 42 StructPtr& operator=(decltype(nullptr)) { |
| 50 reset(); | 43 reset(); |
| 51 return *this; | 44 return *this; |
| 52 } | 45 } |
| 53 | 46 |
| 54 StructPtr(StructPtr&& other) : ptr_(nullptr) { Take(&other); } | 47 StructPtr(StructPtr&& other) { Take(&other); } |
| 55 StructPtr& operator=(StructPtr&& other) { | 48 StructPtr& operator=(StructPtr&& other) { |
| 56 Take(&other); | 49 Take(&other); |
| 57 return *this; | 50 return *this; |
| 58 } | 51 } |
| 59 | 52 |
| 53 template <typename... Args> |
| 54 StructPtr(base::in_place_t, Args&&... args) |
| 55 : ptr_(new Struct(std::forward<Args>(args)...)) {} |
| 56 |
| 60 template <typename U> | 57 template <typename U> |
| 61 U To() const { | 58 U To() const { |
| 62 return TypeConverter<U, StructPtr>::Convert(*this); | 59 return TypeConverter<U, StructPtr>::Convert(*this); |
| 63 } | 60 } |
| 64 | 61 |
| 65 void reset() { | 62 void reset() { ptr_.reset(); } |
| 66 if (ptr_) { | |
| 67 delete ptr_; | |
| 68 ptr_ = nullptr; | |
| 69 } | |
| 70 } | |
| 71 | 63 |
| 72 bool is_null() const { return ptr_ == nullptr; } | 64 bool is_null() const { return !ptr_; } |
| 73 | 65 |
| 74 Struct& operator*() const { | 66 Struct& operator*() const { |
| 75 DCHECK(ptr_); | 67 DCHECK(ptr_); |
| 76 return *ptr_; | 68 return *ptr_; |
| 77 } | 69 } |
| 78 Struct* operator->() const { | 70 Struct* operator->() const { |
| 79 DCHECK(ptr_); | 71 DCHECK(ptr_); |
| 80 return ptr_; | 72 return ptr_.get(); |
| 81 } | 73 } |
| 82 Struct* get() const { return ptr_; } | 74 Struct* get() const { return ptr_.get(); } |
| 83 | 75 |
| 84 void Swap(StructPtr* other) { std::swap(ptr_, other->ptr_); } | 76 void Swap(StructPtr* other) { std::swap(ptr_, other->ptr_); } |
| 85 | 77 |
| 86 // Please note that calling this method will fail compilation if the value | 78 // Please note that calling this method will fail compilation if the value |
| 87 // type |Struct| doesn't have a Clone() method defined (which usually means | 79 // type |Struct| doesn't have a Clone() method defined (which usually means |
| 88 // that it contains Mojo handles). | 80 // that it contains Mojo handles). |
| 89 StructPtr Clone() const { return is_null() ? StructPtr() : ptr_->Clone(); } | 81 StructPtr Clone() const { return is_null() ? StructPtr() : ptr_->Clone(); } |
| 90 | 82 |
| 91 // Compares the pointees (which might both be null). | 83 // Compares the pointees (which might both be null). |
| 92 // TODO(tibell): Get rid of Equals in favor of the operator. Same for Hash. | 84 // TODO(tibell): Get rid of Equals in favor of the operator. Same for Hash. |
| 93 bool Equals(const StructPtr& other) const { | 85 bool Equals(const StructPtr& other) const { |
| 94 if (is_null() || other.is_null()) | 86 if (is_null() || other.is_null()) |
| 95 return is_null() && other.is_null(); | 87 return is_null() && other.is_null(); |
| 96 return ptr_->Equals(*other.ptr_); | 88 return ptr_->Equals(*other.ptr_); |
| 97 } | 89 } |
| 98 | 90 |
| 99 // Hashes based on the pointee (which might be null). | 91 // Hashes based on the pointee (which might be null). |
| 100 size_t Hash(size_t seed) const { | 92 size_t Hash(size_t seed) const { |
| 101 if (is_null()) | 93 if (is_null()) |
| 102 return internal::HashCombine(seed, 0); | 94 return internal::HashCombine(seed, 0); |
| 103 return ptr_->Hash(seed); | 95 return ptr_->Hash(seed); |
| 104 } | 96 } |
| 105 | 97 |
| 106 explicit operator bool() const { return !is_null(); } | 98 explicit operator bool() const { return !is_null(); } |
| 107 | 99 |
| 108 private: | 100 private: |
| 109 friend class internal::StructHelper<Struct>; | |
| 110 friend class internal::StructPtrWTFHelper<Struct>; | 101 friend class internal::StructPtrWTFHelper<Struct>; |
| 111 | |
| 112 void Initialize() { | |
| 113 DCHECK(!ptr_); | |
| 114 ptr_ = new Struct(); | |
| 115 } | |
| 116 | |
| 117 void Take(StructPtr* other) { | 102 void Take(StructPtr* other) { |
| 118 reset(); | 103 reset(); |
| 119 Swap(other); | 104 Swap(other); |
| 120 } | 105 } |
| 121 | 106 |
| 122 Struct* ptr_; | 107 std::unique_ptr<Struct> ptr_; |
| 123 | 108 |
| 124 DISALLOW_COPY_AND_ASSIGN(StructPtr); | 109 DISALLOW_COPY_AND_ASSIGN(StructPtr); |
| 125 }; | 110 }; |
| 126 | 111 |
| 127 template <typename T> | 112 template <typename T> |
| 128 bool operator==(const StructPtr<T>& lhs, const StructPtr<T>& rhs) { | 113 bool operator==(const StructPtr<T>& lhs, const StructPtr<T>& rhs) { |
| 129 return lhs.Equals(rhs); | 114 return lhs.Equals(rhs); |
| 130 } | 115 } |
| 131 template <typename T> | 116 template <typename T> |
| 132 bool operator!=(const StructPtr<T>& lhs, const StructPtr<T>& rhs) { | 117 bool operator!=(const StructPtr<T>& lhs, const StructPtr<T>& rhs) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 148 reset(); | 133 reset(); |
| 149 return *this; | 134 return *this; |
| 150 } | 135 } |
| 151 | 136 |
| 152 InlinedStructPtr(InlinedStructPtr&& other) : state_(NIL) { Take(&other); } | 137 InlinedStructPtr(InlinedStructPtr&& other) : state_(NIL) { Take(&other); } |
| 153 InlinedStructPtr& operator=(InlinedStructPtr&& other) { | 138 InlinedStructPtr& operator=(InlinedStructPtr&& other) { |
| 154 Take(&other); | 139 Take(&other); |
| 155 return *this; | 140 return *this; |
| 156 } | 141 } |
| 157 | 142 |
| 143 template <typename... Args> |
| 144 InlinedStructPtr(base::in_place_t, Args&&... args) |
| 145 : value_(std::forward<Args>(args)...), state_(VALID) {} |
| 146 |
| 158 template <typename U> | 147 template <typename U> |
| 159 U To() const { | 148 U To() const { |
| 160 return TypeConverter<U, InlinedStructPtr>::Convert(*this); | 149 return TypeConverter<U, InlinedStructPtr>::Convert(*this); |
| 161 } | 150 } |
| 162 | 151 |
| 163 void reset() { | 152 void reset() { |
| 164 state_ = NIL; | 153 state_ = NIL; |
| 165 value_. ~Struct(); | 154 value_. ~Struct(); |
| 166 new (&value_) Struct(); | 155 new (&value_) Struct(); |
| 167 } | 156 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 197 // Hashes based on the pointee (which might be null). | 186 // Hashes based on the pointee (which might be null). |
| 198 size_t Hash(size_t seed) const { | 187 size_t Hash(size_t seed) const { |
| 199 if (is_null()) | 188 if (is_null()) |
| 200 return internal::HashCombine(seed, 0); | 189 return internal::HashCombine(seed, 0); |
| 201 return value_.Hash(seed); | 190 return value_.Hash(seed); |
| 202 } | 191 } |
| 203 | 192 |
| 204 explicit operator bool() const { return !is_null(); } | 193 explicit operator bool() const { return !is_null(); } |
| 205 | 194 |
| 206 private: | 195 private: |
| 207 friend class internal::StructHelper<Struct>; | |
| 208 friend class internal::InlinedStructPtrWTFHelper<Struct>; | 196 friend class internal::InlinedStructPtrWTFHelper<Struct>; |
| 209 | |
| 210 void Initialize() { state_ = VALID; } | |
| 211 | |
| 212 void Take(InlinedStructPtr* other) { | 197 void Take(InlinedStructPtr* other) { |
| 213 reset(); | 198 reset(); |
| 214 Swap(other); | 199 Swap(other); |
| 215 } | 200 } |
| 216 | 201 |
| 217 enum State { | 202 enum State { |
| 218 VALID, | 203 VALID, |
| 219 NIL, | 204 NIL, |
| 220 DELETED, // For use in WTF::HashMap only | 205 DELETED, // For use in WTF::HashMap only |
| 221 }; | 206 }; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 template <typename T> | 274 template <typename T> |
| 290 struct hash<mojo::InlinedStructPtr<T>> { | 275 struct hash<mojo::InlinedStructPtr<T>> { |
| 291 size_t operator()(const mojo::InlinedStructPtr<T>& value) const { | 276 size_t operator()(const mojo::InlinedStructPtr<T>& value) const { |
| 292 return value.Hash(mojo::internal::kHashSeed); | 277 return value.Hash(mojo::internal::kHashSeed); |
| 293 } | 278 } |
| 294 }; | 279 }; |
| 295 | 280 |
| 296 } // namespace std | 281 } // namespace std |
| 297 | 282 |
| 298 #endif // MOJO_PUBLIC_CPP_BINDINGS_STRUCT_PTR_H_ | 283 #endif // MOJO_PUBLIC_CPP_BINDINGS_STRUCT_PTR_H_ |
| OLD | NEW |