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 35namespace WTF { 36 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. 39 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. 42template<typename> 43class FunctionWrapper; 44 45// Bound static functions: 46 47template<typename R> 48class FunctionWrapper<R (*)()> { 49public: 50 typedef R ResultType; 51 52 explicit FunctionWrapper(R (*function)()) 53 : m_function(function) 54 { 55 } 56 57 R operator()() 58 { 59 return m_function(); 60 } 61 62private: 63 R (*m_function)(); 64}; 65 66template<typename R, typename P1> 67class FunctionWrapper<R (*)(P1)> { 68public: 69 typedef R ResultType; 70 71 explicit FunctionWrapper(R (*function)(P1)) 72 : m_function(function) 73 { 74 } 75 76 R operator()(P1 p1) 77 { 78 return m_function(p1); 79 } 80 81private: 82 R (*m_function)(P1); 83}; 84 85template<typename R, typename P1, typename P2> 86class FunctionWrapper<R (*)(P1, P2)> { 87public: 88 typedef R ResultType; 89 90 explicit FunctionWrapper(R (*function)(P1, P2)) 91 : m_function(function) 92 { 93 } 94 95 R operator()(P1 p1, P2 p2) 96 { 97 return m_function(p1, p2); 98 } 99 100private: 101 R (*m_function)(P1, P2); 102}; 103 104template<typename R, typename P1, typename P2, typename P3> 105class FunctionWrapper<R (*)(P1, P2, P3)> { 106public: 107 typedef R ResultType; 108 109 explicit FunctionWrapper(R (*function)(P1, P2, P3)) 110 : m_function(function) 111 { 112 } 113 114 R operator()(P1 p1, P2 p2, P3 p3) 115 { 116 return m_function(p1, p2, p3); 117 } 118 119private: 120 R (*m_function)(P1, P2, P3); 121}; 122 123template<typename R, typename P1, typename P2, typename P3, typename P4> 124class FunctionWrapper<R (*)(P1, P2, P3, P4)> { 125public: 126 typedef R ResultType; 127 128 explicit FunctionWrapper(R (*function)(P1, P2, P3, P4)) 129 : m_function(function) 130 { 131 } 132 133 R operator()(P1 p1, P2 p2, P3 p3, P4 p4) 134 { 135 return m_function(p1, p2, p3, p4); 136 } 137 138private: 139 R (*m_function)(P1, P2, P3, P4); 140}; 141 142template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5> 143class FunctionWrapper<R (*)(P1, P2, P3, P4, P5)> { 144public: 145 typedef R ResultType; 146 147 explicit FunctionWrapper(R (*function)(P1, P2, P3, P4, P5)) 148 : m_function(function) 149 { 150 } 151 152 R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) 153 { 154 return m_function(p1, p2, p3, p4, p5); 155 } 156 157private: 158 R (*m_function)(P1, P2, P3, P4, P5); 159}; 160 161// Bound member functions: 162 163template<typename R, typename C> 164class FunctionWrapper<R (C::*)()> { 165public: 166 typedef R ResultType; 167 168 explicit FunctionWrapper(R (C::*function)()) 169 : m_function(function) 170 { 171 } 172 173 R operator()(C* c) 174 { 175 return (c->*m_function)(); 176 } 177 178 R operator()(const WeakPtr<C>& c) 179 { 180 C* obj = c.get(); 181 if (!obj) 182 return R(); 183 return (obj->*m_function)(); 184 } 185 186private: 187 R (C::*m_function)(); 188}; 189 190template<typename R, typename C, typename P1> 191class FunctionWrapper<R (C::*)(P1)> { 192public: 193 typedef R ResultType; 194 195 explicit FunctionWrapper(R (C::*function)(P1)) 196 : m_function(function) 197 { 198 } 199 200 R operator()(C* c, P1 p1) 201 { 202 return (c->*m_function)(p1); 203 } 204 205 R operator()(const WeakPtr<C>& c, P1 p1) 206 { 207 C* obj = c.get(); 208 if (!obj) 209 return R(); 210 return (obj->*m_function)(p1); 211 } 212 213private: 214 R (C::*m_function)(P1); 215}; 216 217template<typename R, typename C, typename P1, typename P2> 218class FunctionWrapper<R (C::*)(P1, P2)> { 219public: 220 typedef R ResultType; 221 222 explicit FunctionWrapper(R (C::*function)(P1, P2)) 223 : m_function(function) 224 { 225 } 226 227 R operator()(C* c, P1 p1, P2 p2) 228 { 229 return (c->*m_function)(p1, p2); 230 } 231 232 R operator()(const WeakPtr<C>& c, P1 p1, P2 p2) 233 { 234 C* obj = c.get(); 235 if (!obj) 236 return R(); 237 return (obj->*m_function)(p1, p2); 238 } 239 240private: 241 R (C::*m_function)(P1, P2); 242}; 243 244template<typename R, typename C, typename P1, typename P2, typename P3> 245class FunctionWrapper<R (C::*)(P1, P2, P3)> { 246public: 247 typedef R ResultType; 248 249 explicit FunctionWrapper(R (C::*function)(P1, P2, P3)) 250 : m_function(function) 251 { 252 } 253 254 R operator()(C* c, P1 p1, P2 p2, P3 p3) 255 { 256 return (c->*m_function)(p1, p2, p3); 257 } 258 259 R operator()(const WeakPtr<C>& c, P1 p1, P2 p2, P3 p3) 260 { 261 C* obj = c.get(); 262 if (!obj) 263 return R(); 264 return (obj->*m_function)(p1, p2, p3); 265 } 266 267private: 268 R (C::*m_function)(P1, P2, P3); 269}; 270 271template<typename R, typename C, typename P1, typename P2, typename P3, typename P4> 272class FunctionWrapper<R (C::*)(P1, P2, P3, P4)> { 273public: 274 typedef R ResultType; 275 276 explicit FunctionWrapper(R (C::*function)(P1, P2, P3, P4)) 277 : m_function(function) 278 { 279 } 280 281 R operator()(C* c, P1 p1, P2 p2, P3 p3, P4 p4) 282 { 283 return (c->*m_function)(p1, p2, p3, p4); 284 } 285 286 R operator()(const WeakPtr<C>& c, P1 p1, P2 p2, P3 p3, P4 p4) 287 { 288 C* obj = c.get(); 289 if (!obj) 290 return R(); 291 return (obj->*m_function)(p1, p2, p3, p4); 292 } 293 294private: 295 R (C::*m_function)(P1, P2, P3, P4); 296}; 297 298template<typename R, typename C, typename P1, typename P2, typename P3, typename P4, typename P5> 299class FunctionWrapper<R (C::*)(P1, P2, P3, P4, P5)> { 300public: 301 typedef R ResultType; 302 303 explicit FunctionWrapper(R (C::*function)(P1, P2, P3, P4, P5)) 304 : m_function(function) 305 { 306 } 307 308 R operator()(C* c, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) 309 { 310 return (c->*m_function)(p1, p2, p3, p4, p5); 311 } 312 313 R operator()(const WeakPtr<C>& c, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) 314 { 315 C* obj = c.get(); 316 if (!obj) 317 return R(); 318 return (obj->*m_function)(p1, p2, p3, p4, p5); 319 } 320 321private: 322 R (C::*m_function)(P1, P2, P3, P4, P5); 323}; 324 325template<typename T> struct ParamStorageTraits { 326 typedef T StorageType; 327 328 static StorageType wrap(const T& value) { return value; } 329 static const T& unwrap(const StorageType& value) { return value; } 330}; 331 332template<typename T> struct ParamStorageTraits<PassRefPtr<T> > { 333 typedef RefPtr<T> StorageType; 334 335 static StorageType wrap(PassRefPtr<T> value) { return value; } 336 static T* unwrap(const StorageType& value) { return value.get(); } 337}; 338 339template<typename T> struct ParamStorageTraits<RefPtr<T> > { 340 typedef RefPtr<T> StorageType; 341 342 static StorageType wrap(RefPtr<T> value) { return value.release(); } 343 static T* unwrap(const StorageType& value) { return value.get(); } 344}; 345 346template<typename> class RetainPtr; 347 348template<typename T> struct ParamStorageTraits<RetainPtr<T> > { 349 typedef RetainPtr<T> StorageType; 350 351 static StorageType wrap(const RetainPtr<T>& value) { return value; } 352 static typename RetainPtr<T>::PtrType unwrap(const StorageType& value) { return value.get(); } 353}; 354 355class FunctionImplBase : public ThreadSafeRefCounted<FunctionImplBase> { 356public: 357 virtual ~FunctionImplBase() { } 358}; 359 360template<typename> 361class FunctionImpl; 362 363template<typename R> 364class FunctionImpl<R ()> : public FunctionImplBase { 365public: 366 virtual R operator()() = 0; 367}; 368 369template<typename FunctionWrapper, typename FunctionType> 370class BoundFunctionImpl; 371 372template<typename FunctionWrapper, typename R> 373class BoundFunctionImpl<FunctionWrapper, R ()> : public FunctionImpl<typename FunctionWrapper::ResultType ()> { 374public: 375 explicit BoundFunctionImpl(FunctionWrapper functionWrapper) 376 : m_functionWrapper(functionWrapper) 377 { 378 } 379 380 virtual typename FunctionWrapper::ResultType operator()() 381 { 382 return m_functionWrapper(); 383 } 384 385private: 386 FunctionWrapper m_functionWrapper; 387}; 388 389template<typename FunctionWrapper, typename R, typename P1> 390class BoundFunctionImpl<FunctionWrapper, R (P1)> : public FunctionImpl<typename FunctionWrapper::ResultType ()> { 391public: 392 BoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1) 393 : m_functionWrapper(functionWrapper) 394 , m_p1(ParamStorageTraits<P1>::wrap(p1)) 395 { 396 } 397 398 virtual typename FunctionWrapper::ResultType operator()() 399 { 400 return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1)); 401 } 402 403private: 404 FunctionWrapper m_functionWrapper; 405 typename ParamStorageTraits<P1>::StorageType m_p1; 406}; 407 408template<typename FunctionWrapper, typename R, typename P1, typename P2> 409class BoundFunctionImpl<FunctionWrapper, R (P1, P2)> : public FunctionImpl<typename FunctionWrapper::ResultType ()> { 410public: 411 BoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1, const P2& p2) 412 : m_functionWrapper(functionWrapper) 413 , m_p1(ParamStorageTraits<P1>::wrap(p1)) 414 , m_p2(ParamStorageTraits<P2>::wrap(p2)) 415 { 416 } 417 418 virtual typename FunctionWrapper::ResultType operator()() 419 { 420 return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1), ParamStorageTraits<P2>::unwrap(m_p2)); 421 } 422 423private: 424 FunctionWrapper m_functionWrapper; 425 typename ParamStorageTraits<P1>::StorageType m_p1; 426 typename ParamStorageTraits<P2>::StorageType m_p2; 427}; 428 429template<typename FunctionWrapper, typename R, typename P1, typename P2, typename P3> 430class BoundFunctionImpl<FunctionWrapper, R (P1, P2, P3)> : public FunctionImpl<typename FunctionWrapper::ResultType ()> { 431public: 432 BoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1, const P2& p2, const P3& p3) 433 : m_functionWrapper(functionWrapper) 434 , m_p1(ParamStorageTraits<P1>::wrap(p1)) 435 , m_p2(ParamStorageTraits<P2>::wrap(p2)) 436 , m_p3(ParamStorageTraits<P3>::wrap(p3)) 437 { 438 } 439 440 virtual typename FunctionWrapper::ResultType operator()() 441 { 442 return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1), ParamStorageTraits<P2>::unwrap(m_p2), ParamStorageTraits<P3>::unwrap(m_p3)); 443 } 444 445private: 446 FunctionWrapper m_functionWrapper; 447 typename ParamStorageTraits<P1>::StorageType m_p1; 448 typename ParamStorageTraits<P2>::StorageType m_p2; 449 typename ParamStorageTraits<P3>::StorageType m_p3; 450}; 451 452template<typename FunctionWrapper, typename R, typename P1, typename P2, typename P3, typename P4> 453class BoundFunctionImpl<FunctionWrapper, R (P1, P2, P3, P4)> : public FunctionImpl<typename FunctionWrapper::ResultType ()> { 454public: 455 BoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1, const P2& p2, const P3& p3, const P4& p4) 456 : m_functionWrapper(functionWrapper) 457 , m_p1(ParamStorageTraits<P1>::wrap(p1)) 458 , m_p2(ParamStorageTraits<P2>::wrap(p2)) 459 , m_p3(ParamStorageTraits<P3>::wrap(p3)) 460 , m_p4(ParamStorageTraits<P4>::wrap(p4)) 461 { 462 } 463 464 virtual typename FunctionWrapper::ResultType operator()() 465 { 466 return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1), ParamStorageTraits<P2>::unwrap(m_p2), ParamStorageTraits<P3>::unwrap(m_p3), ParamStorageTraits<P4>::unwrap(m_p4)); 467 } 468 469private: 470 FunctionWrapper m_functionWrapper; 471 typename ParamStorageTraits<P1>::StorageType m_p1; 472 typename ParamStorageTraits<P2>::StorageType m_p2; 473 typename ParamStorageTraits<P3>::StorageType m_p3; 474 typename ParamStorageTraits<P4>::StorageType m_p4; 475}; 476 477template<typename FunctionWrapper, typename R, typename P1, typename P2, typename P3, typename P4, typename P5> 478class BoundFunctionImpl<FunctionWrapper, R (P1, P2, P3, P4, P5)> : public FunctionImpl<typename FunctionWrapper::ResultType ()> { 479public: 480 BoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5) 481 : m_functionWrapper(functionWrapper) 482 , m_p1(ParamStorageTraits<P1>::wrap(p1)) 483 , m_p2(ParamStorageTraits<P2>::wrap(p2)) 484 , m_p3(ParamStorageTraits<P3>::wrap(p3)) 485 , m_p4(ParamStorageTraits<P4>::wrap(p4)) 486 , m_p5(ParamStorageTraits<P5>::wrap(p5)) 487 { 488 } 489 490 virtual typename FunctionWrapper::ResultType operator()() 491 { 492 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)); 493 } 494 495private: 496 FunctionWrapper m_functionWrapper; 497 typename ParamStorageTraits<P1>::StorageType m_p1; 498 typename ParamStorageTraits<P2>::StorageType m_p2; 499 typename ParamStorageTraits<P3>::StorageType m_p3; 500 typename ParamStorageTraits<P4>::StorageType m_p4; 501 typename ParamStorageTraits<P5>::StorageType m_p5; 502}; 503 504template<typename FunctionWrapper, typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6> 505class BoundFunctionImpl<FunctionWrapper, R (P1, P2, P3, P4, P5, P6)> : public FunctionImpl<typename FunctionWrapper::ResultType ()> { 506public: 507 BoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5, const P6& p6) 508 : m_functionWrapper(functionWrapper) 509 , m_p1(ParamStorageTraits<P1>::wrap(p1)) 510 , m_p2(ParamStorageTraits<P2>::wrap(p2)) 511 , m_p3(ParamStorageTraits<P3>::wrap(p3)) 512 , m_p4(ParamStorageTraits<P4>::wrap(p4)) 513 , m_p5(ParamStorageTraits<P5>::wrap(p5)) 514 , m_p6(ParamStorageTraits<P6>::wrap(p6)) 515 { 516 } 517 518 virtual typename FunctionWrapper::ResultType operator()() 519 { 520 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)); 521 } 522 523private: 524 FunctionWrapper m_functionWrapper; 525 typename ParamStorageTraits<P1>::StorageType m_p1; 526 typename ParamStorageTraits<P2>::StorageType m_p2; 527 typename ParamStorageTraits<P3>::StorageType m_p3; 528 typename ParamStorageTraits<P4>::StorageType m_p4; 529 typename ParamStorageTraits<P5>::StorageType m_p5; 530 typename ParamStorageTraits<P6>::StorageType m_p6; 531}; 532 533class FunctionBase { 534public: 535 bool isNull() const 536 { 537 return !m_impl; 538 } 539 540protected: 541 FunctionBase() 542 { 543 } 544 545 explicit FunctionBase(PassRefPtr<FunctionImplBase> impl) 546 : m_impl(impl) 547 { 548 } 549 550 template<typename FunctionType> FunctionImpl<FunctionType>* impl() const 551 { 552 return static_cast<FunctionImpl<FunctionType>*>(m_impl.get()); 553 } 554 555private: 556 RefPtr<FunctionImplBase> m_impl; 557}; 558 559template<typename> 560class Function; 561 562template<typename R> 563class Function<R ()> : public FunctionBase { 564public: 565 Function() 566 { 567 } 568 569 Function(PassRefPtr<FunctionImpl<R ()> > impl) 570 : FunctionBase(impl) 571 { 572 } 573 574 R operator()() const 575 { 576 ASSERT(!isNull()); 577 return impl<R ()>()->operator()(); 578 } 579}; 580 581template<typename FunctionType> 582Function<typename FunctionWrapper<FunctionType>::ResultType ()> bind(FunctionType function) 583{ 584 return Function<typename FunctionWrapper<FunctionType>::ResultType ()>(adoptRef(new BoundFunctionImpl<FunctionWrapper<FunctionType>, typename FunctionWrapper<FunctionType>::ResultType ()>(FunctionWrapper<FunctionType>(function)))); 585} 586 587template<typename FunctionType, typename A1> 588Function<typename FunctionWrapper<FunctionType>::ResultType ()> bind(FunctionType function, const A1& a1) 589{ 590 return Function<typename FunctionWrapper<FunctionType>::ResultType ()>(adoptRef(new BoundFunctionImpl<FunctionWrapper<FunctionType>, typename FunctionWrapper<FunctionType>::ResultType (A1)>(FunctionWrapper<FunctionType>(function), a1))); 591} 592 593template<typename FunctionType, typename A1, typename A2> 594Function<typename FunctionWrapper<FunctionType>::ResultType ()> bind(FunctionType function, const A1& a1, const A2& a2) 595{ 596 return Function<typename FunctionWrapper<FunctionType>::ResultType ()>(adoptRef(new BoundFunctionImpl<FunctionWrapper<FunctionType>, typename FunctionWrapper<FunctionType>::ResultType (A1, A2)>(FunctionWrapper<FunctionType>(function), a1, a2))); 597} 598 599template<typename FunctionType, typename A1, typename A2, typename A3> 600Function<typename FunctionWrapper<FunctionType>::ResultType ()> bind(FunctionType function, const A1& a1, const A2& a2, const A3& a3) 601{ 602 return Function<typename FunctionWrapper<FunctionType>::ResultType ()>(adoptRef(new BoundFunctionImpl<FunctionWrapper<FunctionType>, typename FunctionWrapper<FunctionType>::ResultType (A1, A2, A3)>(FunctionWrapper<FunctionType>(function), a1, a2, a3))); 603} 604 605template<typename FunctionType, typename A1, typename A2, typename A3, typename A4> 606Function<typename FunctionWrapper<FunctionType>::ResultType ()> bind(FunctionType function, const A1& a1, const A2& a2, const A3& a3, const A4& a4) 607{ 608 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))); 609} 610 611template<typename FunctionType, typename A1, typename A2, typename A3, typename A4, typename A5> 612Function<typename FunctionWrapper<FunctionType>::ResultType ()> bind(FunctionType function, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) 613{ 614 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))); 615} 616 617template<typename FunctionType, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6> 618Function<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) 619{ 620 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))); 621} 622 623typedef Function<void()> Closure; 624 625} 626 627using WTF::Function; 628using WTF::bind; 629using WTF::Closure; 630 631#endif // WTF_Functional_h 632