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:
parent
3f8606c474
commit
3f9565a156
3 changed files with 98 additions and 24 deletions
|
|
@ -76,21 +76,23 @@ using std::string;
|
|||
cout << "typeof( " << STRINGIFY(_TY_) << " )= " << lib::meta::typeStr<_TY_>() <<endl;
|
||||
|
||||
|
||||
template<typename...ARGS>
|
||||
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
|
||||
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::BuildIndexSeq;
|
||||
using lib::meta::BuildIdxIter;
|
||||
|
||||
|
||||
template<size_t i>
|
||||
|
|
@ -140,7 +142,7 @@ dispatch (ARGS...args)
|
|||
enum {SIZ = sizeof...(args)};
|
||||
|
||||
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...);
|
||||
}
|
||||
|
|
@ -149,8 +151,9 @@ dispatch (ARGS...args)
|
|||
int
|
||||
main (int, char**)
|
||||
{
|
||||
fun1 (1,2,3);
|
||||
fun2 (4,5,6);
|
||||
fun2 (1,2,3,4);
|
||||
fun2 (5,6);
|
||||
fun2 ();
|
||||
|
||||
auto arr = dispatch (2,3,4,5,6,7,8);
|
||||
cout << util::join(arr) << "| " << showSizeof(arr) <<endl;
|
||||
|
|
|
|||
|
|
@ -179,11 +179,12 @@ namespace meta {
|
|||
struct TupleConstructor
|
||||
: Tuple<TYPES>
|
||||
{
|
||||
using TypeIdxIterator = typename IndexIter<TYPES>::Seq;
|
||||
/** meta-sequence to drive instantiation of the ElmMapper */
|
||||
using SequenceIterator = typename BuildIdxIter<TYPES>::Ascending;
|
||||
|
||||
protected:
|
||||
template<class SRC, size_t...idx>
|
||||
TupleConstructor (SRC values, IndexSeq<idx...>*)
|
||||
TupleConstructor (SRC values, IndexSeq<idx...>)
|
||||
: Tuple<TYPES> (_ElmMapper_<SRC, Tuple<TYPES>, idx>{values}...)
|
||||
{ }
|
||||
|
||||
|
|
@ -191,7 +192,7 @@ namespace meta {
|
|||
public:
|
||||
template<class SRC>
|
||||
TupleConstructor (SRC values)
|
||||
: TupleConstructor (values, (TypeIdxIterator*)nullptr)
|
||||
: TupleConstructor (values, SequenceIterator())
|
||||
{ }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -57,7 +57,6 @@
|
|||
#include "lib/meta/typeseq-util.hpp"
|
||||
#include "lib/meta/util.hpp"
|
||||
|
||||
|
||||
namespace lib {
|
||||
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 */
|
||||
template<size_t...idx>
|
||||
struct IndexSeq
|
||||
|
|
@ -132,7 +152,10 @@ namespace meta {
|
|||
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>
|
||||
struct BuildIndexSeq
|
||||
{
|
||||
|
|
@ -141,36 +164,83 @@ namespace meta {
|
|||
template<size_t d>
|
||||
using OffsetBy = typename BuildIndexSeq<n-1>::template OffsetBy<d>::template AppendElm<n-1+d>;
|
||||
|
||||
template<size_t i>
|
||||
using FilledWith = typename BuildIndexSeq<n-1>::template FilledWith<i>::template AppendElm<i>;
|
||||
template<size_t x>
|
||||
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<>
|
||||
struct BuildIndexSeq<0>
|
||||
{
|
||||
using Ascending = IndexSeq<>;
|
||||
using Empty = IndexSeq<>;
|
||||
|
||||
template<size_t d>
|
||||
using OffsetBy = IndexSeq<>;
|
||||
using Ascending = Empty;
|
||||
|
||||
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>
|
||||
struct IndexIter;
|
||||
|
||||
/**
|
||||
* build a sequence of index numbers based on a type sequence
|
||||
*/
|
||||
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 */
|
||||
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)
|
||||
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>;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue