On Saturday, 2 March 2019 at 02:38:09 UTC, H. S. Teoh wrote:
On Sat, Mar 02, 2019 at 02:16:22AM +0000, Victor Porton via
Digitalmars-d-learn wrote:
[...]
Keep in mind that sequences produced by AliasSeq are
auto-expanding, meaning the above construct will automatically
flatten into a flat AliasSeq!(int, "x", float, "y", double,
"z"). If that's not what you want, you need to wrap your
subsequences in a separate, non-eponymous template.
[...]
I'm not sure what "alias enum" is supposed to mean; is that a
typo? Surely you mean just "alias"?
[...]
This line doesn't do what you think it does, because of
auto-expansion. It's essentially exactly the same thing as:
private alias processFields(T, name, Fields...) =
AliasSeq!(T, name, processFields!(Fields));
i.e., the nested AliasSeq has no effect.
[...]
If you want anything that retains a nested structure, you
cannot use AliasSeq because of auto-expansion. You need to
define your own, non-eponymous template container, e.g.:
template MySeq(T...) {
alias data = T;
}
alias processFields(T, name, Fields...) =
AliasSeq!(MySeq!(T, name), MySeq!(processFields!(Fields)));
The MySeq!(...) "protect" their contents from flattening into
the outer list, while the outer AliasSeq causes individual
MySeq!(...)'s to be promoted to the top level sequence rather
than producing a tree-like structure.
Note that to access the data inside a MySeq, you'll have to use
.data, for example:
alias fields = processFields!(int, "x", float, "y");
alias type0 = fields[0].data[0]; // int
string name0 = fields[0].data[1]; // "x"
alias type1 = fields[1].data[0]; // float
string name1 = fields[1].data[1]; // "y"
Hope this helps.
T
There's a package called bolts that has an AliasPack defined that
could allow you to do something like:
template split(seq...) if (seq.length % 2 == 0) {
static if (seq.length >= 2) {
alias Pair = AliasPack!(seq[0], seq[1]);
alias split = AliasSeq!(Pair, .split!(seq[2..$]));
} else {
alias split = AliasSeq!();
}
}
Running code: https://run.dlang.io/is/lfTOBz
Cheers,
- Ali