September 07, 2019
On Friday, 6 September 2019 at 18:31:29 UTC, Ali Çehreli wrote:
> ...
>   void enforceMemberWiseEquality(Demo d, const(float)[] values) {
>     switch (values.length) {
>     case 4:
>       assert(d.d == values[3]);
>       goto case;
>
>     case 3:
>       assert(d.c == values[2]);
>       goto case;
>
>     case 2:
>       assert(d.b == values[1]);
>       goto case;
>
>     case 1:
>       assert(d.a == values[0]);
>       goto default;
>
>     default:
>       break;
>     }
>   }

Please could you tell what "goto case;" do here?

Max
September 07, 2019
On Saturday, 7 September 2019 at 11:22:09 UTC, Maximillian wrote:
> Please could you tell what "goto case;" do here?

I see now "fall-through" [1].

To be honest I like this feature in C and I was sad it didn't work in D, at least now I know how to solve it. :)

Max.

[1] https://dlang.org/spec/statement.html#GotoStatement
"This is to set apart with C's error-prone implicit fall-through behavior. goto case; could be used for explicit fall-through:"
September 07, 2019
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
1 2
Next ›   Last »