@@ -40,16 +40,13 @@ struct generator<0, S...> {
4040} // namespace index
4141
4242template <typename FunctionType, ContainerAllocator & Allocator, typename ... CapturedTypes>
43- class CapturedArguments ;
43+ class CaptureFirst ;
4444
4545template <typename ReturnType, typename ... ArgTypes, ContainerAllocator & Allocator, typename ... CapturedTypes>
46- class CapturedArguments <ReturnType(ArgTypes...), Allocator, CapturedTypes...>
46+ class CaptureFirst <ReturnType(ArgTypes...), Allocator, CapturedTypes...>
4747 : public FunctionInterface <ReturnType(ArgTypes...)> {
4848public:
49- // CapturedArguments(Function<ReturnType(CapturedTypes..., ArgTypes...)> & f, CapturedTypes&&... CapturedArgs) :
50- // f(f), storage(CapturedArgs...)
51- // {}
52- CapturedArguments (const std::tuple<CapturedTypes...>& t, Function<ReturnType(CapturedTypes..., ArgTypes...)>& f):
49+ CaptureFirst (const std::tuple<CapturedTypes...>& t, Function<ReturnType(CapturedTypes..., ArgTypes...)>& f):
5350 f (f), storage(t)
5451 {}
5552
@@ -61,13 +58,13 @@ class CapturedArguments <ReturnType(ArgTypes...), Allocator, CapturedTypes...>
6158 return f (forward<CapturedTypes>(std::get<S>(storage))..., forward<ArgTypes>(Args)...);
6259 }
6360
64- virtual ContainerAllocator * getAllocator () {
61+ virtual ContainerAllocator * get_allocator () {
6562 return & Allocator;
6663 }
6764protected:
6865 /*
6966 * Future Optimization Note: It is possible to reduce memory consumption and call
70- * overhead by making CapturedArguments inherit from each of the FunctionInterface
67+ * overhead by making CaptureFirst inherit from each of the FunctionInterface
7168 * types, rather than just from FunctionInterface.
7269 *
7370 * In this case, however, a smarter allocator would help
@@ -76,19 +73,73 @@ class CapturedArguments <ReturnType(ArgTypes...), Allocator, CapturedTypes...>
7673 std::tuple<CapturedTypes...> storage;
7774};
7875
79- template <typename FunctionType, typename ... ToRemove> struct RemoveArgs {};
76+ template <typename FunctionType, ContainerAllocator & Allocator, typename ... CapturedTypes>
77+ class CaptureLast ;
78+
79+ template <typename ReturnType, typename ... ArgTypes, ContainerAllocator & Allocator, typename ... CapturedTypes>
80+ class CaptureLast <ReturnType(ArgTypes...), Allocator, CapturedTypes...>
81+ : public FunctionInterface <ReturnType(ArgTypes...)> {
82+ public:
83+ CaptureLast (Function<ReturnType(ArgTypes..., CapturedTypes...)> & f, CapturedTypes&&... CapturedArgs) :
84+ f (f), storage(CapturedArgs...)
85+ {}
86+
87+ virtual ReturnType operator () (ArgTypes&&... Args) {
88+ return idxcall (typename index::generator<sizeof ...(CapturedTypes)>::type (), forward<ArgTypes>(Args)...);
89+ }
90+ template <size_t ... S>
91+ inline ReturnType idxcall (index::sequence<S...>, ArgTypes&&... Args) {
92+ return f (forward<ArgTypes>(Args)..., forward<CapturedTypes>(std::get<S>(storage))...);
93+ }
94+
95+ virtual ContainerAllocator * get_allocator () {
96+ return & Allocator;
97+ }
98+ protected:
99+
100+ Function<ReturnType(ArgTypes..., CapturedTypes...)> & f;
101+ std::tuple<CapturedTypes...> storage;
102+ };
103+
104+ template <typename FunctionType, typename ... ToRemove> struct RemoveFirstArgs {};
80105
81106template <typename ReturnType, typename ... ArgTypes>
82- struct RemoveArgs <ReturnType(ArgTypes...)> {
107+ struct RemoveFirstArgs <ReturnType(ArgTypes...)> {
83108 typedef Function<ReturnType(ArgTypes...)> type;
84109};
85110
86111template <typename ReturnType, typename RemovedArg, typename ... ArgTypes, typename ToRemove0, typename ... ToRemove>
87- struct RemoveArgs <ReturnType(RemovedArg, ArgTypes...), ToRemove0, ToRemove...> {
112+ struct RemoveFirstArgs <ReturnType(RemovedArg, ArgTypes...), ToRemove0, ToRemove...> {
88113 static_assert (std::is_same<RemovedArg, ToRemove0>::value, " Type mismatch in argument removal" );
89- typedef typename RemoveArgs <ReturnType(ArgTypes...), ToRemove...>::type type;
114+ typedef typename RemoveFirstArgs <ReturnType(ArgTypes...), ToRemove...>::type type;
90115};
91116
117+ template <typename FunctionType0, typename FunctionType1, typename ... RemoveTypes> struct RemoveLastArgs ;
118+
119+ template <typename ReturnType, typename ... Types, typename ... RemoveTypes>
120+ struct RemoveLastArgs <ReturnType(Types...), ReturnType(), RemoveTypes...> {
121+ using type = void ;
122+ };
123+
124+ template <typename ReturnType, typename ... Types0, typename Transfer1, typename ... Types1, typename ... RemoveTypes>
125+ struct RemoveLastArgs <ReturnType(Types0...), ReturnType(Transfer1, Types1...), RemoveTypes...> {
126+ using type = typename std::conditional<
127+ std::is_same<std::tuple<Types1...>,std::tuple<RemoveTypes...> >::value,
128+ Function<ReturnType(Types0..., Transfer1)>,
129+ typename RemoveLastArgs<ReturnType(Types0..., Transfer1), ReturnType(Types1...), RemoveTypes...>::type
130+ >::type;
131+ };
132+
133+ template <typename ReturnType, typename ... ArgTypes, typename ... ParentTypes, typename ... CapturedTypes>
134+ Function<ReturnType(ArgTypes...)> bind_last (Function<ReturnType(ArgTypes...)> &&, Function<ReturnType(ParentTypes...)>& f, CapturedTypes... CapturedArgs) {
135+ using CaptureFP = CaptureLast<ReturnType (ArgTypes...), FunctorFPAllocator, CapturedTypes...>;
136+ static_assert (sizeof (CaptureFP) <= FUNCTOR_SIZE, " Size of bound arguments is too large" );
137+ CaptureFP * newf = reinterpret_cast <CaptureFP *>(detail::FunctorFPAllocator.alloc ());
138+ new (newf) CaptureFP (f,forward<CapturedTypes>(CapturedArgs)...);
139+ return Function<ReturnType (ArgTypes...)>(static_cast <FunctionInterface<ReturnType (ArgTypes...)>*>(newf));
140+ }
141+
142+
92143} // namespace detail
93144} // namespace functional
94145#endif // FUNCTIONAL_DETAIL_CAPTURE_HPP
0 commit comments