Filtering a tuple of containers with indices
anonymous via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Tue Nov 17 07:48:10 PST 2015
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.
More information about the Digitalmars-d-learn
mailing list