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 |