Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(610)

Side by Side Diff: mojo/public/cpp/bindings/wtf_map.h

Issue 2034273002: Mojo C++ bindings: introduce mojo::WTFMap for blink bindings. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_WTF_MAP_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_WTF_MAP_H_
7
8 #include <stddef.h>
9 #include <utility>
10
11 #include "base/move.h"
12 #include "mojo/public/cpp/bindings/lib/template_util.h"
13 #include "mojo/public/cpp/bindings/type_converter.h"
14 #include "third_party/WebKit/Source/wtf/HashMap.h"
15 #include "third_party/WebKit/Source/wtf/text/StringHash.h"
16
17 namespace mojo {
18
19 // Represents a map backed by WTF::HashMap. Comparing with WTF::HashMap,
20 // mojo::WTFMap is move-only and can be null.
21 //
22 // It is easy to convert between WTF::HashMap<K, V> and mojo::WTFMap<K, V>:
23 // - constructor WTFMap(WTF::HashMap<K, V>&&) takes the contents of a
24 // WTF::HashMap<K, V>;
25 // - method PassStorage() passes the underlying WTF::HashMap.
26 template <typename Key, typename Value>
27 class WTFMap {
28 MOVE_ONLY_TYPE_FOR_CPP_03(WTFMap);
29
30 public:
31 using Iterator = typename WTF::HashMap<Key, Value>::iterator;
32 using ConstIterator = typename WTF::HashMap<Key, Value>::const_iterator;
33
34 // Constructs an empty map.
35 WTFMap() : is_null_(false) {}
36 // Constructs a null map.
37 WTFMap(std::nullptr_t null_pointer) : is_null_(true) {}
38
39 ~WTFMap() {}
40
41 WTFMap(WTF::HashMap<Key, Value>&& other)
42 : map_(std::move(other)), is_null_(false) {}
43 WTFMap(WTFMap&& other) : is_null_(true) { Take(&other); }
44
45 WTFMap& operator=(WTF::HashMap<Key, Value>&& other) {
46 is_null_ = false;
47 map_ = std::move(other);
48 return *this;
49 }
50 WTFMap& operator=(WTFMap&& other) {
51 Take(&other);
52 return *this;
53 }
54
55 WTFMap& operator=(std::nullptr_t null_pointer) {
56 is_null_ = true;
57 map_.clear();
58 return *this;
59 }
60
61 // Copies the contents of some other type of map into a new WTFMap using a
62 // TypeConverter.
63 template <typename U>
64 static WTFMap From(const U& other) {
65 return TypeConverter<WTFMap, U>::Convert(other);
66 }
67
68 // Copies the contents of the WTFMap into some other type of map.
69 template <typename U>
70 U To() const {
71 return TypeConverter<U, WTFMap>::Convert(*this);
72 }
73
74 // Indicates whether the map is null (which is distinct from empty).
75 bool is_null() const { return is_null_; }
76
77 // Indicates whether the map is empty (which is distinct from null).
78 bool empty() const { return map_.isEmpty() && !is_null_; }
79
80 // Indicates the number of keys in the map, which will be zero if the map is
81 // null.
82 size_t size() const { return map_.size(); }
83
84 // Inserts a key-value pair into the map. Like WTF::HashMap::add(), this does
85 // not insert |value| if |key| is already a member of the map.
86 void insert(const Key& key, const Value& value) {
87 is_null_ = false;
88 map_.add(key, value);
89 }
90 void insert(const Key& key, Value&& value) {
91 is_null_ = false;
92 map_.add(key, std::move(value));
93 }
94
95 // Returns a reference to the value associated with the specified key,
96 // crashing the process if the key is not present in the map.
97 Value& at(const Key& key) { return map_.find(key)->value; }
98 const Value& at(const Key& key) const { return map_.find(key)->value; }
99
100 // Returns a reference to the value associated with the specified key,
101 // creating a new entry if the key is not already present in the map. A
102 // newly-created value will be value-initialized (meaning that it will be
103 // initialized by the default constructor of the value type, if any, or else
104 // will be zero-initialized).
105 Value& operator[](const Key& key) {
106 is_null_ = false;
107 if (!map_.contains(key))
108 map_.add(key, Value());
109 return at(key);
110 }
111
112 // Sets the map to empty (even if previously it was null).
113 void SetToEmpty() {
114 is_null_ = false;
115 map_.clear();
116 }
117
118 // Returns a const reference to the WTF::HashMap managed by this class. If
119 // this object is null, the return value will be an empty map.
120 const WTF::HashMap<Key, Value>& storage() const { return map_; }
121
122 // Passes the underlying storage and resets this map to null.
123 WTF::HashMap<Key, Value> PassStorage() {
124 is_null_ = true;
125 return std::move(map_);
126 }
127
128 // Swaps the contents of this WTFMap with another WTFMap of the same type
129 // (including nullness).
130 void Swap(WTFMap<Key, Value>* other) {
131 std::swap(is_null_, other->is_null_);
132 map_.swap(other->map_);
133 }
134
135 // Swaps the contents of this WTFMap with an WTF::HashMap containing keys and
136 // values of the same type. Since WTF::HashMap cannot represent the null
137 // state, the WTF::HashMap will be empty if WTFMap is null. The WTFMap will
138 // always be left in a non-null state.
139 void Swap(WTF::HashMap<Key, Value>* other) {
140 is_null_ = false;
141 map_.swap(*other);
142 }
143
144 // Returns a new WTFMap that contains a copy of the contents of this map. If
145 // the key/value type defines a Clone() method, it will be used; otherwise
146 // copy constructor/assignment will be used.
147 //
148 // Please note that calling this method will fail compilation if the key/value
149 // type cannot be cloned (which usually means that it is a Mojo handle type or
150 // a type containing Mojo handles).
151 WTFMap Clone() const {
152 WTFMap result;
153 result.is_null_ = is_null_;
154 auto map_end = map_.end();
155 for (auto it = map_.begin(); it != map_end; ++it)
156 result.map_.add(internal::Clone(it->key), internal::Clone(it->value));
157 return result;
158 }
159
160 // Indicates whether the contents of this map are equal to those of another
161 // WTFMap (including nullness). If the key/value type defines an Equals()
162 // method, it will be used; otherwise == operator will be used.
163 bool Equals(const WTFMap& other) const {
164 if (is_null() != other.is_null())
165 return false;
166 if (size() != other.size())
167 return false;
168
169 auto this_end = map_.end();
170 auto other_end = other.map_.end();
171
172 for (auto iter = map_.begin(); iter != this_end; ++iter) {
173 auto other_iter = other.map_.find(iter->key);
174 if (other_iter == other_end ||
175 !internal::Equals(iter->value, other_iter->value)) {
176 return false;
177 }
178 }
179 return true;
180 }
181
182 ConstIterator begin() const { return map_.begin(); }
183 Iterator begin() { return map_.begin(); }
184
185 ConstIterator end() const { return map_.end(); }
186 Iterator end() { return map_.end(); }
187
188 // Returns the iterator pointing to the entry for |key|, if present, or else
189 // returns end().
190 ConstIterator find(const Key& key) const { return map_.find(key); }
191 Iterator find(const Key& key) { return map_.find(key); }
192
193 private:
194 typedef WTF::HashMap<Key, Value> WTFMap::*Testable;
195
196 public:
197 // The WTFMap may be used in boolean expressions to determine if it is
198 // non-null, but is not implicitly convertible to an actual bool value (which
199 // would be dangerous).
200 operator Testable() const { return is_null_ ? 0 : &WTFMap::map_; }
Yuta Kitamura 2016/06/06 05:29:42 Now you can safely use "explicit operator bool()".
yzshen1 2016/06/07 23:49:11 Done. Good point!
201
202 private:
203 // Forbid the == and != operators explicitly, otherwise WTFMap will be
204 // converted to Testable to do == or != comparison.
205 template <typename T, typename U>
206 bool operator==(const WTFMap<T, U>& other) const = delete;
207 template <typename T, typename U>
208 bool operator!=(const WTFMap<T, U>& other) const = delete;
209
210 void Take(WTFMap* other) {
211 operator=(nullptr);
212 Swap(other);
213 }
214
215 WTF::HashMap<Key, Value> map_;
Yuta Kitamura 2016/06/06 05:29:42 What's a bit tricky is that WTF::HashMap does not
yzshen1 2016/06/07 23:49:11 I have added comments. And also added code to reje
216 bool is_null_;
217 };
218
219 } // namespace mojo
220
221 #endif // MOJO_PUBLIC_CPP_BINDINGS_WTF_MAP_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698