June 24, 2018
On Sunday, June 24, 2018 23:53:09 Timoses via Digitalmars-d wrote:
> On Sunday, 24 June 2018 at 23:34:49 UTC, Per Nordlöw wrote:
> > Provided that
> >
> >     __traits(allMembers, E)
> >
> > is a cheap operation as it's called once for every enumerator. I could get it out of the loop; if I do as
> >
> >     @property string toString() @safe pure nothrow @nogc
> >     {
> >
> >         final switch (_enum)
> >         {
> >
> >             enum members = __traits(allMembers, E);
>
> enum members = [_traits(allMembers, E)];
>
> seems to work

Or if you want it to stay an AliasSeq, then just use Alias or AliasSeq on it. e.g.

alias members = AliasSeq!(__traits(allMembers, E));

Given that the result of __traits in this case is an AliasSeq, I have no idea why the gramar doesn't allow you to just use the result of __traits directly as an AliasSeq with something like

alias members = __traits(allMembers, E);

but it doesn't. So, you have to wrap it, dumb as that may be. There's a bug report about it in bugzilla somewhere.

- Jonathan M Davis


June 25, 2018
On Sunday, 24 June 2018 at 23:53:09 UTC, Timoses wrote:
> enum members = [_traits(allMembers, E)];
>
> seems to work

Great!

Now becomes:


@safe:

/** Enumeration wrapper that uses optimized conversion to string (via `toString`
 * member).
 */
struct Enum(E)
if (is(E == enum))
{
    @property string toString() @safe pure nothrow @nogc
    {
        enum members = [__traits(allMembers, E)];
        final switch (_enum)
        {
            static foreach (index, member; members)
            {
                static if (index == 0 ||
                           (__traits(getMember, E, members[index - 1]) !=
                            __traits(getMember, E, member)))
                {
                case __traits(getMember, E, member):
                    return member;
                }
            }
        }
    }
    E _enum;                    // the wrapped enum
    alias _enum this;
}
June 25, 2018
On Monday, 25 June 2018 at 00:35:40 UTC, Jonathan M Davis wrote:
> Or if you want it to stay an AliasSeq, then just use Alias or AliasSeq on it. e.g.
>
> alias members = AliasSeq!(__traits(allMembers, E));

Thanks! Should we prefer this over

    enum members = [__traits(allMembers, E)];

?
June 25, 2018
On Monday, 25 June 2018 at 07:43:53 UTC, Per Nordlöw wrote:
> On Monday, 25 June 2018 at 00:35:40 UTC, Jonathan M Davis wrote:
>> Or if you want it to stay an AliasSeq, then just use Alias or AliasSeq on it. e.g.
>>
>> alias members = AliasSeq!(__traits(allMembers, E));
>
> Thanks! Should we prefer this over
>
>     enum members = [__traits(allMembers, E)];
>
> ?

I tested on a really big enum:

    alias members = AliasSeq!(__traits(allMembers, E));

is faster. :)
June 25, 2018
On Monday, June 25, 2018 07:43:53 Per Nordlöw via Digitalmars-d wrote:
> On Monday, 25 June 2018 at 00:35:40 UTC, Jonathan M Davis wrote:
> > Or if you want it to stay an AliasSeq, then just use Alias or AliasSeq on it. e.g.
> >
> > alias members = AliasSeq!(__traits(allMembers, E));
>
> Thanks! Should we prefer this over
>
>      enum members = [__traits(allMembers, E)];

Which is better depends on what you're doing.

    alias members = AliasSeq!(_traits(allMembers, E));

gives you an AliasSeq, whereas

    enum members = [__traits(allMembers, E)];

gives you a dynamic array. The AliasSeq means needing to use templates to operate on it, whereas using the dynamic array means using CTFE to operate on it. If you're just going to use a static foreach on it, I wouldn't expect it to matter much which you use, but ultimately, you'll have to see what works best with your exact use case. In the long run, once newCTFE is complete, I suspect that using CTFE where possible instead of templates is going to be better, but I think that it tends to be less of a clear win with how inefficient CTFE currently is. But again, it depends on what exactly the code is doing.

- Jonathan M Davis


June 25, 2018
On Monday, 25 June 2018 at 00:35:40 UTC, Jonathan M Davis wrote:
> On Sunday, June 24, 2018 23:53:09 Timoses via Digitalmars-d wrote:
>> On Sunday, 24 June 2018 at 23:34:49 UTC, Per Nordlöw wrote:
>> > Provided that
>> >
>> >     __traits(allMembers, E)
>> >
>> > is a cheap operation as it's called once for every enumerator. I could get it out of the loop; if I do as
>> >
>> >     @property string toString() @safe pure nothrow @nogc
>> >     {
>> >
>> >         final switch (_enum)
>> >         {
>> >
>> >             enum members = __traits(allMembers, E);
>>
>> enum members = [_traits(allMembers, E)];
>>
>> seems to work
>
> Or if you want it to stay an AliasSeq, then just use Alias or AliasSeq on it. e.g.
>
> alias members = AliasSeq!(__traits(allMembers, E));
>
> Given that the result of __traits in this case is an AliasSeq, I have no idea why the gramar doesn't allow you to just use the result of __traits directly as an AliasSeq with something like
>
> alias members = __traits(allMembers, E);
>
> but it doesn't. So, you have to wrap it, dumb as that may be. There's a bug report about it in bugzilla somewhere.

https://issues.dlang.org/show_bug.cgi?id=16390

I guess? First search result : D


1 2 3
Next ›   Last »