Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2024)

Unified Diff: third_party/WebKit/Source/wtf/Functional.h

Issue 1679773002: WTF::bind: Remove the need of hand-rolled code for bound arguments. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Make callInternal() private. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/WebKit/Source/wtf/DEPS ('k') | third_party/WebKit/Source/wtf/FunctionalTest.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/wtf/Functional.h
diff --git a/third_party/WebKit/Source/wtf/Functional.h b/third_party/WebKit/Source/wtf/Functional.h
index 307237cb16b75b73204586473aa1a510ed4ae8b2..6694776f9bd680d3728ac3ba691c86c78d3ec847 100644
--- a/third_party/WebKit/Source/wtf/Functional.h
+++ b/third_party/WebKit/Source/wtf/Functional.h
@@ -26,6 +26,7 @@
#ifndef WTF_Functional_h
#define WTF_Functional_h
+#include "base/tuple.h"
#include "wtf/Allocator.h"
#include "wtf/Assertions.h"
#include "wtf/PassOwnPtr.h"
@@ -33,6 +34,7 @@
#include "wtf/RefPtr.h"
#include "wtf/ThreadSafeRefCounted.h"
#include "wtf/WeakPtr.h"
+#include <tuple>
Nico 2016/02/09 03:16:53 It's a bit unfortunate that this includes both bas
Yuta Kitamura 2016/02/09 05:47:43 The only reason I added base/tuple.h was base::Ind
namespace WTF {
@@ -147,209 +149,47 @@ protected:
Function() = default;
};
-template<int boundArgsCount, typename FunctionWrapper, typename FunctionType>
+template <typename BoundParametersTuple, typename FunctionWrapper, typename... UnboundParameters>
class PartBoundFunctionImpl;
-// Specialization for unbound functions.
-template<typename FunctionWrapper, typename R, typename... UnboundParams>
-class PartBoundFunctionImpl<0, FunctionWrapper, R(UnboundParams...)> final : public Function<typename FunctionWrapper::ResultType(UnboundParams...)> {
+template <typename... BoundParameters, typename FunctionWrapper, typename... UnboundParameters>
+class PartBoundFunctionImpl<std::tuple<BoundParameters...>, FunctionWrapper, UnboundParameters...> final : public Function<typename FunctionWrapper::ResultType(UnboundParameters...)> {
public:
- PartBoundFunctionImpl(FunctionWrapper functionWrapper)
+ explicit PartBoundFunctionImpl(FunctionWrapper functionWrapper, const BoundParameters&... bound)
: m_functionWrapper(functionWrapper)
+ , m_bound(ParamStorageTraits<BoundParameters>::wrap(bound)...)
{
}
- typename FunctionWrapper::ResultType operator()(UnboundParams... params) override
+ typename FunctionWrapper::ResultType operator()(UnboundParameters... unbound) override
{
- return m_functionWrapper(params...);
+ // What we really want to do is to call m_functionWrapper(m_bound..., unbound...), but to do that we need to
+ // pass a list of indices to a worker function template.
+ return callInternal(unbound..., base::MakeIndexSequence<sizeof...(BoundParameters)>());
}
private:
- FunctionWrapper m_functionWrapper;
-};
-
-template<typename FunctionWrapper, typename R, typename P1, typename... UnboundParams>
-class PartBoundFunctionImpl<1, FunctionWrapper, R(P1, UnboundParams...)> final : public Function<typename FunctionWrapper::ResultType(UnboundParams...)> {
-public:
- PartBoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1)
- : m_functionWrapper(functionWrapper)
- , m_p1(ParamStorageTraits<P1>::wrap(p1))
- {
- }
-
- typename FunctionWrapper::ResultType operator()(UnboundParams... params) override
- {
- return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1), params...);
- }
-
-private:
- FunctionWrapper m_functionWrapper;
- typename ParamStorageTraits<P1>::StorageType m_p1;
-};
-
-template<typename FunctionWrapper, typename R, typename P1, typename P2, typename... UnboundParams>
-class PartBoundFunctionImpl<2, FunctionWrapper, R(P1, P2, UnboundParams...)> final : public Function<typename FunctionWrapper::ResultType(UnboundParams...)> {
-public:
- PartBoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1, const P2& p2)
- : m_functionWrapper(functionWrapper)
- , m_p1(ParamStorageTraits<P1>::wrap(p1))
- , m_p2(ParamStorageTraits<P2>::wrap(p2))
- {
- }
-
- typename FunctionWrapper::ResultType operator()(UnboundParams... params) override
- {
- return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1), ParamStorageTraits<P2>::unwrap(m_p2), params...);
- }
-
-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, typename... UnboundParams>
-class PartBoundFunctionImpl<3, FunctionWrapper, R(P1, P2, P3, UnboundParams...)> final : public Function<typename FunctionWrapper::ResultType(UnboundParams...)> {
-public:
- PartBoundFunctionImpl(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))
- {
- }
-
- typename FunctionWrapper::ResultType operator()(UnboundParams... params) override
- {
- return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1), ParamStorageTraits<P2>::unwrap(m_p2), ParamStorageTraits<P3>::unwrap(m_p3), params...);
- }
-
-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, typename... UnboundParams>
-class PartBoundFunctionImpl<4, FunctionWrapper, R(P1, P2, P3, P4, UnboundParams...)> final : public Function<typename FunctionWrapper::ResultType(UnboundParams...)> {
-public:
- PartBoundFunctionImpl(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))
+ template <std::size_t... boundIndices>
+ typename FunctionWrapper::ResultType callInternal(UnboundParameters... unbound, const base::IndexSequence<boundIndices...>&)
{
+ // Get each element in m_bound, unwrap them, and call the function with the desired arguments.
+ return m_functionWrapper(ParamStorageTraits<BoundParameters>::unwrap(std::get<boundIndices>(m_bound))..., unbound...);
}
- typename FunctionWrapper::ResultType operator()(UnboundParams... params) override
- {
- return m_functionWrapper(ParamStorageTraits<P1>::unwrap(m_p1), ParamStorageTraits<P2>::unwrap(m_p2), ParamStorageTraits<P3>::unwrap(m_p3), ParamStorageTraits<P4>::unwrap(m_p4), params...);
- }
-
-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, typename... UnboundParams>
-class PartBoundFunctionImpl<5, FunctionWrapper, R(P1, P2, P3, P4, P5, UnboundParams...)> final : public Function<typename FunctionWrapper::ResultType(UnboundParams...)> {
-public:
- PartBoundFunctionImpl(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))
- {
- }
-
- typename FunctionWrapper::ResultType operator()(UnboundParams... params) override
- {
- 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...);
- }
-
-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, typename... UnboundParams>
-class PartBoundFunctionImpl<6, FunctionWrapper, R(P1, P2, P3, P4, P5, P6, UnboundParams...)> final : public Function<typename FunctionWrapper::ResultType(UnboundParams...)> {
-public:
- PartBoundFunctionImpl(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))
- {
- }
-
- typename FunctionWrapper::ResultType operator()(UnboundParams... params) override
- {
- 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...);
- }
-
-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;
-};
-
-template<typename FunctionWrapper, typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename... UnboundParams>
-class PartBoundFunctionImpl<7, FunctionWrapper, R(P1, P2, P3, P4, P5, P6, P7, UnboundParams...)> final : public Function<typename FunctionWrapper::ResultType(UnboundParams...)> {
-public:
- PartBoundFunctionImpl(FunctionWrapper functionWrapper, const P1& p1, const P2& p2, const P3& p3, const P4& p4, const P5& p5, const P6& p6, const P7& p7)
- : 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))
- , m_p7(ParamStorageTraits<P7>::wrap(p7))
- {
- }
-
- typename FunctionWrapper::ResultType operator()(UnboundParams... params) override
- {
- 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), ParamStorageTraits<P7>::unwrap(m_p7), params...);
- }
-
-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;
- typename ParamStorageTraits<P7>::StorageType m_p7;
+ std::tuple<typename ParamStorageTraits<BoundParameters>::StorageType...> m_bound;
};
-template<typename... UnboundArgs, typename FunctionType, typename... BoundArgs>
-PassOwnPtr<Function<typename FunctionWrapper<FunctionType>::ResultType(UnboundArgs...)>> bind(FunctionType function, const BoundArgs&... boundArgs)
+template<typename... UnboundParameters, typename FunctionType, typename... BoundParameters>
+PassOwnPtr<Function<typename FunctionWrapper<FunctionType>::ResultType(UnboundParameters...)>> bind(FunctionType function, const BoundParameters&... boundParameters)
{
- const int boundArgsCount = sizeof...(BoundArgs);
- using BoundFunctionType = PartBoundFunctionImpl<boundArgsCount, FunctionWrapper<FunctionType>, typename FunctionWrapper<FunctionType>::ResultType(BoundArgs..., UnboundArgs...)>;
- return adoptPtr(new BoundFunctionType(FunctionWrapper<FunctionType>(function), boundArgs...));
+ // Bound parameters' types are wrapped with std::tuple so we can pass two template parameter packs (bound
+ // parameters and unbound) to PartBoundFunctionImpl. Note that a tuple of this type isn't actually created;
+ // std::tuple<> is just for carrying the bound parameters' types. Any other class template taking a type parameter
+ // pack can be used instead of std::tuple. std::tuple is used just because it's most convenient for this purpose.
+ using BoundFunctionType = PartBoundFunctionImpl<std::tuple<BoundParameters...>, FunctionWrapper<FunctionType>, UnboundParameters...>;
+ return adoptPtr(new BoundFunctionType(FunctionWrapper<FunctionType>(function), boundParameters...));
}
typedef Function<void()> Closure;
« no previous file with comments | « third_party/WebKit/Source/wtf/DEPS ('k') | third_party/WebKit/Source/wtf/FunctionalTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698