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..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 { |