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

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

Issue 294833002: Mojo: more idiomatic C++ bindings (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix windows bustage Created 6 years, 6 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 | Annotate | Revision Log
OLDNEW
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 <string.h> 8 #include <string.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
11 #include <string> 11 #include <string>
12 #include <vector> 12 #include <vector>
13 13
14 #include "mojo/public/cpp/bindings/lib/array_internal.h" 14 #include "mojo/public/cpp/bindings/lib/array_internal.h"
15 #include "mojo/public/cpp/bindings/lib/template_util.h"
15 #include "mojo/public/cpp/bindings/type_converter.h" 16 #include "mojo/public/cpp/bindings/type_converter.h"
16 17
17 namespace mojo { 18 namespace mojo {
18 19
19 // Provides read-only access to array data. 20 // Provides read-only access to array data.
20 template <typename T> 21 template <typename T>
21 class Array { 22 class Array {
23 MOJO_MOVE_ONLY_TYPE_FOR_CPP_03(Array, RValue)
22 public: 24 public:
23 typedef internal::ArrayTraits<T, 25 typedef internal::ArrayTraits<T, internal::IsMoveOnlyType<T>::value>
24 internal::TypeTraits<T>::kIsObject, 26 Traits;
25 internal::TypeTraits<T>::kIsHandle> Traits_; 27 typedef typename Traits::ConstRefType ConstRefType;
26 typedef typename Traits_::DataType Data; 28 typedef typename Traits::RefType RefType;
27 typedef typename Traits_::ConstRef ConstRef; 29 typedef typename Traits::StorageType StorageType;
28 30
29 Array() : data_(NULL) { 31 typedef internal::Array_Data<typename internal::WrapperTraits<T>::DataType>
32 Data_;
33
34 Array() : is_null_(true) {}
35 explicit Array(size_t size) : vec_(size), is_null_(false) {
36 Traits::Initialize(&vec_);
37 }
38 ~Array() { Traits::Finalize(&vec_); }
39
40 Array(RValue other) : is_null_(true) { Take(other.object); }
41 Array& operator=(RValue other) {
42 Take(other.object);
43 return *this;
44 }
45
46 static Array New(size_t size) {
47 return Array(size).Pass();
30 } 48 }
31 49
32 template <typename U> 50 template <typename U>
33 Array(const U& u, Buffer* buf = Buffer::current()) { 51 static Array From(const U& other) {
34 TypeConverter<Array<T>,U>::AssertAllowImplicitTypeConversion(); 52 return TypeConverter<Array, U>::ConvertFrom(other);
35 *this = TypeConverter<Array<T>,U>::ConvertFrom(u, buf);
36 }
37
38 template <typename U>
39 Array& operator=(const U& u) {
40 TypeConverter<Array<T>,U>::AssertAllowImplicitTypeConversion();
41 *this = TypeConverter<Array<T>,U>::ConvertFrom(u, Buffer::current());
42 return *this;
43 }
44
45 template <typename U>
46 operator U() const {
47 TypeConverter<Array<T>,U>::AssertAllowImplicitTypeConversion();
48 return To<U>();
49 } 53 }
50 54
51 template <typename U> 55 template <typename U>
52 U To() const { 56 U To() const {
53 return TypeConverter<Array<T>,U>::ConvertTo(*this); 57 return TypeConverter<Array, U>::ConvertTo(*this);
54 } 58 }
55 59
56 template <typename U> 60 void reset() {
57 static Array From(const U& u, Buffer* buf = Buffer::current()) { 61 if (!vec_.empty()) {
58 return TypeConverter<Array<T>,U>::ConvertFrom(u, buf); 62 Traits::Finalize(&vec_);
63 vec_.clear();
64 }
65 is_null_ = true;
59 } 66 }
60 67
61 bool is_null() const { return !data_; } 68 bool is_null() const { return is_null_; }
62 69
63 size_t size() const { return data_->size(); } 70 size_t size() const { return vec_.size(); }
64 71
65 ConstRef at(size_t offset) const { 72 ConstRefType at(size_t offset) const { return Traits::at(&vec_, offset); }
66 return Traits_::ToConstRef(data_->at(offset)); 73 ConstRefType operator[](size_t offset) const { return at(offset); }
74
75 RefType at(size_t offset) { return Traits::at(&vec_, offset); }
76 RefType operator[](size_t offset) { return at(offset); }
77
78 const std::vector<StorageType>& storage() const {
79 return vec_;
67 } 80 }
68 ConstRef operator[](size_t offset) const { return at(offset); } 81 operator const std::vector<StorageType>&() const {
69 82 return vec_;
70 // Provides a way to initialize an array element-by-element.
71 class Builder {
72 public:
73 typedef typename Array<T>::Data Data;
74 typedef typename Array<T>::Traits_ Traits_;
75 typedef typename Traits_::Ref Ref;
76
77 explicit Builder(size_t num_elements, Buffer* buf = mojo::Buffer::current())
78 : data_(Data::New(num_elements, buf, Traits_::GetDestructor())) {
79 }
80
81 size_t size() const { return data_->size(); }
82
83 Ref at(size_t offset) {
84 return Traits_::ToRef(data_->at(offset));
85 }
86 Ref operator[](size_t offset) { return at(offset); }
87
88 Array<T> Finish() {
89 Data* data = NULL;
90 std::swap(data, data_);
91 return internal::Wrap(data);
92 }
93
94 private:
95 Data* data_;
96 MOJO_DISALLOW_COPY_AND_ASSIGN(Builder);
97 };
98
99 protected:
100 friend class internal::WrapperHelper<Array<T> >;
101
102 struct Wrap {};
103 Array(Wrap, const Data* data) : data_(data) {}
104
105 const Data* data_;
106 };
107
108 // UTF-8 encoded
109 typedef Array<char> String;
110
111 template <>
112 class TypeConverter<String, std::string> {
113 public:
114 static String ConvertFrom(const std::string& input, Buffer* buf);
115 static std::string ConvertTo(const String& input);
116
117 MOJO_ALLOW_IMPLICIT_TYPE_CONVERSION();
118 };
119
120 template <size_t N>
121 class TypeConverter<String, char[N]> {
122 public:
123 static String ConvertFrom(const char input[N], Buffer* buf) {
124 String::Builder result(N - 1, buf);
125 memcpy(&result[0], input, N - 1);
126 return result.Finish();
127 } 83 }
128 84
129 MOJO_ALLOW_IMPLICIT_TYPE_CONVERSION(); 85 void Swap(Array* other) {
130 }; 86 std::swap(is_null_, other->is_null_);
131 87 vec_.swap(other->vec_);
132 // Appease MSVC. 88 }
133 template <size_t N> 89 void Swap(std::vector<StorageType>* other) {
134 class TypeConverter<String, const char[N]> { 90 is_null_ = false;
135 public: 91 vec_.swap(*other);
136 static String ConvertFrom(const char input[N], Buffer* buf) {
137 return TypeConverter<String, char[N]>::ConvertFrom(input, buf);
138 } 92 }
139 93
140 MOJO_ALLOW_IMPLICIT_TYPE_CONVERSION(); 94 private:
141 }; 95 typedef std::vector<StorageType> Array::*Testable;
142 96
143 template <>
144 class TypeConverter<String, const char*> {
145 public: 97 public:
146 static String ConvertFrom(const char* input, Buffer* buf); 98 operator Testable() const { return is_null_ ? 0 : &Array::vec_; }
147 // NOTE: |ConvertTo| explicitly not implemented since String is not null
148 // terminated (and may have embedded null bytes).
149 99
150 MOJO_ALLOW_IMPLICIT_TYPE_CONVERSION(); 100 private:
101 void Take(Array* other) {
102 reset();
103 Swap(other);
104 }
105
106 std::vector<StorageType> vec_;
107 bool is_null_;
151 }; 108 };
152 109
153 template <typename T, typename E> 110 template <typename T, typename E>
154 class TypeConverter<Array<T>, std::vector<E> > { 111 class TypeConverter<Array<T>, std::vector<E> > {
155 public: 112 public:
156 static Array<T> ConvertFrom(const std::vector<E>& input, Buffer* buf) { 113 static Array<T> ConvertFrom(const std::vector<E>& input) {
157 typename Array<T>::Builder result(input.size(), buf); 114 Array<T> result(input.size());
158 for (size_t i = 0; i < input.size(); ++i) 115 for (size_t i = 0; i < input.size(); ++i)
159 result[i] = TypeConverter<T, E>::ConvertFrom(input[i], buf); 116 result[i] = TypeConverter<T, E>::ConvertFrom(input[i]);
160 return result.Finish(); 117 return result.Pass();
161 } 118 }
162 static std::vector<E> ConvertTo(const Array<T>& input) { 119 static std::vector<E> ConvertTo(const Array<T>& input) {
163 std::vector<E> result; 120 std::vector<E> result;
164 if (!input.is_null()) { 121 if (!input.is_null()) {
165 result.resize(input.size()); 122 result.resize(input.size());
166 for (size_t i = 0; i < input.size(); ++i) 123 for (size_t i = 0; i < input.size(); ++i)
167 result[i] = TypeConverter<T, E>::ConvertTo(input[i]); 124 result[i] = TypeConverter<T, E>::ConvertTo(input[i]);
168 } 125 }
169 return result; 126 return result;
170 } 127 }
171
172 MOJO_INHERIT_IMPLICIT_TYPE_CONVERSION(T, E);
173 }; 128 };
174 129
175 } // namespace mojo 130 } // namespace mojo
176 131
177 #endif // MOJO_PUBLIC_CPP_BINDINGS_ARRAY_H_ 132 #endif // MOJO_PUBLIC_CPP_BINDINGS_ARRAY_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698