Add WTF::move()
[WebKit-https.git] / Source / WebKit2 / Platform / IPC / HandleMessage.h
1 #ifndef HandleMessage_h
2 #define HandleMessage_h
3
4 #include "Arguments.h"
5 #include "MessageDecoder.h"
6 #include "MessageEncoder.h"
7 #include <wtf/StdLibExtras.h>
8
9 namespace IPC {
10
11 // Dispatch functions with no reply arguments.
12
13 template <typename C, typename MF, typename ArgsTuple, size_t... ArgsIndex>
14 void callMemberFunctionImpl(C* object, MF function, ArgsTuple&& args, std::index_sequence<ArgsIndex...>)
15 {
16     (object->*function)(std::get<ArgsIndex>(args)...);
17 }
18
19 template<typename C, typename MF, typename ArgsTuple, typename ArgsIndicies = std::make_index_sequence<std::tuple_size<ArgsTuple>::value>>
20 void callMemberFunction(ArgsTuple&& args, C* object, MF function)
21 {
22     callMemberFunctionImpl(object, function, std::forward<ArgsTuple>(args), ArgsIndicies());
23 }
24
25 // Dispatch functions with reply arguments.
26
27 template <typename C, typename MF, typename ArgsTuple, size_t... ArgsIndex, typename ReplyArgsTuple, size_t... ReplyArgsIndex>
28 void callMemberFunctionImpl(C* object, MF function, ArgsTuple&& args, ReplyArgsTuple& replyArgs, std::index_sequence<ArgsIndex...>, std::index_sequence<ReplyArgsIndex...>)
29 {
30     (object->*function)(std::get<ArgsIndex>(std::forward<ArgsTuple>(args))..., std::get<ReplyArgsIndex>(replyArgs)...);
31 }
32
33 template <typename C, typename MF, typename ArgsTuple, typename ArgsIndicies = std::make_index_sequence<std::tuple_size<ArgsTuple>::value>, typename ReplyArgsTuple, typename ReplyArgsIndicies = std::make_index_sequence<std::tuple_size<ReplyArgsTuple>::value>>
34 void callMemberFunction(ArgsTuple&& args, ReplyArgsTuple& replyArgs, C* object, MF function)
35 {
36     callMemberFunctionImpl(object, function, std::forward<ArgsTuple>(args), replyArgs, ArgsIndicies(), ReplyArgsIndicies());
37 }
38
39 // Dispatch functions with delayed reply arguments.
40
41 template <typename C, typename MF, typename R, typename ArgsTuple, size_t... ArgsIndex>
42 void callMemberFunctionImpl(C* object, MF function, PassRefPtr<R> delayedReply, ArgsTuple&& args, std::index_sequence<ArgsIndex...>)
43 {
44     (object->*function)(std::get<ArgsIndex>(args)..., delayedReply);
45 }
46
47 template<typename C, typename MF, typename R, typename ArgsTuple, typename ArgsIndicies = std::make_index_sequence<std::tuple_size<ArgsTuple>::value>>
48 void callMemberFunction(ArgsTuple&& args, PassRefPtr<R> delayedReply, C* object, MF function)
49 {
50     callMemberFunctionImpl(object, function, delayedReply, std::forward<ArgsTuple>(args), ArgsIndicies());
51 }
52
53 // Dispatch functions with connection parameter with no reply arguments.
54
55 template <typename C, typename MF, typename ArgsTuple, size_t... ArgsIndex>
56 void callMemberFunctionImpl(C* object, MF function, Connection* connection, ArgsTuple&& args, std::index_sequence<ArgsIndex...>)
57 {
58     (object->*function)(connection, std::get<ArgsIndex>(args)...);
59 }
60
61 template<typename C, typename MF, typename ArgsTuple, typename ArgsIndicies = std::make_index_sequence<std::tuple_size<ArgsTuple>::value>>
62 void callMemberFunction(Connection* connection, ArgsTuple&& args, C* object, MF function)
63 {
64     callMemberFunctionImpl(object, function, connection, std::forward<ArgsTuple>(args), ArgsIndicies());
65 }
66
67 // Dispatch functions with connection parameter with reply arguments.
68
69 template <typename C, typename MF, typename ArgsTuple, size_t... ArgsIndex, typename ReplyArgsTuple, size_t... ReplyArgsIndex>
70 void callMemberFunctionImpl(C* object, MF function, Connection* connection, ArgsTuple&& args, ReplyArgsTuple& replyArgs, std::index_sequence<ArgsIndex...>, std::index_sequence<ReplyArgsIndex...>)
71 {
72     (object->*function)(connection, std::get<ArgsIndex>(std::forward<ArgsTuple>(args))..., std::get<ReplyArgsIndex>(replyArgs)...);
73 }
74
75 template <typename C, typename MF, typename ArgsTuple, typename ArgsIndicies = std::make_index_sequence<std::tuple_size<ArgsTuple>::value>, typename ReplyArgsTuple, typename ReplyArgsIndicies = std::make_index_sequence<std::tuple_size<ReplyArgsTuple>::value>>
76 void callMemberFunction(Connection* connection, ArgsTuple&& args, ReplyArgsTuple& replyArgs, C* object, MF function)
77 {
78     callMemberFunctionImpl(object, function, connection, std::forward<ArgsTuple>(args), replyArgs, ArgsIndicies(), ReplyArgsIndicies());
79 }
80
81 // Variadic dispatch functions.
82
83 template <typename C, typename MF, typename ArgsTuple, size_t... ArgsIndex>
84 void callMemberFunctionImpl(C* object, MF function, MessageDecoder& decoder, ArgsTuple&& args, std::index_sequence<ArgsIndex...>)
85 {
86     (object->*function)(std::get<ArgsIndex>(args)..., decoder);
87 }
88
89 template<typename C, typename MF, typename ArgsTuple, typename ArgsIndicies = std::make_index_sequence<std::tuple_size<ArgsTuple>::value>>
90 void callMemberFunction(ArgsTuple&& args, MessageDecoder& decoder, C* object, MF function)
91 {
92     callMemberFunctionImpl(object, function, decoder, std::forward<ArgsTuple>(args), ArgsIndicies());
93 }
94
95 // Variadic dispatch functions with non-variadic reply arguments.
96
97 template <typename C, typename MF, typename ArgsTuple, size_t... ArgsIndex, typename ReplyArgsTuple, size_t... ReplyArgsIndex>
98 void callMemberFunctionImpl(C* object, MF function, MessageDecoder& decoder, ArgsTuple&& args, ReplyArgsTuple& replyArgs, std::index_sequence<ArgsIndex...>, std::index_sequence<ReplyArgsIndex...>)
99 {
100     (object->*function)(std::get<ArgsIndex>(std::forward<ArgsTuple>(args))..., decoder, std::get<ReplyArgsIndex>(replyArgs)...);
101 }
102
103 template <typename C, typename MF, typename ArgsTuple, typename ArgsIndicies = std::make_index_sequence<std::tuple_size<ArgsTuple>::value>, typename ReplyArgsTuple, typename ReplyArgsIndicies = std::make_index_sequence<std::tuple_size<ReplyArgsTuple>::value>>
104 void callMemberFunction(ArgsTuple&& args, MessageDecoder& decoder, ReplyArgsTuple& replyArgs, C* object, MF function)
105 {
106     callMemberFunctionImpl(object, function, decoder, std::forward<ArgsTuple>(args), replyArgs, ArgsIndicies(), ReplyArgsIndicies());
107 }
108
109 // Main dispatch functions
110
111 template<typename T, typename C, typename MF>
112 void handleMessage(MessageDecoder& decoder, C* object, MF function)
113 {
114     typename T::DecodeType arguments;
115     if (!decoder.decode(arguments)) {
116         ASSERT(decoder.isInvalid());
117         return;
118     }
119
120     callMemberFunction(WTF::move(arguments), object, function);
121 }
122
123 template<typename T, typename C, typename MF>
124 void handleMessage(MessageDecoder& decoder, MessageEncoder& replyEncoder, C* object, MF function)
125 {
126     typename T::DecodeType arguments;
127     if (!decoder.decode(arguments)) {
128         ASSERT(decoder.isInvalid());
129         return;
130     }
131
132     typename T::Reply::ValueType replyArguments;
133     callMemberFunction(WTF::move(arguments), replyArguments, object, function);
134     replyEncoder << replyArguments;
135 }
136
137 template<typename T, typename C, typename MF>
138 void handleMessage(Connection* connection, MessageDecoder& decoder, MessageEncoder& replyEncoder, C* object, MF function)
139 {
140     typename T::DecodeType arguments;
141     if (!decoder.decode(arguments)) {
142         ASSERT(decoder.isInvalid());
143         return;
144     }
145
146     typename T::Reply::ValueType replyArguments;
147     callMemberFunction(connection, WTF::move(arguments), replyArguments, object, function);
148     replyEncoder << replyArguments;
149 }
150
151 template<typename T, typename C, typename MF>
152 void handleMessage(Connection* connection, MessageDecoder& decoder, C* object, MF function)
153 {
154     typename T::DecodeType arguments;
155     if (!decoder.decode(arguments)) {
156         ASSERT(decoder.isInvalid());
157         return;
158     }
159     callMemberFunction(connection, WTF::move(arguments), object, function);
160 }
161
162 template<typename T, typename C, typename MF>
163 void handleMessageVariadic(MessageDecoder& decoder, C* object, MF function)
164 {
165     typename T::DecodeType arguments;
166     if (!decoder.decode(arguments)) {
167         ASSERT(decoder.isInvalid());
168         return;
169     }
170     callMemberFunction(WTF::move(arguments), decoder, object, function);
171 }
172
173 template<typename T, typename C, typename MF>
174 void handleMessageVariadic(MessageDecoder& decoder, MessageEncoder& replyEncoder, C* object, MF function)
175 {
176     typename T::DecodeType arguments;
177     if (!decoder.decode(arguments)) {
178         ASSERT(decoder.isInvalid());
179         return;
180     }
181
182     typename T::Reply::ValueType replyArguments;
183     callMemberFunction(WTF::move(arguments), decoder, replyArguments, object, function);
184     replyEncoder << replyArguments;
185 }
186
187 template<typename T, typename C, typename MF>
188 void handleMessageDelayed(Connection* connection, MessageDecoder& decoder, std::unique_ptr<MessageEncoder>& replyEncoder, C* object, MF function)
189 {
190     typename T::DecodeType arguments;
191     if (!decoder.decode(arguments)) {
192         ASSERT(decoder.isInvalid());
193         return;
194     }
195
196     RefPtr<typename T::DelayedReply> delayedReply = adoptRef(new typename T::DelayedReply(connection, WTF::move(replyEncoder)));
197     callMemberFunction(WTF::move(arguments), delayedReply.release(), object, function);
198 }
199
200 } // namespace IPC
201
202 #endif // HandleMessage_h