September 25, 2016
On Sunday, 25 September 2016 at 16:26:11 UTC, Basile B. wrote:
> On Sunday, 25 September 2016 at 16:07:59 UTC, Basile B. wrote:
>> On Sunday, 25 September 2016 at 09:01:44 UTC, Namespace wrote:
>>> On Sunday, 25 September 2016 at 04:54:31 UTC, grampus wrote:
>>>> Dear all
>>>>
>>>> For example, I have a struct
>>>> struct point{int x;int y}
>>>> point a;
>>>>
>>>> Is there an easy way to access x and y by using a["x"] and a["y"]
>>>>
>>>> I guess I need to overload [], but can't figure out how.
>>>>
>>>> Someone can help? Thank you very much
>>>
>>> ----
>>> import std.stdio;
>>>
>>> struct Something
>>> {
>>>     int x, y;
>>>     float z;
>>>
>>>     auto opIndex()(string member) {
>>> 		switch (member) {
>>> 			case "x": return this.x;
>>> 			case "y": return this.y;
>>> 			case "z": return this.z;
>>> 			default: assert(0);
>>> 		}
>>>     }
>>> }
>>>
>>> void main(string[] args)
>>> {
>>>     Something s;
>>>     writeln(s["x"]);
>>>     writeln(s["z"]);
>>> }
>>> ----
>>
>> WooW I have to say that I'm mesmerized !
>>
>> How can this works ? "member" is run time variable so the return type shouldn't be inferable.
>
> Ther's no trick related to compile time:
>
> import std.stdio;
>
>  struct Something
>  {
>      int y;
>      float z;
>      double e;
>      float x = 1234;
>
>      auto opIndex()(const(char)[] member) {
>  		switch (member) {
>  			case "x": return this.x;
>  			case "y": return this.y;
>  			case "z": return this.z;
>             case "e": return this.e;
>  			default: assert(0);
>  		}
>      }
>  }
>
>  void main(string[] args)
>  {
>      Something s;
>      char[] member = "w".dup;
>      member[0]  += args.length;
>      writeln(s[member]);
>  }
>
> Can we get an explanation from a compiler guy ? It seems the the switch statement is already evaluated at compiled time...

"return" in "case" can infer...TIL. That's still a bit strange from the ABI point of view...because it means that under win32 it knows that z and x have to be returned in ST0, y in EAX...but cases are known at compile time...ok I think I get it :]. Depending on a static case, another CPU register is filled...
September 25, 2016
On 09/25/2016 06:26 PM, Basile B. wrote:
> Can we get an explanation from a compiler guy ? It seems the the switch
> statement is already evaluated at compiled time...

Lodovico has already answered this.

It's just an ordinary `auto` return type function. The actual return type is the common type of the different returns. Note that it falls apart when you add member with an incompatible type, like `string` or `Object`.
September 26, 2016
On Sunday, 25 September 2016 at 16:07:59 UTC, Basile B. wrote:
> WooW I have to say that I'm mesmerized !
>
> How can this works ? "member" is run time variable so the return type shouldn't be inferable.

The int fields are promoted to and returned as floats.
September 26, 2016
On Sunday, 25 September 2016 at 04:54:31 UTC, grampus wrote:
> Dear all
>
> For example, I have a struct
> struct point{int x;int y}
> point a;
>
> Is there an easy way to access x and y by using a["x"] and a["y"]
>
> I guess I need to overload [], but can't figure out how.
>
> Someone can help? Thank you very much

Here's my solution. It's very similar to Namespace's solution, the main difference being that it doesn't coerce the result to the common type of all the fields which may not be always possible and is also looses information. It also uses this.tupleof and foreach, so you don't have to write the switch cases by hand.

```
struct Something
{
    int x, y;
    float z;
    string w;

    auto opIndex(string member)
    {
        import std.variant : Algebraic;
        import std.traits : Fields;
        alias FieldTypes = Fields!(typeof(this));
        alias CommonType = Algebraic!(FieldTypes, typeof(null));

        switch (member)
        {
            foreach (idx, field; this.tupleof)
            {
                case this.tupleof[idx].stringof[5 .. $]:
                    return CommonType(this.tupleof[idx]);
            }

            default:
                assert (0, "Type `" ~ typeof(this).stringof ~
                   "` doesn't contain any member named `" ~ member ~ "`!");
                // or return CommonType(null);
        }
    }
}

void main()
{
    import std.stdio;
    auto s = Something(3, 4, 4.5, "asd");

    writeln(s["x"]);
    writeln(s["y"]);
    writeln(s["z"]);
    writeln(s["w"]);
    writeln(s["missing_field"]);
}
```

Application output:
3
4
4.5
asd

Application error:
core.exception.AssertError@/home/d623/f162.d(26): Type `Something` doesn't contain any member named `missing_field`!

The [5 .. $] trick is needed, because for e.g. idx = 0, this.tupleof[0].stringof returns "this.x" and we want to skip the "this." part (because otherwise the user would need to type s["this.x"]).
1 2
Next ›   Last »