OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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_ARRAY_H_ | 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_ARRAY_H_ |
6 #define MOJO_PUBLIC_CPP_BINDINGS_ARRAY_H_ | 6 #define MOJO_PUBLIC_CPP_BINDINGS_ARRAY_H_ |
7 | 7 |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 #include <string.h> | 9 #include <string.h> |
10 #include <algorithm> | 10 #include <algorithm> |
11 #include <set> | 11 #include <set> |
12 #include <string> | 12 #include <string> |
13 #include <utility> | 13 #include <utility> |
14 #include <vector> | 14 #include <vector> |
15 | 15 |
16 #include "base/move.h" | 16 #include "base/move.h" |
17 #include "mojo/public/cpp/bindings/lib/array_internal.h" | 17 #include "mojo/public/cpp/bindings/lib/array_internal.h" |
18 #include "mojo/public/cpp/bindings/lib/bindings_internal.h" | 18 #include "mojo/public/cpp/bindings/lib/bindings_internal.h" |
19 #include "mojo/public/cpp/bindings/lib/template_util.h" | 19 #include "mojo/public/cpp/bindings/lib/template_util.h" |
20 #include "mojo/public/cpp/bindings/lib/value_traits.h" | |
21 #include "mojo/public/cpp/bindings/type_converter.h" | 20 #include "mojo/public/cpp/bindings/type_converter.h" |
22 | 21 |
23 namespace mojo { | 22 namespace mojo { |
24 | 23 |
25 // Represents a moveable array with contents of type |T|. The array can be null, | 24 // Represents a moveable array with contents of type |T|. The array can be null, |
26 // meaning that no value has been assigned to it. Null is distinct from empty. | 25 // meaning that no value has been assigned to it. Null is distinct from empty. |
27 template <typename T> | 26 template <typename T> |
28 class Array { | 27 class Array { |
29 MOVE_ONLY_TYPE_FOR_CPP_03(Array); | 28 MOVE_ONLY_TYPE_FOR_CPP_03(Array); |
| 29 |
30 public: | 30 public: |
31 using ConstRefType = typename std::vector<T>::const_reference; | 31 using ConstRefType = typename std::vector<T>::const_reference; |
32 using RefType = typename std::vector<T>::reference; | 32 using RefType = typename std::vector<T>::reference; |
33 | 33 |
34 using Element = T; | 34 using Element = T; |
35 using Data_ = internal::Array_Data< | 35 using Data_ = internal::Array_Data< |
36 typename internal::GetDataTypeAsArrayElement<T>::Data>; | 36 typename internal::GetDataTypeAsArrayElement<T>::Data>; |
37 | 37 |
38 using iterator = typename std::vector<T>::iterator; | 38 using iterator = typename std::vector<T>::iterator; |
39 using const_iterator = typename std::vector<T>::const_iterator; | 39 using const_iterator = typename std::vector<T>::const_iterator; |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 | 156 |
157 // Swaps the contents of this array with the specified vector, making this | 157 // Swaps the contents of this array with the specified vector, making this |
158 // array non-null. Since the vector cannot represent null, it will just be | 158 // array non-null. Since the vector cannot represent null, it will just be |
159 // made empty if this array is null. | 159 // made empty if this array is null. |
160 void Swap(std::vector<T>* other) { | 160 void Swap(std::vector<T>* other) { |
161 is_null_ = false; | 161 is_null_ = false; |
162 vec_.swap(*other); | 162 vec_.swap(*other); |
163 } | 163 } |
164 | 164 |
165 // Returns a copy of the array where each value of the new array has been | 165 // Returns a copy of the array where each value of the new array has been |
166 // "cloned" from the corresponding value of this array. If this array contains | 166 // "cloned" from the corresponding value of this array. If the element type |
167 // primitive data types, this is equivalent to simply copying the contents. | 167 // defines a Clone() method, it will be used; otherwise copy |
168 // However, if the array contains objects, then each new element is created by | 168 // constructor/assignment will be used. |
169 // calling the |Clone| method of the source element, which should make a copy | |
170 // of the element. | |
171 // | 169 // |
172 // Please note that calling this method will fail compilation if the element | 170 // Please note that calling this method will fail compilation if the element |
173 // type cannot be cloned (which usually means that it is a Mojo handle type or | 171 // type cannot be cloned (which usually means that it is a Mojo handle type or |
174 // a type contains Mojo handles). | 172 // a type containing Mojo handles). |
175 Array Clone() const { | 173 Array Clone() const { |
176 Array result; | 174 Array result; |
177 result.is_null_ = is_null_; | 175 result.is_null_ = is_null_; |
178 CloneTraits<T>::Clone(vec_, &result.vec_); | 176 result.vec_.reserve(vec_.size()); |
| 177 for (const auto& element : vec_) |
| 178 result.vec_.push_back(internal::Clone(element)); |
179 return std::move(result); | 179 return std::move(result); |
180 } | 180 } |
181 | 181 |
182 // Indicates whether the contents of this array are equal to |other|. A null | 182 // Indicates whether the contents of this array are equal to |other|. A null |
183 // array is only equal to another null array. Elements are compared using the | 183 // array is only equal to another null array. If the element type defines an |
184 // |ValueTraits::Equals| method, which in most cases calls the |Equals| method | 184 // Equals() method, it will be used; otherwise == operator will be used. |
185 // of the element. | |
186 bool Equals(const Array& other) const { | 185 bool Equals(const Array& other) const { |
187 if (is_null() != other.is_null()) | 186 if (is_null() != other.is_null()) |
188 return false; | 187 return false; |
189 if (size() != other.size()) | 188 if (size() != other.size()) |
190 return false; | 189 return false; |
191 for (size_t i = 0; i < size(); ++i) { | 190 for (size_t i = 0; i < size(); ++i) { |
192 if (!internal::ValueTraits<T>::Equals(at(i), other.at(i))) | 191 if (!internal::Equals(at(i), other.at(i))) |
193 return false; | 192 return false; |
194 } | 193 } |
195 return true; | 194 return true; |
196 } | 195 } |
197 | 196 |
198 private: | 197 private: |
199 typedef std::vector<T> Array::*Testable; | 198 typedef std::vector<T> Array::*Testable; |
200 | 199 |
201 public: | 200 public: |
202 operator Testable() const { return is_null_ ? 0 : &Array::vec_; } | 201 operator Testable() const { return is_null_ ? 0 : &Array::vec_; } |
203 | 202 |
204 private: | 203 private: |
205 // Forbid the == and != operators explicitly, otherwise Array will be | 204 // Forbid the == and != operators explicitly, otherwise Array will be |
206 // converted to Testable to do == or != comparison. | 205 // converted to Testable to do == or != comparison. |
207 template <typename U> | 206 template <typename U> |
208 bool operator==(const Array<U>& other) const = delete; | 207 bool operator==(const Array<U>& other) const = delete; |
209 template <typename U> | 208 template <typename U> |
210 bool operator!=(const Array<U>& other) const = delete; | 209 bool operator!=(const Array<U>& other) const = delete; |
211 | 210 |
212 template <typename U, | |
213 bool is_move_only_type = internal::IsMoveOnlyType<U>::value> | |
214 struct CloneTraits {}; | |
215 | |
216 template <typename U> | |
217 struct CloneTraits<U, false> { | |
218 static inline void Clone(const std::vector<T>& src_vec, | |
219 std::vector<T>* dest_vec) { | |
220 dest_vec->assign(src_vec.begin(), src_vec.end()); | |
221 } | |
222 }; | |
223 | |
224 template <typename U> | |
225 struct CloneTraits<U, true> { | |
226 static inline void Clone(const std::vector<T>& src_vec, | |
227 std::vector<T>* dest_vec) { | |
228 DCHECK(dest_vec->empty()); | |
229 dest_vec->reserve(src_vec.size()); | |
230 for (const auto& element : src_vec) | |
231 dest_vec->push_back(element.Clone()); | |
232 } | |
233 }; | |
234 | |
235 void Take(Array* other) { | 211 void Take(Array* other) { |
236 operator=(nullptr); | 212 operator=(nullptr); |
237 Swap(other); | 213 Swap(other); |
238 } | 214 } |
239 | 215 |
240 std::vector<T> vec_; | 216 std::vector<T> vec_; |
241 bool is_null_; | 217 bool is_null_; |
242 }; | 218 }; |
243 | 219 |
244 // A |TypeConverter| that will create an |Array<T>| containing a copy of the | 220 // A |TypeConverter| that will create an |Array<T>| containing a copy of the |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 if (a.is_null()) | 280 if (a.is_null()) |
305 return !b.is_null(); | 281 return !b.is_null(); |
306 if (b.is_null()) | 282 if (b.is_null()) |
307 return false; | 283 return false; |
308 return a.storage() < b.storage(); | 284 return a.storage() < b.storage(); |
309 } | 285 } |
310 | 286 |
311 } // namespace mojo | 287 } // namespace mojo |
312 | 288 |
313 #endif // MOJO_PUBLIC_CPP_BINDINGS_ARRAY_H_ | 289 #endif // MOJO_PUBLIC_CPP_BINDINGS_ARRAY_H_ |
OLD | NEW |