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 <string.h> 9 10 #include <algorithm> 11 #include <string> 12 #include <vector> 13 14 #include "mojo/public/cpp/bindings/lib/array_internal.h" 15 #include "mojo/public/cpp/bindings/lib/template_util.h" 16 #include "mojo/public/cpp/bindings/type_converter.h" 17 18 namespace mojo { 19 20 // Provides read-only access to array data. 21 template <typename T> 22 class Array { 23 MOJO_MOVE_ONLY_TYPE_FOR_CPP_03(Array, RValue) 24 public: 25 typedef internal::ArrayTraits<T, internal::IsMoveOnlyType<T>::value> 26 Traits; 27 typedef typename Traits::ConstRefType ConstRefType; 28 typedef typename Traits::RefType RefType; 29 typedef typename Traits::StorageType StorageType; 30 typedef typename Traits::ForwardType ForwardType; 31 32 typedef internal::Array_Data<typename internal::WrapperTraits<T>::DataType> 33 Data_; 34 35 Array() : is_null_(true) {} 36 explicit Array(size_t size) : vec_(size), is_null_(false) { 37 Traits::Initialize(&vec_); 38 } 39 ~Array() { Traits::Finalize(&vec_); } 40 41 Array(RValue other) : is_null_(true) { Take(other.object); } 42 Array& operator=(RValue other) { 43 Take(other.object); 44 return *this; 45 } 46 47 static Array New(size_t size) { 48 return Array(size).Pass(); 49 } 50 51 template <typename U> 52 static Array From(const U& other) { 53 return TypeConverter<Array, U>::Convert(other); 54 } 55 56 template <typename U> 57 U To() const { 58 return TypeConverter<U, Array>::Convert(*this); 59 } 60 61 void reset() { 62 if (!vec_.empty()) { 63 Traits::Finalize(&vec_); 64 vec_.clear(); 65 } 66 is_null_ = true; 67 } 68 69 bool is_null() const { return is_null_; } 70 71 ConstRefType front() const { return vec_.front(); } 72 RefType front() { return vec_.front(); } 73 74 size_t size() const { return vec_.size(); } 75 76 ConstRefType at(size_t offset) const { return Traits::at(&vec_, offset); } 77 ConstRefType operator[](size_t offset) const { return at(offset); } 78 79 RefType at(size_t offset) { return Traits::at(&vec_, offset); } 80 RefType operator[](size_t offset) { return at(offset); } 81 82 void push_back(ForwardType value) { 83 is_null_ = false; 84 Traits::PushBack(&vec_, value); 85 } 86 87 void resize(size_t size) { 88 is_null_ = false; 89 Traits::Resize(&vec_, size); 90 } 91 92 const std::vector<StorageType>& storage() const { 93 return vec_; 94 } 95 operator const std::vector<StorageType>&() const { 96 return vec_; 97 } 98 99 void Swap(Array* other) { 100 std::swap(is_null_, other->is_null_); 101 vec_.swap(other->vec_); 102 } 103 void Swap(std::vector<StorageType>* other) { 104 is_null_ = false; 105 vec_.swap(*other); 106 } 107 108 private: 109 typedef std::vector<StorageType> Array::*Testable; 110 111 public: 112 operator Testable() const { return is_null_ ? 0 : &Array::vec_; } 113 114 private: 115 void Take(Array* other) { 116 reset(); 117 Swap(other); 118 } 119 120 std::vector<StorageType> vec_; 121 bool is_null_; 122 }; 123 124 template <typename T, typename E> 125 struct TypeConverter<Array<T>, std::vector<E> > { 126 static Array<T> Convert(const std::vector<E>& input) { 127 Array<T> result(input.size()); 128 for (size_t i = 0; i < input.size(); ++i) 129 result[i] = TypeConverter<T, E>::Convert(input[i]); 130 return result.Pass(); 131 } 132 }; 133 134 template <typename E, typename T> 135 struct TypeConverter<std::vector<E>, Array<T> > { 136 static std::vector<E> Convert(const Array<T>& input) { 137 std::vector<E> result; 138 if (!input.is_null()) { 139 result.resize(input.size()); 140 for (size_t i = 0; i < input.size(); ++i) 141 result[i] = TypeConverter<E, T>::Convert(input[i]); 142 } 143 return result; 144 } 145 }; 146 147 } // namespace mojo 148 149 #endif // MOJO_PUBLIC_CPP_BINDINGS_ARRAY_H_ 150