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

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

Issue 2250183003: Make the fuchsia mojo/public repo the source of truth. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 4 years, 4 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
« no previous file with comments | « mojo/public/cpp/bindings/lib/validation_util.cc ('k') | mojo/public/cpp/bindings/message.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_MAP_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_MAP_H_
7
8 #include <map>
9 #include <type_traits>
10
11 #include "mojo/public/cpp/bindings/lib/map_internal.h"
12 #include "mojo/public/cpp/bindings/lib/template_util.h"
13
14 namespace mojo {
15
16 // A move-only map that can handle move-only values. Map has the following
17 // characteristics:
18 // - The map itself can be null, and this is distinct from empty.
19 // - Keys must not be move-only.
20 // - The Key-type's "<" operator is used to sort the entries, and also is
21 // used to determine equality of the key values.
22 // - There can only be one entry per unique key.
23 // - Values of move-only types will be moved into the Map when they are added
24 // using the insert() method.
25 template <typename Key, typename Value>
26 class Map {
27 public:
28 // Map keys cannot be move only classes.
29 static_assert(!internal::IsMoveOnlyType<Key>::value,
30 "Map keys cannot be move only types.");
31
32 using KeyType = Key;
33 using ValueType = Value;
34
35 using Traits =
36 internal::MapTraits<KeyType,
37 ValueType,
38 internal::IsMoveOnlyType<ValueType>::value>;
39 using ValueForwardType = typename Traits::ValueForwardType;
40
41 using Data_ =
42 internal::Map_Data<typename internal::WrapperTraits<KeyType>::DataType,
43 typename internal::WrapperTraits<ValueType>::DataType>;
44
45 Map() : is_null_(true) {}
46
47 // Constructs a non-null Map containing the specified |keys| mapped to the
48 // corresponding |values|.
49 Map(mojo::Array<KeyType> keys, mojo::Array<ValueType> values)
50 : is_null_(false) {
51 MOJO_DCHECK(keys.size() == values.size());
52 for (size_t i = 0; i < keys.size(); ++i)
53 Traits::Insert(&map_, keys[i], values[i]);
54 }
55
56 ~Map() {}
57
58 Map(Map&& other) : is_null_(true) { Take(&other); }
59 Map& operator=(Map&& other) {
60 Take(&other);
61 return *this;
62 }
63
64 // Copies the contents of some other type of map into a new Map using a
65 // TypeConverter. A TypeConverter for std::map to Map is defined below.
66 template <typename U>
67 static Map From(const U& other) {
68 return TypeConverter<Map, U>::Convert(other);
69 }
70
71 // Copies the contents of the Map into some other type of map. A TypeConverter
72 // for Map to std::map is defined below.
73 template <typename U>
74 U To() const {
75 return TypeConverter<U, Map>::Convert(*this);
76 }
77
78 // Destroys the contents of the Map and leaves it in the null state.
79 void reset() {
80 map_.clear();
81 is_null_ = true;
82 }
83
84 // Tests as true if non-null, false if null.
85 explicit operator bool() const { return !is_null_; }
86
87 bool is_null() const { return is_null_; }
88
89 // Indicates the number of keys in the map.
90 size_t size() const { return map_.size(); }
91
92 void mark_non_null() { is_null_ = false; }
93
94 // Inserts a key-value pair into the map, moving the value by calling its
95 // Pass() method if it is a move-only type. Like std::map, this does not
96 // insert |value| if |key| is already a member of the map.
97 void insert(const KeyType& key, ValueForwardType value) {
98 is_null_ = false;
99 Traits::Insert(&map_, key, value);
100 }
101
102 // Returns a reference to the value associated with the specified key,
103 // crashing the process if the key is not present in the map.
104 ValueType& at(const KeyType& key) { return map_.at(key); }
105 const ValueType& at(const KeyType& key) const { return map_.at(key); }
106
107 // Returns a reference to the value associated with the specified key,
108 // creating a new entry if the key is not already present in the map. A
109 // newly-created value will be value-initialized (meaning that it will be
110 // initialized by the default constructor of the value type, if any, or else
111 // will be zero-initialized).
112 ValueType& operator[](const KeyType& key) {
113 is_null_ = false;
114 return map_[key];
115 }
116
117 // Swaps the contents of this Map with another Map of the same type (including
118 // nullness).
119 void Swap(Map<KeyType, ValueType>* other) {
120 std::swap(is_null_, other->is_null_);
121 map_.swap(other->map_);
122 }
123
124 // Swaps the contents of this Map with an std::map containing keys and values
125 // of the same type. Since std::map cannot represent the null state, the
126 // std::map will be empty if Map is null. The Map will always be left in a
127 // non-null state.
128 void Swap(std::map<KeyType, ValueType>* other) {
129 is_null_ = false;
130 map_.swap(*other);
131 }
132
133 // Returns a new Map that contains a copy of the contents of this map. If the
134 // values are of a type that is designated move-only, they will be cloned
135 // using the Clone() method of the type. Please note that calling this method
136 // will fail compilation if the value type cannot be cloned (which usually
137 // means that it is a Mojo handle type or a type that contains Mojo handles).
138 Map Clone() const {
139 Map result;
140 result.is_null_ = is_null_;
141 Traits::Clone(map_, &result.map_);
142 return result;
143 }
144
145 // Indicates whether the contents of this map are equal to those of another
146 // Map (including nullness). Keys are compared by the != operator. Values are
147 // compared as follows:
148 // - Map, Array, Struct, or StructPtr values are compared by their Equals()
149 // method.
150 // - ScopedHandleBase-derived types are compared by their handles.
151 // - Values of other types are compared by their "==" operator.
152 bool Equals(const Map& other) const {
153 if (is_null() != other.is_null())
154 return false;
155 if (size() != other.size())
156 return false;
157 auto i = cbegin();
158 auto j = other.cbegin();
159 while (i != cend()) {
160 if (i.GetKey() != j.GetKey())
161 return false;
162 if (!internal::ValueTraits<ValueType>::Equals(i.GetValue(), j.GetValue()))
163 return false;
164 ++i;
165 ++j;
166 }
167 return true;
168 }
169
170 private:
171 // A Map Iterator, templated for mutable and const iterator behaviour.
172 // If |IsConstIterator| is true, the iterator behaves like a const-iterator.
173 //
174 // TODO(vardhan): Make this adhere to the BidirectionalIterator concept.
175 enum class IteratorMutability { kConst, kMutable };
176 template <IteratorMutability MutabilityType = IteratorMutability::kMutable>
177 class InternalIterator {
178 using InternalIteratorType = typename std::conditional<
179 MutabilityType == IteratorMutability::kConst,
180 typename std::map<KeyType, ValueType>::const_iterator,
181 typename std::map<KeyType, ValueType>::iterator>::type;
182
183 using ReturnValueType =
184 typename std::conditional<MutabilityType == IteratorMutability::kConst,
185 const ValueType&,
186 ValueType&>::type;
187
188 public:
189 InternalIterator() : it_() {}
190 InternalIterator(InternalIteratorType it) : it_(it) {}
191
192 // The key is always a const reference, but the value is conditional on
193 // whether this is a const iterator or not.
194 const KeyType& GetKey() { return it_->first; }
195 ReturnValueType GetValue() { return it_->second; }
196
197 InternalIterator& operator++() {
198 ++it_;
199 return *this;
200 }
201 InternalIterator<MutabilityType> operator++(int) {
202 InternalIterator<MutabilityType> original(*this);
203 ++it_;
204 return original;
205 }
206 InternalIterator& operator--() {
207 --it_;
208 return *this;
209 }
210 InternalIterator<MutabilityType> operator--(int) {
211 InternalIterator<MutabilityType> original(*this);
212 --it_;
213 return original;
214 }
215 bool operator!=(const InternalIterator& rhs) const {
216 return it_ != rhs.it_;
217 }
218 bool operator==(const InternalIterator& rhs) const {
219 return it_ == rhs.it_;
220 }
221
222 private:
223 InternalIteratorType it_;
224 };
225
226 public:
227 using MapIterator = InternalIterator<IteratorMutability::kMutable>;
228 using ConstMapIterator = InternalIterator<IteratorMutability::kConst>;
229
230 // Provide read-only and mutable iteration over map members in a way similar
231 // to STL collections.
232 ConstMapIterator cbegin() const { return ConstMapIterator(map_.cbegin()); }
233 ConstMapIterator cend() const { return ConstMapIterator(map_.cend()); }
234 MapIterator begin() { return MapIterator(map_.begin()); }
235 MapIterator end() { return MapIterator(map_.end()); }
236
237 // Returns the iterator pointing to the entry for |key|, if present, or else
238 // returns |cend()| or |end()|, respectively.
239 ConstMapIterator find(const KeyType& key) const {
240 return ConstMapIterator(map_.find(key));
241 }
242 MapIterator find(const KeyType& key) { return MapIterator(map_.find(key)); }
243
244 private:
245 void Take(Map* other) {
246 reset();
247 Swap(other);
248 }
249
250 std::map<KeyType, ValueType> map_;
251 bool is_null_;
252
253 MOJO_MOVE_ONLY_TYPE(Map);
254 };
255
256 // Copies the contents of an std::map to a new Map, optionally changing the
257 // types of the keys and values along the way using TypeConverter.
258 template <typename MojoKey,
259 typename MojoValue,
260 typename STLKey,
261 typename STLValue>
262 struct TypeConverter<Map<MojoKey, MojoValue>, std::map<STLKey, STLValue>> {
263 static Map<MojoKey, MojoValue> Convert(
264 const std::map<STLKey, STLValue>& input) {
265 Map<MojoKey, MojoValue> result;
266 result.mark_non_null();
267 for (auto& pair : input) {
268 result.insert(TypeConverter<MojoKey, STLKey>::Convert(pair.first),
269 TypeConverter<MojoValue, STLValue>::Convert(pair.second));
270 }
271 return result;
272 }
273 };
274
275 // Copies the contents of a Map to an std::map, optionally changing the types of
276 // the keys and values along the way using TypeConverter.
277 template <typename MojoKey,
278 typename MojoValue,
279 typename STLKey,
280 typename STLValue>
281 struct TypeConverter<std::map<STLKey, STLValue>, Map<MojoKey, MojoValue>> {
282 static std::map<STLKey, STLValue> Convert(
283 const Map<MojoKey, MojoValue>& input) {
284 std::map<STLKey, STLValue> result;
285 if (!input.is_null()) {
286 for (auto it = input.cbegin(); it != input.cend(); ++it) {
287 result.insert(std::make_pair(
288 TypeConverter<STLKey, MojoKey>::Convert(it.GetKey()),
289 TypeConverter<STLValue, MojoValue>::Convert(it.GetValue())));
290 }
291 }
292 return result;
293 }
294 };
295
296 } // namespace mojo
297
298 #endif // MOJO_PUBLIC_CPP_BINDINGS_MAP_H_
OLDNEW
« no previous file with comments | « mojo/public/cpp/bindings/lib/validation_util.cc ('k') | mojo/public/cpp/bindings/message.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698