How to enumerate a sequence?
Simen Kjærås
simen.kjaras at gmail.com
Wed Feb 27 13:38:55 UTC 2019
On Wednesday, 27 February 2019 at 13:15:06 UTC, Victor Porton
wrote:
> .enumerate does not work for compile-time sequences. Consider
> for the sake of discussion the following nonsense (I know it
> cannot be done without enumerate) code:
>
> import std.meta;
> import std.range;
>
> string join(Fields...)() {
> enum f(size_t i) = __traits(identifier, Fields[i]);
> return staticMap!f(Fields.enumerate).join('\n'); // does not
> compile because of .enumerate
> }
>
> void main(string[] args)
> {
> string r = join!(int, float)();
> }
>
> How to make it compile?
Sadly, we cannot treat all compile-time values the same way we do
run-time values. In this case, that's evident with Fields being
an AliasSeq, not an array or other range. Since enumerate and
join operate on ranges, they get confused when you give them an
AliasSeq.
You also are probably not giving enough information about what
you're actually trying to do. First, __traits(identifier,
Fields[0]) simply fails to compile with the given arguments,
since int doesn't have an identifier. Second, it's very unclear
why you need an int index, since you're not using it in a way you
couldn't easier do without. Here's how I would implement your
join function wihout any further knowledge of these questions:
// Moved outside join due to the thrice-damned issue 5710
enum getIdentifier(T...) = __traits(identifier, T[0]);
string join(Fields...)() {
import std.range : join;
import std.meta : staticMap;
alias names = staticMap!(getIdentifier, Fields);
return [names].join('\n');
}
However, since you seem adamant you need the index as an int or
size_t:
string join(Fields...)() {
import std.range : join, iota;
import std.meta : staticMap, aliasSeqOf;
enum getIdentifier(size_t i) = __traits(identifier,
Fields[i]);
alias numbers = aliasSeqOf!(Fields.length.iota);
return [staticMap!(getIdentifier, numbers)].join('\n');
}
Also, fixed the calling code so it has actual identifiers:
void main(string[] args)
{
int i;
float f;
string r = join!(i, f)();
}
--
Simen
More information about the Digitalmars-d-learn
mailing list