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/PassRefPtr.h"
31 #include "wtf/RefPtr.h"
32 #include "wtf/ThreadSafeRefCounted.h"
33 #include "wtf/WeakPtr.h"
37 // Functional.h provides a very simple way to bind a function pointer and arguments together into a function object
38 // that can be stored, copied and invoked, similar to how boost::bind and std::bind in C++11.
40 // A FunctionWrapper is a class template that can wrap a function pointer or a member function pointer and
41 // provide a unified interface for calling that function.
43 class FunctionWrapper;
45 // Bound static functions:
46 template<typename R, typename... P>
47 class FunctionWrapper<R(*)(P...)> {
51 explicit FunctionWrapper(R(*function)(P...))
52 : m_function(function)
56 R operator()(P... params)
58 return m_function(params...);
65 // Bound member functions:
67 template<typename R, typename C, typename... P>
68 class FunctionWrapper<R(C::*)(P...)> {
72 explicit FunctionWrapper(R(C::*function)(P...))
73 : m_function(function)
77 R operator()(C* c, P... params)
79 return (c->*m_function)(params...);
82 R operator()(const WeakPtr<C>& c, P... params)
87 return (obj->*m_function)(params...);
91 R(C::*m_function)(P...);
94 template<typename T> struct ParamStorageTraits {
95 typedef T StorageType;
97 static StorageType wrap(const T& value) { return value; }
98 static const T& unwrap(const StorageType& value) { return value; }
101 template<typename T> struct ParamStorageTraits<PassRefPtr<T> > {
102 typedef RefPtr<T> StorageType;
104 static StorageType wrap(PassRefPtr<T> value) { return value; }
105 static T* unwrap(const StorageType& value) { return value.get(); }
108 template<typename T> struct ParamStorageTraits<RefPtr<T> > {
109 typedef RefPtr<T> StorageType;
111 static StorageType wrap(RefPtr<T> value) { return value.release(); }
112 static T* unwrap(const StorageType& value) { return value.get(); }
115 template<typename> class RetainPtr;
117 template<typename T> struct ParamStorageTraits<RetainPtr<T> > {
118 typedef RetainPtr<T> StorageType;
120 static StorageType wrap(const RetainPtr<T>& value) { return value; }
121 static typename RetainPtr<T>::PtrType unwrap(const StorageType& value) { return value.get(); }
124 class FunctionImplBase : public ThreadSafeRefCounted<FunctionImplBase> {
126 virtual ~FunctionImplBase() { }
132 template<typename R, typename... A>
133 class FunctionImpl<R(A...)> : public FunctionImplBase {
135 virtual R operator()(A... args) = 0;
138 template<int boundArgsCount, typename FunctionWrapper, typename FunctionType>
139 class PartBoundFunctionImpl;
141 // Specialization for unbound functions.
142 template<typename FunctionWrapper, typename R, typename... P>
143 class PartBoundFunctionImpl<0, FunctionWrapper, R(P...)> final : public FunctionImpl<typename FunctionWrapper::ResultType(P...)> {
145 PartBoundFunctionImpl(FunctionWrapper functionWrapper)
146 : m_functionWrapper(functionWrapper)
150 virtual typename FunctionWrapper::ResultType operator()(P... params) override
152 return m_functionWrapper(params...);
156 FunctionWrapper m_functionWrapper;
159 template<typename FunctionWrapper, typename R, typename P1, typename... P>
160 class PartBoundFunctionImpl<1, FunctionWrapper, R(P1, P...)> final : public FunctionImpl<typename FunctionWrapper::ResultType(P...)> {
162 PartBoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1)
163 : m_functionWrapper(functionWrapper)
164 , m_p1(ParamStorageTraits<P1>::wrap(p1))
168 virtual typename FunctionWrapper::ResultType operator()(P... params) override
170 return m_functionWrapper(m_p1, params...);
174 FunctionWrapper m_functionWrapper;
175 typename ParamStorageTraits<P1>::StorageType m_p1;
178 template<typename FunctionWrapper, typename R, typename P1, typename P2, typename... P>
179 class PartBoundFunctionImpl<2, FunctionWrapper, R(P1, P2, P...)> final : public FunctionImpl<typename FunctionWrapper::ResultType(P...)> {
181 PartBoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1, const P2& p2)
182 : m_functionWrapper(functionWrapper)
183 , m_p1(ParamStorageTraits<P1>::wrap(p1))
184 , m_p2(ParamStorageTraits<P2>::wrap(p2))
188 virtual typename FunctionWrapper::ResultType operator()(P... params) override
190 return m_functionWrapper(m_p1, m_p2, params...);
194 FunctionWrapper m_functionWrapper;
195 typename ParamStorageTraits<P1>::StorageType m_p1;
196 typename ParamStorageTraits<P2>::StorageType m_p2;
199 template<typename FunctionWrapper, typename R, typename P1, typename P2, typename P3, typename... P>
200 class PartBoundFunctionImpl<3, FunctionWrapper, R(P1, P2, P3, P...)> final : public FunctionImpl<typename FunctionWrapper::ResultType(P...)> {
202 PartBoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1, const P2& p2, const P3& p3)
203 : m_functionWrapper(functionWrapper)
204 , m_p1(ParamStorageTraits<P1>::wrap(p1))
205 , m_p2(ParamStorageTraits<P2>::wrap(p2))
206 , m_p3(ParamStorageTraits<P3>::wrap(p3))
210 virtual typename FunctionWrapper::ResultType operator()(P... params) override
212 return m_functionWrapper(m_p1, m_p2, m_p3, params...);
216 FunctionWrapper m_functionWrapper;
217 typename ParamStorageTraits<P1>::StorageType m_p1;
218 typename ParamStorageTraits<P2>::StorageType m_p2;
219 typename ParamStorageTraits<P3>::StorageType m_p3;
222 template<typename FunctionWrapper, typename R, typename P1, typename P2, typename P3, typename P4, typename... P>
223 class PartBoundFunctionImpl<4, FunctionWrapper, R(P1, P2, P3, P4, P...)> final : public FunctionImpl<typename FunctionWrapper::ResultType(P...)> {
225 PartBoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1, const P2& p2, const P3& p3, const P4& p4)
226 : m_functionWrapper(functionWrapper)
227 , m_p1(ParamStorageTraits<P1>::wrap(p1))
228 , m_p2(ParamStorageTraits<P2>::wrap(p2))
229 , m_p3(ParamStorageTraits<P3>::wrap(p3))
230 , m_p4(ParamStorageTraits<P4>::wrap(p4))
234 virtual typename FunctionWrapper::ResultType operator()(P... params) override
236 return m_functionWrapper(m_p1, m_p2, m_p3, m_p4, params...);
240 FunctionWrapper m_functionWrapper;
241 typename ParamStorageTraits<P1>::StorageType m_p1;
242 typename ParamStorageTraits<P2>::StorageType m_p2;
243 typename ParamStorageTraits<P3>::StorageType m_p3;
244 typename ParamStorageTraits<P4>::StorageType m_p4;
247 template<typename FunctionWrapper, typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename... P>
248 class PartBoundFunctionImpl<5, FunctionWrapper, R(P1, P2, P3, P4, P5, P...)> final : public FunctionImpl<typename FunctionWrapper::ResultType(P...)> {
250 PartBoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5)
251 : m_functionWrapper(functionWrapper)
252 , m_p1(ParamStorageTraits<P1>::wrap(p1))
253 , m_p2(ParamStorageTraits<P2>::wrap(p2))
254 , m_p3(ParamStorageTraits<P3>::wrap(p3))
255 , m_p4(ParamStorageTraits<P4>::wrap(p4))
256 , m_p5(ParamStorageTraits<P5>::wrap(p5))
260 virtual typename FunctionWrapper::ResultType operator()(P... params) override
262 return m_functionWrapper(m_p1, m_p2, m_p3, m_p4, m_p5, params...);
266 FunctionWrapper m_functionWrapper;
267 typename ParamStorageTraits<P1>::StorageType m_p1;
268 typename ParamStorageTraits<P2>::StorageType m_p2;
269 typename ParamStorageTraits<P3>::StorageType m_p3;
270 typename ParamStorageTraits<P4>::StorageType m_p4;
271 typename ParamStorageTraits<P5>::StorageType m_p5;
274 template<typename FunctionWrapper, typename FunctionType>
275 class BoundFunctionImpl;
277 template<typename FunctionWrapper, typename R>
278 class BoundFunctionImpl<FunctionWrapper, R()> final : public FunctionImpl<typename FunctionWrapper::ResultType()> {
280 explicit BoundFunctionImpl(FunctionWrapper functionWrapper)
281 : m_functionWrapper(functionWrapper)
285 virtual typename FunctionWrapper::ResultType operator()() override
287 return m_functionWrapper();
291 FunctionWrapper m_functionWrapper;
294 template<typename FunctionWrapper, typename R, typename P1>
295 class BoundFunctionImpl<FunctionWrapper, R(P1)> final : public FunctionImpl<typename FunctionWrapper::ResultType()> {
297 BoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1)
298 : m_functionWrapper(functionWrapper)
299 , m_p1(ParamStorageTraits<P1>::wrap(p1))
303 virtual typename FunctionWrapper::ResultType operator()() override
305 return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1));
309 FunctionWrapper m_functionWrapper;
310 typename ParamStorageTraits<P1>::StorageType m_p1;
313 template<typename FunctionWrapper, typename R, typename P1, typename P2>
314 class BoundFunctionImpl<FunctionWrapper, R(P1, P2)> final : public FunctionImpl<typename FunctionWrapper::ResultType()> {
316 BoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1, const P2& p2)
317 : m_functionWrapper(functionWrapper)
318 , m_p1(ParamStorageTraits<P1>::wrap(p1))
319 , m_p2(ParamStorageTraits<P2>::wrap(p2))
323 virtual typename FunctionWrapper::ResultType operator()() override
325 return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1), ParamStorageTraits<P2>::unwrap(m_p2));
329 FunctionWrapper m_functionWrapper;
330 typename ParamStorageTraits<P1>::StorageType m_p1;
331 typename ParamStorageTraits<P2>::StorageType m_p2;
334 template<typename FunctionWrapper, typename R, typename P1, typename P2, typename P3>
335 class BoundFunctionImpl<FunctionWrapper, R(P1, P2, P3)> final : public FunctionImpl<typename FunctionWrapper::ResultType()> {
337 BoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1, const P2& p2, const P3& p3)
338 : m_functionWrapper(functionWrapper)
339 , m_p1(ParamStorageTraits<P1>::wrap(p1))
340 , m_p2(ParamStorageTraits<P2>::wrap(p2))
341 , m_p3(ParamStorageTraits<P3>::wrap(p3))
345 virtual typename FunctionWrapper::ResultType operator()() override
347 return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1), ParamStorageTraits<P2>::unwrap(m_p2), ParamStorageTraits<P3>::unwrap(m_p3));
351 FunctionWrapper m_functionWrapper;
352 typename ParamStorageTraits<P1>::StorageType m_p1;
353 typename ParamStorageTraits<P2>::StorageType m_p2;
354 typename ParamStorageTraits<P3>::StorageType m_p3;
357 template<typename FunctionWrapper, typename R, typename P1, typename P2, typename P3, typename P4>
358 class BoundFunctionImpl<FunctionWrapper, R(P1, P2, P3, P4)> final : public FunctionImpl<typename FunctionWrapper::ResultType()> {
360 BoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1, const P2& p2, const P3& p3, const P4& p4)
361 : m_functionWrapper(functionWrapper)
362 , m_p1(ParamStorageTraits<P1>::wrap(p1))
363 , m_p2(ParamStorageTraits<P2>::wrap(p2))
364 , m_p3(ParamStorageTraits<P3>::wrap(p3))
365 , m_p4(ParamStorageTraits<P4>::wrap(p4))
369 virtual typename FunctionWrapper::ResultType operator()() override
371 return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1), ParamStorageTraits<P2>::unwrap(m_p2), ParamStorageTraits<P3>::unwrap(m_p3), ParamStorageTraits<P4>::unwrap(m_p4));
375 FunctionWrapper m_functionWrapper;
376 typename ParamStorageTraits<P1>::StorageType m_p1;
377 typename ParamStorageTraits<P2>::StorageType m_p2;
378 typename ParamStorageTraits<P3>::StorageType m_p3;
379 typename ParamStorageTraits<P4>::StorageType m_p4;
382 template<typename FunctionWrapper, typename R, typename P1, typename P2, typename P3, typename P4, typename P5>
383 class BoundFunctionImpl<FunctionWrapper, R(P1, P2, P3, P4, P5)> final : public FunctionImpl<typename FunctionWrapper::ResultType()> {
385 BoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5)
386 : m_functionWrapper(functionWrapper)
387 , m_p1(ParamStorageTraits<P1>::wrap(p1))
388 , m_p2(ParamStorageTraits<P2>::wrap(p2))
389 , m_p3(ParamStorageTraits<P3>::wrap(p3))
390 , m_p4(ParamStorageTraits<P4>::wrap(p4))
391 , m_p5(ParamStorageTraits<P5>::wrap(p5))
395 virtual typename FunctionWrapper::ResultType operator()() override
397 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));
401 FunctionWrapper m_functionWrapper;
402 typename ParamStorageTraits<P1>::StorageType m_p1;
403 typename ParamStorageTraits<P2>::StorageType m_p2;
404 typename ParamStorageTraits<P3>::StorageType m_p3;
405 typename ParamStorageTraits<P4>::StorageType m_p4;
406 typename ParamStorageTraits<P5>::StorageType m_p5;
409 template<typename FunctionWrapper, typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
410 class BoundFunctionImpl<FunctionWrapper, R(P1, P2, P3, P4, P5, P6)> final : public FunctionImpl<typename FunctionWrapper::ResultType()> {
412 BoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5, const P6& p6)
413 : m_functionWrapper(functionWrapper)
414 , m_p1(ParamStorageTraits<P1>::wrap(p1))
415 , m_p2(ParamStorageTraits<P2>::wrap(p2))
416 , m_p3(ParamStorageTraits<P3>::wrap(p3))
417 , m_p4(ParamStorageTraits<P4>::wrap(p4))
418 , m_p5(ParamStorageTraits<P5>::wrap(p5))
419 , m_p6(ParamStorageTraits<P6>::wrap(p6))
423 virtual typename FunctionWrapper::ResultType operator()() override
425 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));
429 FunctionWrapper m_functionWrapper;
430 typename ParamStorageTraits<P1>::StorageType m_p1;
431 typename ParamStorageTraits<P2>::StorageType m_p2;
432 typename ParamStorageTraits<P3>::StorageType m_p3;
433 typename ParamStorageTraits<P4>::StorageType m_p4;
434 typename ParamStorageTraits<P5>::StorageType m_p5;
435 typename ParamStorageTraits<P6>::StorageType m_p6;
450 explicit FunctionBase(PassRefPtr<FunctionImplBase> impl)
455 template<typename FunctionType> FunctionImpl<FunctionType>* impl() const
457 return static_cast<FunctionImpl<FunctionType>*>(m_impl.get());
461 RefPtr<FunctionImplBase> m_impl;
467 template<typename R, typename... A>
468 class Function<R(A...)> : public FunctionBase {
474 Function(PassRefPtr<FunctionImpl<R(A...)>> impl)
479 R operator()(A... args) const
482 return impl<R(A...)>()->operator()(args...);
486 template<typename FunctionType, typename... A>
487 Function<typename FunctionWrapper<FunctionType>::ResultType()> bind(FunctionType function, const A... args)
489 return Function<typename FunctionWrapper<FunctionType>::ResultType()>(adoptRef(new BoundFunctionImpl<FunctionWrapper<FunctionType>, typename FunctionWrapper<FunctionType>::ResultType (A...)>(FunctionWrapper<FunctionType>(function), args...)));
492 // Partial parameter binding.
494 template<typename A1, typename FunctionType, typename... A>
495 Function<typename FunctionWrapper<FunctionType>::ResultType(A1)> bind(FunctionType function, const A&... args)
497 const int boundArgsCount = sizeof...(A);
498 return Function<typename FunctionWrapper<FunctionType>::ResultType(A1)>(adoptRef(new PartBoundFunctionImpl<boundArgsCount, FunctionWrapper<FunctionType>, typename FunctionWrapper<FunctionType>::ResultType (A..., A1)>(FunctionWrapper<FunctionType>(function), args...)));
501 template<typename A1, typename A2, typename FunctionType, typename... A>
502 Function<typename FunctionWrapper<FunctionType>::ResultType(A1, A2)> bind(FunctionType function, const A&... args)
504 const int boundArgsCount = sizeof...(A);
505 return Function<typename FunctionWrapper<FunctionType>::ResultType(A1, A2)>(adoptRef(new PartBoundFunctionImpl<boundArgsCount, FunctionWrapper<FunctionType>, typename FunctionWrapper<FunctionType>::ResultType (A..., A1, A2)>(FunctionWrapper<FunctionType>(function), args...)));
508 template<typename A1, typename A2, typename A3, typename FunctionType, typename... A>
509 Function<typename FunctionWrapper<FunctionType>::ResultType(A1, A2, A3)> bind(FunctionType function, const A&... args)
511 const int boundArgsCount = sizeof...(A);
512 return Function<typename FunctionWrapper<FunctionType>::ResultType(A1, A2, A3)>(adoptRef(new PartBoundFunctionImpl<boundArgsCount, FunctionWrapper<FunctionType>, typename FunctionWrapper<FunctionType>::ResultType (A..., A1, A2, A3)>(FunctionWrapper<FunctionType>(function), args...)));
515 template<typename A1, typename A2, typename A3, typename A4, typename FunctionType, typename... A>
516 Function<typename FunctionWrapper<FunctionType>::ResultType(A1, A2, A3, A4)> bind(FunctionType function, const A&... args)
518 const int boundArgsCount = sizeof...(A);
519 return Function<typename FunctionWrapper<FunctionType>::ResultType(A1, A2, A3, A4)>(adoptRef(new PartBoundFunctionImpl<boundArgsCount, FunctionWrapper<FunctionType>, typename FunctionWrapper<FunctionType>::ResultType (A..., A1, A2, A3, A4)>(FunctionWrapper<FunctionType>(function), args...)));
522 template<typename A1, typename A2, typename A3, typename A4, typename A5, typename FunctionType, typename... A>
523 Function<typename FunctionWrapper<FunctionType>::ResultType(A1, A2, A3, A4, A5)> bind(FunctionType function, const A&... args)
525 const int boundArgsCount = sizeof...(A);
526 return Function<typename FunctionWrapper<FunctionType>::ResultType(A1, A2, A3, A4, A5)>(adoptRef(new PartBoundFunctionImpl<boundArgsCount, FunctionWrapper<FunctionType>, typename FunctionWrapper<FunctionType>::ResultType (A..., A1, A2, A3, A4, A5)>(FunctionWrapper<FunctionType>(function), args...)));
529 template<typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename FunctionType, typename... A>
530 Function<typename FunctionWrapper<FunctionType>::ResultType(A1, A2, A3, A4, A5, A6)> bind(FunctionType function, const A&... args)
532 const int boundArgsCount = sizeof...(A);
533 return Function<typename FunctionWrapper<FunctionType>::ResultType(A1, A2, A3, A4, A5, A6)>(adoptRef(new PartBoundFunctionImpl<boundArgsCount, FunctionWrapper<FunctionType>, typename FunctionWrapper<FunctionType>::ResultType (A..., A1, A2, A3, A4, A5, A6)>(FunctionWrapper<FunctionType>(function), args...)));
536 typedef Function<void()> Closure;
544 #endif // WTF_Functional_h