Index: mojo/public/cpp/bindings/lib/array_internal.h |
diff --git a/mojo/public/cpp/bindings/lib/array_internal.h b/mojo/public/cpp/bindings/lib/array_internal.h |
index 865bf1cc8647e82a949ade03dac505887266c184..5e7dea878ef399863ca019e202be1714fd29df3e 100644 |
--- a/mojo/public/cpp/bindings/lib/array_internal.h |
+++ b/mojo/public/cpp/bindings/lib/array_internal.h |
@@ -6,21 +6,21 @@ |
#define MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_ |
#include <new> |
+#include <vector> |
-#include "mojo/public/cpp/bindings/buffer.h" |
#include "mojo/public/cpp/bindings/lib/bindings_internal.h" |
#include "mojo/public/cpp/bindings/lib/bindings_serialization.h" |
-#include "mojo/public/cpp/bindings/passable.h" |
+#include "mojo/public/cpp/bindings/lib/buffer.h" |
namespace mojo { |
template <typename T> class Array; |
+class String; |
namespace internal { |
template <typename T> |
struct ArrayDataTraits { |
typedef T StorageType; |
- typedef Array<T> Wrapper; |
typedef T& Ref; |
typedef T const& ConstRef; |
@@ -38,7 +38,6 @@ struct ArrayDataTraits { |
template <typename P> |
struct ArrayDataTraits<P*> { |
typedef StructPointer<P> StorageType; |
- typedef Array<typename P::Wrapper> Wrapper; |
typedef P*& Ref; |
typedef P* const& ConstRef; |
@@ -77,7 +76,6 @@ struct ArrayDataTraits<bool> { |
}; |
typedef uint8_t StorageType; |
- typedef Array<bool> Wrapper; |
typedef BitRef Ref; |
typedef bool ConstRef; |
@@ -102,23 +100,6 @@ template <typename T> |
struct ArraySerializationHelper<T, false> { |
typedef typename ArrayDataTraits<T>::StorageType ElementType; |
- static size_t ComputeSizeOfElements(const ArrayHeader* header, |
- const ElementType* elements) { |
- return 0; |
- } |
- |
- static void CloneElements(const ArrayHeader* header, |
- ElementType* elements, |
- Buffer* buf) { |
- } |
- |
- static void ClearHandles(const ArrayHeader* header, ElementType* elements) { |
- } |
- |
- static void CloseHandles(const ArrayHeader* header, |
- ElementType* elements) { |
- } |
- |
static void EncodePointersAndHandles(const ArrayHeader* header, |
ElementType* elements, |
std::vector<Handle>* handles) { |
@@ -135,20 +116,6 @@ template <> |
struct ArraySerializationHelper<Handle, true> { |
typedef ArrayDataTraits<Handle>::StorageType ElementType; |
- static size_t ComputeSizeOfElements(const ArrayHeader* header, |
- const ElementType* elements) { |
- return 0; |
- } |
- |
- static void CloneElements(const ArrayHeader* header, |
- ElementType* elements, |
- Buffer* buf) { |
- } |
- |
- static void ClearHandles(const ArrayHeader* header, ElementType* elements); |
- |
- static void CloseHandles(const ArrayHeader* header, ElementType* elements); |
- |
static void EncodePointersAndHandles(const ArrayHeader* header, |
ElementType* elements, |
std::vector<Handle>* handles); |
@@ -162,24 +129,6 @@ template <typename H> |
struct ArraySerializationHelper<H, true> { |
typedef typename ArrayDataTraits<H>::StorageType ElementType; |
- static size_t ComputeSizeOfElements(const ArrayHeader* header, |
- const ElementType* elements) { |
- return 0; |
- } |
- |
- static void CloneElements(const ArrayHeader* header, |
- ElementType* elements, |
- Buffer* buf) { |
- } |
- |
- static void ClearHandles(const ArrayHeader* header, ElementType* elements) { |
- ArraySerializationHelper<Handle, true>::ClearHandles(header, elements); |
- } |
- |
- static void CloseHandles(const ArrayHeader* header, ElementType* elements) { |
- ArraySerializationHelper<Handle, true>::CloseHandles(header, elements); |
- } |
- |
static void EncodePointersAndHandles(const ArrayHeader* header, |
ElementType* elements, |
std::vector<Handle>* handles) { |
@@ -199,36 +148,6 @@ template <typename P> |
struct ArraySerializationHelper<P*, false> { |
typedef typename ArrayDataTraits<P*>::StorageType ElementType; |
- static size_t ComputeSizeOfElements(const ArrayHeader* header, |
- const ElementType* elements) { |
- size_t result = 0; |
- for (uint32_t i = 0; i < header->num_elements; ++i) { |
- if (elements[i].ptr) |
- result += elements[i].ptr->ComputeSize(); |
- } |
- return result; |
- } |
- |
- static void CloneElements(const ArrayHeader* header, |
- ElementType* elements, |
- Buffer* buf) { |
- for (uint32_t i = 0; i < header->num_elements; ++i) { |
- if (elements[i].ptr) |
- elements[i].ptr = elements[i].ptr->Clone(buf); |
- } |
- } |
- |
- static void ClearHandles(const ArrayHeader* header, ElementType* elements) { |
- } |
- |
- static void CloseHandles(const ArrayHeader* header, |
- ElementType* elements) { |
- for (uint32_t i = 0; i < header->num_elements; ++i) { |
- if (elements[i].ptr) |
- elements[i].ptr->CloseHandles(); |
- } |
- } |
- |
static void EncodePointersAndHandles(const ArrayHeader* header, |
ElementType* elements, |
std::vector<Handle>* handles) { |
@@ -252,21 +171,15 @@ class Array_Data { |
public: |
typedef ArrayDataTraits<T> Traits; |
typedef typename Traits::StorageType StorageType; |
- typedef typename Traits::Wrapper Wrapper; |
typedef typename Traits::Ref Ref; |
typedef typename Traits::ConstRef ConstRef; |
- typedef ArraySerializationHelper<T, TypeTraits<T>::kIsHandle> Helper; |
+ typedef ArraySerializationHelper<T, IsHandle<T>::value> Helper; |
- static Array_Data<T>* New(size_t num_elements, Buffer* buf, |
- Buffer::Destructor dtor = NULL) { |
+ static Array_Data<T>* New(size_t num_elements, Buffer* buf) { |
size_t num_bytes = sizeof(Array_Data<T>) + |
Traits::GetStorageSize(num_elements); |
- return new (buf->Allocate(num_bytes, dtor)) Array_Data<T>(num_bytes, |
- num_elements); |
- } |
- |
- static void Destructor(void* address) { |
- static_cast<Array_Data*>(address)->CloseHandles(); |
+ return new (buf->Allocate(num_bytes)) Array_Data<T>(num_bytes, |
+ num_elements); |
} |
size_t size() const { return header_.num_elements; } |
@@ -291,28 +204,6 @@ class Array_Data { |
reinterpret_cast<const char*>(this) + sizeof(*this)); |
} |
- size_t ComputeSize() const { |
- return Align(header_.num_bytes) + |
- Helper::ComputeSizeOfElements(&header_, storage()); |
- } |
- |
- Array_Data<T>* Clone(Buffer* buf) { |
- Array_Data<T>* clone = New(header_.num_elements, buf); |
- memcpy(clone->storage(), |
- storage(), |
- header_.num_bytes - sizeof(Array_Data<T>)); |
- Helper::CloneElements(&clone->header_, clone->storage(), buf); |
- |
- // Zero-out handles in the original storage as they have been transferred |
- // to the clone. |
- Helper::ClearHandles(&header_, storage()); |
- return clone; |
- } |
- |
- void CloseHandles() { |
- Helper::CloseHandles(&header_, storage()); |
- } |
- |
void EncodePointersAndHandles(std::vector<Handle>* handles) { |
Helper::EncodePointersAndHandles(&header_, storage(), handles); |
} |
@@ -337,73 +228,49 @@ MOJO_COMPILE_ASSERT(sizeof(Array_Data<char>) == 8, bad_sizeof_Array_Data); |
// UTF-8 encoded |
typedef Array_Data<char> String_Data; |
-template <typename T, bool kIsObject, bool kIsHandle> struct ArrayTraits {}; |
+template <typename T, bool kIsMoveOnlyType> struct ArrayTraits {}; |
-// When T is an object type: |
-template <typename T> struct ArrayTraits<T, true, false> { |
- typedef Array_Data<typename T::Data*> DataType; |
- typedef const T& ConstRef; |
- typedef T& Ref; |
- static Buffer::Destructor GetDestructor() { |
- return NULL; |
+template <typename T> struct ArrayTraits<T, false> { |
+ typedef T StorageType; |
+ typedef typename std::vector<T>::reference RefType; |
+ typedef typename std::vector<T>::const_reference ConstRefType; |
+ static inline void Initialize(std::vector<T>* vec) { |
} |
- static typename T::Data* ToArrayElement(const T& value) { |
- return Unwrap(value); |
+ static inline void Finalize(std::vector<T>* vec) { |
} |
- // Something sketchy is indeed happening here... |
- static Ref ToRef(typename T::Data*& data) { |
- return *reinterpret_cast<T*>(&data); |
+ static inline ConstRefType at(const std::vector<T>* vec, size_t offset) { |
+ return vec->at(offset); |
} |
- static ConstRef ToConstRef(typename T::Data* const& data) { |
- return *reinterpret_cast<const T*>(&data); |
+ static inline RefType at(std::vector<T>* vec, size_t offset) { |
+ return vec->at(offset); |
} |
}; |
-// When T is a primitive (non-bool) type: |
-template <typename T> struct ArrayTraits<T, false, false> { |
- typedef Array_Data<T> DataType; |
- typedef const T& ConstRef; |
- typedef T& Ref; |
- static Buffer::Destructor GetDestructor() { |
- return NULL; |
+template <typename T> struct ArrayTraits<T, true> { |
+ struct StorageType { |
+ char buf[sizeof(T) + (8 - (sizeof(T) % 8)) % 8]; // Make 8-byte aligned. |
+ }; |
+ typedef T& RefType; |
+ typedef const T& ConstRefType; |
+ static inline void Initialize(std::vector<StorageType>* vec) { |
+ for (size_t i = 0; i < vec->size(); ++i) |
+ new (vec->at(i).buf) T(); |
} |
- static T ToArrayElement(const T& value) { |
- return value; |
+ static inline void Finalize(std::vector<StorageType>* vec) { |
+ for (size_t i = 0; i < vec->size(); ++i) |
+ reinterpret_cast<T*>(vec->at(i).buf)->~T(); |
} |
- static Ref ToRef(T& data) { return data; } |
- static ConstRef ToConstRef(const T& data) { return data; } |
-}; |
- |
-// When T is a bool type: |
-template <> struct ArrayTraits<bool, false, false> { |
- typedef Array_Data<bool> DataType; |
- typedef bool ConstRef; |
- typedef ArrayDataTraits<bool>::Ref Ref; |
- static Buffer::Destructor GetDestructor() { |
- return NULL; |
+ static inline ConstRefType at(const std::vector<StorageType>* vec, |
+ size_t offset) { |
+ return *reinterpret_cast<const T*>(vec->at(offset).buf); |
} |
- static bool ToArrayElement(const bool& value) { |
- return value; |
+ static inline RefType at(std::vector<StorageType>* vec, size_t offset) { |
+ return *reinterpret_cast<T*>(vec->at(offset).buf); |
} |
- static Ref ToRef(const Ref& data) { return data; } |
- static ConstRef ToConstRef(ConstRef data) { return data; } |
}; |
-// When T is a handle type: |
-template <typename H> struct ArrayTraits<H, false, true> { |
- typedef Array_Data<H> DataType; |
- typedef Passable<H> ConstRef; |
- typedef AssignableAndPassable<H> Ref; |
- static Buffer::Destructor GetDestructor() { |
- return &DataType::Destructor; |
- } |
- static H ToArrayElement(const H& value) { |
- return value; |
- } |
- static Ref ToRef(H& data) { return Ref(&data); } |
- static ConstRef ToConstRef(const H& data) { |
- return ConstRef(const_cast<H*>(&data)); |
- } |
+template <> struct WrapperTraits<String, false> { |
+ typedef String_Data* DataType; |
}; |
} // namespace internal |