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

Side by Side Diff: Source/WTF/wtf/Functional.h

Issue 14238015: Move Source/WTF/wtf to Source/wtf (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 8 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 | Annotate | Revision Log
OLDNEW
(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
OLDNEW
« no previous file with comments | « Source/WTF/wtf/Forward.h ('k') | Source/WTF/wtf/GetPtr.h » ('j') | Source/config.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698