On 17.11.2015 15:32, maik klein wrote:
template tupIndexToRange(alias Tup, Indices...){
[snip]

I don't quite understand how that code is supposed to work. Maybe there's just some detail missing, but it could also be that your approach can't work.

This is roughly what I want to achieve

   alias Integrals = AliasSeq!(Array!int, Array!float, Array!double);
   Integrals integrals;
   integrals[0].insertBack(1);
   integrals[1].insertBack(2);
   integrals[2].insertBack(3);

   auto range = zip(tuple(integrals[0][],integrals[1][]).expand);
   writeln(range);
   foreach(e;range){
     writeln("element: ",e);
   }
But instead of "auto range =
zip(tuple(integrals[0][],integrals[1][]).expand);" I want it to be
generic "auto range = zip(tupIndexToRange!(integrals, AliasSeq!(0,
1)).expand);"

I think the problem can be split up into two independent tasks:

1) Select fields of a tuple by indices (to drop `integrals[3]`).
2) A "map" function for tuples (to apply `[]` to the selected arrays).

Here are two quick implementations of those applied to your problem:

----
template selectFromTuple(indices ...)
{
    auto selectFromTuple(Types...)(Types values)
    {
        import std.typecons: tuple, Tuple;
        static if (indices.length == 0) return Tuple!()();
        else
        {
            enum headIndex = indices[0];
            auto tail = .selectFromTuple!(indices[1 .. $])(values);
            return tuple(values[headIndex], tail.expand);
        }
    }
}

auto mapTuple(alias op, Types ...)(Types values)
{
    import std.meta: staticMap;
    import std.typecons: tuple;

    alias ResultType(T) = typeof(op(T.init));
    alias ResultTypes = staticMap!(ResultType, Types);

    ResultTypes results;
    foreach (i, v; values) results[i] = op(v);
    return tuple(results);
}

void main()
{
  import std.container.array;
  import std.meta: AliasSeq;
  import std.range: zip;
  import std.stdio: writeln;

  alias Integrals = AliasSeq!(Array!int, Array!float, Array!double);
  Integrals integrals;
  integrals[0].insertBack(1);
  integrals[1].insertBack(2);
  integrals[2].insertBack(3);

  auto range = integrals
    .selectFromTuple!(0, 1).expand
    .mapTuple!(a => a[]).expand
    .zip;

  writeln(range);
  foreach(e;range){
    writeln("element: ",e);
  }
}
----

That looks a lot like range based programming, which makes me think that there could be a way to use actual range algorithms from std.algorithm for this. But I don't see how.

Reply via email to