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

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

Issue 2607063002: Remove mojo::Array. (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
(Empty)
1 // Copyright 2013 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_ARRAY_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_ARRAY_H_
7
8 #include <stddef.h>
9 #include <string.h>
10 #include <algorithm>
11 #include <set>
12 #include <string>
13 #include <utility>
14 #include <vector>
15
16 #include "base/macros.h"
17 #include "base/optional.h"
18 #include "mojo/public/cpp/bindings/lib/array_internal.h"
19 #include "mojo/public/cpp/bindings/lib/bindings_internal.h"
20 #include "mojo/public/cpp/bindings/lib/clone_equals_util.h"
21 #include "mojo/public/cpp/bindings/lib/hash_util.h"
22 #include "mojo/public/cpp/bindings/lib/template_util.h"
23 #include "mojo/public/cpp/bindings/type_converter.h"
24
25 namespace mojo {
26
27 // Represents a moveable array with contents of type |T|. The array can be null,
28 // meaning that no value has been assigned to it. Null is distinct from empty.
29 template <typename T>
30 class Array {
31 public:
32 using ConstRefType = typename std::vector<T>::const_reference;
33 using RefType = typename std::vector<T>::reference;
34
35 using Element = T;
36
37 using iterator = typename std::vector<T>::iterator;
38 using const_iterator = typename std::vector<T>::const_iterator;
39
40 // Constructs an empty array.
41 Array() : is_null_(false) {}
42 // Constructs a null array.
43 Array(std::nullptr_t null_pointer) : is_null_(true) {}
44
45 // Constructs a new non-null array of the specified size. The elements will
46 // be value-initialized (meaning that they will be initialized by their
47 // default constructor, if any, or else zero-initialized).
48 explicit Array(size_t size) : vec_(size), is_null_(false) {}
49 ~Array() {}
50
51 // Copies the contents of |other| into this array.
52 Array(const std::vector<T>& other) : vec_(other), is_null_(false) {}
53 Array(const base::Optional<std::vector<T>>& other)
54 : vec_(other.value_or(std::vector<T>())), is_null_(!other) {}
55
56 // Moves the contents of |other| into this array.
57 Array(std::vector<T>&& other) : vec_(std::move(other)), is_null_(false) {}
58 Array(base::Optional<std::vector<T>>&& other) : is_null_(!other) {
59 if (!is_null_)
60 vec_ = std::move(other.value());
61 }
62 Array(Array&& other) : is_null_(true) { Take(&other); }
63
64 Array& operator=(std::vector<T>&& other) {
65 vec_ = std::move(other);
66 is_null_ = false;
67 return *this;
68 }
69 Array& operator=(base::Optional<std::vector<T>>&& other) {
70 is_null_ = !other;
71 vec_ = std::move(other).value_or(std::vector<T>());
72 return *this;
73 }
74 Array& operator=(Array&& other) {
75 Take(&other);
76 return *this;
77 }
78
79 Array& operator=(std::nullptr_t null_pointer) {
80 is_null_ = true;
81 vec_.clear();
82 return *this;
83 }
84
85 // Creates a non-null array of the specified size. The elements will be
86 // value-initialized (meaning that they will be initialized by their default
87 // constructor, if any, or else zero-initialized).
88 static Array New(size_t size) { return Array(size); }
89
90 // Creates a new array with a copy of the contents of |other|.
91 template <typename U>
92 static Array From(const U& other) {
93 return TypeConverter<Array, U>::Convert(other);
94 }
95
96 // Copies the contents of this array to a new object of type |U|.
97 template <typename U>
98 U To() const {
99 return TypeConverter<U, Array>::Convert(*this);
100 }
101
102 // Indicates whether the array is null (which is distinct from empty).
103 bool is_null() const { return is_null_; }
104
105 // Indicates whether the array is empty (which is distinct from null).
106 bool empty() const { return vec_.empty() && !is_null_; }
107
108 // Returns a reference to the first element of the array. Calling this on a
109 // null or empty array causes undefined behavior.
110 ConstRefType front() const { return vec_.front(); }
111 RefType front() { return vec_.front(); }
112
113 iterator begin() { return vec_.begin(); }
114 const_iterator begin() const { return vec_.begin(); }
115 iterator end() { return vec_.end(); }
116 const_iterator end() const { return vec_.end(); }
117
118 // Returns the size of the array, which will be zero if the array is null.
119 size_t size() const { return vec_.size(); }
120
121 // Returns a reference to the element at zero-based |offset|. Calling this on
122 // an array with size less than |offset|+1 causes undefined behavior.
123 ConstRefType at(size_t offset) const { return vec_.at(offset); }
124 ConstRefType operator[](size_t offset) const { return at(offset); }
125 RefType at(size_t offset) { return vec_.at(offset); }
126 RefType operator[](size_t offset) { return at(offset); }
127
128 // Pushes |value| onto the back of the array. If this array was null, it will
129 // become non-null with a size of 1.
130 void push_back(const T& value) {
131 is_null_ = false;
132 vec_.push_back(value);
133 }
134 void push_back(T&& value) {
135 is_null_ = false;
136 vec_.push_back(std::move(value));
137 }
138
139 // Resizes the array to |size| and makes it non-null. Otherwise, works just
140 // like the resize method of |std::vector|.
141 void resize(size_t size) {
142 is_null_ = false;
143 vec_.resize(size);
144 }
145
146 // Sets the array to empty (even if previously it was null.)
147 void SetToEmpty() { resize(0); }
148
149 // Ensures the underlying storage can store up to |size| elements without
150 // performing reallocations. This works like the reserve method of
151 // |std::vector|.
152 void reserve(size_t size) { vec_.reserve(size); }
153
154 // Returns a const reference to the |std::vector| managed by this class. If
155 // the array is null, this will be an empty vector.
156 const std::vector<T>& storage() const { return vec_; }
157
158 // Passes the underlying storage and resets this array to null.
159 std::vector<T> PassStorage() {
160 is_null_ = true;
161 return std::move(vec_);
162 }
163
164 base::Optional<std::vector<T>> PassStorageAsOptional() {
165 base::Optional<std::vector<T>> result;
166 if (!is_null_)
167 result.emplace(std::move(vec_));
168 is_null_ = true;
169 return result;
170 }
171
172 operator const std::vector<T>&() const { return vec_; }
173
174 void Swap(Array* other) {
175 std::swap(is_null_, other->is_null_);
176 vec_.swap(other->vec_);
177 }
178
179 // Swaps the contents of this array with the specified vector, making this
180 // array non-null. Since the vector cannot represent null, it will just be
181 // made empty if this array is null.
182 void Swap(std::vector<T>* other) {
183 is_null_ = false;
184 vec_.swap(*other);
185 }
186
187 // Returns a copy of the array where each value of the new array has been
188 // "cloned" from the corresponding value of this array. If the element type
189 // defines a Clone() method, it will be used; otherwise copy
190 // constructor/assignment will be used.
191 //
192 // Please note that calling this method will fail compilation if the element
193 // type cannot be cloned (which usually means that it is a Mojo handle type or
194 // a type containing Mojo handles).
195 Array Clone() const {
196 Array result;
197 result.is_null_ = is_null_;
198 result.vec_ = internal::Clone(vec_);
199 return result;
200 }
201
202 // Indicates whether the contents of this array are equal to |other|. A null
203 // array is only equal to another null array. If the element type defines an
204 // Equals() method, it will be used; otherwise == operator will be used.
205 bool Equals(const Array& other) const {
206 if (is_null() != other.is_null())
207 return false;
208 return internal::Equals(vec_, other.vec_);
209 }
210
211 size_t Hash(size_t seed) const {
212 return is_null() ? seed : internal::Hash(seed, vec_);
213 }
214
215 private:
216 typedef std::vector<T> Array::*Testable;
217
218 public:
219 operator Testable() const { return is_null_ ? 0 : &Array::vec_; }
220
221 private:
222 // Forbid the == and != operators explicitly, otherwise Array will be
223 // converted to Testable to do == or != comparison.
224 template <typename U>
225 bool operator==(const Array<U>& other) const = delete;
226 template <typename U>
227 bool operator!=(const Array<U>& other) const = delete;
228
229 void Take(Array* other) {
230 operator=(nullptr);
231 Swap(other);
232 }
233
234 std::vector<T> vec_;
235 bool is_null_;
236
237 DISALLOW_COPY_AND_ASSIGN(Array);
238 };
239
240 // A |TypeConverter| that will create an |Array<T>| containing a copy of the
241 // contents of an |std::vector<E>|, using |TypeConverter<T, E>| to copy each
242 // element. The returned array will always be non-null.
243 template <typename T, typename E>
244 struct TypeConverter<Array<T>, std::vector<E>> {
245 static Array<T> Convert(const std::vector<E>& input) {
246 Array<T> result(input.size());
247 for (size_t i = 0; i < input.size(); ++i)
248 result[i] = TypeConverter<T, E>::Convert(input[i]);
249 return std::move(result);
250 }
251 };
252
253 // A |TypeConverter| that will create an |std::vector<E>| containing a copy of
254 // the contents of an |Array<T>|, using |TypeConverter<E, T>| to copy each
255 // element. If the input array is null, the output vector will be empty.
256 template <typename E, typename T>
257 struct TypeConverter<std::vector<E>, Array<T>> {
258 static std::vector<E> Convert(const Array<T>& input) {
259 std::vector<E> result;
260 if (!input.is_null()) {
261 result.resize(input.size());
262 for (size_t i = 0; i < input.size(); ++i)
263 result[i] = TypeConverter<E, T>::Convert(input[i]);
264 }
265 return result;
266 }
267 };
268
269 // A |TypeConverter| that will create an |Array<T>| containing a copy of the
270 // contents of an |std::set<E>|, using |TypeConverter<T, E>| to copy each
271 // element. The returned array will always be non-null.
272 template <typename T, typename E>
273 struct TypeConverter<Array<T>, std::set<E>> {
274 static Array<T> Convert(const std::set<E>& input) {
275 Array<T> result;
276 for (auto i : input)
277 result.push_back(TypeConverter<T, E>::Convert(i));
278 return std::move(result);
279 }
280 };
281
282 // A |TypeConverter| that will create an |std::set<E>| containing a copy of
283 // the contents of an |Array<T>|, using |TypeConverter<E, T>| to copy each
284 // element. If the input array is null, the output set will be empty.
285 template <typename E, typename T>
286 struct TypeConverter<std::set<E>, Array<T>> {
287 static std::set<E> Convert(const Array<T>& input) {
288 std::set<E> result;
289 if (!input.is_null()) {
290 for (size_t i = 0; i < input.size(); ++i)
291 result.insert(TypeConverter<E, T>::Convert(input[i]));
292 }
293 return result;
294 }
295 };
296
297 // Less than operator to allow Arrays as keys in std maps and sets.
298 template <typename T>
299 inline bool operator<(const Array<T>& a, const Array<T>& b) {
300 if (a.is_null())
301 return !b.is_null();
302 if (b.is_null())
303 return false;
304 return a.storage() < b.storage();
305 }
306
307 } // namespace mojo
308
309 #endif // MOJO_PUBLIC_CPP_BINDINGS_ARRAY_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698