Lumiera  0.pre.03
»edit your freedom«
function-closure.hpp
Go to the documentation of this file.
1 /*
2  FUNCTION-CLOSURE.hpp - metaprogramming tools for closing a function over given arguments
3 
4  Copyright (C) Lumiera.org
5  2009, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
23 
52 #ifndef LIB_META_FUNCTION_CLOSURE_H
53 #define LIB_META_FUNCTION_CLOSURE_H
54 
55 #include "lib/meta/function.hpp"
57 #include "lib/util.hpp"
58 
59 #include <functional>
60 #include <utility>
61 #include <tuple>
62 
63 
64 
65 namespace lib {
66 namespace meta{
67 namespace func{
68 
69  using std::tuple;
70  using std::function;
71  using std::forward;
72  using std::move;
73 
74 
75 
76 
77  namespace { // helpers for binding and applying a function to an argument tuple
78 
79  using std::get;
80 
86  template<uint n>
87  struct Apply;
88 
89 
90  template<> //__________________________________
91  struct Apply<0>
92  {
93  template<typename RET, class FUN, class TUP>
94  static RET
95  invoke (FUN& f, TUP&)
96  {
97  return f ();
98  }
99 
100  template<typename RET, class FUN, class TUP>
101  static RET
102  bind (FUN& f, TUP&)
103  {
104  return std::bind (f);
105  }
106  };
107 
108 
109  template<> //_________________________________
110  struct Apply<1>
111  {
112  template<typename RET, class FUN, class TUP>
113  static RET
114  invoke (FUN& f, TUP & arg)
115  {
116  return f (get<0>(arg));
117  }
118 
119  template<typename RET, class FUN, class TUP>
120  static RET
121  bind (FUN& f, TUP & arg)
122  {
123  return std::bind (f, get<0>(arg));
124  }
125  };
126 
127 
128  template<> //_________________________________
129  struct Apply<2>
130  {
131  template<typename RET, class FUN, class TUP>
132  static RET
133  invoke (FUN& f, TUP & arg)
134  {
135  return f ( get<0>(arg)
136  , get<1>(arg)
137  );
138  }
139 
140  template<typename RET, class FUN, class TUP>
141  static RET
142  bind (FUN& f, TUP & arg)
143  {
144  return std::bind (f, get<0>(arg)
145  , get<1>(arg)
146  );
147  }
148  };
149 
150 
151  template<> //_________________________________
152  struct Apply<3>
153  {
154  template<typename RET, class FUN, class TUP>
155  static RET
156  invoke (FUN& f, TUP & arg)
157  {
158  return f ( get<0>(arg)
159  , get<1>(arg)
160  , get<2>(arg)
161  );
162  }
163 
164  template<typename RET, class FUN, class TUP>
165  static RET
166  bind (FUN& f, TUP & arg)
167  {
168  return std::bind (f, get<0>(arg)
169  , get<1>(arg)
170  , get<2>(arg)
171  );
172  }
173  };
174 
175 
176  template<> //_________________________________
177  struct Apply<4>
178  {
179  template<typename RET, class FUN, class TUP>
180  static RET
181  invoke (FUN& f, TUP & arg)
182  {
183  return f ( get<0>(arg)
184  , get<1>(arg)
185  , get<2>(arg)
186  , get<3>(arg)
187  );
188  }
189 
190  template<typename RET, class FUN, class TUP>
191  static RET
192  bind (FUN& f, TUP & arg)
193  {
194  return std::bind (f, get<0>(arg)
195  , get<1>(arg)
196  , get<2>(arg)
197  , get<3>(arg)
198  );
199  }
200  };
201 
202 
203  template<> //_________________________________
204  struct Apply<5>
205  {
206  template<typename RET, class FUN, class TUP>
207  static RET
208  invoke (FUN& f, TUP & arg)
209  {
210  return f ( get<0>(arg)
211  , get<1>(arg)
212  , get<2>(arg)
213  , get<3>(arg)
214  , get<4>(arg)
215  );
216  }
217 
218  template<typename RET, class FUN, class TUP>
219  static RET
220  bind (FUN& f, TUP & arg)
221  {
222  return std::bind (f, get<0>(arg)
223  , get<1>(arg)
224  , get<2>(arg)
225  , get<3>(arg)
226  , get<4>(arg)
227  );
228  }
229  };
230 
231 
232  template<> //_________________________________
233  struct Apply<6>
234  {
235  template<typename RET, class FUN, class TUP>
236  static RET
237  invoke (FUN& f, TUP & arg)
238  {
239  return f ( get<0>(arg)
240  , get<1>(arg)
241  , get<2>(arg)
242  , get<3>(arg)
243  , get<4>(arg)
244  , get<5>(arg)
245  );
246  }
247 
248  template<typename RET, class FUN, class TUP>
249  static RET
250  bind (FUN& f, TUP & arg)
251  {
252  return std::bind (f, get<0>(arg)
253  , get<1>(arg)
254  , get<2>(arg)
255  , get<3>(arg)
256  , get<4>(arg)
257  , get<5>(arg)
258  );
259  }
260  };
261 
262 
263  template<> //_________________________________
264  struct Apply<7>
265  {
266  template<typename RET, class FUN, class TUP>
267  static RET
268  invoke (FUN& f, TUP & arg)
269  {
270  return f ( get<0>(arg)
271  , get<1>(arg)
272  , get<2>(arg)
273  , get<3>(arg)
274  , get<4>(arg)
275  , get<5>(arg)
276  , get<6>(arg)
277  );
278  }
279 
280  template<typename RET, class FUN, class TUP>
281  static RET
282  bind (FUN& f, TUP & arg)
283  {
284  return std::bind (f, get<0>(arg)
285  , get<1>(arg)
286  , get<2>(arg)
287  , get<3>(arg)
288  , get<4>(arg)
289  , get<5>(arg)
290  , get<6>(arg)
291  );
292  }
293  };
294 
295 
296  template<> //_________________________________
297  struct Apply<8>
298  {
299  template<typename RET, class FUN, class TUP>
300  static RET
301  invoke (FUN& f, TUP & arg)
302  {
303  return f ( get<0>(arg)
304  , get<1>(arg)
305  , get<2>(arg)
306  , get<3>(arg)
307  , get<4>(arg)
308  , get<5>(arg)
309  , get<6>(arg)
310  , get<7>(arg)
311  );
312  }
313 
314  template<typename RET, class FUN, class TUP>
315  static RET
316  bind (FUN& f, TUP & arg)
317  {
318  return std::bind (f, get<0>(arg)
319  , get<1>(arg)
320  , get<2>(arg)
321  , get<3>(arg)
322  , get<4>(arg)
323  , get<5>(arg)
324  , get<6>(arg)
325  , get<7>(arg)
326  );
327  }
328  };
329 
330 
331  template<> //_________________________________
332  struct Apply<9>
333  {
334  template<typename RET, class FUN, class TUP>
335  static RET
336  invoke (FUN& f, TUP & arg)
337  {
338  return f ( get<0>(arg)
339  , get<1>(arg)
340  , get<2>(arg)
341  , get<3>(arg)
342  , get<4>(arg)
343  , get<5>(arg)
344  , get<6>(arg)
345  , get<7>(arg)
346  , get<8>(arg)
347  );
348  }
349 
350  template<typename RET, class FUN, class TUP>
351  static RET
352  bind (FUN& f, TUP & arg)
353  {
354  return std::bind (f, get<0>(arg)
355  , get<1>(arg)
356  , get<2>(arg)
357  , get<3>(arg)
358  , get<4>(arg)
359  , get<5>(arg)
360  , get<6>(arg)
361  , get<7>(arg)
362  , get<8>(arg)
363  );
364  }
365  };
366 
367 
368 
369 
370 
371 
372  /* ===== Helpers for partial function application ===== */
373 
376  using std::_Placeholder;
377 
378 
384  template<typename TYPES, size_t i=1>
386  : PlaceholderTuple<typename TYPES::List>
387  { };
388 
389  template<typename X, typename TAIL, size_t i>
390  struct PlaceholderTuple<Node<X,TAIL>, i>
391  {
392  using TailPlaceholders = typename PlaceholderTuple<TAIL,i+1>::List;
393 
394  using List = Node<_Placeholder<i>, TailPlaceholders>;
395  };
396 
397  template<size_t i>
399  {
400  using List = NullType;
401  };
402 
403 
404 
405  using std::tuple_element;
406  using std::tuple_size;
407  using std::get;
408 
409 
428  template<typename SRC, typename TAR, size_t start>
430  {
431  template<size_t i>
432  using DestType = typename std::tuple_element<i, TAR>::type;
433 
434 
440  static constexpr bool
441  useArg (size_t idx)
442  {
443  return (start <= idx)
444  and (idx < start + std::tuple_size<SRC>());
445  }
446 
447 
448 
449  template<size_t idx, bool doPick = PartiallyInitTuple::useArg(idx)>
450  struct IndexMapper
451  {
452  SRC const& initArgs;
453 
454  operator DestType<idx>()
455  {
456  return std::get<idx-start> (initArgs);
457  }
458  };
459 
460  template<size_t idx>
461  struct IndexMapper<idx, false>
462  {
463  SRC const& initArgs;
464 
465  operator DestType<idx>()
466  {
467  return DestType<idx>();
468  }
469  };
470  };
471 
472  } // (END) impl-namespace
473 
474 
475 
476 
477  /* ======= core operations: closures and partial application ========= */
478 
486  template<typename SIG>
488  {
489  using Args = typename _Fun<SIG>::Args;
490  using Ret = typename _Fun<SIG>::Ret;
491 
492  using BoundFunc = function<Ret()>;
493 
494  enum { ARG_CNT = count<typename Args::List>::value };
495 
496 
499 
500  public:
502  : params_(args)
503  { }
504 
505  BoundFunc bind (SIG& f) { return Apply<ARG_CNT>::template bind<BoundFunc> (f, params_); }
506  BoundFunc bind (function<SIG> const& f) { return Apply<ARG_CNT>::template bind<BoundFunc> (f, params_); }
507 
508  Ret operator() (SIG& f) { return Apply<ARG_CNT>::template invoke<Ret> (f, params_); }
509  Ret operator() (function<SIG>& f) { return Apply<ARG_CNT>::template invoke<Ret> (f, params_); }
510  };
511 
512 
513 
521  template<typename SIG>
523  {
524  typedef typename _Fun<SIG>::Args Args;
525  typedef typename _Fun<SIG>::Ret Ret;
526 
527  function<Ret(void)> closure_;
528 
529  public:
530  FunctionClosure (SIG& f, Tuple<Args>& arg)
531  : closure_(TupleApplicator<SIG>(arg).bind(f))
532  { }
533  FunctionClosure (function<SIG> const& f, Tuple<Args>& arg)
534  : closure_(TupleApplicator<SIG>(arg).bind(f))
535  { }
536 
537  Ret operator() () { return closure_(); }
538 
539  typedef Ret result_type;
540  typedef void argument_type;
541  };
542 
543 
544 
545 
566  template<typename SIG, typename VAL>
567  class PApply
568  {
569  typedef typename _Fun<SIG>::Args Args;
570  typedef typename _Fun<SIG>::Ret Ret;
571  typedef typename Args::List ArgsList;
572  typedef typename VAL::List ValList;
573  typedef typename Types<ValList>::Seq ValTypes;
574 
575  enum { ARG_CNT = count<ArgsList>::value
576  , VAL_CNT = count<ValList> ::value
577  , ROFFSET = (VAL_CNT < ARG_CNT)? ARG_CNT-VAL_CNT : 0
578  };
579 
580 
581  // create list of the *remaining* arguments, after applying the ValList
582  typedef typename Splice<ArgsList, ValList>::Back LeftReduced;
583  typedef typename Splice<ArgsList, ValList, ROFFSET>::Front RightReduced;
584 
585  typedef typename Types<LeftReduced>::Seq ArgsL;
586  typedef typename Types<RightReduced>::Seq ArgsR;
587 
588 
589  // build a list, where each of the *remaining* arguments is replaced by a placeholder marker
590  typedef typename func::PlaceholderTuple<LeftReduced>::List TrailingPlaceholders;
591  typedef typename func::PlaceholderTuple<RightReduced>::List LeadingPlaceholders;
592 
593  // ... and splice these placeholders on top of the original argument type list,
594  // thus retaining the types to be closed, but setting a placeholder for each remaining argument
595  typedef typename Splice<ArgsList, TrailingPlaceholders, VAL_CNT>::List LeftReplaced;
596  typedef typename Splice<ArgsList, LeadingPlaceholders, 0 >::List RightReplaced;
597 
600 
601  // create a "builder" helper, which accepts exactly the value tuple elements
602  // and puts them at the right location, while default-constructing the remaining
603  // (=placeholder)-arguments. Using this builder helper, we can finally set up
604  // the argument tuples (Left/RightReplacedArgs) used for the std::bind call
605  template<class SRC, class TAR, size_t i>
606  using IdxSelectorL = typename PartiallyInitTuple<SRC, TAR, 0>::template IndexMapper<i>;
607 
608  template<class SRC, class TAR, size_t i>
609  using IdxSelectorR = typename PartiallyInitTuple<SRC, TAR, ROFFSET>::template IndexMapper<i>;
610 
613 
614 
618 
622 
623 
624  public:
625  typedef function<typename BuildFunType<Ret,ArgsL>::Sig> LeftReducedFunc;
626  typedef function<typename BuildFunType<Ret,ArgsR>::Sig> RightReducedFunc;
627 
628 
637  static LeftReducedFunc
638  bindFront (SIG const& f, Tuple<ValTypes> const& arg)
639  {
640  LeftReplacedArgs params {BuildL(arg)};
641  return func::Apply<ARG_CNT>::template bind<LeftReducedFunc> (f, params);
642  }
643 
652  static RightReducedFunc
653  bindBack (SIG const& f, Tuple<ValTypes> const& arg)
654  {
655  RightReplacedArgs params {BuildR(arg)};
656  return func::Apply<ARG_CNT>::template bind<RightReducedFunc> (f, params);
657  }
658  };
659 
660 
661 
666  template<typename SIG, typename X, uint pos>
668  {
669  typedef typename _Fun<SIG>::Args Args;
670  typedef typename _Fun<SIG>::Ret Ret;
671  typedef typename Args::List ArgsList;
672  typedef typename Types<X>::List ValList;
673 
674  enum { ARG_CNT = count<ArgsList>::value };
675 
676  typedef typename Splice<ArgsList, ValList, pos>::Front RemainingFront;
677  typedef typename Splice<ArgsList, ValList, pos>::Back RemainingBack;
678  typedef typename func::PlaceholderTuple<RemainingFront>::List PlaceholdersBefore;
679  typedef typename func::PlaceholderTuple<RemainingBack,pos+1>::List PlaceholdersBehind;
680  typedef typename Append< typename Append< PlaceholdersBefore
681  , ValList >::List
682  , PlaceholdersBehind >::List PreparedArgs;
684 
685  using PreparedArgTypes = typename Types<PreparedArgs>::Seq;
686  using RemainingArgs = typename Types<ReducedArgs>::Seq;
687 
688  using ReducedSig = typename BuildFunType<Ret,RemainingArgs>::Sig;
689 
690  template<class SRC, class TAR, size_t i>
691  using IdxSelector = typename PartiallyInitTuple<SRC, TAR, pos>::template IndexMapper<i>;
692 
694 
695 
696 
697  public:
698  typedef function<ReducedSig> ReducedFunc;
699 
700  static ReducedFunc
701  reduced (SIG& f, Tuple<Types<X>> const& val)
702  {
704  return func::Apply<ARG_CNT>::template bind<ReducedFunc> (f, params);
705  }
706  };
707 
708 
709 
710  namespace { // ...helpers for specifying types in function declarations....
711 
712  using std::get;
713  using util::unConst;
714 
715 
716  template<typename RET, typename ARG>
717  struct _Sig
718  {
719  typedef typename BuildFunType<RET, ARG>::Sig Type;
721  };
722 
723  template<typename SIG, typename ARG>
724  struct _Clo
725  {
726  typedef typename _Fun<SIG>::Ret Ret;
727  typedef typename _Sig<Ret,ARG>::Type Signature;
729  };
730 
731  template<typename FUN1, typename FUN2>
732  struct _Chain
733  {
734  using Ret = typename _Fun<FUN2>::Ret;
735  using Args = typename _Fun<FUN1>::Args;
736 
737  using FunType = typename BuildFunType<Ret,Args>::Fun;
738  static auto adaptedFunType() { return FunType{}; }
739 
740 
741  template<typename F1, typename F2
742  ,typename RET, typename... ARGS>
743  static auto
744  composedFunctions (F1&& f1, F2&& f2, _Fun<RET(ARGS...)>)
745  {
746  tuple<F1,F2> binding{forward<F1> (f1)
747  ,forward<F2> (f2)
748  };
749  return [binding = move(binding)]
750  (ARGS ...args) -> RET
751  {
752  auto& functor1 = get<0>(binding);
753  auto& functor2 = get<1>(binding);
754  //
755  return functor2 (functor1 (forward<ARGS> (args)...));
756  };
757  }
758  };
759 
760  template<typename FUN>
761  struct _PapS
762  {
763  using Ret = typename _Fun<FUN>::Ret;
764  using Args = typename _Fun<FUN>::Args;
765  using Arg = typename Split<Args>::Head;
766  using Rest = typename Split<Args>::Tail;
767 
768  using FunType = typename BuildFunType<Ret,Rest>::Fun;
769  static auto adaptedFunType() { return FunType{}; }
770 
771 
772  template<typename F, typename A
773  ,typename RET, typename... ARGS>
774  static auto
775  bindFrontArg (F&& fun, A&& arg, _Fun<RET(ARGS...)>)
776  {
777  tuple<F,A> binding{forward<F> (fun)
778  ,forward<A> (arg)
779  };
780  return [binding = move(binding)]
781  (ARGS ...args) -> RET
782  {
783  auto& functor = get<0>(binding);
784  // //Warning: might corrupt ownership
785  return functor ( forward<A> (unConst (get<1>(binding)))
786  , forward<ARGS> (args)...);
787  };
788  }
789  };
790 
791  template<typename FUN>
792  struct _PapE
793  {
794  using Ret = typename _Fun<FUN>::Ret;
795  using Args = typename _Fun<FUN>::Args;
796  using Arg = typename Split<Args>::End;
797  using Rest = typename Split<Args>::Prefix;
798 
799  using FunType = typename BuildFunType<Ret,Rest>::Fun;
800  static auto adaptedFunType() { return FunType{}; }
801 
802 
803  template<typename F, typename A
804  ,typename RET, typename... ARGS>
805  static auto
806  bindBackArg (F&& fun, A&& arg, _Fun<RET(ARGS...)>)
807  {
808  tuple<F,A> binding{forward<F> (fun)
809  ,forward<A> (arg)
810  };
811  return [binding = move(binding)]
812  (ARGS ...args) -> RET
813  {
814  auto& functor = get<0>(binding);
815  //
816  return functor ( forward<ARGS> (args)...
817  , forward<A> (unConst (get<1>(binding))));
818  };
819  }
820  };
821 
822  } // (End) argument type shortcuts
823 
824 
825 
826 
827  /* ========== function-style interface ============= */
828 
833  template<typename...ARG>
834  inline
835  typename _Sig<void, Types<ARG...>>::Applicator
836  tupleApplicator (std::tuple<ARG...>& args)
837  {
838  typedef typename _Sig<void,Types<ARG...>>::Type Signature;
839  return TupleApplicator<Signature> (args);
840  }
841 
842 
845  template<typename SIG, typename...ARG>
846  inline
847  typename _Fun<SIG>::Ret
848  apply (SIG& f, std::tuple<ARG...>& args)
849  {
850  typedef typename _Fun<SIG>::Ret Ret; //
851  typedef typename _Sig<Ret,Types<ARG...>>::Type Signature; // Note: deliberately re-building the Signature Type
852  return TupleApplicator<Signature> (args) (f); // in order to get better error messages here
853  }
854 
860  template<typename SIG, typename...ARG>
861  inline
862  typename _Clo<SIG,Types<ARG...>>::Type
863  closure (SIG& f, std::tuple<ARG...>& args)
864  {
865  typedef typename _Clo<SIG,Types<ARG...>>::Type Closure;
866  return Closure (f,args);
867  }
868 
869 
872  template<typename FUN, typename ARG>
873  inline auto
874  applyFirst (FUN&& fun, ARG&& arg)
875  {
876  static_assert (_Fun<FUN>(), "expect something function-like");
877  return _PapS<FUN>::bindFrontArg (forward<FUN> (fun)
878  ,forward<ARG> (arg)
879  ,_PapS<FUN>::adaptedFunType());
880  }
881 
883  template<typename FUN, typename ARG>
884  inline auto
885  applyLast (FUN&& fun, ARG&& arg)
886  {
887  static_assert (_Fun<FUN>(), "expect something function-like");
888  return _PapE<FUN>::bindBackArg (forward<FUN> (fun)
889  ,forward<ARG> (arg)
890  ,_PapE<FUN>::adaptedFunType());
891  }
892 
893 
896  template<typename SIG, typename TERM>
897  inline
898  typename _PapE<SIG>::FunType::Functor
899  bindLast (SIG& f, TERM const& arg)
900  {
901  typedef Types<TERM> ArgTypeSeq;
902  typedef Tuple<ArgTypeSeq> ArgTuple;
903  ArgTuple argT(arg);
904  enum { LAST_POS = -1 + count<typename _Fun<SIG>::Args::List>::value };
906  }
907 
908 
912  template<typename FUN1, typename FUN2>
913  inline auto
914  chained (FUN1&& f1, FUN2&& f2)
915  {
916  static_assert (_Fun<FUN1>(), "expect something function-like for function-1");
917  static_assert (_Fun<FUN2>(), "expect something function-like for function-2");
918  using Chain = _Chain<FUN1,FUN2>;
919  return Chain::composedFunctions (forward<FUN1> (f1)
920  ,forward<FUN2> (f2)
921  ,Chain::adaptedFunType());
922  }
923 
924 
925 
926 }}} // namespace lib::meta::func
927 #endif
Build function types from given Argument types.
Definition: function.hpp:350
_Clo< SIG, Types< ARG... > >::Type closure(SIG &f, std::tuple< ARG... > &args)
close the given function over all arguments, using the values from the argument tuple.
Build a list of standard function argument placeholder types.
Bind a specific argument to an arbitrary value.
typename BuildTupleType< TYPES >::Type Tuple
Build a std::tuple from types given as type sequence.
Extensible Adapter to construct a distinct tuple from some arbitrary source type. ...
auto applyFirst(FUN &&fun, ARG &&arg)
close the given function over the first argument.
Helper for uniform access to function signature types.
Definition: function.hpp:108
static RightReducedFunc bindBack(SIG const &f, Tuple< ValTypes > const &arg)
do a partial function application, closing the last arguments f(a,b,c)->res + (b,c) yields f(a)->res
_PapE< SIG >::FunType::Functor bindLast(SIG &f, TERM const &arg)
bind the last function argument to an arbitrary term, which especially might be a (nested) binder...
static constexpr bool useArg(size_t idx)
define those index positions in the target tuple, where init arguments shall be used on construction...
Implementation namespace for support and library code.
Metaprogramming with tuples-of-types and the std::tuple record.
Partial function application Takes a function and a value tuple, using the latter to close function a...
Tuple< LeftReplacedTypes > LeftReplacedArgs
Tuple to hold all argument values, starting from left.
auto applyLast(FUN &&fun, ARG &&arg)
close the given function over the last argument
Metaprogramming tools for transforming functor types.
Tuple< Args > & params_
storing a ref to the parameter tuple
Metafunction counting the number of Types in the collection.
append lists-of-types
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
Helper: separate parts of a type sequence.
splice a typelist like an overlay into an base typelist, starting at given index. ...
auto chained(FUN1 &&f1, FUN2 &&f2)
build a functor chaining the given functions: feed the result of f1 into f2.
Closing a function over its arguments.
static LeftReducedFunc bindFront(SIG const &f, Tuple< ValTypes > const &arg)
do a partial function application, closing the first arguments f(a,b,c)->res + (a,b) yields f(c)->res
_Sig< void, Types< ARG... > >::Applicator tupleApplicator(std::tuple< ARG... > &args)
build a TupleApplicator, which embodies the given argument tuple and can be used to apply them to var...
Tuple< RightReplacedTypes > RightReplacedArgs
Tuple to hold all argument values, aligned to the end of the function argument list.
this Helper with repetitive specialisations for up to nine arguments is used either to apply a functi...
Closure-creating template.
_Fun< SIG >::Ret apply(SIG &f, std::tuple< ARG... > &args)
apply the given function to the argument tuple
apply a transformation (template) to each type in the list
Builder for a tuple instance, where only some ctor parameters are supplied, while the remaining argum...