OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2011 Apple Inc. All rights reserved. | |
3 * | |
4 * Redistribution and use in source and binary forms, with or without | |
5 * modification, are permitted provided that the following conditions | |
6 * are met: | |
7 * 1. Redistributions of source code must retain the above copyright | |
8 * notice, this list of conditions and the following disclaimer. | |
9 * 2. Redistributions in binary form must reproduce the above copyright | |
10 * notice, this list of conditions and the following disclaimer in the | |
11 * documentation and/or other materials provided with the distribution. | |
12 * | |
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, | |
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS | |
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
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 | |
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 | |
23 * THE POSSIBILITY OF SUCH DAMAGE. | |
24 */ | |
25 | |
26 #ifndef WTF_Functional_h | |
27 #define WTF_Functional_h | |
28 | |
29 #include <wtf/Assertions.h> | |
30 #include <wtf/PassRefPtr.h> | |
31 #include <wtf/RefPtr.h> | |
32 #include <wtf/ThreadSafeRefCounted.h> | |
33 #include <wtf/WeakPtr.h> | |
34 | |
35 #if OS(DARWIN) && COMPILER_SUPPORTS(BLOCKS) | |
36 #include <Block.h> | |
37 #include <wtf/ObjcRuntimeExtras.h> | |
38 #endif | |
39 | |
40 namespace WTF { | |
41 | |
42 // Functional.h provides a very simple way to bind a function pointer and argume
nts together into a function object | |
43 // that can be stored, copied and invoked, similar to how boost::bind and std::b
ind in C++11. | |
44 | |
45 // Helper class template to determine whether a given type has ref and deref mem
ber functions | |
46 // with the right type signature. | |
47 template<typename T> | |
48 class HasRefAndDeref { | |
49 typedef char YesType; | |
50 struct NoType { | |
51 char padding[8]; | |
52 }; | |
53 | |
54 struct BaseMixin { | |
55 void deref(); | |
56 void ref(); | |
57 }; | |
58 | |
59 struct Base : public T, public BaseMixin { }; | |
60 | |
61 template<typename U, U> struct | |
62 TypeChecker { }; | |
63 | |
64 template<typename U> | |
65 static NoType refCheck(U*, TypeChecker<void (BaseMixin::*)(), &U::ref>* = 0)
; | |
66 static YesType refCheck(...); | |
67 | |
68 template<typename U> | |
69 static NoType derefCheck(U*, TypeChecker<void (BaseMixin::*)(), &U::deref>*
= 0); | |
70 static YesType derefCheck(...); | |
71 | |
72 public: | |
73 static const bool value = sizeof(refCheck(static_cast<Base*>(0))) == sizeof(
YesType) && sizeof(derefCheck(static_cast<Base*>(0))) == sizeof(YesType); | |
74 }; | |
75 | |
76 // A FunctionWrapper is a class template that can wrap a function pointer or a m
ember function pointer and | |
77 // provide a unified interface for calling that function. | |
78 template<typename> | |
79 class FunctionWrapper; | |
80 | |
81 // Bound static functions: | |
82 | |
83 template<typename R> | |
84 class FunctionWrapper<R (*)()> { | |
85 public: | |
86 typedef R ResultType; | |
87 static const bool shouldRefFirstParameter = false; | |
88 | |
89 explicit FunctionWrapper(R (*function)()) | |
90 : m_function(function) | |
91 { | |
92 } | |
93 | |
94 R operator()() | |
95 { | |
96 return m_function(); | |
97 } | |
98 | |
99 private: | |
100 R (*m_function)(); | |
101 }; | |
102 | |
103 template<typename R, typename P1> | |
104 class FunctionWrapper<R (*)(P1)> { | |
105 public: | |
106 typedef R ResultType; | |
107 static const bool shouldRefFirstParameter = false; | |
108 | |
109 explicit FunctionWrapper(R (*function)(P1)) | |
110 : m_function(function) | |
111 { | |
112 } | |
113 | |
114 R operator()(P1 p1) | |
115 { | |
116 return m_function(p1); | |
117 } | |
118 | |
119 private: | |
120 R (*m_function)(P1); | |
121 }; | |
122 | |
123 template<typename R, typename P1, typename P2> | |
124 class FunctionWrapper<R (*)(P1, P2)> { | |
125 public: | |
126 typedef R ResultType; | |
127 static const bool shouldRefFirstParameter = false; | |
128 | |
129 explicit FunctionWrapper(R (*function)(P1, P2)) | |
130 : m_function(function) | |
131 { | |
132 } | |
133 | |
134 R operator()(P1 p1, P2 p2) | |
135 { | |
136 return m_function(p1, p2); | |
137 } | |
138 | |
139 private: | |
140 R (*m_function)(P1, P2); | |
141 }; | |
142 | |
143 template<typename R, typename P1, typename P2, typename P3> | |
144 class FunctionWrapper<R (*)(P1, P2, P3)> { | |
145 public: | |
146 typedef R ResultType; | |
147 static const bool shouldRefFirstParameter = false; | |
148 | |
149 explicit FunctionWrapper(R (*function)(P1, P2, P3)) | |
150 : m_function(function) | |
151 { | |
152 } | |
153 | |
154 R operator()(P1 p1, P2 p2, P3 p3) | |
155 { | |
156 return m_function(p1, p2, p3); | |
157 } | |
158 | |
159 private: | |
160 R (*m_function)(P1, P2, P3); | |
161 }; | |
162 | |
163 template<typename R, typename P1, typename P2, typename P3, typename P4> | |
164 class FunctionWrapper<R (*)(P1, P2, P3, P4)> { | |
165 public: | |
166 typedef R ResultType; | |
167 static const bool shouldRefFirstParameter = false; | |
168 | |
169 explicit FunctionWrapper(R (*function)(P1, P2, P3, P4)) | |
170 : m_function(function) | |
171 { | |
172 } | |
173 | |
174 R operator()(P1 p1, P2 p2, P3 p3, P4 p4) | |
175 { | |
176 return m_function(p1, p2, p3, p4); | |
177 } | |
178 | |
179 private: | |
180 R (*m_function)(P1, P2, P3, P4); | |
181 }; | |
182 | |
183 template<typename R, typename P1, typename P2, typename P3, typename P4, typenam
e P5> | |
184 class FunctionWrapper<R (*)(P1, P2, P3, P4, P5)> { | |
185 public: | |
186 typedef R ResultType; | |
187 static const bool shouldRefFirstParameter = false; | |
188 | |
189 explicit FunctionWrapper(R (*function)(P1, P2, P3, P4, P5)) | |
190 : m_function(function) | |
191 { | |
192 } | |
193 | |
194 R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) | |
195 { | |
196 return m_function(p1, p2, p3, p4, p5); | |
197 } | |
198 | |
199 private: | |
200 R (*m_function)(P1, P2, P3, P4, P5); | |
201 }; | |
202 | |
203 // Bound member functions: | |
204 | |
205 template<typename R, typename C> | |
206 class FunctionWrapper<R (C::*)()> { | |
207 public: | |
208 typedef R ResultType; | |
209 static const bool shouldRefFirstParameter = HasRefAndDeref<C>::value; | |
210 | |
211 explicit FunctionWrapper(R (C::*function)()) | |
212 : m_function(function) | |
213 { | |
214 } | |
215 | |
216 R operator()(C* c) | |
217 { | |
218 return (c->*m_function)(); | |
219 } | |
220 | |
221 R operator()(const WeakPtr<C>& c) | |
222 { | |
223 C* obj = c.get(); | |
224 if (!obj) | |
225 return R(); | |
226 return (obj->*m_function)(); | |
227 } | |
228 | |
229 private: | |
230 R (C::*m_function)(); | |
231 }; | |
232 | |
233 template<typename R, typename C, typename P1> | |
234 class FunctionWrapper<R (C::*)(P1)> { | |
235 public: | |
236 typedef R ResultType; | |
237 static const bool shouldRefFirstParameter = HasRefAndDeref<C>::value; | |
238 | |
239 explicit FunctionWrapper(R (C::*function)(P1)) | |
240 : m_function(function) | |
241 { | |
242 } | |
243 | |
244 R operator()(C* c, P1 p1) | |
245 { | |
246 return (c->*m_function)(p1); | |
247 } | |
248 | |
249 R operator()(const WeakPtr<C>& c, P1 p1) | |
250 { | |
251 C* obj = c.get(); | |
252 if (!obj) | |
253 return R(); | |
254 return (obj->*m_function)(p1); | |
255 } | |
256 | |
257 private: | |
258 R (C::*m_function)(P1); | |
259 }; | |
260 | |
261 template<typename R, typename C, typename P1, typename P2> | |
262 class FunctionWrapper<R (C::*)(P1, P2)> { | |
263 public: | |
264 typedef R ResultType; | |
265 static const bool shouldRefFirstParameter = HasRefAndDeref<C>::value; | |
266 | |
267 explicit FunctionWrapper(R (C::*function)(P1, P2)) | |
268 : m_function(function) | |
269 { | |
270 } | |
271 | |
272 R operator()(C* c, P1 p1, P2 p2) | |
273 { | |
274 return (c->*m_function)(p1, p2); | |
275 } | |
276 | |
277 R operator()(const WeakPtr<C>& c, P1 p1, P2 p2) | |
278 { | |
279 C* obj = c.get(); | |
280 if (!obj) | |
281 return R(); | |
282 return (obj->*m_function)(p1, p2); | |
283 } | |
284 | |
285 private: | |
286 R (C::*m_function)(P1, P2); | |
287 }; | |
288 | |
289 template<typename R, typename C, typename P1, typename P2, typename P3> | |
290 class FunctionWrapper<R (C::*)(P1, P2, P3)> { | |
291 public: | |
292 typedef R ResultType; | |
293 static const bool shouldRefFirstParameter = HasRefAndDeref<C>::value; | |
294 | |
295 explicit FunctionWrapper(R (C::*function)(P1, P2, P3)) | |
296 : m_function(function) | |
297 { | |
298 } | |
299 | |
300 R operator()(C* c, P1 p1, P2 p2, P3 p3) | |
301 { | |
302 return (c->*m_function)(p1, p2, p3); | |
303 } | |
304 | |
305 R operator()(const WeakPtr<C>& c, P1 p1, P2 p2, P3 p3) | |
306 { | |
307 C* obj = c.get(); | |
308 if (!obj) | |
309 return R(); | |
310 return (obj->*m_function)(p1, p2, p3); | |
311 } | |
312 | |
313 private: | |
314 R (C::*m_function)(P1, P2, P3); | |
315 }; | |
316 | |
317 template<typename R, typename C, typename P1, typename P2, typename P3, typename
P4> | |
318 class FunctionWrapper<R (C::*)(P1, P2, P3, P4)> { | |
319 public: | |
320 typedef R ResultType; | |
321 static const bool shouldRefFirstParameter = HasRefAndDeref<C>::value; | |
322 | |
323 explicit FunctionWrapper(R (C::*function)(P1, P2, P3, P4)) | |
324 : m_function(function) | |
325 { | |
326 } | |
327 | |
328 R operator()(C* c, P1 p1, P2 p2, P3 p3, P4 p4) | |
329 { | |
330 return (c->*m_function)(p1, p2, p3, p4); | |
331 } | |
332 | |
333 R operator()(const WeakPtr<C>& c, P1 p1, P2 p2, P3 p3, P4 p4) | |
334 { | |
335 C* obj = c.get(); | |
336 if (!obj) | |
337 return R(); | |
338 return (obj->*m_function)(p1, p2, p3, p4); | |
339 } | |
340 | |
341 private: | |
342 R (C::*m_function)(P1, P2, P3, P4); | |
343 }; | |
344 | |
345 template<typename R, typename C, typename P1, typename P2, typename P3, typename
P4, typename P5> | |
346 class FunctionWrapper<R (C::*)(P1, P2, P3, P4, P5)> { | |
347 public: | |
348 typedef R ResultType; | |
349 static const bool shouldRefFirstParameter = HasRefAndDeref<C>::value; | |
350 | |
351 explicit FunctionWrapper(R (C::*function)(P1, P2, P3, P4, P5)) | |
352 : m_function(function) | |
353 { | |
354 } | |
355 | |
356 R operator()(C* c, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) | |
357 { | |
358 return (c->*m_function)(p1, p2, p3, p4, p5); | |
359 } | |
360 | |
361 R operator()(const WeakPtr<C>& c, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) | |
362 { | |
363 C* obj = c.get(); | |
364 if (!obj) | |
365 return R(); | |
366 return (obj->*m_function)(p1, p2, p3, p4, p5); | |
367 } | |
368 | |
369 private: | |
370 R (C::*m_function)(P1, P2, P3, P4, P5); | |
371 }; | |
372 | |
373 #if OS(DARWIN) && COMPILER_SUPPORTS(BLOCKS) | |
374 template<typename R> | |
375 class FunctionWrapper<R (^)()> { | |
376 public: | |
377 typedef R ResultType; | |
378 static const bool shouldRefFirstParameter = false; | |
379 | |
380 explicit FunctionWrapper(R (^block)()) | |
381 : m_block(Block_copy(block)) | |
382 { | |
383 } | |
384 | |
385 FunctionWrapper(const FunctionWrapper& other) | |
386 : m_block(Block_copy(other.m_block)) | |
387 { | |
388 } | |
389 | |
390 ~FunctionWrapper() | |
391 { | |
392 Block_release(m_block); | |
393 } | |
394 | |
395 R operator()() | |
396 { | |
397 return m_block(); | |
398 } | |
399 | |
400 private: | |
401 R (^m_block)(); | |
402 }; | |
403 #endif | |
404 | |
405 template<typename T, bool shouldRefAndDeref> struct RefAndDeref { | |
406 static void ref(T) { } | |
407 static void deref(T) { } | |
408 }; | |
409 | |
410 template<typename T> struct RefAndDeref<T*, true> { | |
411 static void ref(T* t) { t->ref(); } | |
412 static void deref(T* t) { t->deref(); } | |
413 }; | |
414 | |
415 template<typename T> struct ParamStorageTraits { | |
416 typedef T StorageType; | |
417 | |
418 static StorageType wrap(const T& value) { return value; } | |
419 static const T& unwrap(const StorageType& value) { return value; } | |
420 }; | |
421 | |
422 template<typename T> struct ParamStorageTraits<PassRefPtr<T> > { | |
423 typedef RefPtr<T> StorageType; | |
424 | |
425 static StorageType wrap(PassRefPtr<T> value) { return value; } | |
426 static T* unwrap(const StorageType& value) { return value.get(); } | |
427 }; | |
428 | |
429 template<typename T> struct ParamStorageTraits<RefPtr<T> > { | |
430 typedef RefPtr<T> StorageType; | |
431 | |
432 static StorageType wrap(RefPtr<T> value) { return value.release(); } | |
433 static T* unwrap(const StorageType& value) { return value.get(); } | |
434 }; | |
435 | |
436 template<typename> class RetainPtr; | |
437 | |
438 template<typename T> struct ParamStorageTraits<RetainPtr<T> > { | |
439 typedef RetainPtr<T> StorageType; | |
440 | |
441 static StorageType wrap(const RetainPtr<T>& value) { return value; } | |
442 static typename RetainPtr<T>::PtrType unwrap(const StorageType& value) { ret
urn value.get(); } | |
443 }; | |
444 | |
445 class FunctionImplBase : public ThreadSafeRefCounted<FunctionImplBase> { | |
446 public: | |
447 virtual ~FunctionImplBase() { } | |
448 }; | |
449 | |
450 template<typename> | |
451 class FunctionImpl; | |
452 | |
453 template<typename R> | |
454 class FunctionImpl<R ()> : public FunctionImplBase { | |
455 public: | |
456 virtual R operator()() = 0; | |
457 }; | |
458 | |
459 template<typename FunctionWrapper, typename FunctionType> | |
460 class BoundFunctionImpl; | |
461 | |
462 template<typename FunctionWrapper, typename R> | |
463 class BoundFunctionImpl<FunctionWrapper, R ()> : public FunctionImpl<typename Fu
nctionWrapper::ResultType ()> { | |
464 public: | |
465 explicit BoundFunctionImpl(FunctionWrapper functionWrapper) | |
466 : m_functionWrapper(functionWrapper) | |
467 { | |
468 } | |
469 | |
470 virtual typename FunctionWrapper::ResultType operator()() | |
471 { | |
472 return m_functionWrapper(); | |
473 } | |
474 | |
475 private: | |
476 FunctionWrapper m_functionWrapper; | |
477 }; | |
478 | |
479 template<typename FunctionWrapper, typename R, typename P1> | |
480 class BoundFunctionImpl<FunctionWrapper, R (P1)> : public FunctionImpl<typename
FunctionWrapper::ResultType ()> { | |
481 public: | |
482 BoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1) | |
483 : m_functionWrapper(functionWrapper) | |
484 , m_p1(ParamStorageTraits<P1>::wrap(p1)) | |
485 { | |
486 RefAndDeref<P1, FunctionWrapper::shouldRefFirstParameter>::ref(m_p1); | |
487 } | |
488 | |
489 ~BoundFunctionImpl() | |
490 { | |
491 RefAndDeref<P1, FunctionWrapper::shouldRefFirstParameter>::deref(m_p1); | |
492 } | |
493 | |
494 virtual typename FunctionWrapper::ResultType operator()() | |
495 { | |
496 return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1)); | |
497 } | |
498 | |
499 private: | |
500 FunctionWrapper m_functionWrapper; | |
501 typename ParamStorageTraits<P1>::StorageType m_p1; | |
502 }; | |
503 | |
504 template<typename FunctionWrapper, typename R, typename P1, typename P2> | |
505 class BoundFunctionImpl<FunctionWrapper, R (P1, P2)> : public FunctionImpl<typen
ame FunctionWrapper::ResultType ()> { | |
506 public: | |
507 BoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1, const P2& p
2) | |
508 : m_functionWrapper(functionWrapper) | |
509 , m_p1(ParamStorageTraits<P1>::wrap(p1)) | |
510 , m_p2(ParamStorageTraits<P2>::wrap(p2)) | |
511 { | |
512 RefAndDeref<P1, FunctionWrapper::shouldRefFirstParameter>::ref(m_p1); | |
513 } | |
514 | |
515 ~BoundFunctionImpl() | |
516 { | |
517 RefAndDeref<P1, FunctionWrapper::shouldRefFirstParameter>::deref(m_p1); | |
518 } | |
519 | |
520 virtual typename FunctionWrapper::ResultType operator()() | |
521 { | |
522 return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1), ParamStor
ageTraits<P2>::unwrap(m_p2)); | |
523 } | |
524 | |
525 private: | |
526 FunctionWrapper m_functionWrapper; | |
527 typename ParamStorageTraits<P1>::StorageType m_p1; | |
528 typename ParamStorageTraits<P2>::StorageType m_p2; | |
529 }; | |
530 | |
531 template<typename FunctionWrapper, typename R, typename P1, typename P2, typenam
e P3> | |
532 class BoundFunctionImpl<FunctionWrapper, R (P1, P2, P3)> : public FunctionImpl<t
ypename FunctionWrapper::ResultType ()> { | |
533 public: | |
534 BoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1, const P2& p
2, const P3& p3) | |
535 : m_functionWrapper(functionWrapper) | |
536 , m_p1(ParamStorageTraits<P1>::wrap(p1)) | |
537 , m_p2(ParamStorageTraits<P2>::wrap(p2)) | |
538 , m_p3(ParamStorageTraits<P3>::wrap(p3)) | |
539 { | |
540 RefAndDeref<P1, FunctionWrapper::shouldRefFirstParameter>::ref(m_p1); | |
541 } | |
542 | |
543 ~BoundFunctionImpl() | |
544 { | |
545 RefAndDeref<P1, FunctionWrapper::shouldRefFirstParameter>::deref(m_p1); | |
546 } | |
547 | |
548 virtual typename FunctionWrapper::ResultType operator()() | |
549 { | |
550 return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1), ParamStor
ageTraits<P2>::unwrap(m_p2), ParamStorageTraits<P3>::unwrap(m_p3)); | |
551 } | |
552 | |
553 private: | |
554 FunctionWrapper m_functionWrapper; | |
555 typename ParamStorageTraits<P1>::StorageType m_p1; | |
556 typename ParamStorageTraits<P2>::StorageType m_p2; | |
557 typename ParamStorageTraits<P3>::StorageType m_p3; | |
558 }; | |
559 | |
560 template<typename FunctionWrapper, typename R, typename P1, typename P2, typenam
e P3, typename P4> | |
561 class BoundFunctionImpl<FunctionWrapper, R (P1, P2, P3, P4)> : public FunctionIm
pl<typename FunctionWrapper::ResultType ()> { | |
562 public: | |
563 BoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1, const P2& p
2, const P3& p3, const P4& p4) | |
564 : m_functionWrapper(functionWrapper) | |
565 , m_p1(ParamStorageTraits<P1>::wrap(p1)) | |
566 , m_p2(ParamStorageTraits<P2>::wrap(p2)) | |
567 , m_p3(ParamStorageTraits<P3>::wrap(p3)) | |
568 , m_p4(ParamStorageTraits<P4>::wrap(p4)) | |
569 { | |
570 RefAndDeref<P1, FunctionWrapper::shouldRefFirstParameter>::ref(m_p1); | |
571 } | |
572 | |
573 ~BoundFunctionImpl() | |
574 { | |
575 RefAndDeref<P1, FunctionWrapper::shouldRefFirstParameter>::deref(m_p1); | |
576 } | |
577 | |
578 virtual typename FunctionWrapper::ResultType operator()() | |
579 { | |
580 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)); | |
581 } | |
582 | |
583 private: | |
584 FunctionWrapper m_functionWrapper; | |
585 typename ParamStorageTraits<P1>::StorageType m_p1; | |
586 typename ParamStorageTraits<P2>::StorageType m_p2; | |
587 typename ParamStorageTraits<P3>::StorageType m_p3; | |
588 typename ParamStorageTraits<P4>::StorageType m_p4; | |
589 }; | |
590 | |
591 template<typename FunctionWrapper, typename R, typename P1, typename P2, typenam
e P3, typename P4, typename P5> | |
592 class BoundFunctionImpl<FunctionWrapper, R (P1, P2, P3, P4, P5)> : public Functi
onImpl<typename FunctionWrapper::ResultType ()> { | |
593 public: | |
594 BoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1, const P2& p
2, const P3& p3, const P4& p4, const P5& p5) | |
595 : m_functionWrapper(functionWrapper) | |
596 , m_p1(ParamStorageTraits<P1>::wrap(p1)) | |
597 , m_p2(ParamStorageTraits<P2>::wrap(p2)) | |
598 , m_p3(ParamStorageTraits<P3>::wrap(p3)) | |
599 , m_p4(ParamStorageTraits<P4>::wrap(p4)) | |
600 , m_p5(ParamStorageTraits<P5>::wrap(p5)) | |
601 { | |
602 RefAndDeref<P1, FunctionWrapper::shouldRefFirstParameter>::ref(m_p1); | |
603 } | |
604 | |
605 ~BoundFunctionImpl() | |
606 { | |
607 RefAndDeref<P1, FunctionWrapper::shouldRefFirstParameter>::deref(m_p1); | |
608 } | |
609 | |
610 virtual typename FunctionWrapper::ResultType operator()() | |
611 { | |
612 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)); | |
613 } | |
614 | |
615 private: | |
616 FunctionWrapper m_functionWrapper; | |
617 typename ParamStorageTraits<P1>::StorageType m_p1; | |
618 typename ParamStorageTraits<P2>::StorageType m_p2; | |
619 typename ParamStorageTraits<P3>::StorageType m_p3; | |
620 typename ParamStorageTraits<P4>::StorageType m_p4; | |
621 typename ParamStorageTraits<P5>::StorageType m_p5; | |
622 }; | |
623 | |
624 template<typename FunctionWrapper, typename R, typename P1, typename P2, typenam
e P3, typename P4, typename P5, typename P6> | |
625 class BoundFunctionImpl<FunctionWrapper, R (P1, P2, P3, P4, P5, P6)> : public Fu
nctionImpl<typename FunctionWrapper::ResultType ()> { | |
626 public: | |
627 BoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1, const P2& p
2, const P3& p3, const P4& p4, const P5& p5, const P6& p6) | |
628 : m_functionWrapper(functionWrapper) | |
629 , m_p1(ParamStorageTraits<P1>::wrap(p1)) | |
630 , m_p2(ParamStorageTraits<P2>::wrap(p2)) | |
631 , m_p3(ParamStorageTraits<P3>::wrap(p3)) | |
632 , m_p4(ParamStorageTraits<P4>::wrap(p4)) | |
633 , m_p5(ParamStorageTraits<P5>::wrap(p5)) | |
634 , m_p6(ParamStorageTraits<P6>::wrap(p6)) | |
635 { | |
636 RefAndDeref<P1, FunctionWrapper::shouldRefFirstParameter>::ref(m_p1); | |
637 } | |
638 | |
639 ~BoundFunctionImpl() | |
640 { | |
641 RefAndDeref<P1, FunctionWrapper::shouldRefFirstParameter>::deref(m_p1); | |
642 } | |
643 | |
644 virtual typename FunctionWrapper::ResultType operator()() | |
645 { | |
646 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)); | |
647 } | |
648 | |
649 private: | |
650 FunctionWrapper m_functionWrapper; | |
651 typename ParamStorageTraits<P1>::StorageType m_p1; | |
652 typename ParamStorageTraits<P2>::StorageType m_p2; | |
653 typename ParamStorageTraits<P3>::StorageType m_p3; | |
654 typename ParamStorageTraits<P4>::StorageType m_p4; | |
655 typename ParamStorageTraits<P5>::StorageType m_p5; | |
656 typename ParamStorageTraits<P6>::StorageType m_p6; | |
657 }; | |
658 | |
659 class FunctionBase { | |
660 public: | |
661 bool isNull() const | |
662 { | |
663 return !m_impl; | |
664 } | |
665 | |
666 protected: | |
667 FunctionBase() | |
668 { | |
669 } | |
670 | |
671 explicit FunctionBase(PassRefPtr<FunctionImplBase> impl) | |
672 : m_impl(impl) | |
673 { | |
674 } | |
675 | |
676 template<typename FunctionType> FunctionImpl<FunctionType>* impl() const | |
677 { | |
678 return static_cast<FunctionImpl<FunctionType>*>(m_impl.get()); | |
679 } | |
680 | |
681 private: | |
682 RefPtr<FunctionImplBase> m_impl; | |
683 }; | |
684 | |
685 template<typename> | |
686 class Function; | |
687 | |
688 template<typename R> | |
689 class Function<R ()> : public FunctionBase { | |
690 public: | |
691 Function() | |
692 { | |
693 } | |
694 | |
695 Function(PassRefPtr<FunctionImpl<R ()> > impl) | |
696 : FunctionBase(impl) | |
697 { | |
698 } | |
699 | |
700 R operator()() const | |
701 { | |
702 ASSERT(!isNull()); | |
703 | |
704 return impl<R ()>()->operator()(); | |
705 } | |
706 | |
707 #if OS(DARWIN) && COMPILER_SUPPORTS(BLOCKS) | |
708 typedef void (^BlockType)(); | |
709 operator BlockType() const | |
710 { | |
711 // Declare a RefPtr here so we'll be sure that the underlying FunctionIm
pl object's | |
712 // lifecycle is managed correctly. | |
713 RefPtr<FunctionImpl<R ()> > functionImpl = impl<R ()>(); | |
714 BlockType block = ^{ | |
715 functionImpl->operator()(); | |
716 }; | |
717 | |
718 // This is equivalent to: | |
719 // | |
720 // return [[block copy] autorelease]; | |
721 // | |
722 // We're using manual objc_msgSend calls here because we don't want to m
ake the entire | |
723 // file Objective-C. It's useful to be able to implicitly convert a Func
tion to | |
724 // a block even in C++ code, since that allows us to do things like: | |
725 // | |
726 // dispatch_async(queue, bind(...)); | |
727 // | |
728 id copiedBlock = wtfObjcMsgSend<id>((id)block, sel_registerName("copy"))
; | |
729 id autoreleasedBlock = wtfObjcMsgSend<id>(copiedBlock, sel_registerName(
"autorelease")); | |
730 return (BlockType)autoreleasedBlock; | |
731 } | |
732 #endif | |
733 }; | |
734 | |
735 template<typename FunctionType> | |
736 Function<typename FunctionWrapper<FunctionType>::ResultType ()> bind(FunctionTyp
e function) | |
737 { | |
738 return Function<typename FunctionWrapper<FunctionType>::ResultType ()>(adopt
Ref(new BoundFunctionImpl<FunctionWrapper<FunctionType>, typename FunctionWrappe
r<FunctionType>::ResultType ()>(FunctionWrapper<FunctionType>(function)))); | |
739 } | |
740 | |
741 template<typename FunctionType, typename A1> | |
742 Function<typename FunctionWrapper<FunctionType>::ResultType ()> bind(FunctionTyp
e function, const A1& a1) | |
743 { | |
744 return Function<typename FunctionWrapper<FunctionType>::ResultType ()>(adopt
Ref(new BoundFunctionImpl<FunctionWrapper<FunctionType>, typename FunctionWrappe
r<FunctionType>::ResultType (A1)>(FunctionWrapper<FunctionType>(function), a1)))
; | |
745 } | |
746 | |
747 template<typename FunctionType, typename A1, typename A2> | |
748 Function<typename FunctionWrapper<FunctionType>::ResultType ()> bind(FunctionTyp
e function, const A1& a1, const A2& a2) | |
749 { | |
750 return Function<typename FunctionWrapper<FunctionType>::ResultType ()>(adopt
Ref(new BoundFunctionImpl<FunctionWrapper<FunctionType>, typename FunctionWrappe
r<FunctionType>::ResultType (A1, A2)>(FunctionWrapper<FunctionType>(function), a
1, a2))); | |
751 } | |
752 | |
753 template<typename FunctionType, typename A1, typename A2, typename A3> | |
754 Function<typename FunctionWrapper<FunctionType>::ResultType ()> bind(FunctionTyp
e function, const A1& a1, const A2& a2, const A3& a3) | |
755 { | |
756 return Function<typename FunctionWrapper<FunctionType>::ResultType ()>(adopt
Ref(new BoundFunctionImpl<FunctionWrapper<FunctionType>, typename FunctionWrappe
r<FunctionType>::ResultType (A1, A2, A3)>(FunctionWrapper<FunctionType>(function
), a1, a2, a3))); | |
757 } | |
758 | |
759 template<typename FunctionType, typename A1, typename A2, typename A3, typename
A4> | |
760 Function<typename FunctionWrapper<FunctionType>::ResultType ()> bind(FunctionTyp
e function, const A1& a1, const A2& a2, const A3& a3, const A4& a4) | |
761 { | |
762 return Function<typename FunctionWrapper<FunctionType>::ResultType ()>(adopt
Ref(new BoundFunctionImpl<FunctionWrapper<FunctionType>, typename FunctionWrappe
r<FunctionType>::ResultType (A1, A2, A3, A4)>(FunctionWrapper<FunctionType>(func
tion), a1, a2, a3, a4))); | |
763 } | |
764 | |
765 template<typename FunctionType, typename A1, typename A2, typename A3, typename
A4, typename A5> | |
766 Function<typename FunctionWrapper<FunctionType>::ResultType ()> bind(FunctionTyp
e function, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5
) | |
767 { | |
768 return Function<typename FunctionWrapper<FunctionType>::ResultType ()>(adopt
Ref(new BoundFunctionImpl<FunctionWrapper<FunctionType>, typename FunctionWrappe
r<FunctionType>::ResultType (A1, A2, A3, A4, A5)>(FunctionWrapper<FunctionType>(
function), a1, a2, a3, a4, a5))); | |
769 } | |
770 | |
771 template<typename FunctionType, typename A1, typename A2, typename A3, typename
A4, typename A5, typename A6> | |
772 Function<typename FunctionWrapper<FunctionType>::ResultType ()> bind(FunctionTyp
e function, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5
, const A6& a6) | |
773 { | |
774 return Function<typename FunctionWrapper<FunctionType>::ResultType ()>(adopt
Ref(new BoundFunctionImpl<FunctionWrapper<FunctionType>, typename FunctionWrappe
r<FunctionType>::ResultType (A1, A2, A3, A4, A5, A6)>(FunctionWrapper<FunctionTy
pe>(function), a1, a2, a3, a4, a5, a6))); | |
775 } | |
776 | |
777 } | |
778 | |
779 using WTF::Function; | |
780 using WTF::bind; | |
781 | |
782 #endif // WTF_Functional_h | |
OLD | NEW |