mojo::TypeConverter: support inherting implicit conversion settings from another...
[chromium-blink-merge.git] / mojo / public / cpp / bindings / array.h
blobfaa39f56a34ecf5162199c8079c446a0b41e5963
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.
5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_ARRAY_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_ARRAY_H_
8 #include <string.h>
10 #include <algorithm>
11 #include <string>
12 #include <vector>
14 #include "mojo/public/cpp/bindings/lib/array_internal.h"
15 #include "mojo/public/cpp/bindings/type_converter.h"
17 namespace mojo {
19 // Provides read-only access to array data.
20 template <typename T>
21 class Array {
22 public:
23 typedef internal::ArrayTraits<T,
24 internal::TypeTraits<T>::kIsObject,
25 internal::TypeTraits<T>::kIsHandle> Traits_;
26 typedef typename Traits_::DataType Data;
27 typedef typename Traits_::ConstRef ConstRef;
29 Array() : data_(NULL) {
32 template <typename U>
33 Array(const U& u, Buffer* buf = Buffer::current()) {
34 TypeConverter<Array<T>,U>::AssertAllowImplicitTypeConversion();
35 *this = TypeConverter<Array<T>,U>::ConvertFrom(u, buf);
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;
45 template <typename U>
46 operator U() const {
47 TypeConverter<Array<T>,U>::AssertAllowImplicitTypeConversion();
48 return To<U>();
51 template <typename U>
52 U To() const {
53 return TypeConverter<Array<T>,U>::ConvertTo(*this);
56 template <typename U>
57 static Array From(const U& u, Buffer* buf = Buffer::current()) {
58 return TypeConverter<Array<T>,U>::ConvertFrom(u, buf);
61 bool is_null() const { return !data_; }
63 size_t size() const { return data_->size(); }
65 ConstRef at(size_t offset) const {
66 return Traits_::ToConstRef(data_->at(offset));
68 ConstRef operator[](size_t offset) const { return at(offset); }
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;
77 explicit Builder(size_t num_elements, Buffer* buf = mojo::Buffer::current())
78 : data_(Data::New(num_elements, buf, Traits_::GetDestructor())) {
81 size_t size() const { return data_->size(); }
83 Ref at(size_t offset) {
84 return Traits_::ToRef(data_->at(offset));
86 Ref operator[](size_t offset) { return at(offset); }
88 Array<T> Finish() {
89 Data* data = NULL;
90 std::swap(data, data_);
91 return internal::Wrap(data);
94 private:
95 Data* data_;
96 MOJO_DISALLOW_COPY_AND_ASSIGN(Builder);
99 protected:
100 friend class internal::WrapperHelper<Array<T> >;
102 struct Wrap {};
103 Array(Wrap, const Data* data) : data_(data) {}
105 const Data* data_;
108 // UTF-8 encoded
109 typedef Array<char> String;
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);
117 MOJO_ALLOW_IMPLICIT_TYPE_CONVERSION();
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();
129 MOJO_ALLOW_IMPLICIT_TYPE_CONVERSION();
132 // Appease MSVC.
133 template <size_t N>
134 class TypeConverter<String, const char[N]> {
135 public:
136 static String ConvertFrom(const char input[N], Buffer* buf) {
137 return TypeConverter<String, char[N]>::ConvertFrom(input, buf);
140 MOJO_ALLOW_IMPLICIT_TYPE_CONVERSION();
143 template <>
144 class TypeConverter<String, const char*> {
145 public:
146 static String ConvertFrom(const char* input, Buffer* buf);
147 // NOTE: |ConvertTo| explicitly not implemented since String is not null
148 // terminated (and may have embedded null bytes).
150 MOJO_ALLOW_IMPLICIT_TYPE_CONVERSION();
153 template <typename T, typename E>
154 class TypeConverter<Array<T>, std::vector<E> > {
155 public:
156 static Array<T> ConvertFrom(const std::vector<E>& input, Buffer* buf) {
157 typename Array<T>::Builder result(input.size(), buf);
158 for (size_t i = 0; i < input.size(); ++i)
159 result[i] = TypeConverter<T, E>::ConvertFrom(input[i], buf);
160 return result.Finish();
162 static std::vector<E> ConvertTo(const Array<T>& input) {
163 std::vector<E> result;
164 if (!input.is_null()) {
165 result.resize(input.size());
166 for (size_t i = 0; i < input.size(); ++i)
167 result[i] = TypeConverter<T, E>::ConvertTo(input[i]);
169 return result;
172 MOJO_INHERIT_IMPLICIT_TYPE_CONVERSION(T, E);
175 } // namespace mojo
177 #endif // MOJO_PUBLIC_CPP_BINDINGS_ARRAY_H_