On 2019-09-06 11:14, Andrew Edwards wrote:
C++ allows the for following:

struct Demo
{
     float a, b, c, d;
     Demo() { a = b = c = d = 0.0f; }
     Demo(float _a, float _b, float _c, float _d) {
         a = _a;
         b = _b;
         c = _c;
         d = _d;
     }
     float  operator[] (size_t i) const { return (&a)[i]; } //[3]
     float& operator[] (size_t i) { return (&a)[i]; } //[4]
}

void fun(float col[3])
{
     // do fun stuff
}

void moreFun(const Demo& d = Demo(0.1f, 0.3f, 7.5f, 1.5f)) // [1]
{
     // you guessed it... more fun stuff
}

int main(int argv, const char** argc)
{
     Demo inst = Demo(0.1f, 0.3f, 7.5f, 1.5f);
     fun((float*)&inst); // [2]
     moreFun();
     return 0;
}

I'm seeking some pointers on how to define these in D so that I can instantiate them in D while still linking to the associated C++ library or object file for the implementation. The main points of contention are at [1] and [2] because I have no idea how to accomplish these.  I assume that I can accomplish [3] and [4] with opIndex() and opIndexAssign(), however I'm not understanding the slicing of the memory address at the first member variable. I know that by indexing the memory address at the member variable we are able treat the struct as an array but i do not understand how to implement it in D.

In D you can use the built-in property `.tupleof` [1], available for structs and classes. That will give you a tuple, not an array. To get an array you can just wrap it in square brackets:

Demo inst = Demo(0.1f, 0.3f, 7.5f, 1.5f);
auto tuple = inst.tupleof; // "tuple" is a tuple
auto arr = [tuple];
static assert(is(typeof(arr) == float[]));

Converting the tuple to an array like that only works then all of the elements of the tuple has the same type.

Here's an example:

struct Test
{
    float a, b, c, d;

    float opIndex(size_t i)
    in(i >= 0 && i <= 3)
    {
        return [this.tupleof][i];
    }

    float get(size_t i)()
    {
        return this.tupleof[i];
    }
}

void main()
{
    auto t = Test(1, 2, 3, 4);
    assert(t[3] == 4);

    assert(t.get!3 == 4);
}

If you can provide the index at compile time you don't need to create an array of the the tuple. The "get" method shows that technique. Unfortunately "opIndex" cannot take the index as a template parameter. Here's the runnable version [2].

[1] https://dlang.org/spec/struct.html#struct_instance_properties
[2] https://run.dlang.io/is/7QYljZ

--
/Jacob Carlborg

Reply via email to