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 
46 #ifndef LIB_META_FUNCTION_CLOSURE_H
47 #define LIB_META_FUNCTION_CLOSURE_H
48 
49 #include "lib/meta/function.hpp"
51 
52 #include <functional>
53 #include <tuple>
54 
55 
56 
57 namespace lib {
58 namespace meta{
59 namespace func{
60 
61  using std::function;
62  using std::tuple;
63 
64 
65 
66 
67  namespace { // helpers for binding and applying a function to an argument tuple
68 
69  using std::get;
70 
76  template<uint n>
77  struct Apply;
78 
79 
80  template<> //__________________________________
81  struct Apply<0>
82  {
83  template<typename RET, class FUN, class TUP>
84  static RET
85  invoke (FUN& f, TUP&)
86  {
87  return f ();
88  }
89 
90  template<typename RET, class FUN, class TUP>
91  static RET
92  bind (FUN& f, TUP&)
93  {
94  return std::bind (f);
95  }
96  };
97 
98 
99  template<> //_________________________________
100  struct Apply<1>
101  {
102  template<typename RET, class FUN, class TUP>
103  static RET
104  invoke (FUN& f, TUP & arg)
105  {
106  return f (get<0>(arg));
107  }
108 
109  template<typename RET, class FUN, class TUP>
110  static RET
111  bind (FUN& f, TUP & arg)
112  {
113  return std::bind (f, get<0>(arg));
114  }
115  };
116 
117 
118  template<> //_________________________________
119  struct Apply<2>
120  {
121  template<typename RET, class FUN, class TUP>
122  static RET
123  invoke (FUN& f, TUP & arg)
124  {
125  return f ( get<0>(arg)
126  , get<1>(arg)
127  );
128  }
129 
130  template<typename RET, class FUN, class TUP>
131  static RET
132  bind (FUN& f, TUP & arg)
133  {
134  return std::bind (f, get<0>(arg)
135  , get<1>(arg)
136  );
137  }
138  };
139 
140 
141  template<> //_________________________________
142  struct Apply<3>
143  {
144  template<typename RET, class FUN, class TUP>
145  static RET
146  invoke (FUN& f, TUP & arg)
147  {
148  return f ( get<0>(arg)
149  , get<1>(arg)
150  , get<2>(arg)
151  );
152  }
153 
154  template<typename RET, class FUN, class TUP>
155  static RET
156  bind (FUN& f, TUP & arg)
157  {
158  return std::bind (f, get<0>(arg)
159  , get<1>(arg)
160  , get<2>(arg)
161  );
162  }
163  };
164 
165 
166  template<> //_________________________________
167  struct Apply<4>
168  {
169  template<typename RET, class FUN, class TUP>
170  static RET
171  invoke (FUN& f, TUP & arg)
172  {
173  return f ( get<0>(arg)
174  , get<1>(arg)
175  , get<2>(arg)
176  , get<3>(arg)
177  );
178  }
179 
180  template<typename RET, class FUN, class TUP>
181  static RET
182  bind (FUN& f, TUP & arg)
183  {
184  return std::bind (f, get<0>(arg)
185  , get<1>(arg)
186  , get<2>(arg)
187  , get<3>(arg)
188  );
189  }
190  };
191 
192 
193  template<> //_________________________________
194  struct Apply<5>
195  {
196  template<typename RET, class FUN, class TUP>
197  static RET
198  invoke (FUN& f, TUP & arg)
199  {
200  return f ( get<0>(arg)
201  , get<1>(arg)
202  , get<2>(arg)
203  , get<3>(arg)
204  , get<4>(arg)
205  );
206  }
207 
208  template<typename RET, class FUN, class TUP>
209  static RET
210  bind (FUN& f, TUP & arg)
211  {
212  return std::bind (f, get<0>(arg)
213  , get<1>(arg)
214  , get<2>(arg)
215  , get<3>(arg)
216  , get<4>(arg)
217  );
218  }
219  };
220 
221 
222  template<> //_________________________________
223  struct Apply<6>
224  {
225  template<typename RET, class FUN, class TUP>
226  static RET
227  invoke (FUN& f, TUP & arg)
228  {
229  return f ( get<0>(arg)
230  , get<1>(arg)
231  , get<2>(arg)
232  , get<3>(arg)
233  , get<4>(arg)
234  , get<5>(arg)
235  );
236  }
237 
238  template<typename RET, class FUN, class TUP>
239  static RET
240  bind (FUN& f, TUP & arg)
241  {
242  return std::bind (f, get<0>(arg)
243  , get<1>(arg)
244  , get<2>(arg)
245  , get<3>(arg)
246  , get<4>(arg)
247  , get<5>(arg)
248  );
249  }
250  };
251 
252 
253  template<> //_________________________________
254  struct Apply<7>
255  {
256  template<typename RET, class FUN, class TUP>
257  static RET
258  invoke (FUN& f, TUP & arg)
259  {
260  return f ( get<0>(arg)
261  , get<1>(arg)
262  , get<2>(arg)
263  , get<3>(arg)
264  , get<4>(arg)
265  , get<5>(arg)
266  , get<6>(arg)
267  );
268  }
269 
270  template<typename RET, class FUN, class TUP>
271  static RET
272  bind (FUN& f, TUP & arg)
273  {
274  return std::bind (f, get<0>(arg)
275  , get<1>(arg)
276  , get<2>(arg)
277  , get<3>(arg)
278  , get<4>(arg)
279  , get<5>(arg)
280  , get<6>(arg)
281  );
282  }
283  };
284 
285 
286  template<> //_________________________________
287  struct Apply<8>
288  {
289  template<typename RET, class FUN, class TUP>
290  static RET
291  invoke (FUN& f, TUP & arg)
292  {
293  return f ( get<0>(arg)
294  , get<1>(arg)
295  , get<2>(arg)
296  , get<3>(arg)
297  , get<4>(arg)
298  , get<5>(arg)
299  , get<6>(arg)
300  , get<7>(arg)
301  );
302  }
303 
304  template<typename RET, class FUN, class TUP>
305  static RET
306  bind (FUN& f, TUP & arg)
307  {
308  return std::bind (f, get<0>(arg)
309  , get<1>(arg)
310  , get<2>(arg)
311  , get<3>(arg)
312  , get<4>(arg)
313  , get<5>(arg)
314  , get<6>(arg)
315  , get<7>(arg)
316  );
317  }
318  };
319 
320 
321  template<> //_________________________________
322  struct Apply<9>
323  {
324  template<typename RET, class FUN, class TUP>
325  static RET
326  invoke (FUN& f, TUP & arg)
327  {
328  return f ( get<0>(arg)
329  , get<1>(arg)
330  , get<2>(arg)
331  , get<3>(arg)
332  , get<4>(arg)
333  , get<5>(arg)
334  , get<6>(arg)
335  , get<7>(arg)
336  , get<8>(arg)
337  );
338  }
339 
340  template<typename RET, class FUN, class TUP>
341  static RET
342  bind (FUN& f, TUP & arg)
343  {
344  return std::bind (f, get<0>(arg)
345  , get<1>(arg)
346  , get<2>(arg)
347  , get<3>(arg)
348  , get<4>(arg)
349  , get<5>(arg)
350  , get<6>(arg)
351  , get<7>(arg)
352  , get<8>(arg)
353  );
354  }
355  };
356 
357 
358 
359 
360 
361 
362  /* ===== Helpers for partial function application ===== */
363 
366  using std::_Placeholder;
367 
368 
374  template<typename TYPES, size_t i=1>
376  : PlaceholderTuple<typename TYPES::List>
377  { };
378 
379  template<typename X, typename TAIL, size_t i>
380  struct PlaceholderTuple<Node<X,TAIL>, i>
381  {
382  using TailPlaceholders = typename PlaceholderTuple<TAIL,i+1>::List;
383 
384  using List = Node<_Placeholder<i>, TailPlaceholders>;
385  };
386 
387  template<size_t i>
389  {
390  using List = NullType;
391  };
392 
393 
394 
395  using std::tuple_element;
396  using std::tuple_size;
397  using std::get;
398 
399 
418  template<typename SRC, typename TAR, size_t start>
420  {
421  template<size_t i>
422  using DestType = typename std::tuple_element<i, TAR>::type;
423 
424 
430  static constexpr bool
431  useArg (size_t idx)
432  {
433  return (start <= idx)
434  and (idx < start + std::tuple_size<SRC>());
435  }
436 
437 
438 
439  template<size_t idx, bool doPick = PartiallyInitTuple::useArg(idx)>
440  struct IndexMapper
441  {
442  SRC const& initArgs;
443 
444  operator DestType<idx>()
445  {
446  return std::get<idx-start> (initArgs);
447  }
448  };
449 
450  template<size_t idx>
451  struct IndexMapper<idx, false>
452  {
453  SRC const& initArgs;
454 
455  operator DestType<idx>()
456  {
457  return DestType<idx>();
458  }
459  };
460  };
461 
462  } // (END) impl-namespace
463 
464 
465 
466 
467  /* ======= core operations: closures and partial application ========= */
468 
476  template<typename SIG>
478  {
479  using Args = typename _Fun<SIG>::Args;
480  using Ret = typename _Fun<SIG>::Ret;
481 
482  using BoundFunc = function<Ret()>;
483 
484  enum { ARG_CNT = count<typename Args::List>::value };
485 
486 
489 
490  public:
492  : params_(args)
493  { }
494 
495  BoundFunc bind (SIG& f) { return Apply<ARG_CNT>::template bind<BoundFunc> (f, params_); }
496  BoundFunc bind (function<SIG> const& f) { return Apply<ARG_CNT>::template bind<BoundFunc> (f, params_); }
497 
498  Ret operator() (SIG& f) { return Apply<ARG_CNT>::template invoke<Ret> (f, params_); }
499  Ret operator() (function<SIG>& f) { return Apply<ARG_CNT>::template invoke<Ret> (f, params_); }
500  };
501 
502 
503 
511  template<typename SIG>
513  {
514  typedef typename _Fun<SIG>::Args Args;
515  typedef typename _Fun<SIG>::Ret Ret;
516 
517  function<Ret(void)> closure_;
518 
519  public:
520  FunctionClosure (SIG& f, Tuple<Args>& arg)
521  : closure_(TupleApplicator<SIG>(arg).bind(f))
522  { }
523  FunctionClosure (function<SIG> const& f, Tuple<Args>& arg)
524  : closure_(TupleApplicator<SIG>(arg).bind(f))
525  { }
526 
527  Ret operator() () { return closure_(); }
528 
529  typedef Ret result_type;
530  typedef void argument_type;
531  };
532 
533 
534 
535 
551  template<typename SIG, typename VAL>
552  class PApply
553  {
554  typedef typename _Fun<SIG>::Args Args;
555  typedef typename _Fun<SIG>::Ret Ret;
556  typedef typename Args::List ArgsList;
557  typedef typename VAL::List ValList;
558  typedef typename Types<ValList>::Seq ValTypes;
559 
560  enum { ARG_CNT = count<ArgsList>::value
561  , VAL_CNT = count<ValList> ::value
562  , ROFFSET = (VAL_CNT < ARG_CNT)? ARG_CNT-VAL_CNT : 0
563  };
564 
565 
566  // create list of the *remaining* arguments, after applying the ValList
567  typedef typename Splice<ArgsList, ValList>::Back LeftReduced;
568  typedef typename Splice<ArgsList, ValList, ROFFSET>::Front RightReduced;
569 
570  typedef typename Types<LeftReduced>::Seq ArgsL;
571  typedef typename Types<RightReduced>::Seq ArgsR;
572 
573 
574  // build a list, where each of the *remaining* arguments is replaced by a placeholder marker
575  typedef typename func::PlaceholderTuple<LeftReduced>::List TrailingPlaceholders;
576  typedef typename func::PlaceholderTuple<RightReduced>::List LeadingPlaceholders;
577 
578  // ... and splice these placeholders on top of the original argument type list,
579  // thus retaining the types to be closed, but setting a placeholder for each remaining argument
580  typedef typename Splice<ArgsList, TrailingPlaceholders, VAL_CNT>::List LeftReplaced;
581  typedef typename Splice<ArgsList, LeadingPlaceholders, 0 >::List RightReplaced;
582 
585 
586  // create a "builder" helper, which accepts exactly the value tuple elements
587  // and puts them at the right location, while default-constructing the remaining
588  // (=placeholder)-arguments. Using this builder helper, we can finally set up
589  // the argument tuples (Left/RightReplacedArgs) used for the std::bind call
590  template<class SRC, class TAR, size_t i>
591  using IdxSelectorL = typename PartiallyInitTuple<SRC, TAR, 0>::template IndexMapper<i>;
592 
593  template<class SRC, class TAR, size_t i>
594  using IdxSelectorR = typename PartiallyInitTuple<SRC, TAR, ROFFSET>::template IndexMapper<i>;
595 
598 
599 
603 
607 
608 
609  public:
610  typedef function<typename FunctionTypedef<Ret,ArgsL>::Sig> LeftReducedFunc;
611  typedef function<typename FunctionTypedef<Ret,ArgsR>::Sig> RightReducedFunc;
612 
613 
622  static LeftReducedFunc
623  bindFront (SIG const& f, Tuple<ValTypes> const& arg)
624  {
625  LeftReplacedArgs params {BuildL(arg)};
626  return func::Apply<ARG_CNT>::template bind<LeftReducedFunc> (f, params);
627  }
628 
637  static RightReducedFunc
638  bindBack (SIG const& f, Tuple<ValTypes> const& arg)
639  {
640  RightReplacedArgs params {BuildR(arg)};
641  return func::Apply<ARG_CNT>::template bind<RightReducedFunc> (f, params);
642  }
643  };
644 
645 
646 
647 
648 
649 
650 
651  namespace _composed { // repetitive impl.code for function composition
652  using std::bind;
653  using std::function;
654  using std::placeholders::_1;
655  using std::placeholders::_2;
656  using std::placeholders::_3;
657  using std::placeholders::_4;
658  using std::placeholders::_5;
659  using std::placeholders::_6;
660  using std::placeholders::_7;
661  using std::placeholders::_8;
662  using std::placeholders::_9;
663 
664  template<typename RES, typename F1, typename F2, uint n>
665  struct Build;
666 
667  template<typename RES, typename F1, typename F2>
668  struct Build<RES,F1,F2, 0 >
669  {
670  static function<RES> func(F1& f1, F2& f2) { return bind (f2, bind (f1)); }
671  };
672 
673  template<typename RES, typename F1, typename F2>
674  struct Build<RES,F1,F2, 1 >
675  {
676  static function<RES> func(F1& f1, F2& f2) { return bind (f2, bind (f1,_1)); }
677  };
678 
679  template<typename RES, typename F1, typename F2>
680  struct Build<RES,F1,F2, 2 >
681  {
682  static function<RES> func(F1& f1, F2& f2) { return bind (f2, bind (f1,_1,_2)); }
683  };
684 
685  template<typename RES, typename F1, typename F2>
686  struct Build<RES,F1,F2, 3 >
687  {
688  static function<RES> func(F1& f1, F2& f2) { return bind (f2, bind (f1,_1,_2,_3)); }
689  };
690 
691  template<typename RES, typename F1, typename F2>
692  struct Build<RES,F1,F2, 4 >
693  {
694  static function<RES> func(F1& f1, F2& f2) { return bind (f2, bind (f1,_1,_2,_3,_4)); }
695  };
696 
697  template<typename RES, typename F1, typename F2>
698  struct Build<RES,F1,F2, 5 >
699  {
700  static function<RES> func(F1& f1, F2& f2) { return bind (f2, bind (f1,_1,_2,_3,_4,_5)); }
701  };
702 
703  template<typename RES, typename F1, typename F2>
704  struct Build<RES,F1,F2, 6 >
705  {
706  static function<RES> func(F1& f1, F2& f2) { return bind (f2, bind (f1,_1,_2,_3,_4,_5,_6)); }
707  };
708 
709  template<typename RES, typename F1, typename F2>
710  struct Build<RES,F1,F2, 7 >
711  {
712  static function<RES> func(F1& f1, F2& f2) { return bind (f2, bind (f1,_1,_2,_3,_4,_5,_6,_7)); }
713  };
714 
715  template<typename RES, typename F1, typename F2>
716  struct Build<RES,F1,F2, 8 >
717  {
718  static function<RES> func(F1& f1, F2& f2) { return bind (f2, bind (f1,_1,_2,_3,_4,_5,_6,_7,_8)); }
719  };
720 
721  template<typename RES, typename F1, typename F2>
722  struct Build<RES,F1,F2, 9 >
723  {
724  static function<RES> func(F1& f1, F2& f2) { return bind (f2, bind (f1,_1,_2,_3,_4,_5,_6,_7,_8,_9)); }
725  };
726  } // (End) impl namespace (_composed)
727 
728 
729 
736  template<typename F1, typename RET>
738  {
739  typedef typename _Fun<F1>::Args Args;
740  typedef typename _Fun<F1>::Ret Ret1;
741 
742  typedef Types<Ret1> ArgsF2;
743  typedef typename FunctionTypedef<RET, ArgsF2>::Sig SigF2;
744  typedef typename FunctionTypedef<RET, Args>::Sig ChainedSig;
745 
746  enum { ARG_CNT = count<typename Args::List>::value };
747 
748 
749  public:
750  static function<ChainedSig>
751  chain (F1& f1, SigF2& f2)
752  {
754  }
755  static function<ChainedSig>
756  chain (F1& f1, function<SigF2>& f2)
757  {
758  return _composed::Build<ChainedSig,F1,function<SigF2>, ARG_CNT>::func (f1,f2);
759  }
760  };
761 
762 
763 
768  template<typename SIG, typename X, uint pos>
770  {
771  typedef typename _Fun<SIG>::Args Args;
772  typedef typename _Fun<SIG>::Ret Ret;
773  typedef typename Args::List ArgsList;
774  typedef typename Types<X>::List ValList;
775 
776  enum { ARG_CNT = count<ArgsList>::value };
777 
778  typedef typename Splice<ArgsList, ValList, pos>::Front RemainingFront;
779  typedef typename Splice<ArgsList, ValList, pos>::Back RemainingBack;
780  typedef typename func::PlaceholderTuple<RemainingFront>::List PlaceholdersBefore;
781  typedef typename func::PlaceholderTuple<RemainingBack,pos+1>::List PlaceholdersBehind;
782  typedef typename Append< typename Append< PlaceholdersBefore
783  , ValList >::List
784  , PlaceholdersBehind >::List PreparedArgs;
786 
787  using PreparedArgTypes = typename Types<PreparedArgs>::Seq;
788  using RemainingArgs = typename Types<ReducedArgs>::Seq;
789 
790  using ReducedSig = typename FunctionTypedef<Ret,RemainingArgs>::Sig;
791 
792  template<class SRC, class TAR, size_t i>
793  using IdxSelector = typename PartiallyInitTuple<SRC, TAR, pos>::template IndexMapper<i>;
794 
796 
797 
798 
799  public:
800  typedef function<ReducedSig> ReducedFunc;
801 
802  static ReducedFunc
803  reduced (SIG& f, Tuple<Types<X>> const& val)
804  {
806  return func::Apply<ARG_CNT>::template bind<ReducedFunc> (f, params);
807  }
808  };
809 
810 
811 
812  namespace { // ...helpers for specifying types in function declarations....
813 
814  template<typename RET, typename ARG>
815  struct _Sig
816  {
817  typedef typename FunctionTypedef<RET, ARG>::Sig Type;
819  };
820 
821  template<typename SIG, typename ARG>
822  struct _Clo
823  {
824  typedef typename _Fun<SIG>::Ret Ret;
825  typedef typename _Sig<Ret,ARG>::Type Signature;
827  };
828 
829  template<typename SIG1, typename SIG2>
830  struct _Chain
831  {
832  typedef typename _Fun<SIG1>::Args Args;
833  typedef typename _Fun<SIG2>::Ret Ret;
834  typedef typename FunctionTypedef<Ret, Args>::Sig Chained;
835  typedef function<Chained> Function;
836  };
837 
838  template<typename SIG>
839  struct _PapS
840  {
841  typedef typename _Fun<SIG>::Ret Ret;
842  typedef typename _Fun<SIG>::Args Args;
843  typedef typename Split<Args>::Head Arg;
844  typedef typename Split<Args>::Tail Rest;
845  typedef typename _Sig<Ret,Rest>::Type Signature;
846  typedef function<Signature> Function;
847  };
848 
849  template<typename SIG>
850  struct _PapE
851  {
852  typedef typename _Fun<SIG>::Ret Ret;
853  typedef typename _Fun<SIG>::Args Args;
854  typedef typename Split<Args>::End Arg;
855  typedef typename Split<Args>::Prefix Rest;
856  typedef typename _Sig<Ret,Rest>::Type Signature;
857  typedef function<Signature> Function;
858  };
859 
860  } // (End) argument type shortcuts
861 
862 
863 
864 
865  /* ========== function-style interface ============= */
866 
871  template<typename...ARG>
872  inline
873  typename _Sig<void, Types<ARG...>>::Applicator
874  tupleApplicator (std::tuple<ARG...>& args)
875  {
876  typedef typename _Sig<void,Types<ARG...>>::Type Signature;
877  return TupleApplicator<Signature> (args);
878  }
879 
880 
882  template<typename SIG, typename...ARG>
883  inline
884  typename _Fun<SIG>::Ret
885  apply (SIG& f, std::tuple<ARG...>& args)
886  {
887  typedef typename _Fun<SIG>::Ret Ret; //
888  typedef typename _Sig<Ret,Types<ARG...>>::Type Signature; // Note: deliberately re-building the Signature Type
889  return TupleApplicator<Signature> (args) (f); // in order to get better error messages here
890  }
891 
897  template<typename SIG, typename...ARG>
898  inline
899  typename _Clo<SIG,Types<ARG...>>::Type
900  closure (SIG& f, std::tuple<ARG...>& args)
901  {
902  typedef typename _Clo<SIG,Types<ARG...>>::Type Closure;
903  return Closure (f,args);
904  }
905 
906 
908  template<typename SIG, typename ARG>
909  inline
910  typename _PapS<SIG>::Function
911  applyFirst (SIG& f, ARG arg)
912  {
913  typedef typename _PapS<SIG>::Arg ArgType;
914  typedef Types<ArgType> ArgTypeSeq;
915  typedef Tuple<ArgTypeSeq> ArgTuple;
916  ArgTuple val(arg);
917  return PApply<SIG,ArgTypeSeq>::bindFront (f, val);
918  }
919 
921  template<typename SIG, typename ARG>
922  inline
923  typename _PapE<SIG>::Function
924  applyLast (SIG& f, ARG arg)
925  {
926  typedef typename _PapE<SIG>::Arg ArgType;
927  typedef Types<ArgType> ArgTypeSeq;
928  typedef Tuple<ArgTypeSeq> ArgTuple;
929  ArgTuple val(arg);
930  return PApply<SIG,ArgTypeSeq>::bindBack (f, val);
931  }
932 
933 
936  template<typename SIG, typename TERM>
937  inline
938  typename _PapE<SIG>::Function
939  bindLast (SIG& f, TERM const& arg)
940  {
941  typedef Types<TERM> ArgTypeSeq;
942  typedef Tuple<ArgTypeSeq> ArgTuple;
943  ArgTuple argT(arg);
944  enum { LAST_POS = -1 + count<typename _Fun<SIG>::Args::List>::value };
946  }
947 
948 
950  template<typename SIG1, typename SIG2>
951  inline
952  typename _Chain<SIG1,SIG2>::Function
953  chained (SIG1& f1, SIG2& f2)
954  {
955  typedef typename _Chain<SIG1,SIG2>::Ret Ret;
956  return FunctionComposition<SIG1,Ret>::chain (f1, f2);
957  }
958 
959 
960 
961 }}} // namespace lib::meta::func
962 #endif
_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.
_PapS< SIG >::Function applyFirst(SIG &f, ARG arg)
close the given function over the first argument
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. ...
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
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.
_PapE< SIG >::Function applyLast(SIG &f, ARG arg)
close the given function over the last argument
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.
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
Helper: separate parts of a type sequence.
splice a typelist like an overlay into an base typelist, starting at given index. ...
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...
_PapE< SIG >::Function bindLast(SIG &f, TERM const &arg)
bind the last function argument to an arbitrary term, which especially might be a (nested) binder...
_Chain< SIG1, SIG2 >::Function chained(SIG1 &f1, SIG2 &f2)
build a functor chaining the given functions
Build function types from given Argument types.
Definition: function.hpp:306
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...