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

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

Issue 2603893002: Remove mojo::Map. (Closed)
Patch Set: rebase Created 3 years, 11 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
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_MAP_H_ 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_MAP_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_MAP_H_ 6 #define MOJO_PUBLIC_CPP_BINDINGS_MAP_H_
7 7
8 #include <stddef.h>
9 #include <map> 8 #include <map>
10 #include <unordered_map> 9 #include <unordered_map>
11 #include <utility> 10 #include <utility>
12 11
13 #include "base/logging.h"
14 #include "base/macros.h"
15 #include "mojo/public/cpp/bindings/array.h"
16 #include "mojo/public/cpp/bindings/lib/map_data_internal.h"
17 #include "mojo/public/cpp/bindings/lib/template_util.h"
18 #include "mojo/public/cpp/bindings/type_converter.h"
19
20 namespace mojo { 12 namespace mojo {
21 13
22 // A move-only map that can handle move-only values. Map has the following
23 // characteristics:
24 // - The map itself can be null, and this is distinct from empty.
25 // - Keys must not be move-only.
26 // - The Key-type's "<" operator is used to sort the entries, and also is
27 // used to determine equality of the key values.
28 // - There can only be one entry per unique key.
29 // - Values of move-only types will be moved into the Map when they are added
30 // using the insert() method.
31 template <typename K, typename V>
32 class Map {
33 public:
34 using Key = K;
35 using Value = V;
36
37 // Map keys cannot be move only classes.
38 static_assert(!internal::IsMoveOnlyType<Key>::value,
39 "Map keys cannot be move only types.");
40
41 using Iterator = typename std::map<Key, Value>::iterator;
42 using ConstIterator = typename std::map<Key, Value>::const_iterator;
43
44 // Constructs an empty map.
45 Map() : is_null_(false) {}
46 // Constructs a null map.
47 Map(std::nullptr_t null_pointer) : is_null_(true) {}
48
49 // Constructs a non-null Map containing the specified |keys| mapped to the
50 // corresponding |values|.
51 Map(mojo::Array<Key> keys, mojo::Array<Value> values) : is_null_(false) {
52 DCHECK(keys.size() == values.size());
53 for (size_t i = 0; i < keys.size(); ++i)
54 map_.insert(std::make_pair(keys[i], std::move(values[i])));
55 }
56
57 ~Map() {}
58
59 Map(std::map<Key, Value>&& other) : map_(std::move(other)), is_null_(false) {}
60 Map(Map&& other) : is_null_(true) { Take(&other); }
61
62 Map& operator=(std::map<Key, Value>&& other) {
63 is_null_ = false;
64 map_ = std::move(other);
65 return *this;
66 }
67 Map& operator=(Map&& other) {
68 Take(&other);
69 return *this;
70 }
71
72 Map& operator=(std::nullptr_t null_pointer) {
73 is_null_ = true;
74 map_.clear();
75 return *this;
76 }
77
78 // Copies the contents of some other type of map into a new Map using a
79 // TypeConverter. A TypeConverter for std::map to Map is defined below.
80 template <typename U>
81 static Map From(const U& other) {
82 return TypeConverter<Map, U>::Convert(other);
83 }
84
85 // Copies the contents of the Map into some other type of map. A TypeConverter
86 // for Map to std::map is defined below.
87 template <typename U>
88 U To() const {
89 return TypeConverter<U, Map>::Convert(*this);
90 }
91
92 // Indicates whether the map is null (which is distinct from empty).
93 bool is_null() const { return is_null_; }
94
95 // Indicates whether the map is empty (which is distinct from null).
96 bool empty() const { return map_.empty() && !is_null_; }
97
98 // Indicates the number of keys in the map, which will be zero if the map is
99 // null.
100 size_t size() const { return map_.size(); }
101
102 // Inserts a key-value pair into the map. Like std::map, this does not insert
103 // |value| if |key| is already a member of the map.
104 void insert(const Key& key, const Value& value) {
105 is_null_ = false;
106 map_.insert(std::make_pair(key, value));
107 }
108 void insert(const Key& key, Value&& value) {
109 is_null_ = false;
110 map_.insert(std::make_pair(key, std::move(value)));
111 }
112
113 // Returns a reference to the value associated with the specified key,
114 // crashing the process if the key is not present in the map.
115 Value& at(const Key& key) { return map_.at(key); }
116 const Value& at(const Key& key) const { return map_.at(key); }
117
118 // Returns a reference to the value associated with the specified key,
119 // creating a new entry if the key is not already present in the map. A
120 // newly-created value will be value-initialized (meaning that it will be
121 // initialized by the default constructor of the value type, if any, or else
122 // will be zero-initialized).
123 Value& operator[](const Key& key) {
124 is_null_ = false;
125 return map_[key];
126 }
127
128 // Sets the map to empty (even if previously it was null).
129 void SetToEmpty() {
130 is_null_ = false;
131 map_.clear();
132 }
133
134 // Returns a const reference to the std::map managed by this class. If this
135 // object is null, the return value will be an empty map.
136 const std::map<Key, Value>& storage() const { return map_; }
137
138 // Passes the underlying storage and resets this map to null.
139 std::map<Key, Value> PassStorage() {
140 is_null_ = true;
141 return std::move(map_);
142 }
143
144 operator const std::map<Key, Value>&() const { return map_; }
145
146 // Swaps the contents of this Map with another Map of the same type (including
147 // nullness).
148 void Swap(Map<Key, Value>* other) {
149 std::swap(is_null_, other->is_null_);
150 map_.swap(other->map_);
151 }
152
153 // Swaps the contents of this Map with an std::map containing keys and values
154 // of the same type. Since std::map cannot represent the null state, the
155 // std::map will be empty if Map is null. The Map will always be left in a
156 // non-null state.
157 void Swap(std::map<Key, Value>* other) {
158 is_null_ = false;
159 map_.swap(*other);
160 }
161
162 // Removes all contents from the Map and places them into parallel key/value
163 // arrays. Each key will be copied from the source to the destination, and
164 // values will be copied unless their type is designated move-only, in which
165 // case they will be moved. Either way, the Map will be left in a null state.
166 void DecomposeMapTo(mojo::Array<Key>* keys, mojo::Array<Value>* values) {
167 std::vector<Key> key_vector;
168 key_vector.reserve(map_.size());
169 std::vector<Value> value_vector;
170 value_vector.reserve(map_.size());
171
172 for (auto& entry : map_) {
173 key_vector.push_back(entry.first);
174 value_vector.push_back(std::move(entry.second));
175 }
176
177 map_.clear();
178 is_null_ = true;
179
180 keys->Swap(&key_vector);
181 values->Swap(&value_vector);
182 }
183
184 // Returns a new Map that contains a copy of the contents of this map. If the
185 // key/value type defines a Clone() method, it will be used; otherwise copy
186 // constructor/assignment will be used.
187 //
188 // Please note that calling this method will fail compilation if the key/value
189 // type cannot be cloned (which usually means that it is a Mojo handle type or
190 // a type containing Mojo handles).
191 Map Clone() const {
192 Map result;
193 result.is_null_ = is_null_;
194 for (auto it = map_.begin(); it != map_.end(); ++it) {
195 result.map_.insert(std::make_pair(internal::Clone(it->first),
196 internal::Clone(it->second)));
197 }
198 return result;
199 }
200
201 // Indicates whether the contents of this map are equal to those of another
202 // Map (including nullness). If the key/value type defines an Equals() method,
203 // it will be used; otherwise == operator will be used.
204 bool Equals(const Map& other) const {
205 if (is_null() != other.is_null())
206 return false;
207 if (size() != other.size())
208 return false;
209 auto i = begin();
210 auto j = other.begin();
211 while (i != end()) {
212 if (!internal::Equals(i->first, j->first))
213 return false;
214 if (!internal::Equals(i->second, j->second))
215 return false;
216 ++i;
217 ++j;
218 }
219 return true;
220 }
221
222 // Provide read-only iteration over map members in a way similar to STL
223 // collections.
224 ConstIterator begin() const { return map_.begin(); }
225 Iterator begin() { return map_.begin(); }
226
227 ConstIterator end() const { return map_.end(); }
228 Iterator end() { return map_.end(); }
229
230 // Returns the iterator pointing to the entry for |key|, if present, or else
231 // returns end().
232 ConstIterator find(const Key& key) const { return map_.find(key); }
233 Iterator find(const Key& key) { return map_.find(key); }
234
235 private:
236 typedef std::map<Key, Value> Map::*Testable;
237
238 public:
239 // The Map may be used in boolean expressions to determine if it is non-null,
240 // but is not implicitly convertible to an actual bool value (which would be
241 // dangerous).
242 operator Testable() const { return is_null_ ? 0 : &Map::map_; }
243
244 private:
245 // Forbid the == and != operators explicitly, otherwise Map will be converted
246 // to Testable to do == or != comparison.
247 template <typename T, typename U>
248 bool operator==(const Map<T, U>& other) const = delete;
249 template <typename T, typename U>
250 bool operator!=(const Map<T, U>& other) const = delete;
251
252 void Take(Map* other) {
253 operator=(nullptr);
254 Swap(other);
255 }
256
257 std::map<Key, Value> map_;
258 bool is_null_;
259
260 DISALLOW_COPY_AND_ASSIGN(Map);
261 };
262
263 // Copies the contents of an std::map to a new Map, optionally changing the
264 // types of the keys and values along the way using TypeConverter.
265 template <typename MojoKey,
266 typename MojoValue,
267 typename STLKey,
268 typename STLValue>
269 struct TypeConverter<Map<MojoKey, MojoValue>, std::map<STLKey, STLValue>> {
270 static Map<MojoKey, MojoValue> Convert(
271 const std::map<STLKey, STLValue>& input) {
272 Map<MojoKey, MojoValue> result;
273 for (auto& pair : input) {
274 result.insert(TypeConverter<MojoKey, STLKey>::Convert(pair.first),
275 TypeConverter<MojoValue, STLValue>::Convert(pair.second));
276 }
277 return result;
278 }
279 };
280
281 // Copies the contents of a Map to an std::map, optionally changing the types of
282 // the keys and values along the way using TypeConverter.
283 template <typename MojoKey,
284 typename MojoValue,
285 typename STLKey,
286 typename STLValue>
287 struct TypeConverter<std::map<STLKey, STLValue>, Map<MojoKey, MojoValue>> {
288 static std::map<STLKey, STLValue> Convert(
289 const Map<MojoKey, MojoValue>& input) {
290 std::map<STLKey, STLValue> result;
291 if (!input.is_null()) {
292 for (auto it = input.begin(); it != input.end(); ++it) {
293 result.insert(std::make_pair(
294 TypeConverter<STLKey, MojoKey>::Convert(it->first),
295 TypeConverter<STLValue, MojoValue>::Convert(it->second)));
296 }
297 }
298 return result;
299 }
300 };
301
302 // TODO(yzshen): These conversion functions should be removed and callsites 14 // TODO(yzshen): These conversion functions should be removed and callsites
303 // should be revisited and changed to use the same map type. 15 // should be revisited and changed to use the same map type.
304 template <typename Key, typename Value> 16 template <typename Key, typename Value>
305 std::unordered_map<Key, Value> MapToUnorderedMap( 17 std::unordered_map<Key, Value> MapToUnorderedMap(
306 const std::map<Key, Value>& input) { 18 const std::map<Key, Value>& input) {
307 return std::unordered_map<Key, Value>(input.begin(), input.end()); 19 return std::unordered_map<Key, Value>(input.begin(), input.end());
308 } 20 }
309 21
310 template <typename Key, typename Value> 22 template <typename Key, typename Value>
311 std::unordered_map<Key, Value> MapToUnorderedMap(std::map<Key, Value>&& input) { 23 std::unordered_map<Key, Value> MapToUnorderedMap(std::map<Key, Value>&& input) {
312 return std::unordered_map<Key, Value>(std::make_move_iterator(input.begin()), 24 return std::unordered_map<Key, Value>(std::make_move_iterator(input.begin()),
313 std::make_move_iterator(input.end())); 25 std::make_move_iterator(input.end()));
314 } 26 }
315 27
316 template <typename Key, typename Value> 28 template <typename Key, typename Value>
317 std::map<Key, Value> UnorderedMapToMap( 29 std::map<Key, Value> UnorderedMapToMap(
318 const std::unordered_map<Key, Value>& input) { 30 const std::unordered_map<Key, Value>& input) {
319 return std::map<Key, Value>(input.begin(), input.end()); 31 return std::map<Key, Value>(input.begin(), input.end());
320 } 32 }
321 33
322 template <typename Key, typename Value> 34 template <typename Key, typename Value>
323 std::map<Key, Value> UnorderedMapToMap(std::unordered_map<Key, Value>&& input) { 35 std::map<Key, Value> UnorderedMapToMap(std::unordered_map<Key, Value>&& input) {
324 return std::map<Key, Value>(std::make_move_iterator(input.begin()), 36 return std::map<Key, Value>(std::make_move_iterator(input.begin()),
325 std::make_move_iterator(input.end())); 37 std::make_move_iterator(input.end()));
326 } 38 }
327 39
328 } // namespace mojo 40 } // namespace mojo
329 41
330 #endif // MOJO_PUBLIC_CPP_BINDINGS_MAP_H_ 42 #endif // MOJO_PUBLIC_CPP_BINDINGS_MAP_H_
OLDNEW
« no previous file with comments | « mojo/public/cpp/bindings/lib/serialization.h ('k') | mojo/public/cpp/bindings/map_traits_standard.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698