diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-01-06 14:44:00 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-01-06 14:44:00 +0100 |
commit | 40736c5763bf61337c8c14e16d8587db021a87d4 (patch) | |
tree | b17a9c00042ad89cb1308e2484491799aa14e9f8 /Source/JavaScriptCore/wtf/Functional.h | |
download | qtwebkit-40736c5763bf61337c8c14e16d8587db021a87d4.tar.gz |
Imported WebKit commit 2ea9d364d0f6efa8fa64acf19f451504c59be0e4 (http://svn.webkit.org/repository/webkit/trunk@104285)
Diffstat (limited to 'Source/JavaScriptCore/wtf/Functional.h')
-rw-r--r-- | Source/JavaScriptCore/wtf/Functional.h | 638 |
1 files changed, 638 insertions, 0 deletions
diff --git a/Source/JavaScriptCore/wtf/Functional.h b/Source/JavaScriptCore/wtf/Functional.h new file mode 100644 index 000000000..86d6203cf --- /dev/null +++ b/Source/JavaScriptCore/wtf/Functional.h @@ -0,0 +1,638 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WTF_Functional_h +#define WTF_Functional_h + +#include "Assertions.h" +#include "PassRefPtr.h" +#include "RefPtr.h" +#include "ThreadSafeRefCounted.h" + +#if PLATFORM(MAC) && COMPILER_SUPPORTS(BLOCKS) +#include <objc/objc-runtime.h> +#endif + +namespace WTF { + +// Functional.h provides a very simple way to bind a function pointer and arguments together into a function object +// that can be stored, copied and invoked, similar to how boost::bind and std::bind in C++11. + +// Helper class template to determine whether a given type has ref and deref member functions +// with the right type signature. +template<typename T> +class HasRefAndDeref { + typedef char YesType; + struct NoType { + char padding[8]; + }; + + struct BaseMixin { + void deref(); + void ref(); + }; + + struct Base : public T, public BaseMixin { }; + + template<typename U, U> struct + TypeChecker { }; + + template<typename U> + static NoType refCheck(U*, TypeChecker<void (BaseMixin::*)(), &U::ref>* = 0); + static YesType refCheck(...); + + template<typename U> + static NoType derefCheck(U*, TypeChecker<void (BaseMixin::*)(), &U::deref>* = 0); + static YesType derefCheck(...); + +public: + static const bool value = sizeof(refCheck(static_cast<Base*>(0))) == sizeof(YesType) && sizeof(derefCheck(static_cast<Base*>(0))) == sizeof(YesType); +}; + +// A FunctionWrapper is a class template that can wrap a function pointer or a member function pointer and +// provide a unified interface for calling that function. +template<typename> +class FunctionWrapper; + +template<typename R> +class FunctionWrapper<R (*)()> { +public: + typedef R ResultType; + static const bool shouldRefFirstParameter = false; + + explicit FunctionWrapper(R (*function)()) + : m_function(function) + { + } + + R operator()() + { + return m_function(); + } + +private: + R (*m_function)(); +}; + +template<typename R, typename P1> +class FunctionWrapper<R (*)(P1)> { +public: + typedef R ResultType; + static const bool shouldRefFirstParameter = false; + + explicit FunctionWrapper(R (*function)(P1)) + : m_function(function) + { + } + + R operator()(P1 p1) + { + return m_function(p1); + } + +private: + R (*m_function)(P1); +}; + +template<typename R, typename P1, typename P2> +class FunctionWrapper<R (*)(P1, P2)> { +public: + typedef R ResultType; + static const bool shouldRefFirstParameter = false; + + explicit FunctionWrapper(R (*function)(P1, P2)) + : m_function(function) + { + } + + R operator()(P1 p1, P2 p2) + { + return m_function(p1, p2); + } + +private: + R (*m_function)(P1, P2); +}; + +template<typename R, typename C> +class FunctionWrapper<R (C::*)()> { +public: + typedef R ResultType; + static const bool shouldRefFirstParameter = HasRefAndDeref<C>::value; + + explicit FunctionWrapper(R (C::*function)()) + : m_function(function) + { + } + + R operator()(C* c) + { + return (c->*m_function)(); + } + +private: + R (C::*m_function)(); +}; + +template<typename R, typename C, typename P1> +class FunctionWrapper<R (C::*)(P1)> { +public: + typedef R ResultType; + static const bool shouldRefFirstParameter = HasRefAndDeref<C>::value; + + explicit FunctionWrapper(R (C::*function)(P1)) + : m_function(function) + { + } + + R operator()(C* c, P1 p1) + { + return (c->*m_function)(p1); + } + +private: + R (C::*m_function)(P1); +}; + +template<typename R, typename C, typename P1, typename P2> +class FunctionWrapper<R (C::*)(P1, P2)> { +public: + typedef R ResultType; + static const bool shouldRefFirstParameter = HasRefAndDeref<C>::value; + + explicit FunctionWrapper(R (C::*function)(P1, P2)) + : m_function(function) + { + } + + R operator()(C* c, P1 p1, P2 p2) + { + return (c->*m_function)(p1, p2); + } + +private: + R (C::*m_function)(P1, P2); +}; + +template<typename R, typename C, typename P1, typename P2, typename P3> +class FunctionWrapper<R (C::*)(P1, P2, P3)> { +public: + typedef R ResultType; + static const bool shouldRefFirstParameter = HasRefAndDeref<C>::value; + + explicit FunctionWrapper(R (C::*function)(P1, P2, P3)) + : m_function(function) + { + } + + R operator()(C* c, P1 p1, P2 p2, P3 p3) + { + return (c->*m_function)(p1, p2, p3); + } + +private: + R (C::*m_function)(P1, P2, P3); +}; + +template<typename R, typename C, typename P1, typename P2, typename P3, typename P4> +class FunctionWrapper<R (C::*)(P1, P2, P3, P4)> { +public: + typedef R ResultType; + static const bool shouldRefFirstParameter = HasRefAndDeref<C>::value; + + explicit FunctionWrapper(R (C::*function)(P1, P2, P3, P4)) + : m_function(function) + { + } + + R operator()(C* c, P1 p1, P2 p2, P3 p3, P4 p4) + { + return (c->*m_function)(p1, p2, p3, p4); + } + +private: + R (C::*m_function)(P1, P2, P3, P4); +}; + +template<typename R, typename C, typename P1, typename P2, typename P3, typename P4, typename P5> +class FunctionWrapper<R (C::*)(P1, P2, P3, P4, P5)> { +public: + typedef R ResultType; + static const bool shouldRefFirstParameter = HasRefAndDeref<C>::value; + + explicit FunctionWrapper(R (C::*function)(P1, P2, P3, P4, P5)) + : m_function(function) + { + } + + R operator()(C* c, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) + { + return (c->*m_function)(p1, p2, p3, p4, p5); + } + +private: + R (C::*m_function)(P1, P2, P3, P4, P5); +}; + +template<typename T, bool shouldRefAndDeref> struct RefAndDeref { + static void ref(T) { } + static void deref(T) { } +}; + +template<typename T> struct RefAndDeref<T*, true> { + static void ref(T* t) { t->ref(); } + static void deref(T* t) { t->deref(); } +}; + +template<typename T> struct ParamStorageTraits { + typedef T StorageType; + + static StorageType wrap(const T& value) { return value; } + static const T& unwrap(const StorageType& value) { return value; } +}; + +template<typename T> struct ParamStorageTraits<PassRefPtr<T> > { + typedef RefPtr<T> StorageType; + + static StorageType wrap(PassRefPtr<T> value) { return value; } + static T* unwrap(const StorageType& value) { return value.get(); } +}; + +template<typename T> struct ParamStorageTraits<RefPtr<T> > { + typedef RefPtr<T> StorageType; + + static StorageType wrap(RefPtr<T> value) { return value.release(); } + static T* unwrap(const StorageType& value) { return value.get(); } +}; + + +template<typename> class RetainPtr; + +template<typename T> struct ParamStorageTraits<RetainPtr<T> > { + typedef RetainPtr<T> StorageType; + + static StorageType wrap(const RetainPtr<T>& value) { return value; } + static typename RetainPtr<T>::PtrType unwrap(const StorageType& value) { return value.get(); } +}; + +class FunctionImplBase : public ThreadSafeRefCounted<FunctionImplBase> { +public: + virtual ~FunctionImplBase() { } +}; + +template<typename> +class FunctionImpl; + +template<typename R> +class FunctionImpl<R ()> : public FunctionImplBase { +public: + virtual R operator()() = 0; +}; + +template<typename FunctionWrapper, typename FunctionType> +class BoundFunctionImpl; + +template<typename FunctionWrapper, typename R> +class BoundFunctionImpl<FunctionWrapper, R ()> : public FunctionImpl<typename FunctionWrapper::ResultType ()> { +public: + explicit BoundFunctionImpl(FunctionWrapper functionWrapper) + : m_functionWrapper(functionWrapper) + { + } + + virtual R operator()() + { + return m_functionWrapper(); + } + +private: + FunctionWrapper m_functionWrapper; +}; + +template<typename FunctionWrapper, typename R, typename P1> +class BoundFunctionImpl<FunctionWrapper, R (P1)> : public FunctionImpl<typename FunctionWrapper::ResultType ()> { + +public: + BoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1) + : m_functionWrapper(functionWrapper) + , m_p1(ParamStorageTraits<P1>::wrap(p1)) + { + RefAndDeref<P1, FunctionWrapper::shouldRefFirstParameter>::ref(m_p1); + } + + ~BoundFunctionImpl() + { + RefAndDeref<P1, FunctionWrapper::shouldRefFirstParameter>::deref(m_p1); + } + + virtual R operator()() + { + return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1)); + } + +private: + FunctionWrapper m_functionWrapper; + typename ParamStorageTraits<P1>::StorageType m_p1; +}; + +template<typename FunctionWrapper, typename R, typename P1, typename P2> +class BoundFunctionImpl<FunctionWrapper, R (P1, P2)> : public FunctionImpl<typename FunctionWrapper::ResultType ()> { +public: + BoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1, const P2& p2) + : m_functionWrapper(functionWrapper) + , m_p1(ParamStorageTraits<P1>::wrap(p1)) + , m_p2(ParamStorageTraits<P2>::wrap(p2)) + { + RefAndDeref<P1, FunctionWrapper::shouldRefFirstParameter>::ref(m_p1); + } + + ~BoundFunctionImpl() + { + RefAndDeref<P1, FunctionWrapper::shouldRefFirstParameter>::deref(m_p1); + } + + virtual typename FunctionWrapper::ResultType operator()() + { + return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1), ParamStorageTraits<P2>::unwrap(m_p2)); + } + +private: + FunctionWrapper m_functionWrapper; + typename ParamStorageTraits<P1>::StorageType m_p1; + typename ParamStorageTraits<P2>::StorageType m_p2; +}; + +template<typename FunctionWrapper, typename R, typename P1, typename P2, typename P3> +class BoundFunctionImpl<FunctionWrapper, R (P1, P2, P3)> : public FunctionImpl<typename FunctionWrapper::ResultType ()> { +public: + BoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1, const P2& p2, const P3& p3) + : m_functionWrapper(functionWrapper) + , m_p1(ParamStorageTraits<P1>::wrap(p1)) + , m_p2(ParamStorageTraits<P2>::wrap(p2)) + , m_p3(ParamStorageTraits<P3>::wrap(p3)) + { + RefAndDeref<P1, FunctionWrapper::shouldRefFirstParameter>::ref(m_p1); + } + + ~BoundFunctionImpl() + { + RefAndDeref<P1, FunctionWrapper::shouldRefFirstParameter>::deref(m_p1); + } + + virtual typename FunctionWrapper::ResultType operator()() + { + return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1), ParamStorageTraits<P2>::unwrap(m_p2), ParamStorageTraits<P3>::unwrap(m_p3)); + } + +private: + FunctionWrapper m_functionWrapper; + typename ParamStorageTraits<P1>::StorageType m_p1; + typename ParamStorageTraits<P2>::StorageType m_p2; + typename ParamStorageTraits<P3>::StorageType m_p3; +}; + +template<typename FunctionWrapper, typename R, typename P1, typename P2, typename P3, typename P4> +class BoundFunctionImpl<FunctionWrapper, R (P1, P2, P3, P4)> : public FunctionImpl<typename FunctionWrapper::ResultType ()> { +public: + BoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1, const P2& p2, const P3& p3, const P4& p4) + : m_functionWrapper(functionWrapper) + , m_p1(ParamStorageTraits<P1>::wrap(p1)) + , m_p2(ParamStorageTraits<P2>::wrap(p2)) + , m_p3(ParamStorageTraits<P3>::wrap(p3)) + , m_p4(ParamStorageTraits<P4>::wrap(p4)) + { + RefAndDeref<P1, FunctionWrapper::shouldRefFirstParameter>::ref(m_p1); + } + + ~BoundFunctionImpl() + { + RefAndDeref<P1, FunctionWrapper::shouldRefFirstParameter>::deref(m_p1); + } + + virtual typename FunctionWrapper::ResultType operator()() + { + return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1), ParamStorageTraits<P2>::unwrap(m_p2), ParamStorageTraits<P3>::unwrap(m_p3), ParamStorageTraits<P4>::unwrap(m_p4)); + } + +private: + FunctionWrapper m_functionWrapper; + typename ParamStorageTraits<P1>::StorageType m_p1; + typename ParamStorageTraits<P2>::StorageType m_p2; + typename ParamStorageTraits<P3>::StorageType m_p3; + typename ParamStorageTraits<P4>::StorageType m_p4; +}; + +template<typename FunctionWrapper, typename R, typename P1, typename P2, typename P3, typename P4, typename P5> +class BoundFunctionImpl<FunctionWrapper, R (P1, P2, P3, P4, P5)> : public FunctionImpl<typename FunctionWrapper::ResultType ()> { +public: + BoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5) + : m_functionWrapper(functionWrapper) + , m_p1(ParamStorageTraits<P1>::wrap(p1)) + , m_p2(ParamStorageTraits<P2>::wrap(p2)) + , m_p3(ParamStorageTraits<P3>::wrap(p3)) + , m_p4(ParamStorageTraits<P4>::wrap(p4)) + , m_p5(ParamStorageTraits<P5>::wrap(p5)) + { + RefAndDeref<P1, FunctionWrapper::shouldRefFirstParameter>::ref(m_p1); + } + + ~BoundFunctionImpl() + { + RefAndDeref<P1, FunctionWrapper::shouldRefFirstParameter>::deref(m_p1); + } + + virtual typename FunctionWrapper::ResultType operator()() + { + 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)); + } + +private: + FunctionWrapper m_functionWrapper; + typename ParamStorageTraits<P1>::StorageType m_p1; + typename ParamStorageTraits<P2>::StorageType m_p2; + typename ParamStorageTraits<P3>::StorageType m_p3; + typename ParamStorageTraits<P4>::StorageType m_p4; + typename ParamStorageTraits<P5>::StorageType m_p5; +}; + +template<typename FunctionWrapper, typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6> +class BoundFunctionImpl<FunctionWrapper, R (P1, P2, P3, P4, P5, P6)> : public FunctionImpl<typename FunctionWrapper::ResultType ()> { +public: + BoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5, const P6& p6) + : m_functionWrapper(functionWrapper) + , m_p1(ParamStorageTraits<P1>::wrap(p1)) + , m_p2(ParamStorageTraits<P2>::wrap(p2)) + , m_p3(ParamStorageTraits<P3>::wrap(p3)) + , m_p4(ParamStorageTraits<P4>::wrap(p4)) + , m_p5(ParamStorageTraits<P5>::wrap(p5)) + , m_p6(ParamStorageTraits<P6>::wrap(p6)) + { + RefAndDeref<P1, FunctionWrapper::shouldRefFirstParameter>::ref(m_p1); + } + + ~BoundFunctionImpl() + { + RefAndDeref<P1, FunctionWrapper::shouldRefFirstParameter>::deref(m_p1); + } + + virtual typename FunctionWrapper::ResultType operator()() + { + 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)); + } + +private: + FunctionWrapper m_functionWrapper; + typename ParamStorageTraits<P1>::StorageType m_p1; + typename ParamStorageTraits<P2>::StorageType m_p2; + typename ParamStorageTraits<P3>::StorageType m_p3; + typename ParamStorageTraits<P4>::StorageType m_p4; + typename ParamStorageTraits<P5>::StorageType m_p5; + typename ParamStorageTraits<P6>::StorageType m_p6; +}; + +class FunctionBase { +public: + bool isNull() const + { + return !m_impl; + } + +protected: + FunctionBase() + { + } + + explicit FunctionBase(PassRefPtr<FunctionImplBase> impl) + : m_impl(impl) + { + } + + template<typename FunctionType> FunctionImpl<FunctionType>* impl() const + { + return static_cast<FunctionImpl<FunctionType>*>(m_impl.get()); + } + +private: + RefPtr<FunctionImplBase> m_impl; +}; + +template<typename> +class Function; + +template<typename R> +class Function<R ()> : public FunctionBase { +public: + Function() + { + } + + Function(PassRefPtr<FunctionImpl<R ()> > impl) + : FunctionBase(impl) + { + } + + R operator()() const + { + ASSERT(!isNull()); + + return impl<R ()>()->operator()(); + } + +#if PLATFORM(MAC) && COMPILER_SUPPORTS(BLOCKS) + typedef void (^BlockType)(); + operator BlockType() const + { + // Declare a RefPtr here so we'll be sure that the underlying FunctionImpl object's + // lifecycle is managed correctly. + RefPtr<FunctionImpl<R ()> > functionImpl = impl<R ()>(); + BlockType block = ^{ + functionImpl->operator()(); + }; + + // This is equivalent to: + // + // return [[block copy] autorelease]; + // + // We're using manual objc_msgSend calls here because we don't want to make the entire + // file Objective-C. It's useful to be able to implicitly convert a Function to + // a block even in C++ code, since that allows us to do things like: + // + // dispatch_async(queue, bind(...)); + // + id copiedBlock = objc_msgSend((id)block, sel_registerName("copy")); + id autoreleasedBlock = objc_msgSend(copiedBlock, sel_registerName("autorelease")); + return (BlockType)autoreleasedBlock; + } +#endif +}; + +template<typename FunctionType> +Function<typename FunctionWrapper<FunctionType>::ResultType ()> bind(FunctionType function) +{ + return Function<typename FunctionWrapper<FunctionType>::ResultType ()>(adoptRef(new BoundFunctionImpl<FunctionWrapper<FunctionType>, typename FunctionWrapper<FunctionType>::ResultType ()>(FunctionWrapper<FunctionType>(function)))); +} + +template<typename FunctionType, typename A1> +Function<typename FunctionWrapper<FunctionType>::ResultType ()> bind(FunctionType function, const A1& a1) +{ + return Function<typename FunctionWrapper<FunctionType>::ResultType ()>(adoptRef(new BoundFunctionImpl<FunctionWrapper<FunctionType>, typename FunctionWrapper<FunctionType>::ResultType (A1)>(FunctionWrapper<FunctionType>(function), a1))); +} + +template<typename FunctionType, typename A1, typename A2> +Function<typename FunctionWrapper<FunctionType>::ResultType ()> bind(FunctionType function, const A1& a1, const A2& a2) +{ + return Function<typename FunctionWrapper<FunctionType>::ResultType ()>(adoptRef(new BoundFunctionImpl<FunctionWrapper<FunctionType>, typename FunctionWrapper<FunctionType>::ResultType (A1, A2)>(FunctionWrapper<FunctionType>(function), a1, a2))); +} + +template<typename FunctionType, typename A1, typename A2, typename A3> +Function<typename FunctionWrapper<FunctionType>::ResultType ()> bind(FunctionType function, const A1& a1, const A2& a2, const A3& a3) +{ + return Function<typename FunctionWrapper<FunctionType>::ResultType ()>(adoptRef(new BoundFunctionImpl<FunctionWrapper<FunctionType>, typename FunctionWrapper<FunctionType>::ResultType (A1, A2, A3)>(FunctionWrapper<FunctionType>(function), a1, a2, a3))); +} + +template<typename FunctionType, typename A1, typename A2, typename A3, typename A4> +Function<typename FunctionWrapper<FunctionType>::ResultType ()> bind(FunctionType function, const A1& a1, const A2& a2, const A3& a3, const A4& a4) +{ + 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))); +} + +template<typename FunctionType, typename A1, typename A2, typename A3, typename A4, typename A5> +Function<typename FunctionWrapper<FunctionType>::ResultType ()> bind(FunctionType function, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) +{ + 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))); +} + +template<typename FunctionType, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6> +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) +{ + 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))); +} + +} + +using WTF::Function; +using WTF::bind; + +#endif // WTF_Functional_h |