Chromium Code Reviews| Index: mojo/public/cpp/bindings/array.h |
| diff --git a/mojo/public/cpp/bindings/array.h b/mojo/public/cpp/bindings/array.h |
| index faa39f56a34ecf5162199c8079c446a0b41e5963..23e1b193be9af282e1dc468ef118246ca81d5a26 100644 |
| --- a/mojo/public/cpp/bindings/array.h |
| +++ b/mojo/public/cpp/bindings/array.h |
| @@ -12,6 +12,7 @@ |
| #include <vector> |
| #include "mojo/public/cpp/bindings/lib/array_internal.h" |
| +#include "mojo/public/cpp/bindings/lib/template_util.h" |
| #include "mojo/public/cpp/bindings/type_converter.h" |
| namespace mojo { |
| @@ -19,145 +20,98 @@ namespace mojo { |
| // Provides read-only access to array data. |
| template <typename T> |
| class Array { |
| + MOJO_MOVE_ONLY_TYPE_FOR_CPP_03(Array, RValue) |
| public: |
| - typedef internal::ArrayTraits<T, |
| - internal::TypeTraits<T>::kIsObject, |
| - internal::TypeTraits<T>::kIsHandle> Traits_; |
| - typedef typename Traits_::DataType Data; |
| - typedef typename Traits_::ConstRef ConstRef; |
| - |
| - Array() : data_(NULL) { |
| + typedef internal::ArrayTraits<T, internal::IsMoveOnlyType<T>::value> |
| + Traits; |
| + typedef typename Traits::ConstRefType ConstRefType; |
| + typedef typename Traits::RefType RefType; |
| + typedef typename Traits::StorageType StorageType; |
| + |
| + Array() : is_null_(true) {} |
| + explicit Array(size_t size) : vec_(size), is_null_(true) { |
|
yzshen1
2014/05/22 17:13:53
nit: is_null_(false)?
|
| + Traits::Initialize(&vec_); |
| } |
| + ~Array() { Traits::Finalize(&vec_); } |
| - template <typename U> |
| - Array(const U& u, Buffer* buf = Buffer::current()) { |
| - TypeConverter<Array<T>,U>::AssertAllowImplicitTypeConversion(); |
| - *this = TypeConverter<Array<T>,U>::ConvertFrom(u, buf); |
| - } |
| - |
| - template <typename U> |
| - Array& operator=(const U& u) { |
| - TypeConverter<Array<T>,U>::AssertAllowImplicitTypeConversion(); |
| - *this = TypeConverter<Array<T>,U>::ConvertFrom(u, Buffer::current()); |
| + Array(RValue other) : is_null_(true) { Take(other.object); } |
| + Array& operator=(RValue other) { |
| + Take(other.object); |
| return *this; |
| } |
| - template <typename U> |
| - operator U() const { |
| - TypeConverter<Array<T>,U>::AssertAllowImplicitTypeConversion(); |
| - return To<U>(); |
| + static Array New(size_t size) { |
| + return Array(size).Pass(); |
| } |
| template <typename U> |
| - U To() const { |
| - return TypeConverter<Array<T>,U>::ConvertTo(*this); |
| + static Array From(const U& other) { |
| + return TypeConverter<Array, U>::ConvertFrom(other); |
| } |
| template <typename U> |
| - static Array From(const U& u, Buffer* buf = Buffer::current()) { |
| - return TypeConverter<Array<T>,U>::ConvertFrom(u, buf); |
| + const U& To() const { |
| + return TypeConverter<Array, U>::ConvertTo(*this); |
| } |
| - bool is_null() const { return !data_; } |
| - |
| - size_t size() const { return data_->size(); } |
| - |
| - ConstRef at(size_t offset) const { |
| - return Traits_::ToConstRef(data_->at(offset)); |
| - } |
| - ConstRef operator[](size_t offset) const { return at(offset); } |
| - |
| - // Provides a way to initialize an array element-by-element. |
| - class Builder { |
| - public: |
| - typedef typename Array<T>::Data Data; |
| - typedef typename Array<T>::Traits_ Traits_; |
| - typedef typename Traits_::Ref Ref; |
| - |
| - explicit Builder(size_t num_elements, Buffer* buf = mojo::Buffer::current()) |
| - : data_(Data::New(num_elements, buf, Traits_::GetDestructor())) { |
| - } |
| - |
| - size_t size() const { return data_->size(); } |
| - |
| - Ref at(size_t offset) { |
| - return Traits_::ToRef(data_->at(offset)); |
| - } |
| - Ref operator[](size_t offset) { return at(offset); } |
| - |
| - Array<T> Finish() { |
| - Data* data = NULL; |
| - std::swap(data, data_); |
| - return internal::Wrap(data); |
| + void reset() { |
| + if (!vec_.empty()) { |
| + Traits::Finalize(&vec_); |
| + vec_.clear(); |
| } |
| + is_null_ = true; |
| + } |
| - private: |
| - Data* data_; |
| - MOJO_DISALLOW_COPY_AND_ASSIGN(Builder); |
| - }; |
| - |
| - protected: |
| - friend class internal::WrapperHelper<Array<T> >; |
| - |
| - struct Wrap {}; |
| - Array(Wrap, const Data* data) : data_(data) {} |
| - |
| - const Data* data_; |
| -}; |
| + bool is_null() const { return is_null_; } |
| -// UTF-8 encoded |
| -typedef Array<char> String; |
| + size_t size() const { return vec_.size(); } |
| -template <> |
| -class TypeConverter<String, std::string> { |
| - public: |
| - static String ConvertFrom(const std::string& input, Buffer* buf); |
| - static std::string ConvertTo(const String& input); |
| + ConstRefType at(size_t offset) const { return Traits::at(&vec_, offset); } |
| + ConstRefType operator[](size_t offset) const { return at(offset); } |
| - MOJO_ALLOW_IMPLICIT_TYPE_CONVERSION(); |
| -}; |
| + RefType at(size_t offset) { return Traits::at(&vec_, offset); } |
| + RefType operator[](size_t offset) { return at(offset); } |
| -template <size_t N> |
| -class TypeConverter<String, char[N]> { |
| - public: |
| - static String ConvertFrom(const char input[N], Buffer* buf) { |
| - String::Builder result(N - 1, buf); |
| - memcpy(&result[0], input, N - 1); |
| - return result.Finish(); |
| + const std::vector<StorageType>& storage() const { |
| + return vec_; |
| + } |
| + operator const std::vector<StorageType>&() const { |
| + return vec_; |
| } |
| - MOJO_ALLOW_IMPLICIT_TYPE_CONVERSION(); |
| -}; |
| - |
| -// Appease MSVC. |
| -template <size_t N> |
| -class TypeConverter<String, const char[N]> { |
| - public: |
| - static String ConvertFrom(const char input[N], Buffer* buf) { |
| - return TypeConverter<String, char[N]>::ConvertFrom(input, buf); |
| + void Swap(Array* other) { |
| + std::swap(is_null_, other->is_null_); |
| + vec_.swap(other->vec_); |
| + } |
| + void Swap(std::vector<StorageType>* other) { |
| + is_null_ = false; |
| + vec_.swap(*other); |
| } |
| - MOJO_ALLOW_IMPLICIT_TYPE_CONVERSION(); |
| -}; |
| + private: |
| + typedef std::vector<StorageType> Array::*Testable; |
| -template <> |
| -class TypeConverter<String, const char*> { |
| public: |
| - static String ConvertFrom(const char* input, Buffer* buf); |
| - // NOTE: |ConvertTo| explicitly not implemented since String is not null |
| - // terminated (and may have embedded null bytes). |
| + operator Testable() const { return is_null_ ? 0 : &Array::vec_; } |
| + |
| + private: |
| + void Take(Array* other) { |
| + reset(); |
| + Swap(other); |
| + } |
| - MOJO_ALLOW_IMPLICIT_TYPE_CONVERSION(); |
| + std::vector<StorageType> vec_; |
| + bool is_null_; |
| }; |
| template <typename T, typename E> |
| class TypeConverter<Array<T>, std::vector<E> > { |
| public: |
| - static Array<T> ConvertFrom(const std::vector<E>& input, Buffer* buf) { |
| - typename Array<T>::Builder result(input.size(), buf); |
| + static Array<T> ConvertFrom(const std::vector<E>& input) { |
| + Array<T> result(input.size()); |
| for (size_t i = 0; i < input.size(); ++i) |
| - result[i] = TypeConverter<T, E>::ConvertFrom(input[i], buf); |
| - return result.Finish(); |
| + result[i] = TypeConverter<T, E>::ConvertFrom(input[i]); |
| + return result.Pass(); |
| } |
| static std::vector<E> ConvertTo(const Array<T>& input) { |
| std::vector<E> result; |
| @@ -168,8 +122,6 @@ class TypeConverter<Array<T>, std::vector<E> > { |
| } |
| return result; |
| } |
| - |
| - MOJO_INHERIT_IMPLICIT_TYPE_CONVERSION(T, E); |
| }; |
| } // namespace mojo |