Index: mojo/public/cpp/bindings/lib/serialization_forward.h |
diff --git a/mojo/public/cpp/bindings/lib/serialization_forward.h b/mojo/public/cpp/bindings/lib/serialization_forward.h |
index 7f73932c85f44edbd5f1321026a462f908c9b789..5bed126da59282d01fee9f50fd3ffe6d012af215 100644 |
--- a/mojo/public/cpp/bindings/lib/serialization_forward.h |
+++ b/mojo/public/cpp/bindings/lib/serialization_forward.h |
@@ -5,8 +5,10 @@ |
#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_SERIALIZATION_FORWARD_H_ |
#define MOJO_PUBLIC_CPP_BINDINGS_LIB_SERIALIZATION_FORWARD_H_ |
+#include "base/optional.h" |
#include "mojo/public/cpp/bindings/array_traits.h" |
#include "mojo/public/cpp/bindings/enum_traits.h" |
+#include "mojo/public/cpp/bindings/lib/template_util.h" |
#include "mojo/public/cpp/bindings/map_traits.h" |
#include "mojo/public/cpp/bindings/string_traits.h" |
#include "mojo/public/cpp/bindings/struct_traits.h" |
@@ -22,11 +24,23 @@ namespace internal { |
template <typename MojomType, typename MaybeConstUserType> |
struct Serializer; |
+template <typename T> |
+struct IsOptionalWrapper { |
+ static const bool value = IsSpecializationOf< |
+ base::Optional, |
+ typename std::remove_const< |
+ typename std::remove_reference<T>::type>::type>::value; |
+}; |
+ |
// PrepareToSerialize() must be matched by a Serialize() for the same input |
// later. Moreover, within the same SerializationContext if PrepareToSerialize() |
// is called for |input_1|, ..., |input_n|, Serialize() must be called for |
// those objects in the exact same order. |
-template <typename MojomType, typename InputUserType, typename... Args> |
+template <typename MojomType, |
+ typename InputUserType, |
+ typename... Args, |
+ typename std::enable_if< |
+ !IsOptionalWrapper<InputUserType>::value>::type* = nullptr> |
size_t PrepareToSerialize(InputUserType&& input, Args&&... args) { |
return Serializer<MojomType, |
typename std::remove_reference<InputUserType>::type>:: |
@@ -34,7 +48,11 @@ size_t PrepareToSerialize(InputUserType&& input, Args&&... args) { |
std::forward<Args>(args)...); |
} |
-template <typename MojomType, typename InputUserType, typename... Args> |
+template <typename MojomType, |
+ typename InputUserType, |
+ typename... Args, |
+ typename std::enable_if< |
+ !IsOptionalWrapper<InputUserType>::value>::type* = nullptr> |
void Serialize(InputUserType&& input, Args&&... args) { |
Serializer<MojomType, typename std::remove_reference<InputUserType>::type>:: |
Serialize(std::forward<InputUserType>(input), |
@@ -44,12 +62,60 @@ void Serialize(InputUserType&& input, Args&&... args) { |
template <typename MojomType, |
typename DataType, |
typename InputUserType, |
- typename... Args> |
+ typename... Args, |
+ typename std::enable_if< |
+ !IsOptionalWrapper<InputUserType>::value>::type* = nullptr> |
bool Deserialize(DataType&& input, InputUserType* output, Args&&... args) { |
return Serializer<MojomType, InputUserType>::Deserialize( |
std::forward<DataType>(input), output, std::forward<Args>(args)...); |
} |
+// Specialization that unwraps base::Optional<>. |
+template <typename MojomType, |
+ typename InputUserType, |
+ typename... Args, |
+ typename std::enable_if< |
+ IsOptionalWrapper<InputUserType>::value>::type* = nullptr> |
+size_t PrepareToSerialize(InputUserType&& input, Args&&... args) { |
+ if (!input) |
+ return 0; |
+ return PrepareToSerialize<MojomType>(*input, std::forward<Args>(args)...); |
+} |
+ |
+template <typename MojomType, |
+ typename InputUserType, |
+ typename DataType, |
+ typename... Args, |
+ typename std::enable_if< |
+ IsOptionalWrapper<InputUserType>::value>::type* = nullptr> |
+void Serialize(InputUserType&& input, |
+ Buffer* buffer, |
+ DataType** output, |
+ Args&&... args) { |
+ if (!input) { |
+ *output = nullptr; |
+ return; |
+ } |
+ Serialize<MojomType>(*input, buffer, output, std::forward<Args>(args)...); |
+} |
+ |
+template <typename MojomType, |
+ typename DataType, |
+ typename InputUserType, |
+ typename... Args, |
+ typename std::enable_if< |
+ IsOptionalWrapper<InputUserType>::value>::type* = nullptr> |
+bool Deserialize(DataType&& input, InputUserType* output, Args&&... args) { |
+ if (!input) { |
+ *output = base::nullopt; |
+ return true; |
+ } |
+ if (!*output) |
+ output->emplace(); |
+ return Deserialize<MojomType>(std::forward<DataType>(input), &output->value(), |
+ std::forward<Args>(args)...); |
+} |
+ |
} // namespace internal |
} // namespace mojo |