Maik Klein
Maik Klein

Reputation: 16168

Filtering a tuple of containers with indices

template tupIndexToRange(alias Tup, Indices...){
  import std.meta;
  static if(Indicies.length == 0){
    alias tupIndexToRange = AliasSeq!();
  }
  else{
    alias tupIndexToRange = AliasSeq!(Tup[ Indices[0] ][], tupIndexToRange!(Tup,Indices[1..$]));
  }
}

void main{
  alias Integrals = AliasSeq!(Array!int, Array!float, Array!double);
  Integrals integrals;

  alias IntegralRange = tupIndexToRange!(integrals,0,1);
}

I want to achieve something like this

auto range = zip(tupIndexToRange!(integrals,0,1));

I think the main problem is that Tup[ Indices[0] ] doesn't work, to me it should have expanded to this AliasSeq!(itegrals[0][],integrals[1][]);

source/app.d(108,22): Error: inout method std.container.array.Array!int.Array.opIndex is not callable using a mutable object source/app.d(108,22): Error: inout method std.container.array.Array!int.Array.opIndex is not callable using a mutable object source/app.d(108,22): Error: only one index allowed to index int source/app.d(108,22): Error: only one index allowed to index int source/app.d(108,54): Error: template instance app.main.tupIndex!(__integrals_field_0, 1) error instantiating source/app.d(108,54): instantiated from here: tupIndex!(__integrals_field_0, 0, 1) source/app.d(108,54):
instantiated from here: tupIndex!(__integrals_field_0, __integrals_field_2, 0, 1) source/app.d(155,3): instantiated from here: tupIndex!(__integrals_field_0, __integrals_field_1, __integrals_field_2, 0, 1) dmd failed with exit code 1

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);

Maybe I need use mixins?

Upvotes: 0

Views: 146

Answers (1)

Maik Klein
Maik Klein

Reputation: 16168

I was able to solve this by using mixins.

string tupleToRange(Indicies...)(string name){
  string r = "zip(";
  foreach(i,idx;Indicies){
    r ~= name ~ "[" ~ idx.stringof ~"][]";
    if(i < Indicies.length -1){
      r~=",";
    }
  }
  r~=")";
  return r;
}

void main()
{
  import std.meta;
  import std.range;
  import std.container;
  import std.stdio;

  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 = mixin(tupleToRange!(0,1)("integrals"));
  writeln(range);
  foreach(e;range){
    writeln("element: ",e);
  }
}

But I still wonder if it would be possible without mixins.

Upvotes: 0

Related Questions