Re: Enumap -- a lightweight AA alternative when your keys are enums

2015-09-21 Thread rcorre via Digitalmars-d-announce

On Wednesday, 16 September 2015 at 03:20:28 UTC, SimonN wrote:
Yes, the 0.4.x version works with my examples perfectly. Thanks 
for adding const support!


(I haven't tested yet every combination of const/mutable 
Enumap, const/mutable foraech-value, and direct/ref 
foreach-value. My examples are exactly what I'd do in normal 
projects anyway, mapping enum-values to ints.)


-- Simon


Good to hear!
I have a pretty long set of static asserts that tries every (?) 
operation between mutable/const/immutable enumaps to verify that 
they do/don't compile as expected, so hopefully that has most 
situations covered.


Re: Enumap -- a lightweight AA alternative when your keys are enums

2015-09-15 Thread SimonN via Digitalmars-d-announce

On Sunday, 13 September 2015 at 03:33:15 UTC, rcorre wrote:
I've released v0.4.0, which implements foreach with ref, and 
(hopefully) atones for my crimes against const-correctness. You 
should be able to modify values in a loop and work with 
const/immutable Enumaps.


Thanks for the feedback!


Yes, the 0.4.x version works with my examples perfectly. Thanks 
for adding const support!


(I haven't tested yet every combination of const/mutable Enumap, 
const/mutable foraech-value, and direct/ref foreach-value. My 
examples are exactly what I'd do in normal projects anyway, 
mapping enum-values to ints.)


-- Simon


Re: Enumap -- a lightweight AA alternative when your keys are enums

2015-09-12 Thread rcorre via Digitalmars-d-announce

On Friday, 11 September 2015 at 03:25:58 UTC, SimonN wrote:


It doesn't seem to matter whether I put const int, or int, in 
the foreach statement.


What's the idiomatic way to loop over a const Enumap? :-)

-- Simon


I've released v0.4.0, which implements foreach with ref, and 
(hopefully) atones for my crimes against const-correctness. You 
should be able to modify values in a loop and work with 
const/immutable Enumaps.


Thanks for the feedback!



Re: Enumap -- a lightweight AA alternative when your keys are enums

2015-09-11 Thread rcorre via Digitalmars-d-announce

On Friday, 11 September 2015 at 08:22:20 UTC, Kagamin wrote:

On Friday, 11 September 2015 at 02:17:25 UTC, rcorre wrote:
@nogc void donFancyHat(Enumap!(Attribute, int) map) { 
map.charisma += 1; }


BTW, what this means? Isn't Enumap a value type?


Correct, the parameter should be passed by ref in that example. 
Good catch!


Re: Enumap -- a lightweight AA alternative when your keys are enums

2015-09-11 Thread rcorre via Digitalmars-d-announce

On Friday, 11 September 2015 at 04:30:31 UTC, SimonN wrote:


Since I have been using "ref val" in the first loop, I expected 
the output to be instead:


e1: 101
e2: 102
e3: 103
e1: 104
e2: 105
e3: 106

-- Simon


Yep, as I was looking at the constness thing, I realized that ref 
parameters in foreach are totally broken. I may just have to use 
opApply instead of opSlice.


Re: Enumap -- a lightweight AA alternative when your keys are enums

2015-09-11 Thread Kagamin via Digitalmars-d-announce

On Friday, 11 September 2015 at 02:17:25 UTC, rcorre wrote:
@nogc void donFancyHat(Enumap!(Attribute, int) map) { 
map.charisma += 1; }


BTW, what this means? Isn't Enumap a value type?


Re: Enumap -- a lightweight AA alternative when your keys are enums

2015-09-10 Thread SimonN via Digitalmars-d-announce

On Friday, 11 September 2015 at 04:02:17 UTC, rcorre wrote:

On Friday, 11 September 2015 at 03:25:58 UTC, SimonN wrote:

Hi,
I've ran into a compilation error when iterating over a const 
Enumap. In the following code:


Interesting, thanks for pointing that out.
I don't think I did a great job with const-correctness here, 
I'll take a look tomorrow.
It should definitely be possible to iterate over (and index, 
etc...) a const/immutable Enumset, though you're right that it 
doesn't work right now.


No worries, take your time! Thanks for the quick clarification.

I've also tested a couple ways of assigning in a foreach. 
Continuing from my code above (struct A { Enumap!(MyEnum, int) 
map; /* ... */ }), I've tried this in the main function:


int some_value = 100;
A a;

foreach (MyEnum e, ref val; a.map)
val = ++some_value;
a.mutable_output();

foreach (MyEnum e, ref val; a.map)
a.map[e] = ++some_value;
a.mutable_output();

Output:

e1: 0
e2: 0
e3: 0
e1: 104
e2: 105
e3: 106

Since I have been using "ref val" in the first loop, I expected 
the output to be instead:


e1: 101
e2: 102
e3: 103
e1: 104
e2: 105
e3: 106

-- Simon


Re: Enumap -- a lightweight AA alternative when your keys are enums

2015-09-10 Thread rcorre via Digitalmars-d-announce

