2 * Copyright (C) 2011 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
26 #ifndef WTF_Functional_h
27 #define WTF_Functional_h
29 #include "wtf/Assertions.h"
30 #include "wtf/PassOwnPtr.h"
31 #include "wtf/PassRefPtr.h"
32 #include "wtf/RefPtr.h"
33 #include "wtf/ThreadSafeRefCounted.h"
34 #include "wtf/WeakPtr.h"
38 // Functional.h provides a very simple way to bind a function pointer and arguments together into a function object
39 // that can be stored, copied and invoked, similar to how boost::bind and std::bind in C++11.
41 // Use threadSafeBind() or createCrossThreadTask() if the function/task is
42 // called on a (potentially) different thread from the current thread.
44 // A FunctionWrapper is a class template that can wrap a function pointer or a member function pointer and
45 // provide a unified interface for calling that function.
47 class FunctionWrapper
;
49 // Bound static functions:
50 template<typename R
, typename
... Params
>
51 class FunctionWrapper
<R(*)(Params
...)> {
55 explicit FunctionWrapper(R(*function
)(Params
...))
56 : m_function(function
)
60 R
operator()(Params
... params
)
62 return m_function(params
...);
66 R(*m_function
)(Params
...);
69 // Bound member functions:
71 template<typename R
, typename C
, typename
... Params
>
72 class FunctionWrapper
<R(C::*)(Params
...)> {
76 explicit FunctionWrapper(R(C::*function
)(Params
...))
77 : m_function(function
)
81 R
operator()(C
* c
, Params
... params
)
83 return (c
->*m_function
)(params
...);
86 R
operator()(PassOwnPtr
<C
> c
, Params
... params
)
88 return (c
.get()->*m_function
)(params
...);
91 R
operator()(const WeakPtr
<C
>& c
, Params
... params
)
96 return (obj
->*m_function
)(params
...);
100 R(C::*m_function
)(Params
...);
103 template<typename T
> struct ParamStorageTraits
{
104 typedef T StorageType
;
106 static StorageType
wrap(const T
& value
) { return value
; }
107 static const T
& unwrap(const StorageType
& value
) { return value
; }
110 template<typename T
> struct ParamStorageTraits
<PassRefPtr
<T
>> {
111 typedef RefPtr
<T
> StorageType
;
113 static StorageType
wrap(PassRefPtr
<T
> value
) { return value
; }
114 static T
* unwrap(const StorageType
& value
) { return value
.get(); }
117 template<typename T
> struct ParamStorageTraits
<RefPtr
<T
>> {
118 typedef RefPtr
<T
> StorageType
;
120 static StorageType
wrap(RefPtr
<T
> value
) { return value
.release(); }
121 static T
* unwrap(const StorageType
& value
) { return value
.get(); }
124 template<typename
> class RetainPtr
;
126 template<typename T
> struct ParamStorageTraits
<RetainPtr
<T
>> {
127 typedef RetainPtr
<T
> StorageType
;
129 static StorageType
wrap(const RetainPtr
<T
>& value
) { return value
; }
130 static typename RetainPtr
<T
>::PtrType
unwrap(const StorageType
& value
) { return value
.get(); }
136 template<typename R
, typename
... Args
>
137 class Function
<R(Args
...)> {
138 WTF_MAKE_NONCOPYABLE(Function
);
140 virtual ~Function() { }
141 virtual R
operator()(Args
... args
) = 0;
143 Function() = default;
146 template<int boundArgsCount
, typename FunctionWrapper
, typename FunctionType
>
147 class PartBoundFunctionImpl
;
149 // Specialization for unbound functions.
150 template<typename FunctionWrapper
, typename R
, typename
... UnboundParams
>
151 class PartBoundFunctionImpl
<0, FunctionWrapper
, R(UnboundParams
...)> final
: public Function
<typename
FunctionWrapper::ResultType(UnboundParams
...)> {
153 PartBoundFunctionImpl(FunctionWrapper functionWrapper
)
154 : m_functionWrapper(functionWrapper
)
158 typename
FunctionWrapper::ResultType
operator()(UnboundParams
... params
) override
160 return m_functionWrapper(params
...);
164 FunctionWrapper m_functionWrapper
;
167 template<typename FunctionWrapper
, typename R
, typename P1
, typename
... UnboundParams
>
168 class PartBoundFunctionImpl
<1, FunctionWrapper
, R(P1
, UnboundParams
...)> final
: public Function
<typename
FunctionWrapper::ResultType(UnboundParams
...)> {
170 PartBoundFunctionImpl(FunctionWrapper functionWrapper
, const P1
& p1
)
171 : m_functionWrapper(functionWrapper
)
172 , m_p1(ParamStorageTraits
<P1
>::wrap(p1
))
176 typename
FunctionWrapper::ResultType
operator()(UnboundParams
... params
) override
178 return m_functionWrapper(ParamStorageTraits
<P1
>::unwrap(m_p1
), params
...);
182 FunctionWrapper m_functionWrapper
;
183 typename ParamStorageTraits
<P1
>::StorageType m_p1
;
186 template<typename FunctionWrapper
, typename R
, typename P1
, typename P2
, typename
... UnboundParams
>
187 class PartBoundFunctionImpl
<2, FunctionWrapper
, R(P1
, P2
, UnboundParams
...)> final
: public Function
<typename
FunctionWrapper::ResultType(UnboundParams
...)> {
189 PartBoundFunctionImpl(FunctionWrapper functionWrapper
, const P1
& p1
, const P2
& p2
)
190 : m_functionWrapper(functionWrapper
)
191 , m_p1(ParamStorageTraits
<P1
>::wrap(p1
))
192 , m_p2(ParamStorageTraits
<P2
>::wrap(p2
))
196 typename
FunctionWrapper::ResultType
operator()(UnboundParams
... params
) override
198 return m_functionWrapper(ParamStorageTraits
<P1
>::unwrap(m_p1
), ParamStorageTraits
<P2
>::unwrap(m_p2
), params
...);
202 FunctionWrapper m_functionWrapper
;
203 typename ParamStorageTraits
<P1
>::StorageType m_p1
;
204 typename ParamStorageTraits
<P2
>::StorageType m_p2
;
207 template<typename FunctionWrapper
, typename R
, typename P1
, typename P2
, typename P3
, typename
... UnboundParams
>
208 class PartBoundFunctionImpl
<3, FunctionWrapper
, R(P1
, P2
, P3
, UnboundParams
...)> final
: public Function
<typename
FunctionWrapper::ResultType(UnboundParams
...)> {
210 PartBoundFunctionImpl(FunctionWrapper functionWrapper
, const P1
& p1
, const P2
& p2
, const P3
& p3
)
211 : m_functionWrapper(functionWrapper
)
212 , m_p1(ParamStorageTraits
<P1
>::wrap(p1
))
213 , m_p2(ParamStorageTraits
<P2
>::wrap(p2
))
214 , m_p3(ParamStorageTraits
<P3
>::wrap(p3
))
218 typename
FunctionWrapper::ResultType
operator()(UnboundParams
... params
) override
220 return m_functionWrapper(ParamStorageTraits
<P1
>::unwrap(m_p1
), ParamStorageTraits
<P2
>::unwrap(m_p2
), ParamStorageTraits
<P3
>::unwrap(m_p3
), params
...);
224 FunctionWrapper m_functionWrapper
;
225 typename ParamStorageTraits
<P1
>::StorageType m_p1
;
226 typename ParamStorageTraits
<P2
>::StorageType m_p2
;
227 typename ParamStorageTraits
<P3
>::StorageType m_p3
;
230 template<typename FunctionWrapper
, typename R
, typename P1
, typename P2
, typename P3
, typename P4
, typename
... UnboundParams
>
231 class PartBoundFunctionImpl
<4, FunctionWrapper
, R(P1
, P2
, P3
, P4
, UnboundParams
...)> final
: public Function
<typename
FunctionWrapper::ResultType(UnboundParams
...)> {
233 PartBoundFunctionImpl(FunctionWrapper functionWrapper
, const P1
& p1
, const P2
& p2
, const P3
& p3
, const P4
& p4
)
234 : m_functionWrapper(functionWrapper
)
235 , m_p1(ParamStorageTraits
<P1
>::wrap(p1
))
236 , m_p2(ParamStorageTraits
<P2
>::wrap(p2
))
237 , m_p3(ParamStorageTraits
<P3
>::wrap(p3
))
238 , m_p4(ParamStorageTraits
<P4
>::wrap(p4
))
242 typename
FunctionWrapper::ResultType
operator()(UnboundParams
... params
) override
244 return m_functionWrapper(ParamStorageTraits
<P1
>::unwrap(m_p1
), ParamStorageTraits
<P2
>::unwrap(m_p2
), ParamStorageTraits
<P3
>::unwrap(m_p3
), ParamStorageTraits
<P4
>::unwrap(m_p4
), params
...);
248 FunctionWrapper m_functionWrapper
;
249 typename ParamStorageTraits
<P1
>::StorageType m_p1
;
250 typename ParamStorageTraits
<P2
>::StorageType m_p2
;
251 typename ParamStorageTraits
<P3
>::StorageType m_p3
;
252 typename ParamStorageTraits
<P4
>::StorageType m_p4
;
255 template<typename FunctionWrapper
, typename R
, typename P1
, typename P2
, typename P3
, typename P4
, typename P5
, typename
... UnboundParams
>
256 class PartBoundFunctionImpl
<5, FunctionWrapper
, R(P1
, P2
, P3
, P4
, P5
, UnboundParams
...)> final
: public Function
<typename
FunctionWrapper::ResultType(UnboundParams
...)> {
258 PartBoundFunctionImpl(FunctionWrapper functionWrapper
, const P1
& p1
, const P2
& p2
, const P3
& p3
, const P4
& p4
, const P5
& p5
)
259 : m_functionWrapper(functionWrapper
)
260 , m_p1(ParamStorageTraits
<P1
>::wrap(p1
))
261 , m_p2(ParamStorageTraits
<P2
>::wrap(p2
))
262 , m_p3(ParamStorageTraits
<P3
>::wrap(p3
))
263 , m_p4(ParamStorageTraits
<P4
>::wrap(p4
))
264 , m_p5(ParamStorageTraits
<P5
>::wrap(p5
))
268 typename
FunctionWrapper::ResultType
operator()(UnboundParams
... params
) override
270 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
), params
...);
274 FunctionWrapper m_functionWrapper
;
275 typename ParamStorageTraits
<P1
>::StorageType m_p1
;
276 typename ParamStorageTraits
<P2
>::StorageType m_p2
;
277 typename ParamStorageTraits
<P3
>::StorageType m_p3
;
278 typename ParamStorageTraits
<P4
>::StorageType m_p4
;
279 typename ParamStorageTraits
<P5
>::StorageType m_p5
;
282 template<typename FunctionWrapper
, typename R
, typename P1
, typename P2
, typename P3
, typename P4
, typename P5
, typename P6
, typename
... UnboundParams
>
283 class PartBoundFunctionImpl
<6, FunctionWrapper
, R(P1
, P2
, P3
, P4
, P5
, P6
, UnboundParams
...)> final
: public Function
<typename
FunctionWrapper::ResultType(UnboundParams
...)> {
285 PartBoundFunctionImpl(FunctionWrapper functionWrapper
, const P1
& p1
, const P2
& p2
, const P3
& p3
, const P4
& p4
, const P5
& p5
, const P6
& p6
)
286 : m_functionWrapper(functionWrapper
)
287 , m_p1(ParamStorageTraits
<P1
>::wrap(p1
))
288 , m_p2(ParamStorageTraits
<P2
>::wrap(p2
))
289 , m_p3(ParamStorageTraits
<P3
>::wrap(p3
))
290 , m_p4(ParamStorageTraits
<P4
>::wrap(p4
))
291 , m_p5(ParamStorageTraits
<P5
>::wrap(p5
))
292 , m_p6(ParamStorageTraits
<P6
>::wrap(p6
))
296 typename
FunctionWrapper::ResultType
operator()(UnboundParams
... params
) override
298 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
), params
...);
302 FunctionWrapper m_functionWrapper
;
303 typename ParamStorageTraits
<P1
>::StorageType m_p1
;
304 typename ParamStorageTraits
<P2
>::StorageType m_p2
;
305 typename ParamStorageTraits
<P3
>::StorageType m_p3
;
306 typename ParamStorageTraits
<P4
>::StorageType m_p4
;
307 typename ParamStorageTraits
<P5
>::StorageType m_p5
;
308 typename ParamStorageTraits
<P6
>::StorageType m_p6
;
311 template<typename
... UnboundArgs
, typename FunctionType
, typename
... BoundArgs
>
312 PassOwnPtr
<Function
<typename FunctionWrapper
<FunctionType
>::ResultType(UnboundArgs
...)>> bind(FunctionType function
, const BoundArgs
&... boundArgs
)
314 const int boundArgsCount
= sizeof...(BoundArgs
);
315 using BoundFunctionType
= PartBoundFunctionImpl
<boundArgsCount
, FunctionWrapper
<FunctionType
>, typename FunctionWrapper
<FunctionType
>::ResultType(BoundArgs
..., UnboundArgs
...)>;
316 return adoptPtr(new BoundFunctionType(FunctionWrapper
<FunctionType
>(function
), boundArgs
...));
319 typedef Function
<void()> Closure
;
327 #endif // WTF_Functional_h