D - list of integral data elements

I am trying to use the following code to get a list of integral data elements from a class:

import std.stdio; import std.traits; class D { static string[] integralMembers = getIntegralMembers(); static string[] getIntegralMembers() { auto allMembers = __traits(allMembers, D); string[] tmp = new string[allMembers.length]; int ct = 0; for(int i = 0; i != allMembers.length; ++i) { bool isInteg = __traits(isIntegral, __traits(getMember, D, allMembers[i])); if(isInteg) { tmp[ct++] = allMembers[i]; } } string[] ret = new string[ct]; for(int i = 0; i != ct; ++i) { ret[i] = tmp[i]; } return ret; } int a; this() { } ~this() { } } void main() { auto integralMembers = D.integralMembers; foreach(mem; integralMembers) { writeln(mem); } } 

But compilation does not work with these errors:

 main.d(17): Error: variable i cannot be read at compile time main.d(17): Error: expression expected as second argument of __traits getMember main.d(19): Error: variable i cannot be read at compile time main.d(7): called from here: getIntegralMembers() 

How to compile this code?

+5
source share
1 answer

Despite the fact that the function will only work during compilation inside this program, it should still be compiled as a function that can be run at run time.

  • You need to declare allMembers as manifest constant:

     enum allMembers = __traits(allMembers, D); 

    allMembers is a tuple. If you use auto , it will be saved as a tuple of lines in the "stack", becoming the runtime, therefore it is not available for estimating compilation time for __traits .

  • You need to use foreach instead of for . foreach over tuple feature is that it will expand statically, so the index (and value) will be available for __traits .

Fixed program:

 import std.stdio; import std.traits; class D { static string[] integralMembers = getIntegralMembers(); static string[] getIntegralMembers() { enum allMembers = __traits(allMembers, D); string[] tmp = new string[allMembers.length]; int ct = 0; foreach(i, member; allMembers) { bool isInteg = __traits(isIntegral, __traits(getMember, D, member)); if(isInteg) { tmp[ct++] = allMembers[i]; } } string[] ret = new string[ct]; for(int i = 0; i != ct; ++i) { ret[i] = tmp[i]; } return ret; } int a; this() { } ~this() { } } void main() { auto integralMembers = D.integralMembers; foreach(mem; integralMembers) { writeln(mem); } } 
+7
source

Source: https://habr.com/ru/post/1204140/


All Articles