On Friday, 11 September 2015 at 03:25:58 UTC, SimonN wrote:

Hi,

this looks excellent! I've been playing around with it, and am 
looking forward to using it regularly.


I've ran into a compilation error when iterating over a const 
Enumap. In the following code:


import std.stdio;
import std.conv;
import enumap;

enum MyEnum { e1, e2, e3 }

struct A
{
Enumap!(MyEnum, int) map;

void mutable_output()
{
foreach (MyEnum e, int i; map)
writefln("%s: %d", e.to!string, i);
}

void const_output() const
{
foreach (MyEnum e, const int i; map)
writefln("%s: %d", e.to!string, i);
}
}

...the first method (mutable_output) compiles and works with no 
errors. The const method, however, gives:


source/app.d(19,13): Error: invalid foreach aggregate 
this.map,

define opApply(), range primitives, or use .tupleof".

It doesn't seem to matter whether I put const int, or int, in 
the foreach statement.


What's the idiomatic way to loop over a const Enumap? :-)

-- Simon


Interesting, thanks for pointing that out.
I don't think I did a great job with const-correctness here, I'll 
take a look tomorrow.
It should definitely be possible to iterate over (and index, 
etc...) a const/immutable Enumset, though you're right that it 
doesn't work right now.


Re: Enumap -- a lightweight AA alternative when your keys are enums

2015-09-10 Thread SimonN via Digitalmars-d-announce

On Friday, 11 September 2015 at 02:17:25 UTC, rcorre wrote:
I frequently find myself needing a data structure that maps 
each member of an enum to a value;
something similar what Java calls an EnumMap 
(http://docs.oracle.com/javase/7/docs/api/java/util/EnumMap.html).


I couldn't find any D implementation out there, so I wrote a 
little module for it.

Enumap is available on Github (https://github.com/rcorre/enumap)
and via dub (http://code.dlang.org/packages/enumap).
Docs are hosted at http://rcorre.github.io/enumap/.


Hi,

this looks excellent! I've been playing around with it, and am 
looking forward to using it regularly.


I've ran into a compilation error when iterating over a const 
Enumap. In the following code:


import std.stdio;
import std.conv;
import enumap;

enum MyEnum { e1, e2, e3 }

struct A
{
Enumap!(MyEnum, int) map;

void mutable_output()
{
foreach (MyEnum e, int i; map)
writefln("%s: %d", e.to!string, i);
}

void const_output() const
{
foreach (MyEnum e, const int i; map)
writefln("%s: %d", e.to!string, i);
}
}

...the first method (mutable_output) compiles and works with no 
errors. The const method, however, gives:


source/app.d(19,13): Error: invalid foreach aggregate 
this.map,

define opApply(), range primitives, or use .tupleof".

It doesn't seem to matter whether I put const int, or int, in the 
foreach statement.


What's the idiomatic way to loop over a const Enumap? :-)

-- Simon


Enumap -- a lightweight AA alternative when your keys are enums

2015-09-10 Thread rcorre via Digitalmars-d-announce
I frequently find myself needing a data structure that maps each 
member of an enum to a value;
something similar what Java calls an EnumMap 
(http://docs.oracle.com/javase/7/docs/api/java/util/EnumMap.html).


I couldn't find any D implementation out there, so I wrote a 
little module for it.

Enumap is available on Github (https://github.com/rcorre/enumap)
and via dub (http://code.dlang.org/packages/enumap).
Docs are hosted at http://rcorre.github.io/enumap/.

An Enumap is basically a thin wrapper that makes a static array 
look like an associative array:


---
enum Attribute {
 strength, dexterity, constitution, wisdom, intellect, charisma
}

Enumap!(Attribute,int) attributes;
attributes[Attribute.strength] = 10;
---

However, you might prefer an Enumap to an associative array if:

You like syntactic sugar:
---
// Boring!
if (hero.attributes[Attribute.wisdom] < 5) 
hero.drink(unidentifiedPotion);


// Fun! And Concise!
if (hero.attributes.wisdom < 5) hero.drink(unidentifiedPotion);
---

You like ranges:
---
// roll for stats!
attributes = generate!(() => uniform!"[]"(1, 20)).take(6);
---

You like default values:
---
int[Attribute] aa;
Enumap!(Attribute, int) em;

aa[Attribute.strength]; // Range violation!
em.strength;// 0
---

You like array-wise operations:
---
// note the convenient constructor function:
auto bonus = enumap(Attribute.charisma, 2, Attribute.wisdom, 1);

// level up! adds 2 to charisma and 1 to wisdom.
hero.attributes += bonus;
---

You dislike garbage day:
---
  void donFancyHat(int[Attribute] aa) { 
aa[Attribute.charisma] += 1; }
@nogc void donFancyHat(Enumap!(Attribute, int) map) { 
map.charisma += 1; }

---

Check it out, report bugs and all that!

P.S.

The above example used to read:
attributes = sequence!((a,n) => uniform!"[]"(1, 20)).take(6);
before Gary's recently posted article at 
http://nomad.so/2015/08/more-hidden-treasure-in-the-d-standard-library/ made me realize generate existed.