Thread overview
How to correctly generate enums at compile time.
Apr 30, 2017
Kevin Balbas
Apr 30, 2017
jkpl
Apr 30, 2017
Kevin Balbas
Apr 30, 2017
jkpl
Apr 30, 2017
Kevin Balbas
Apr 30, 2017
jkpl
April 30, 2017
I've got the following code snippet, which almost does what I want.

struct TaggedType {}

@TaggedType
struct Foo {}

@TaggedType
struct Bar {}

string GenerateTypeEnum()
{
    string enumString = "enum TypeEnum {";
    foreach (name; __traits(allMembers, mixin(__MODULE__)))
    {
        import std.traits;
        static if (hasUDA!(mixin(name), TaggedType))
        {
            enumString ~= name;
            enumString ~= "Type,";
        }
    }
    enumString ~= "}";
    return enumString;
}

// generates enum TypeEnum {FooType,BarType,}
mixin(GenerateTypeEnum());

This works great, except that TypeEnum isn't accessible from other modules (undefined identifier 'TypeEnum'), which is kind of the point of doing this (I'm using the enum as a system-wide tag for inter-thread communication).  I can imagine why this would be the case, but it's a pretty serious problem.  Is there a way to do this?
April 30, 2017
On Sunday, 30 April 2017 at 20:05:59 UTC, Kevin Balbas wrote:
> I've got the following code snippet, which almost does what I want.
>
> struct TaggedType {}
>
> @TaggedType
> struct Foo {}
>
> @TaggedType
> struct Bar {}
>
> string GenerateTypeEnum()
> {
>     string enumString = "enum TypeEnum {";
>     foreach (name; __traits(allMembers, mixin(__MODULE__)))
>     {
>         import std.traits;
>         static if (hasUDA!(mixin(name), TaggedType))
>         {
>             enumString ~= name;
>             enumString ~= "Type,";
>         }
>     }
>     enumString ~= "}";
>     return enumString;
> }
>
> // generates enum TypeEnum {FooType,BarType,}
> mixin(GenerateTypeEnum());
>
> This works great, except that TypeEnum isn't accessible from other modules (undefined identifier 'TypeEnum'), which is kind of the point of doing this (I'm using the enum as a system-wide tag for inter-thread communication).  I can imagine why this would be the case, but it's a pretty serious problem.  Is there a way to do this?

if i put your sniped in b.d and import in a.d b then i'm able to access TypeEnum.
You r problem must be something stupid that's not related to UDA/mixins.

That leads to this question (sorry) but at least do you import the module that contains TypeEnum ?
April 30, 2017
On Sunday, 30 April 2017 at 20:58:36 UTC, jkpl wrote:
> On Sunday, 30 April 2017 at 20:05:59 UTC, Kevin Balbas wrote:
>> I've got the following code snippet, which almost does what I want.
>>
>> struct TaggedType {}
>>
>> @TaggedType
>> struct Foo {}
>>
>> @TaggedType
>> struct Bar {}
>>
>> string GenerateTypeEnum()
>> {
>>     string enumString = "enum TypeEnum {";
>>     foreach (name; __traits(allMembers, mixin(__MODULE__)))
>>     {
>>         import std.traits;
>>         static if (hasUDA!(mixin(name), TaggedType))
>>         {
>>             enumString ~= name;
>>             enumString ~= "Type,";
>>         }
>>     }
>>     enumString ~= "}";
>>     return enumString;
>> }
>>
>> // generates enum TypeEnum {FooType,BarType,}
>> mixin(GenerateTypeEnum());
>>
>> This works great, except that TypeEnum isn't accessible from other modules (undefined identifier 'TypeEnum'), which is kind of the point of doing this (I'm using the enum as a system-wide tag for inter-thread communication).  I can imagine why this would be the case, but it's a pretty serious problem.  Is there a way to do this?
>
> if i put your sniped in b.d and import in a.d b then i'm able to access TypeEnum.
> You r problem must be something stupid that's not related to UDA/mixins.
>
> That leads to this question (sorry) but at least do you import the module that contains TypeEnum ?

Yes, and in fact, if I manually comment out the code (in my actual program, not the test program) in the same module and replace it with a hard-coded enum, the other code can access it perfectly.  I wouldn't be surprised if it was something stupid, but I'm not even sure what could go wrong between those two cases.  I figured it was some kind of ordering thing, but I honestly have no idea.

Strangely enough, it does work fine in the test snippet, so I'm trying to figure out what could be going on since I literally copied the function verbatim from my test program to my main one.  Now that I've realized this I'm working on how to repro it in the smaller program.
April 30, 2017
On Sunday, 30 April 2017 at 21:13:07 UTC, Kevin Balbas wrote:
> On Sunday, 30 April 2017 at 20:58:36 UTC, jkpl wrote:
>> On Sunday, 30 April 2017 at 20:05:59 UTC, Kevin Balbas wrote:
> Strangely enough, it does work fine in the test snippet,

As well if you import the snippet in another module. That's what i tried to tell.
try to reduce step by step; The problem cant be the stuff you mix.


April 30, 2017
On Sunday, 30 April 2017 at 21:31:22 UTC, jkpl wrote:
> On Sunday, 30 April 2017 at 21:13:07 UTC, Kevin Balbas wrote:
>> On Sunday, 30 April 2017 at 20:58:36 UTC, jkpl wrote:
>>> On Sunday, 30 April 2017 at 20:05:59 UTC, Kevin Balbas wrote:
>> Strangely enough, it does work fine in the test snippet,
>
> As well if you import the snippet in another module. That's what i tried to tell.
> try to reduce step by step; The problem cant be the stuff you mix.

I was able to fix the error by simplifying and slashing down my actual code to a few hundred lines and 4 modules (3 plus a stub main), and even then the error only goes away if I compile the modules in a very specific order with dmd.  Namely, both the main() file and the file containing the enum have to be compiled after all of the things that use the enum, and one of the two dependents has to be compiled before the other.  I have no idea *why* that's the case, but it seems to be.

My actual project uses dub/visuald for building, so I don't really tinker with file ordering.  Is this a thing that's supposed to happen?
April 30, 2017
On Sunday, 30 April 2017 at 22:03:02 UTC, Kevin Balbas wrote:
> On Sunday, 30 April 2017 at 21:31:22 UTC, jkpl wrote:
>> On Sunday, 30 April 2017 at 21:13:07 UTC, Kevin Balbas wrote:
>>> On Sunday, 30 April 2017 at 20:58:36 UTC, jkpl wrote:
>>>> On Sunday, 30 April 2017 at 20:05:59 UTC, Kevin Balbas wrote:
>>> Strangely enough, it does work fine in the test snippet,
> [...]
> My actual project uses dub/visuald for building, so I don't really tinker with file ordering.  Is this a thing that's supposed to happen?

Hell no !