Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(29)

Side by Side Diff: third_party/WebKit/Source/wtf/Functional.h

Issue 1679773002: WTF::bind: Remove the need of hand-rolled code for bound arguments. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Make callInternal() private. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/wtf/DEPS ('k') | third_party/WebKit/Source/wtf/FunctionalTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011 Apple Inc. All rights reserved. 2 * Copyright (C) 2011 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * 12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE. 23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */ 24 */
25 25
26 #ifndef WTF_Functional_h 26 #ifndef WTF_Functional_h
27 #define WTF_Functional_h 27 #define WTF_Functional_h
28 28
29 #include "base/tuple.h"
29 #include "wtf/Allocator.h" 30 #include "wtf/Allocator.h"
30 #include "wtf/Assertions.h" 31 #include "wtf/Assertions.h"
31 #include "wtf/PassOwnPtr.h" 32 #include "wtf/PassOwnPtr.h"
32 #include "wtf/PassRefPtr.h" 33 #include "wtf/PassRefPtr.h"
33 #include "wtf/RefPtr.h" 34 #include "wtf/RefPtr.h"
34 #include "wtf/ThreadSafeRefCounted.h" 35 #include "wtf/ThreadSafeRefCounted.h"
35 #include "wtf/WeakPtr.h" 36 #include "wtf/WeakPtr.h"
37 #include <tuple>
Nico 2016/02/09 03:16:53 It's a bit unfortunate that this includes both bas
Yuta Kitamura 2016/02/09 05:47:43 The only reason I added base/tuple.h was base::Ind
36 38
37 namespace WTF { 39 namespace WTF {
38 40
39 // Functional.h provides a very simple way to bind a function pointer and argume nts together into a function object 41 // Functional.h provides a very simple way to bind a function pointer and argume nts together into a function object
40 // that can be stored, copied and invoked, similar to how boost::bind and std::b ind in C++11. 42 // that can be stored, copied and invoked, similar to how boost::bind and std::b ind in C++11.
41 43
42 // Use threadSafeBind() or createCrossThreadTask() if the function/task is 44 // Use threadSafeBind() or createCrossThreadTask() if the function/task is
43 // called on a (potentially) different thread from the current thread. 45 // called on a (potentially) different thread from the current thread.
44 46
45 // A FunctionWrapper is a class template that can wrap a function pointer or a m ember function pointer and 47 // A FunctionWrapper is a class template that can wrap a function pointer or a m ember function pointer and
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 class Function<R(Args...)> { 142 class Function<R(Args...)> {
141 USING_FAST_MALLOC(Function); 143 USING_FAST_MALLOC(Function);
142 WTF_MAKE_NONCOPYABLE(Function); 144 WTF_MAKE_NONCOPYABLE(Function);
143 public: 145 public:
144 virtual ~Function() { } 146 virtual ~Function() { }
145 virtual R operator()(Args... args) = 0; 147 virtual R operator()(Args... args) = 0;
146 protected: 148 protected:
147 Function() = default; 149 Function() = default;
148 }; 150 };
149 151
150 template<int boundArgsCount, typename FunctionWrapper, typename FunctionType> 152 template <typename BoundParametersTuple, typename FunctionWrapper, typename... U nboundParameters>
151 class PartBoundFunctionImpl; 153 class PartBoundFunctionImpl;
152 154
153 // Specialization for unbound functions. 155 template <typename... BoundParameters, typename FunctionWrapper, typename... Unb oundParameters>
154 template<typename FunctionWrapper, typename R, typename... UnboundParams> 156 class PartBoundFunctionImpl<std::tuple<BoundParameters...>, FunctionWrapper, Unb oundParameters...> final : public Function<typename FunctionWrapper::ResultType( UnboundParameters...)> {
155 class PartBoundFunctionImpl<0, FunctionWrapper, R(UnboundParams...)> final : pub lic Function<typename FunctionWrapper::ResultType(UnboundParams...)> {
156 public: 157 public:
157 PartBoundFunctionImpl(FunctionWrapper functionWrapper) 158 explicit PartBoundFunctionImpl(FunctionWrapper functionWrapper, const BoundP arameters&... bound)
158 : m_functionWrapper(functionWrapper) 159 : m_functionWrapper(functionWrapper)
160 , m_bound(ParamStorageTraits<BoundParameters>::wrap(bound)...)
159 { 161 {
160 } 162 }
161 163
162 typename FunctionWrapper::ResultType operator()(UnboundParams... params) ove rride 164 typename FunctionWrapper::ResultType operator()(UnboundParameters... unbound ) override
163 { 165 {
164 return m_functionWrapper(params...); 166 // What we really want to do is to call m_functionWrapper(m_bound..., un bound...), but to do that we need to
167 // pass a list of indices to a worker function template.
168 return callInternal(unbound..., base::MakeIndexSequence<sizeof...(BoundP arameters)>());
165 } 169 }
166 170
167 private: 171 private:
168 FunctionWrapper m_functionWrapper; 172 template <std::size_t... boundIndices>
169 }; 173 typename FunctionWrapper::ResultType callInternal(UnboundParameters... unbou nd, const base::IndexSequence<boundIndices...>&)
170
171 template<typename FunctionWrapper, typename R, typename P1, typename... UnboundP arams>
172 class PartBoundFunctionImpl<1, FunctionWrapper, R(P1, UnboundParams...)> final : public Function<typename FunctionWrapper::ResultType(UnboundParams...)> {
173 public:
174 PartBoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1)
175 : m_functionWrapper(functionWrapper)
176 , m_p1(ParamStorageTraits<P1>::wrap(p1))
177 { 174 {
175 // Get each element in m_bound, unwrap them, and call the function with the desired arguments.
176 return m_functionWrapper(ParamStorageTraits<BoundParameters>::unwrap(std ::get<boundIndices>(m_bound))..., unbound...);
178 } 177 }
179 178
180 typename FunctionWrapper::ResultType operator()(UnboundParams... params) ove rride
181 {
182 return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1), params... );
183 }
184
185 private:
186 FunctionWrapper m_functionWrapper; 179 FunctionWrapper m_functionWrapper;
187 typename ParamStorageTraits<P1>::StorageType m_p1; 180 std::tuple<typename ParamStorageTraits<BoundParameters>::StorageType...> m_b ound;
188 };
189
190 template<typename FunctionWrapper, typename R, typename P1, typename P2, typenam e... UnboundParams>
191 class PartBoundFunctionImpl<2, FunctionWrapper, R(P1, P2, UnboundParams...)> fin al : public Function<typename FunctionWrapper::ResultType(UnboundParams...)> {
192 public:
193 PartBoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1, const P 2& p2)
194 : m_functionWrapper(functionWrapper)
195 , m_p1(ParamStorageTraits<P1>::wrap(p1))
196 , m_p2(ParamStorageTraits<P2>::wrap(p2))
197 {
198 }
199
200 typename FunctionWrapper::ResultType operator()(UnboundParams... params) ove rride
201 {
202 return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1), ParamStor ageTraits<P2>::unwrap(m_p2), params...);
203 }
204
205 private:
206 FunctionWrapper m_functionWrapper;
207 typename ParamStorageTraits<P1>::StorageType m_p1;
208 typename ParamStorageTraits<P2>::StorageType m_p2;
209 };
210
211 template<typename FunctionWrapper, typename R, typename P1, typename P2, typenam e P3, typename... UnboundParams>
212 class PartBoundFunctionImpl<3, FunctionWrapper, R(P1, P2, P3, UnboundParams...)> final : public Function<typename FunctionWrapper::ResultType(UnboundParams...)> {
213 public:
214 PartBoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1, const P 2& p2, const P3& p3)
215 : m_functionWrapper(functionWrapper)
216 , m_p1(ParamStorageTraits<P1>::wrap(p1))
217 , m_p2(ParamStorageTraits<P2>::wrap(p2))
218 , m_p3(ParamStorageTraits<P3>::wrap(p3))
219 {
220 }
221
222 typename FunctionWrapper::ResultType operator()(UnboundParams... params) ove rride
223 {
224 return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1), ParamStor ageTraits<P2>::unwrap(m_p2), ParamStorageTraits<P3>::unwrap(m_p3), params...);
225 }
226
227 private:
228 FunctionWrapper m_functionWrapper;
229 typename ParamStorageTraits<P1>::StorageType m_p1;
230 typename ParamStorageTraits<P2>::StorageType m_p2;
231 typename ParamStorageTraits<P3>::StorageType m_p3;
232 };
233
234 template<typename FunctionWrapper, typename R, typename P1, typename P2, typenam e P3, typename P4, typename... UnboundParams>
235 class PartBoundFunctionImpl<4, FunctionWrapper, R(P1, P2, P3, P4, UnboundParams. ..)> final : public Function<typename FunctionWrapper::ResultType(UnboundParams. ..)> {
236 public:
237 PartBoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1, const P 2& p2, const P3& p3, const P4& p4)
238 : m_functionWrapper(functionWrapper)
239 , m_p1(ParamStorageTraits<P1>::wrap(p1))
240 , m_p2(ParamStorageTraits<P2>::wrap(p2))
241 , m_p3(ParamStorageTraits<P3>::wrap(p3))
242 , m_p4(ParamStorageTraits<P4>::wrap(p4))
243 {
244 }
245
246 typename FunctionWrapper::ResultType operator()(UnboundParams... params) ove rride
247 {
248 return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1), ParamStor ageTraits<P2>::unwrap(m_p2), ParamStorageTraits<P3>::unwrap(m_p3), ParamStorageT raits<P4>::unwrap(m_p4), params...);
249 }
250
251 private:
252 FunctionWrapper m_functionWrapper;
253 typename ParamStorageTraits<P1>::StorageType m_p1;
254 typename ParamStorageTraits<P2>::StorageType m_p2;
255 typename ParamStorageTraits<P3>::StorageType m_p3;
256 typename ParamStorageTraits<P4>::StorageType m_p4;
257 };
258
259 template<typename FunctionWrapper, typename R, typename P1, typename P2, typenam e P3, typename P4, typename P5, typename... UnboundParams>
260 class PartBoundFunctionImpl<5, FunctionWrapper, R(P1, P2, P3, P4, P5, UnboundPar ams...)> final : public Function<typename FunctionWrapper::ResultType(UnboundPar ams...)> {
261 public:
262 PartBoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1, const P 2& p2, const P3& p3, const P4& p4, const P5& p5)
263 : m_functionWrapper(functionWrapper)
264 , m_p1(ParamStorageTraits<P1>::wrap(p1))
265 , m_p2(ParamStorageTraits<P2>::wrap(p2))
266 , m_p3(ParamStorageTraits<P3>::wrap(p3))
267 , m_p4(ParamStorageTraits<P4>::wrap(p4))
268 , m_p5(ParamStorageTraits<P5>::wrap(p5))
269 {
270 }
271
272 typename FunctionWrapper::ResultType operator()(UnboundParams... params) ove rride
273 {
274 return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1), ParamStor ageTraits<P2>::unwrap(m_p2), ParamStorageTraits<P3>::unwrap(m_p3), ParamStorageT raits<P4>::unwrap(m_p4), ParamStorageTraits<P5>::unwrap(m_p5), params...);
275 }
276
277 private:
278 FunctionWrapper m_functionWrapper;
279 typename ParamStorageTraits<P1>::StorageType m_p1;
280 typename ParamStorageTraits<P2>::StorageType m_p2;
281 typename ParamStorageTraits<P3>::StorageType m_p3;
282 typename ParamStorageTraits<P4>::StorageType m_p4;
283 typename ParamStorageTraits<P5>::StorageType m_p5;
284 };
285
286 template<typename FunctionWrapper, typename R, typename P1, typename P2, typenam e P3, typename P4, typename P5, typename P6, typename... UnboundParams>
287 class PartBoundFunctionImpl<6, FunctionWrapper, R(P1, P2, P3, P4, P5, P6, Unboun dParams...)> final : public Function<typename FunctionWrapper::ResultType(Unboun dParams...)> {
288 public:
289 PartBoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1, const P 2& p2, const P3& p3, const P4& p4, const P5& p5, const P6& p6)
290 : m_functionWrapper(functionWrapper)
291 , m_p1(ParamStorageTraits<P1>::wrap(p1))
292 , m_p2(ParamStorageTraits<P2>::wrap(p2))
293 , m_p3(ParamStorageTraits<P3>::wrap(p3))
294 , m_p4(ParamStorageTraits<P4>::wrap(p4))
295 , m_p5(ParamStorageTraits<P5>::wrap(p5))
296 , m_p6(ParamStorageTraits<P6>::wrap(p6))
297 {
298 }
299
300 typename FunctionWrapper::ResultType operator()(UnboundParams... params) ove rride
301 {
302 return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1), ParamStor ageTraits<P2>::unwrap(m_p2), ParamStorageTraits<P3>::unwrap(m_p3), ParamStorageT raits<P4>::unwrap(m_p4), ParamStorageTraits<P5>::unwrap(m_p5), ParamStorageTrait s<P6>::unwrap(m_p6), params...);
303 }
304
305 private:
306 FunctionWrapper m_functionWrapper;
307 typename ParamStorageTraits<P1>::StorageType m_p1;
308 typename ParamStorageTraits<P2>::StorageType m_p2;
309 typename ParamStorageTraits<P3>::StorageType m_p3;
310 typename ParamStorageTraits<P4>::StorageType m_p4;
311 typename ParamStorageTraits<P5>::StorageType m_p5;
312 typename ParamStorageTraits<P6>::StorageType m_p6;
313 };
314
315 template<typename FunctionWrapper, typename R, typename P1, typename P2, typenam e P3, typename P4, typename P5, typename P6, typename P7, typename... UnboundPar ams>
316 class PartBoundFunctionImpl<7, FunctionWrapper, R(P1, P2, P3, P4, P5, P6, P7, Un boundParams...)> final : public Function<typename FunctionWrapper::ResultType(Un boundParams...)> {
317 public:
318 PartBoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1, const P 2& p2, const P3& p3, const P4& p4, const P5& p5, const P6& p6, const P7& p7)
319 : m_functionWrapper(functionWrapper)
320 , m_p1(ParamStorageTraits<P1>::wrap(p1))
321 , m_p2(ParamStorageTraits<P2>::wrap(p2))
322 , m_p3(ParamStorageTraits<P3>::wrap(p3))
323 , m_p4(ParamStorageTraits<P4>::wrap(p4))
324 , m_p5(ParamStorageTraits<P5>::wrap(p5))
325 , m_p6(ParamStorageTraits<P6>::wrap(p6))
326 , m_p7(ParamStorageTraits<P7>::wrap(p7))
327 {
328 }
329
330 typename FunctionWrapper::ResultType operator()(UnboundParams... params) ove rride
331 {
332 return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1), ParamStor ageTraits<P2>::unwrap(m_p2), ParamStorageTraits<P3>::unwrap(m_p3), ParamStorageT raits<P4>::unwrap(m_p4), ParamStorageTraits<P5>::unwrap(m_p5), ParamStorageTrait s<P6>::unwrap(m_p6), ParamStorageTraits<P7>::unwrap(m_p7), params...);
333 }
334
335 private:
336 FunctionWrapper m_functionWrapper;
337 typename ParamStorageTraits<P1>::StorageType m_p1;
338 typename ParamStorageTraits<P2>::StorageType m_p2;
339 typename ParamStorageTraits<P3>::StorageType m_p3;
340 typename ParamStorageTraits<P4>::StorageType m_p4;
341 typename ParamStorageTraits<P5>::StorageType m_p5;
342 typename ParamStorageTraits<P6>::StorageType m_p6;
343 typename ParamStorageTraits<P7>::StorageType m_p7;
344 }; 181 };
345 182
346 183
347 template<typename... UnboundArgs, typename FunctionType, typename... BoundArgs> 184 template<typename... UnboundParameters, typename FunctionType, typename... Bound Parameters>
348 PassOwnPtr<Function<typename FunctionWrapper<FunctionType>::ResultType(UnboundAr gs...)>> bind(FunctionType function, const BoundArgs&... boundArgs) 185 PassOwnPtr<Function<typename FunctionWrapper<FunctionType>::ResultType(UnboundPa rameters...)>> bind(FunctionType function, const BoundParameters&... boundParame ters)
349 { 186 {
350 const int boundArgsCount = sizeof...(BoundArgs); 187 // Bound parameters' types are wrapped with std::tuple so we can pass two te mplate parameter packs (bound
351 using BoundFunctionType = PartBoundFunctionImpl<boundArgsCount, FunctionWrap per<FunctionType>, typename FunctionWrapper<FunctionType>::ResultType(BoundArgs. .., UnboundArgs...)>; 188 // parameters and unbound) to PartBoundFunctionImpl. Note that a tuple of th is type isn't actually created;
352 return adoptPtr(new BoundFunctionType(FunctionWrapper<FunctionType>(function ), boundArgs...)); 189 // std::tuple<> is just for carrying the bound parameters' types. Any other class template taking a type parameter
190 // pack can be used instead of std::tuple. std::tuple is used just because i t's most convenient for this purpose.
191 using BoundFunctionType = PartBoundFunctionImpl<std::tuple<BoundParameters.. .>, FunctionWrapper<FunctionType>, UnboundParameters...>;
192 return adoptPtr(new BoundFunctionType(FunctionWrapper<FunctionType>(function ), boundParameters...));
353 } 193 }
354 194
355 typedef Function<void()> Closure; 195 typedef Function<void()> Closure;
356 196
357 } // namespace WTF 197 } // namespace WTF
358 198
359 using WTF::Function; 199 using WTF::Function;
360 using WTF::bind; 200 using WTF::bind;
361 using WTF::Closure; 201 using WTF::Closure;
362 202
363 #endif // WTF_Functional_h 203 #endif // WTF_Functional_h
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/wtf/DEPS ('k') | third_party/WebKit/Source/wtf/FunctionalTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698