Re: Making enum join variadic

2014-05-02 Thread Nordlöw

artur


Thx!

Here's my final version that compiles and run:

import std.stdio: writeln;
import traits_ex: isEnum;
import std.typetuple: allSatisfy;

/** Join/Chain/Concatenate/Unite Enums $(D E1), $(D E2), ... into 
$(D E).
See also: 
http://forum.dlang.org/thread/f9vc6p$1b7k$1...@digitalmars.com

*/
template join(ES...) if (allSatisfy!(isEnum, ES)) {
mixin({
string r = enum join { ;
foreach (E; ES) {
import std.range: join;
r ~= [__traits(allMembers, E),  ].join(,);
}
return r ~ };
}());
}

unittest
{
enum E1 { a, b, c }
enum E2 { e, f, g }
enum E3 { h, i, j}
alias E1_ = join!(E1);
alias E12 = join!(E1, E2);
alias E123 = join!(E1, E2, E3);
writeln(E123.min, ,, E123.max);
}

Some final questions:

- Is join a good naming for this? Is chain better?
- Is it better to be verbose with joinEnums?
- What other useful enum algorithms are you missing?
- Should this perhaps go into Phobos? If so in what module? 
std.algorithm, range, traits?


Re: Making enum join variadic

2014-05-02 Thread Nordlöw

Its up: https://github.com/nordlow/justd/blob/master/enums.d


Re: Making enum join variadic

2014-05-02 Thread Philippe Sigaud via Digitalmars-d-learn
On Fri, May 2, 2014 at 12:59 PM, Nordlöw
digitalmars-d-learn@puremagic.com wrote:

 Some final questions:

 - Is join a good naming for this? Is chain better?
 - Is it better to be verbose with joinEnums?

I'd be verbose. It's an uncommon operation, bound to surprise a reader
a bit.It's better to type a few more letters.

I did not try to compile it, but what happens if the enum elements
have the same name ? The same min/max/values ?

Like this:

enum E1 { a, b, c }

alias E111 = join!(E1, E1, E1);



 - What other useful enum algorithms are you missing?
 - Should this perhaps go into Phobos? If so in what module? std.algorithm, 
 range, traits?

I would put it in std.typecons, since it's a type constructor



Re: Making enum join variadic

2014-05-02 Thread Nordlöw
I'd be verbose. It's an uncommon operation, bound to surprise a 
reader

a bit.It's better to type a few more letters.


See update.

I did not try to compile it, but what happens if the enum 
elements

have the same name ? The same min/max/values ?

Like this:

enum E1 { a, b, c }

alias E111 = join!(E1, E1, E1);


This should give a better error message, than current mixin error.
I'll work on that.


I would put it in std.typecons, since it's a type constructor


Ok.

Thx!


Re: Making enum join variadic

2014-05-02 Thread Nordlöw

On Friday, 2 May 2014 at 12:45:44 UTC, Nordlöw wrote:
I'd be verbose. It's an uncommon operation, bound to surprise 
a reader

a bit.It's better to type a few more letters.


See update.

I did not try to compile it, but what happens if the enum 
elements

have the same name ? The same min/max/values ?

Like this:

enum E1 { a, b, c }

alias E111 = join!(E1, E1, E1);


This should give a better error message, than current mixin 
error.

I'll work on that.


I would put it in std.typecons, since it's a type constructor


Ok.

Thx!


Here's my try at detecting member names collision at compile time:

template MemberNamesUnion(E...) if (allSatisfy!(isEnum, E))
{
bool[string] allMembers;   // used to detect member collisions
mixin({
string r = enum MemberNamesUnion { ;
foreach (T; E) {
import std.range: join;
foreach (member; __traits(allMembers, T)) {
static assert (member in allMembers, Member 
collision);

allMembers[member] = true;
}
r ~= [__traits(allMembers, T)].join(,) ~ ,;
}
return r ~  };
}());
}

It fails as

enums.d(25,46): Error: static variable allMembers cannot be read 
at compile time
enums.d(25,21):while evaluating: static assert(a in 
allMembers)


Is there a solution to this problem?


Re: Making enum join variadic

2014-05-02 Thread Meta via Digitalmars-d-learn

On Friday, 2 May 2014 at 13:38:39 UTC, Nordlöw wrote:
enums.d(25,46): Error: static variable allMembers cannot be 
read at compile time
enums.d(25,21):while evaluating: static assert(a in 
allMembers)


Is there a solution to this problem?


Associative arrays are not CTFE-able.


Re: Making enum join variadic

2014-05-02 Thread Nordlöw

On Friday, 2 May 2014 at 14:36:16 UTC, Meta wrote:

On Friday, 2 May 2014 at 13:38:39 UTC, Nordlöw wrote:
enums.d(25,46): Error: static variable allMembers cannot be 
read at compile time
enums.d(25,21):while evaluating: static assert(a in 
allMembers)


Is there a solution to this problem?


Associative arrays are not CTFE-able.


So that leaves me with using an array of bool and rank() then, I 
guess...


Re: Making enum join variadic

2014-05-02 Thread Nordlöw
So that leaves me with using an array of bool and rank() then, 
I guess...


Correction: I mean array of strings and find.


Re: Making enum join variadic

