| // Copyright 2015 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #ifndef IPC_IPC_MESSAGE_TEMPLATES_IMPL_H_ | 
 | #define IPC_IPC_MESSAGE_TEMPLATES_IMPL_H_ | 
 |  | 
 | #include <tuple> | 
 |  | 
 | namespace IPC { | 
 |  | 
 | template <typename... Ts> | 
 | class ParamDeserializer : public MessageReplyDeserializer { | 
 |  public: | 
 |   explicit ParamDeserializer(const std::tuple<Ts&...>& out) : out_(out) {} | 
 |  | 
 |   bool SerializeOutputParameters(const IPC::Message& msg, | 
 |                                  base::PickleIterator iter) override { | 
 |     return ReadParam(&msg, &iter, &out_); | 
 |   } | 
 |  | 
 |   std::tuple<Ts&...> out_; | 
 | }; | 
 |  | 
 | template <typename Meta, typename... Ins> | 
 | MessageT<Meta, std::tuple<Ins...>, void>::MessageT(Routing routing, | 
 |                                                     const Ins&... ins) | 
 |     : Message(routing.id, ID, PRIORITY_NORMAL) { | 
 |   WriteParam(this, std::tie(ins...)); | 
 | } | 
 |  | 
 | template <typename Meta, typename... Ins> | 
 | bool MessageT<Meta, std::tuple<Ins...>, void>::Read(const Message* msg, | 
 |                                                      Param* p) { | 
 |   base::PickleIterator iter(*msg); | 
 |   return ReadParam(msg, &iter, p); | 
 | } | 
 |  | 
 | template <typename Meta, typename... Ins> | 
 | void MessageT<Meta, std::tuple<Ins...>, void>::Log(std::string* name, | 
 |                                                     const Message* msg, | 
 |                                                     std::string* l) { | 
 |   if (name) | 
 |     *name = Meta::kName; | 
 |   if (!msg || !l) | 
 |     return; | 
 |   Param p; | 
 |   if (Read(msg, &p)) | 
 |     LogParam(p, l); | 
 | } | 
 |  | 
 | template <typename Meta, typename... Ins, typename... Outs> | 
 | MessageT<Meta, std::tuple<Ins...>, std::tuple<Outs...>>::MessageT( | 
 |     Routing routing, | 
 |     const Ins&... ins, | 
 |     Outs*... outs) | 
 |     : SyncMessage( | 
 |           routing.id, | 
 |           ID, | 
 |           PRIORITY_NORMAL, | 
 |           new ParamDeserializer<Outs...>(std::tie(*outs...))) { | 
 |   WriteParam(this, std::tie(ins...)); | 
 | } | 
 |  | 
 | template <typename Meta, typename... Ins, typename... Outs> | 
 | bool MessageT<Meta, std::tuple<Ins...>, std::tuple<Outs...>>::ReadSendParam( | 
 |     const Message* msg, | 
 |     SendParam* p) { | 
 |   base::PickleIterator iter = SyncMessage::GetDataIterator(msg); | 
 |   return ReadParam(msg, &iter, p); | 
 | } | 
 |  | 
 | template <typename Meta, typename... Ins, typename... Outs> | 
 | bool MessageT<Meta, std::tuple<Ins...>, std::tuple<Outs...>>::ReadReplyParam( | 
 |     const Message* msg, | 
 |     ReplyParam* p) { | 
 |   base::PickleIterator iter = SyncMessage::GetDataIterator(msg); | 
 |   return ReadParam(msg, &iter, p); | 
 | } | 
 |  | 
 | template <typename Meta, typename... Ins, typename... Outs> | 
 | void MessageT<Meta, | 
 |               std::tuple<Ins...>, | 
 |               std::tuple<Outs...>>::WriteReplyParams(Message* reply, | 
 |                                                       const Outs&... outs) { | 
 |   WriteParam(reply, std::tie(outs...)); | 
 | } | 
 |  | 
 | template <typename Meta, typename... Ins, typename... Outs> | 
 | void MessageT<Meta, std::tuple<Ins...>, std::tuple<Outs...>>::Log( | 
 |     std::string* name, | 
 |     const Message* msg, | 
 |     std::string* l) { | 
 |   if (name) | 
 |     *name = Meta::kName; | 
 |   if (!msg || !l) | 
 |     return; | 
 |   if (msg->is_sync()) { | 
 |     SendParam p; | 
 |     if (ReadSendParam(msg, &p)) | 
 |       LogParam(p, l); | 
 |     AddOutputParamsToLog(msg, l); | 
 |   } else { | 
 |     ReplyParam p; | 
 |     if (ReadReplyParam(msg, &p)) | 
 |       LogParam(p, l); | 
 |   } | 
 | } | 
 |  | 
 | }  // namespace IPC | 
 |  | 
 | #endif  // IPC_IPC_MESSAGE_TEMPLATES_IMPL_H_ |