Investigation: augment index iterator to deal with insufficient arguments

basically we want "all the rest" of the arguments to go to the recursive delegate
This commit is contained in:
Fischlurch 2017-09-28 01:40:23 +02:00
parent 3f8606c474
commit 3f9565a156
3 changed files with 98 additions and 24 deletions

View file

@ -76,21 +76,23 @@ using std::string;
cout << "typeof( " << STRINGIFY(_TY_) << " )= " << lib::meta::typeStr<_TY_>() <<endl; cout << "typeof( " << STRINGIFY(_TY_) << " )= " << lib::meta::typeStr<_TY_>() <<endl;
template<typename...ARGS>
void void
fun1 (int i, int j, int k) fun2 (ARGS... is)
{ {
cout << "FUN-1: "<<i<<" "<<j<<" "<<k<<" " <<endl; cout << "FUN-"<<sizeof...(is)<<": "<<util::join({is...}, " ") <<endl;
} }
void void
fun2 (int const& i, int const& j, int const& k) fun2 ()
{ {
cout << "FUN-2: "<<i<<" "<<j<<" "<<k<<" " <<endl; cout << "NO FUN" <<endl;
} }
using lib::meta::IndexSeq; using lib::meta::IndexSeq;
using lib::meta::BuildIndexSeq; using lib::meta::BuildIndexSeq;
using lib::meta::BuildIdxIter;
template<size_t i> template<size_t i>
@ -140,7 +142,7 @@ dispatch (ARGS...args)
enum {SIZ = sizeof...(args)}; enum {SIZ = sizeof...(args)};
using First = typename BuildIndexSeq<3>::Ascending; using First = typename BuildIndexSeq<3>::Ascending;
using Next = typename BuildIndexSeq<3>::OffsetBy<3>; using Next = typename BuildIdxIter<ARGS...>::template After<3>;
return dispatch_ (First(),Next(), args...); return dispatch_ (First(),Next(), args...);
} }
@ -149,8 +151,9 @@ dispatch (ARGS...args)
int int
main (int, char**) main (int, char**)
{ {
fun1 (1,2,3); fun2 (1,2,3,4);
fun2 (4,5,6); fun2 (5,6);
fun2 ();
auto arr = dispatch (2,3,4,5,6,7,8); auto arr = dispatch (2,3,4,5,6,7,8);
cout << util::join(arr) << "| " << showSizeof(arr) <<endl; cout << util::join(arr) << "| " << showSizeof(arr) <<endl;

View file

@ -179,11 +179,12 @@ namespace meta {
struct TupleConstructor struct TupleConstructor
: Tuple<TYPES> : Tuple<TYPES>
{ {
using TypeIdxIterator = typename IndexIter<TYPES>::Seq; /** meta-sequence to drive instantiation of the ElmMapper */
using SequenceIterator = typename BuildIdxIter<TYPES>::Ascending;
protected: protected:
template<class SRC, size_t...idx> template<class SRC, size_t...idx>
TupleConstructor (SRC values, IndexSeq<idx...>*) TupleConstructor (SRC values, IndexSeq<idx...>)
: Tuple<TYPES> (_ElmMapper_<SRC, Tuple<TYPES>, idx>{values}...) : Tuple<TYPES> (_ElmMapper_<SRC, Tuple<TYPES>, idx>{values}...)
{ } { }
@ -191,7 +192,7 @@ namespace meta {
public: public:
template<class SRC> template<class SRC>
TupleConstructor (SRC values) TupleConstructor (SRC values)
: TupleConstructor (values, (TypeIdxIterator*)nullptr) : TupleConstructor (values, SequenceIterator())
{ } { }
}; };

View file

@ -57,7 +57,6 @@
#include "lib/meta/typeseq-util.hpp" #include "lib/meta/typeseq-util.hpp"
#include "lib/meta/util.hpp" #include "lib/meta/util.hpp"
namespace lib { namespace lib {
namespace meta { namespace meta {
@ -124,6 +123,27 @@ namespace meta {
//////////////////////////TICKET #943 : temporary workaround until full C++14 compliance (need constexpr)
template<typename X>
constexpr inline X const&
max (X const& a, X const& b)
{
return a < b? b : a;
}
template<typename X>
constexpr inline X const&
min (X const& a, X const& b)
{
return b < a? b : a;
}
//////////////////////////TICKET #943 : temporary workaround until full C++14 compliance (need constexpr)
/** Hold a sequence of index numbers as template parameters */ /** Hold a sequence of index numbers as template parameters */
template<size_t...idx> template<size_t...idx>
struct IndexSeq struct IndexSeq
@ -132,7 +152,10 @@ namespace meta {
using AppendElm = IndexSeq<idx..., i>; using AppendElm = IndexSeq<idx..., i>;
}; };
/** build an `IndexSeq<0, 1, 2, ..., n-1>` */ /**
* build regular sequences of index number
* e.g. `IndexSeq<0, 1, 2, ..., n-1>`
*/
template<size_t n> template<size_t n>
struct BuildIndexSeq struct BuildIndexSeq
{ {
@ -141,36 +164,83 @@ namespace meta {
template<size_t d> template<size_t d>
using OffsetBy = typename BuildIndexSeq<n-1>::template OffsetBy<d>::template AppendElm<n-1+d>; using OffsetBy = typename BuildIndexSeq<n-1>::template OffsetBy<d>::template AppendElm<n-1+d>;
template<size_t i> template<size_t x>
using FilledWith = typename BuildIndexSeq<n-1>::template FilledWith<i>::template AppendElm<i>; using FilledWith = typename BuildIndexSeq<n-1>::template FilledWith<x>::template AppendElm<x>;
template<size_t c>
using First = typename BuildIndexSeq<min(c,n)>::Ascending;
template<size_t c>
using After = typename BuildIndexSeq<max(size_t(0),n-c)>::template OffsetBy<c>;
}; };
template<> template<>
struct BuildIndexSeq<0> struct BuildIndexSeq<0>
{ {
using Ascending = IndexSeq<>; using Empty = IndexSeq<>;
template<size_t d> using Ascending = Empty;
using OffsetBy = IndexSeq<>;
template<size_t> template<size_t>
using FilledWith = IndexSeq<>; using OffsetBy = Empty;
template<size_t>
using FilledWith = Empty;
template<size_t>
using First = Empty;
template<size_t>
using After = Empty;
}; };
/** build an index number sequence from a structured reference type */ /**
template<class REF> * build a sequence of index numbers based on a type sequence
struct IndexIter; */
template<typename...TYPES>
struct BuildIdxIter
{
enum {SIZ = sizeof...(TYPES) };
using Builder = BuildIndexSeq<SIZ>;
using Ascending = typename Builder::Ascending;
template<size_t d>
using OffsetBy = typename Builder::template OffsetBy<d>;
template<size_t x>
using FilledWith = typename Builder::template FilledWith<x>;
template<size_t c>
using First = typename Builder::template First<c>;
template<size_t c>
using After = typename Builder::template After<c>;
};
/** build an index number sequence from a type sequence */ /** build an index number sequence from a type sequence */
template<typename...TYPES> template<typename...TYPES>
struct IndexIter<Types<TYPES...>> struct BuildIdxIter<Types<TYPES...>>
{ {
/////TODO as long as Types is not variadic (#987), we need to strip NullType here (instead of just using sizeof...(TYPES) /////TODO as long as Types is not variadic (#987), we need to strip NullType here (instead of just using sizeof...(TYPES)
enum {SIZ = lib::meta::count<typename Types<TYPES...>::List>::value }; enum {SIZ = lib::meta::count<typename Types<TYPES...>::List>::value };
using Builder = BuildIndexSeq<SIZ>;
using Seq = typename BuildIndexSeq<SIZ>::Ascending; using Ascending = typename Builder::Ascending;
template<size_t d>
using OffsetBy = typename Builder::template OffsetBy<d>;
template<size_t x>
using FilledWith = typename Builder::template FilledWith<x>;
template<size_t c>
using First = typename Builder::template First<c>;
template<size_t c>
using After = typename Builder::template After<c>;
}; };