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..a5000a19a9cb5f297f30ec2ea80ac5ce2b2226f2 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)))); |
}; |
+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( |
+ MaybeConstUserType& input, |
+ IteratorType& iter) { |
+ auto& value = Traits::GetValue(iter); |
yzshen1
2016/06/10 16:21:32
Please update the comments in array_traits.h
Fady Samuel
2016/06/10 19:05:33
Done.
|
+ 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 UserTypeReader template parameter of ArraySerializer. |
template <typename MaybeConstUserType> |
class ArrayReader { |
yzshen1
2016/06/10 16:21:32
Maybe we should change this to ArrayIterator and l
Fady Samuel
2016/06/10 19:05:33
Done. I'm not sure how to get rid of GetNextHelper
|
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) {} |
+ explicit ArrayReader(MaybeConstUserType& input) |
+ : input_(input), iter_(CallGetBeginIfExists<Traits>(input)) {} |
~ArrayReader() {} |
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,7 +113,7 @@ class ArrayReader { |
private: |
MaybeConstUserType& input_; |
- size_t index_ = 0; |
+ IteratorType iter_; |
}; |
// ArraySerializer is also used to serialize map keys and values. Therefore, it |
@@ -108,6 +138,8 @@ struct ArraySerializer<MojomType, |
using DataElement = typename Data::Element; |
using Element = typename MojomType::Element; |
using Traits = ArrayTraits<UserType>; |
+ using IteratorType = |
+ decltype(CallGetBeginIfExists<Traits>(std::declval<UserType&>())); |
static_assert(std::is_same<Element, DataElement>::value, |
"Incorrect array serializer"); |
@@ -152,8 +184,11 @@ struct ArraySerializer<MojomType, |
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); |
+ IteratorType iter = CallGetBeginIfExists<Traits>(*output); |
+ for (size_t i = 0; i < input->size(); ++i) { |
+ GetNextHelper<Traits, MaybeConstUserType, IteratorType>( |
+ *output, iter) = input->at(i); |
+ } |
} |
} |
return true; |
@@ -221,6 +256,8 @@ struct ArraySerializer<MojomType, |
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"); |
@@ -249,8 +286,11 @@ struct ArraySerializer<MojomType, |
SerializationContext* context) { |
if (!Traits::Resize(*output, input->size())) |
return false; |
- for (size_t i = 0; i < input->size(); ++i) |
- Traits::GetAt(*output, i) = input->at(i); |
+ IteratorType iter = CallGetBeginIfExists<Traits>(*output); |
+ for (size_t i = 0; i < input->size(); ++i) { |
+ GetNextHelper<Traits, MaybeConstUserType, IteratorType>(*output, iter) = |
+ input->at(i); |
+ } |
return true; |
} |
}; |
@@ -324,6 +364,8 @@ struct ArraySerializer<MojomType, |
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, |
SerializationContext* context) { |
@@ -362,12 +404,16 @@ struct ArraySerializer<MojomType, |
bool success = true; |
if (!Traits::Resize(*output, input->size())) |
return false; |
+ IteratorType iter = CallGetBeginIfExists<Traits>(*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), |
+ &GetNextHelper<Traits, MaybeConstUserType, IteratorType>(*output, |
+ iter), |
+ context)) { |
success = false; |
} |
} |
@@ -415,6 +461,8 @@ struct ArraySerializer<MojomType, |
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, |
@@ -455,12 +503,16 @@ struct ArraySerializer<MojomType, |
bool success = true; |
if (!Traits::Resize(*output, input->size())) |
return false; |
+ IteratorType iter = CallGetBeginIfExists<Traits>(*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), |
+ &GetNextHelper<Traits, MaybeConstUserType, IteratorType>(*output, |
+ iter), |
+ context)) { |
success = false; |
} |
} |