Chromium Code Reviews| 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; |
| } |
| } |