Index: mojo/public/cpp/bindings/lib/array_serialization.h |
diff --git a/mojo/public/cpp/bindings/lib/array_serialization.h b/mojo/public/cpp/bindings/lib/array_serialization.h |
index 19c3dabc84ade6b964664ff962e02898d125cd22..0e77a7ba8e41a5e76a94d6ba9a7227c00a0b1173 100644 |
--- a/mojo/public/cpp/bindings/lib/array_serialization.h |
+++ b/mojo/public/cpp/bindings/lib/array_serialization.h |
@@ -56,23 +56,53 @@ struct GetArraySerializerType { |
: ArraySerializerType::POD)))); |
}; |
-// Used as the UserTypeReader template parameter of ArraySerializer. |
+template < |
+ typename Traits, |
+ typename MaybeConstUserType, |
+ typename IteratorType, |
+ typename std::enable_if< |
+ HasGetBeginMethod<Traits, MaybeConstUserType>::value>::type* = nullptr> |
+static decltype(Traits::GetValue(std::declval<IteratorType&>())) GetNextHelper( |
yzshen1
2016/06/11 00:40:27
Is it possible to merge these two helpers into Arr
Fady Samuel
2016/06/11 16:16:37
I agree it's probably easier to understand althoug
|
+ MaybeConstUserType& input, |
+ IteratorType& iter) { |
+ auto& value = Traits::GetValue(iter); |
+ Traits::AdvanceIterator(iter); |
+ return value; |
+} |
+ |
+template < |
+ typename Traits, |
+ typename MaybeConstUserType, |
+ typename IteratorType, |
+ typename std::enable_if< |
+ !HasGetBeginMethod<Traits, MaybeConstUserType>::value>::type* = nullptr> |
+static decltype(Traits::GetAt(std::declval<MaybeConstUserType&>(), 0)) |
+GetNextHelper(MaybeConstUserType& input, size_t& index) { |
+ DCHECK_LT(index, Traits::GetSize(input)); |
+ return Traits::GetAt(input, index++); |
+} |
+ |
+// Used as the UserTypeIterator template parameter of ArraySerializer. |
template <typename MaybeConstUserType> |
-class ArrayReader { |
+class ArrayIterator { |
public: |
using UserType = typename std::remove_const<MaybeConstUserType>::type; |
using Traits = ArrayTraits<UserType>; |
+ using IteratorType = decltype( |
+ CallGetBeginIfExists<Traits>(std::declval<MaybeConstUserType&>())); |
- explicit ArrayReader(MaybeConstUserType& input) : input_(input) {} |
- ~ArrayReader() {} |
+ explicit ArrayIterator(MaybeConstUserType& input) |
+ : input_(input), iter_(CallGetBeginIfExists<Traits>(input)) {} |
+ ~ArrayIterator() {} |
size_t GetSize() const { return Traits::GetSize(input_); } |
- using GetNextResult = |
- decltype(Traits::GetAt(std::declval<MaybeConstUserType&>(), 0)); |
- GetNextResult GetNext() { |
- DCHECK_LT(index_, Traits::GetSize(input_)); |
- return Traits::GetAt(input_, index_++); |
+ decltype(GetNextHelper<Traits, MaybeConstUserType, IteratorType>( |
+ std::declval<MaybeConstUserType&>(), |
+ std::declval<IteratorType&>())) |
+ GetNext() { |
+ return GetNextHelper<Traits, MaybeConstUserType, IteratorType>(input_, |
+ iter_); |
} |
using GetDataIfExistsResult = decltype( |
@@ -83,43 +113,45 @@ class ArrayReader { |
private: |
MaybeConstUserType& input_; |
- size_t index_ = 0; |
+ IteratorType iter_; |
}; |
// ArraySerializer is also used to serialize map keys and values. Therefore, it |
-// has a UserTypeReader parameter which is an adaptor for reading to hide the |
+// has a UserTypeIterator parameter which is an adaptor for reading to hide the |
// difference between ArrayTraits and MapTraits. |
template <typename MojomType, |
typename MaybeConstUserType, |
- typename UserTypeReader, |
+ typename UserTypeIterator, |
ArraySerializerType type = GetArraySerializerType<MojomType>::value> |
struct ArraySerializer; |
// Handles serialization and deserialization of arrays of pod types. |
template <typename MojomType, |
typename MaybeConstUserType, |
- typename UserTypeReader> |
+ typename UserTypeIterator> |
struct ArraySerializer<MojomType, |
MaybeConstUserType, |
- UserTypeReader, |
+ UserTypeIterator, |
ArraySerializerType::POD> { |
using UserType = typename std::remove_const<MaybeConstUserType>::type; |
using Data = typename MojomType::Data_; |
using DataElement = typename Data::Element; |
using Element = typename MojomType::Element; |
using Traits = ArrayTraits<UserType>; |
+ using IteratorType = |
yzshen1
2016/06/11 00:40:27
This is not needed anymore. (and same below)
|
+ decltype(CallGetBeginIfExists<Traits>(std::declval<UserType&>())); |
static_assert(std::is_same<Element, DataElement>::value, |
"Incorrect array serializer"); |
static_assert(std::is_same<Element, typename Traits::Element>::value, |
"Incorrect array serializer"); |
- static size_t GetSerializedSize(UserTypeReader* input, |
+ static size_t GetSerializedSize(UserTypeIterator* input, |
SerializationContext* context) { |
return sizeof(Data) + Align(input->GetSize() * sizeof(DataElement)); |
} |
- static void SerializeElements(UserTypeReader* input, |
+ static void SerializeElements(UserTypeIterator* input, |
Buffer* buf, |
Data* output, |
const ContainerValidateParams* validate_params, |
@@ -147,13 +179,14 @@ struct ArraySerializer<MojomType, |
SerializationContext* context) { |
if (!Traits::Resize(*output, input->size())) |
return false; |
+ ArrayIterator<UserType> iterator(*output); |
if (input->size()) { |
- auto data = CallGetDataIfExists<Traits>(*output); |
+ auto data = iterator.GetDataIfExists(); |
if (data) { |
memcpy(data, input->storage(), input->size() * sizeof(DataElement)); |
} else { |
for (size_t i = 0; i < input->size(); ++i) |
- Traits::GetAt(*output, i) = input->at(i); |
+ iterator.GetNext() = input->at(i); |
} |
} |
return true; |
@@ -163,10 +196,10 @@ struct ArraySerializer<MojomType, |
// Handles serialization and deserialization of arrays of enum types. |
template <typename MojomType, |
typename MaybeConstUserType, |
- typename UserTypeReader> |
+ typename UserTypeIterator> |
struct ArraySerializer<MojomType, |
MaybeConstUserType, |
- UserTypeReader, |
+ UserTypeIterator, |
ArraySerializerType::ENUM> { |
using UserType = typename std::remove_const<MaybeConstUserType>::type; |
using Data = typename MojomType::Data_; |
@@ -177,12 +210,12 @@ struct ArraySerializer<MojomType, |
static_assert(sizeof(Element) == sizeof(DataElement), |
"Incorrect array serializer"); |
- static size_t GetSerializedSize(UserTypeReader* input, |
+ static size_t GetSerializedSize(UserTypeIterator* input, |
SerializationContext* context) { |
return sizeof(Data) + Align(input->GetSize() * sizeof(DataElement)); |
} |
- static void SerializeElements(UserTypeReader* input, |
+ static void SerializeElements(UserTypeIterator* input, |
Buffer* buf, |
Data* output, |
const ContainerValidateParams* validate_params, |
@@ -202,8 +235,9 @@ struct ArraySerializer<MojomType, |
SerializationContext* context) { |
if (!Traits::Resize(*output, input->size())) |
return false; |
+ ArrayIterator<UserType> iterator(*output); |
for (size_t i = 0; i < input->size(); ++i) { |
- if (!Deserialize<Element>(input->at(i), &Traits::GetAt(*output, i))) |
+ if (!Deserialize<Element>(input->at(i), &iterator.GetNext())) |
return false; |
} |
return true; |
@@ -213,24 +247,26 @@ struct ArraySerializer<MojomType, |
// Serializes and deserializes arrays of bools. |
template <typename MojomType, |
typename MaybeConstUserType, |
- typename UserTypeReader> |
+ typename UserTypeIterator> |
struct ArraySerializer<MojomType, |
MaybeConstUserType, |
- UserTypeReader, |
+ UserTypeIterator, |
ArraySerializerType::BOOLEAN> { |
using UserType = typename std::remove_const<MaybeConstUserType>::type; |
using Traits = ArrayTraits<UserType>; |
using Data = typename MojomType::Data_; |
+ using IteratorType = |
+ decltype(CallGetBeginIfExists<Traits>(std::declval<UserType&>())); |
static_assert(std::is_same<bool, typename UserType::Element>::value, |
"Incorrect array serializer"); |
- static size_t GetSerializedSize(UserTypeReader* input, |
+ static size_t GetSerializedSize(UserTypeIterator* input, |
SerializationContext* context) { |
return sizeof(Data) + Align((input->GetSize() + 7) / 8); |
} |
- static void SerializeElements(UserTypeReader* input, |
+ static void SerializeElements(UserTypeIterator* input, |
Buffer* buf, |
Data* output, |
const ContainerValidateParams* validate_params, |
@@ -249,8 +285,9 @@ struct ArraySerializer<MojomType, |
SerializationContext* context) { |
if (!Traits::Resize(*output, input->size())) |
return false; |
+ ArrayIterator<UserType> iterator(*output); |
for (size_t i = 0; i < input->size(); ++i) |
- Traits::GetAt(*output, i) = input->at(i); |
+ iterator.GetNext() = input->at(i); |
return true; |
} |
}; |
@@ -258,10 +295,10 @@ struct ArraySerializer<MojomType, |
// Serializes and deserializes arrays of handles. |
template <typename MojomType, |
typename MaybeConstUserType, |
- typename UserTypeReader> |
+ typename UserTypeIterator> |
struct ArraySerializer<MojomType, |
MaybeConstUserType, |
- UserTypeReader, |
+ UserTypeIterator, |
ArraySerializerType::HANDLE> { |
using UserType = typename std::remove_const<MaybeConstUserType>::type; |
using Data = typename MojomType::Data_; |
@@ -271,13 +308,13 @@ struct ArraySerializer<MojomType, |
static_assert(std::is_same<Element, typename Traits::Element>::value, |
"Incorrect array serializer"); |
- static size_t GetSerializedSize(UserTypeReader* input, |
+ static size_t GetSerializedSize(UserTypeIterator* input, |
SerializationContext* context) { |
return sizeof(Data) + |
Align(input->GetSize() * sizeof(typename Data::Element)); |
} |
- static void SerializeElements(UserTypeReader* input, |
+ static void SerializeElements(UserTypeIterator* input, |
Buffer* buf, |
Data* output, |
const ContainerValidateParams* validate_params, |
@@ -302,8 +339,9 @@ struct ArraySerializer<MojomType, |
using HandleType = typename Element::RawHandleType; |
if (!Traits::Resize(*output, input->size())) |
return false; |
+ ArrayIterator<UserType> iterator(*output); |
for (size_t i = 0; i < input->size(); ++i) { |
- Traits::GetAt(*output, i) = MakeScopedHandle( |
+ iterator.GetNext() = MakeScopedHandle( |
HandleType(context->handles.TakeHandle(input->at(i)).value())); |
} |
return true; |
@@ -314,18 +352,20 @@ struct ArraySerializer<MojomType, |
// arrays and maps). |
template <typename MojomType, |
typename MaybeConstUserType, |
- typename UserTypeReader> |
+ typename UserTypeIterator> |
struct ArraySerializer<MojomType, |
MaybeConstUserType, |
- UserTypeReader, |
+ UserTypeIterator, |
ArraySerializerType::POINTER> { |
using UserType = typename std::remove_const<MaybeConstUserType>::type; |
using Data = typename MojomType::Data_; |
using DataElement = typename Data::Element; |
using Element = typename MojomType::Element; |
using Traits = ArrayTraits<UserType>; |
+ using IteratorType = |
+ decltype(CallGetBeginIfExists<Traits>(std::declval<UserType&>())); |
- static size_t GetSerializedSize(UserTypeReader* input, |
+ static size_t GetSerializedSize(UserTypeIterator* input, |
SerializationContext* context) { |
size_t element_count = input->GetSize(); |
size_t size = |
@@ -337,7 +377,7 @@ struct ArraySerializer<MojomType, |
return size; |
} |
- static void SerializeElements(UserTypeReader* input, |
+ static void SerializeElements(UserTypeIterator* input, |
Buffer* buf, |
Data* output, |
const ContainerValidateParams* validate_params, |
@@ -362,12 +402,12 @@ struct ArraySerializer<MojomType, |
bool success = true; |
if (!Traits::Resize(*output, input->size())) |
return false; |
+ ArrayIterator<UserType> iterator(*output); |
for (size_t i = 0; i < input->size(); ++i) { |
// Note that we rely on complete deserialization taking place in order to |
// transfer ownership of all encoded handles. Therefore we don't |
// short-circuit on failure here. |
- if (!Deserialize<Element>(input->at(i), &Traits::GetAt(*output, i), |
- context)) { |
+ if (!Deserialize<Element>(input->at(i), &iterator.GetNext(), context)) { |
success = false; |
} |
} |
@@ -406,21 +446,23 @@ struct ArraySerializer<MojomType, |
// Handles serialization and deserialization of arrays of unions. |
template <typename MojomType, |
typename MaybeConstUserType, |
- typename UserTypeReader> |
+ typename UserTypeIterator> |
struct ArraySerializer<MojomType, |
MaybeConstUserType, |
- UserTypeReader, |
+ UserTypeIterator, |
ArraySerializerType::UNION> { |
using UserType = typename std::remove_const<MaybeConstUserType>::type; |
using Data = typename MojomType::Data_; |
using Element = typename MojomType::Element; |
using Traits = ArrayTraits<UserType>; |
+ using IteratorType = |
+ decltype(CallGetBeginIfExists<Traits>(std::declval<UserType&>())); |
static_assert(std::is_same<typename MojomType::Element, |
typename Traits::Element>::value, |
"Incorrect array serializer"); |
- static size_t GetSerializedSize(UserTypeReader* input, |
+ static size_t GetSerializedSize(UserTypeIterator* input, |
SerializationContext* context) { |
size_t element_count = input->GetSize(); |
size_t size = sizeof(Data); |
@@ -432,7 +474,7 @@ struct ArraySerializer<MojomType, |
return size; |
} |
- static void SerializeElements(UserTypeReader* input, |
+ static void SerializeElements(UserTypeIterator* input, |
Buffer* buf, |
Data* output, |
const ContainerValidateParams* validate_params, |
@@ -455,12 +497,12 @@ struct ArraySerializer<MojomType, |
bool success = true; |
if (!Traits::Resize(*output, input->size())) |
return false; |
+ ArrayIterator<UserType> iterator(*output); |
for (size_t i = 0; i < input->size(); ++i) { |
// Note that we rely on complete deserialization taking place in order to |
// transfer ownership of all encoded handles. Therefore we don't |
// short-circuit on failure here. |
- if (!Deserialize<Element>(&input->at(i), &Traits::GetAt(*output, i), |
- context)) { |
+ if (!Deserialize<Element>(&input->at(i), &iterator.GetNext(), context)) { |
success = false; |
} |
} |
@@ -473,7 +515,7 @@ struct Serializer<Array<Element>, MaybeConstUserType> { |
using UserType = typename std::remove_const<MaybeConstUserType>::type; |
using Impl = ArraySerializer<Array<Element>, |
MaybeConstUserType, |
- ArrayReader<MaybeConstUserType>>; |
+ ArrayIterator<MaybeConstUserType>>; |
using Traits = ArrayTraits<UserType>; |
using Data = typename Array<Element>::Data_; |
@@ -481,8 +523,8 @@ struct Serializer<Array<Element>, MaybeConstUserType> { |
SerializationContext* context) { |
if (CallIsNullIfExists<Traits>(input)) |
return 0; |
- ArrayReader<MaybeConstUserType> reader(input); |
- return Impl::GetSerializedSize(&reader, context); |
+ ArrayIterator<MaybeConstUserType> iterator(input); |
+ return Impl::GetSerializedSize(&iterator, context); |
} |
static void Serialize(MaybeConstUserType& input, |
@@ -500,8 +542,9 @@ struct Serializer<Array<Element>, MaybeConstUserType> { |
Traits::GetSize(input), validate_params->expected_num_elements)); |
Data* result = Data::New(Traits::GetSize(input), buf); |
if (result) { |
- ArrayReader<MaybeConstUserType> reader(input); |
- Impl::SerializeElements(&reader, buf, result, validate_params, context); |
+ ArrayIterator<MaybeConstUserType> iterator(input); |
+ Impl::SerializeElements(&iterator, buf, result, validate_params, |
+ context); |
} |
*output = result; |
} else { |