Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

D traits - List of integral data members

Tags:

d

typetraits

ctfe

I am trying to use the following code to get a list of integral data members from 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 is failing 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 do I make this code compile?

like image 796
CuriousGeorge Avatar asked Oct 06 '14 23:10

CuriousGeorge


People also ask

What are the integral data types?

Integral data types are data types that represent whole numbers. They are used to store data that cannot be fractional, such as counts or measurements. Integral data types are typically stored as 32-bit or 64-bit values.

Which of the following is integral data?

The integral types are: char , signed char , unsigned char -8 bits. short int , signed short int , and unsigned short int -16 bits.

What are integral types in C#?

C# supports nine integral types: sbyte , byte , short , ushort , int , uint , long , ulong , and char . The integral types have the following sizes and ranges of values: The sbyte type represents signed 8-bit integers with values from -128 to 127 , inclusive.

What is integral type in C++?

Built-in types (also called fundamental types) are specified by the C++ language standard and are built into the compiler. Built-in types aren't defined in any header file. Built-in types are divided into three main categories: integral, floating-point, and void. Integral types represent whole numbers.


1 Answers

Even though the function will only run during compilation within that program, it must still be compilable as a function that can run at runtime.

  1. You need to declare allMembers as a manifest constant:

    enum allMembers = __traits(allMembers, D);
    

    allMembers is a tuple. If you use auto, it will be saved as a tuple of strings on the "stack", becoming a runtime value, thus inaccessible to compile-time evaluation for __traits.

  2. You need to use foreach instead of for. foreach over a tuple is special in that it will unroll statically, thus the index (and value) will be accessible to __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);
    }
}
like image 75
Vladimir Panteleev Avatar answered Sep 19 '22 02:09

Vladimir Panteleev