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