Jump to page: 1 2
Thread overview
Construct an used-defined hash table container type from an AA-literal expression
Jul 05, 2020
Per Nordlöw
Jul 05, 2020
ikod
Jul 05, 2020
Per Nordlöw
Jul 06, 2020
user1234
Jul 06, 2020
Jacob Carlborg
Jul 06, 2020
Atwork
Jul 06, 2020
Jacob Carlborg
Jul 06, 2020
user1234
Jul 06, 2020
Jacob Carlborg
Jul 07, 2020
Per Nordlöw
Jul 08, 2020
Jacob Carlborg
July 05, 2020
Is there a way to construct a custom written hash-table container (struct) from an AA-literal expression?
July 05, 2020
On Sunday, 5 July 2020 at 21:06:32 UTC, Per Nordlöw wrote:
> Is there a way to construct a custom written hash-table container (struct) from an AA-literal expression?

can opAssign help?

struct AA(K,V)
{
    void opAssign(V[K] aa)
    {
    }
}

void main()
{
    AA!(string, int) custom_aa;
    custom_aa = ["one":1, "two":2];
}
July 05, 2020
On Sunday, 5 July 2020 at 21:22:13 UTC, ikod wrote:
> struct AA(K,V)
> {
>     void opAssign(V[K] aa)
>     {
>     }
> }
>
> void main()
> {
>     AA!(string, int) custom_aa;
>     custom_aa = ["one":1, "two":2];
> }

Forget to mention that I want the assign call (to `opAssign`) in `main` to be non-(GC)heap allocating like when using C++'s std::initializer_list.
July 06, 2020
On Sunday, 5 July 2020 at 21:06:32 UTC, Per Nordlöw wrote:
> Is there a way to construct a custom written hash-table container (struct) from an AA-literal expression?

How about iterating the literal, e.g

---

    foreach (k,v; ["one":1, "two":2])
    {
        myCustomAA[k] = v;
    }

---
July 06, 2020
On Sunday, 5 July 2020 at 21:38:12 UTC, Per Nordlöw wrote:
> On Sunday, 5 July 2020 at 21:22:13 UTC, ikod wrote:
>> struct AA(K,V)
>> {
>>     void opAssign(V[K] aa)
>>     {
>>     }
>> }
>>
>> void main()
>> {
>>     AA!(string, int) custom_aa;
>>     custom_aa = ["one":1, "two":2];
>> }
>
> Forget to mention that I want the assign call (to `opAssign`) in `main` to be non-(GC)heap allocating like when using C++'s std::initializer_list.

Hereh we go ;)

---
import std;

struct AA
{
    void opIndexAssign(int v, string k) @nogc
    {}
}

void main(string[] args) @nogc
{
    AA myCustom;

    enum literal = ["one":1, "two":2].stringof[1..$-1];
    enum pairs   = literal.split(',').array;
    static foreach (p; pairs)
    {
        myCustom[mixin(p.split(':')[0])] = mixin(p.split(':')[1]);
    }
}
---
July 06, 2020
On Monday, 6 July 2020 at 01:43:43 UTC, user1234 wrote:

> Hereh we go ;)
>
> ---
> import std;
>
> struct AA
> {
>     void opIndexAssign(int v, string k) @nogc
>     {}
> }
>
> void main(string[] args) @nogc
> {
>     AA myCustom;
>
>     enum literal = ["one":1, "two":2].stringof[1..$-1];
>     enum pairs   = literal.split(',').array;
> ---

That split won't work if you have something more complicated, like struct values:

struct Foo
{
    int a;
    int b;
}

enum literal = ["one":Foo(1, 2), "two":Foo(3, 4)].stringof[1..$-1];
enum pairs = literal.split(',').array;
static assert(pairs == 4);

--
/Jacob Carlborg
July 06, 2020
On Monday, 6 July 2020 at 11:51:19 UTC, Jacob Carlborg wrote:
> On Monday, 6 July 2020 at 01:43:43 UTC, user1234 wrote:
>
>> Hereh we go ;)
>>
>> ---
>> import std;
>>
>> struct AA
>> {
>>     void opIndexAssign(int v, string k) @nogc
>>     {}
>> }
>>
>> void main(string[] args) @nogc
>> {
>>     AA myCustom;
>>
>>     enum literal = ["one":1, "two":2].stringof[1..$-1];
>>     enum pairs   = literal.split(',').array;
>> ---
>
> That split won't work if you have something more complicated, like struct values:
>
> struct Foo
> {
>     int a;
>     int b;
> }
>
> enum literal = ["one":Foo(1, 2), "two":Foo(3, 4)].stringof[1..$-1];
> enum pairs = literal.split(',').array;
> static assert(pairs == 4);
>
> --
> /Jacob Carlborg

Wouldn't work if the keys had , in them either. So don't even need a struct to break it.

enum literal = ["one,two": 12, "two,three": 23].stringof[1..$-1];

// Now split(",") won't work either.
July 06, 2020
On Monday, 6 July 2020 at 01:43:43 UTC, user1234 wrote:

> ---
> import std;
>
> struct AA
> {
>     void opIndexAssign(int v, string k) @nogc
>     {}
> }
>
> void main(string[] args) @nogc
> {
>     AA myCustom;
>
>     enum literal = ["one":1, "two":2].stringof[1..$-1];
>     enum pairs   = literal.split(',').array;
>     static foreach (p; pairs)
>     {
>         myCustom[mixin(p.split(':')[0])] = mixin(p.split(':')[1]);
>     }
> }
> ---

`static foreach` actual works for AA literals in `@nogc` functions. So there's no need complicate things with `.stringof`:

struct Foo
{
    int a;
    int b;
}

enum literal = ["one": Foo(1, 2), "two": Foo(3, 4)];

struct AA
{
    void opIndexAssign(Foo value, string k) @nogc
    {
    }
}

void main() @nogc
{
    AA aa;

    static foreach (k, v; literal)
    {
        aa[k] = v;
    }
}

July 06, 2020
On Sunday, 5 July 2020 at 21:06:32 UTC, Per Nordlöw wrote:
> Is there a way to construct a custom written hash-table container (struct) from an AA-literal expression?

I think your best bet is a tuple of pairs, because then you're not limited to compile time values, but it won't look pretty:

import std;

struct Pair
{
    string key;
    int value;
}

void main() @nogc
{
    auto a = tuple(Pair("foo", 1), Pair("bar", 2));
}

--
/Jacob Carlborg
July 07, 2020
On Monday, 6 July 2020 at 12:04:11 UTC, Jacob Carlborg wrote:
> void main() @nogc
> {
>     auto a = tuple(Pair("foo", 1), Pair("bar", 2));
> }
>
> --
> /Jacob Carlborg

Thanks.

What about construction and assignment from a static array of `Pair`'s? Wouldn't that be easier on the compiler?
« First   ‹ Prev
1 2