2014-05-02 Thread Artur Skawina via Digitalmars-d-learn
On 05/02/14 15:38, Nordlöw via Digitalmars-d-learn wrote:
 
 template MemberNamesUnion(E...) if (allSatisfy!(isEnum, E))
 {
 bool[string] allMembers;   // used to detect member collisions
 mixin({
 string r = enum MemberNamesUnion { ;
 foreach (T; E) {
 import std.range: join;
 foreach (member; __traits(allMembers, T)) {
 static assert (member in allMembers, Member collision);
 allMembers[member] = true;
 }
 r ~= [__traits(allMembers, T)].join(,) ~ ,;
 }
 return r ~  };
 }());
 }
 
 It fails as
 
 enums.d(25,46): Error: static variable allMembers cannot be read at compile 
 time
 enums.d(25,21):while evaluating: static assert(a in allMembers)
 
 Is there a solution to this problem?

Move the AA declaration to inside the lambda, remove the 'static'
from the assert, and fix the condition (member !in allMembers), then
it will work.

artur


Re: Making enum join variadic

2014-05-02 Thread Meta via Digitalmars-d-learn
On Friday, 2 May 2014 at 15:18:06 UTC, Artur Skawina via 
Digitalmars-d-learn wrote:

On 05/02/14 15:38, Nordlöw via Digitalmars-d-learn wrote:


template MemberNamesUnion(E...) if (allSatisfy!(isEnum, E))
{
bool[string] allMembers;   // used to detect member 
collisions

mixin({
string r = enum MemberNamesUnion { ;
foreach (T; E) {
import std.range: join;
foreach (member; __traits(allMembers, T)) {
static assert (member in allMembers, 
Member collision);

allMembers[member] = true;
}
r ~= [__traits(allMembers, T)].join(,) ~ ,;
}
return r ~  };
}());
}

It fails as

enums.d(25,46): Error: static variable allMembers cannot be 
read at compile time
enums.d(25,21):while evaluating: static assert(a in 
allMembers)


Is there a solution to this problem?


Move the AA declaration to inside the lambda, remove the 
'static'
from the assert, and fix the condition (member !in 
allMembers), then

it will work.

artur


But that will also move the compile time check to a runtime one.


Re: Making enum join variadic

2014-05-02 Thread Artur Skawina via Digitalmars-d-learn
On 05/02/14 17:27, Meta via Digitalmars-d-learn wrote:
 On Friday, 2 May 2014 at 15:18:06 UTC, Artur Skawina via Digitalmars-d-learn 
 wrote:
 On 05/02/14 15:38, Nordlöw via Digitalmars-d-learn wrote:

 template MemberNamesUnion(E...) if (allSatisfy!(isEnum, E))
 {
 bool[string] allMembers;   // used to detect member collisions
 mixin({
 string r = enum MemberNamesUnion { ;
 foreach (T; E) {
 import std.range: join;
 foreach (member; __traits(allMembers, T)) {
 static assert (member in allMembers, Member 
 collision);
 allMembers[member] = true;
 }
 r ~= [__traits(allMembers, T)].join(,) ~ ,;
 }
 return r ~  };
 }());
 }

 It fails as

 enums.d(25,46): Error: static variable allMembers cannot be read at compile 
 time
 enums.d(25,21):while evaluating: static assert(a in allMembers)

 Is there a solution to this problem?

 Move the AA declaration to inside the lambda, remove the 'static'
 from the assert, and fix the condition (member !in allMembers), then
 it will work.
 
 But that will also move the compile time check to a runtime one.

No; mixin arguments are always evaluated at CT.

artur


Making enum join variadic

2014-05-01 Thread Nordlöw
How can I make `join` variadic (by filling in njoin) in the 
following code?


import std.stdio: writeln;
import std.traits;

string enumsHelper(S...)(S s)
{
typeof(return) r;
foreach (i, e; s)
{
if (i = 1)
r ~= , ;
r ~= e;
}
return r;
}

/** Join/Chain/Concatenate/Unite Enums $(D E1), $(D E2), ... into 
$(D E).
See also: 
http://forum.dlang.org/thread/f9vc6p$1b7k$1...@digitalmars.com

*/
template join(string E, E1, E2)
{
const join = (enum  ~ E ~  {  ~
   enumsHelper(__traits(allMembers, E1)) ~ , ~
   enumsHelper(__traits(allMembers, E2)) ~  }
);
}

template njoin(string E, Ei...)
{
import std.algorithm: map;
enum string njoin = enum  ~ E ~  {  ~  ~  } ;
}

void main(string[] args)
{
enum E1 { A, B, C }
enum E2 { E, F, G }
mixin(join!(E12, E1, E2));
E12 e12;
writeln(e12.min, ,, e12.max);
}


Re: Making enum join variadic

2014-05-01 Thread bearophile via Digitalmars-d-learn

Nordlöw:

How can I make `join` variadic (by filling in njoin) in the 
following code?


When you have a D tuple (not Phobos tuple), and it contains 
values all of the same type, you can turn it into an array with 
just:


[mytuple]

Once you have an array of strings, you can use the normal phobos 
function to join the strings as you desire.


Bye,
bearophile


Re: Making enum join variadic

2014-05-01 Thread Artur Skawina via Digitalmars-d-learn
On 05/02/14 00:24, Nordlöw via Digitalmars-d-learn wrote:
 How can I make `join` variadic (by filling in njoin) in the following code?

   import std.array, std.range, std.algorithm;
   import std.stdio;

   template Njoin(ES...) {
  mixin({
 string r = enum Njoin { ;
 foreach (E; ES)
r ~= [__traits(allMembers, E),  ].join(,);
 return r ~ };
  }());
   }

   void main(string[] args)
   {
   enum E1 { A, B, C }
   enum E2 { E, F, G }
   alias E12 = Njoin!(E1, E2);
   E12 e12;
   writeln(e12.min, ,, e12.max);
   }

artur