Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / Source / wtf / Functional.h
blob9475043956c77a8f96836a2c080098c858075ad1
1 /*
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
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.
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"
36 namespace WTF {
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.
46 template<typename>
47 class FunctionWrapper;
49 // Bound static functions:
50 template<typename R, typename... Params>
51 class FunctionWrapper<R(*)(Params...)> {
52 public:
53 typedef R ResultType;
55 explicit FunctionWrapper(R(*function)(Params...))
56 : m_function(function)
60 R operator()(Params... params)
62 return m_function(params...);
65 private:
66 R(*m_function)(Params...);
69 // Bound member functions:
71 template<typename R, typename C, typename... Params>
72 class FunctionWrapper<R(C::*)(Params...)> {
73 public:
74 typedef R ResultType;
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)
93 C* obj = c.get();
94 if (!obj)
95 return R();
96 return (obj->*m_function)(params...);
99 private:
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(); }
133 template<typename>
134 class Function;
136 template<typename R, typename... Args>
137 class Function<R(Args...)> {
138 WTF_MAKE_NONCOPYABLE(Function);
139 public:
140 virtual ~Function() { }
141 virtual R operator()(Args... args) = 0;
142 protected:
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...)> {
152 public:
153 PartBoundFunctionImpl(FunctionWrapper functionWrapper)
154 : m_functionWrapper(functionWrapper)
158 typename FunctionWrapper::ResultType operator()(UnboundParams... params) override
160 return m_functionWrapper(params...);
163 private:
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...)> {
169 public:
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...);
181 private:
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...)> {
188 public:
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...);
201 private:
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...)> {
209 public:
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...);
223 private:
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...)> {
232 public:
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...);
247 private:
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...)> {
257 public:
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...);
273 private:
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...)> {
284 public:
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...);
301 private:
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;
323 using WTF::Function;
324 using WTF::bind;
325 using WTF::Closure;
327 #endif // WTF_Functional_h