Re: Constructing an enum using the members of an AliasSeq as enumerator names

2016-04-28 Thread Nordlöw via Digitalmars-d-learn

On Wednesday, 27 April 2016 at 15:30:55 UTC, ag0aep6g wrote:
That takes longer to compile, though. Probably needs more 
memory as well.


Thanks!

Added here

https://github.com/nordlow/phobos-next/blob/master/src/typecons_ex.d#L425


Re: Constructing an enum using the members of an AliasSeq as enumerator names

2016-04-27 Thread ag0aep6g via Digitalmars-d-learn

On 27.04.2016 13:06, Nordlöw wrote:

/** Returns: a `string` containing the definition of an `enum` named
`name` and
 with enumerator names given by `Es`, optionally prepended with
`prefix` and
 appended with `suffix`.

 TODO Move to Phobos std.typecons
*/
string makeEnumDefinitionString(string name,
 string prefix = `_`,
 string suffix = ``,
 Es...)()
 if (Es.length >= 1)
{
 typeof(return) s = `enum ` ~ name ~ ` { `;
 foreach (E; Es)
 {
 s ~= prefix ~ E.stringof ~ suffix ~ `, `;
 }
 s ~= `}`;
 return s;
}

@safe pure nothrow @nogc unittest
{
 import std.meta : AliasSeq;
 alias Types = AliasSeq!(byte, short);
 mixin(makeEnumDefinitionString!("Type", `_`, `_`, Types));
 static assert(is(Type == enum));
 static assert(Type._byte_.stringof == "_byte_");
 static assert(Type._short_.stringof == "_short_");
}

Can it be made more elegant?


I'd hide the string mixin in the template:


template makeEnumFromSymbolNames(string prefix = `_`,
 string suffix = ``,
 Es...)
if (Es.length >= 1)
{
enum members = {
string s = "";
foreach (E; Es)
{
s ~= prefix ~ E.stringof ~ suffix ~ `, `;
}
return s;
}();
mixin("enum makeEnumFromSymbolNames {" ~ members ~ "}");
}

@safe pure nothrow @nogc unittest
{
import std.meta : AliasSeq;
alias Types = AliasSeq!(byte, short);
alias Type = makeEnumFromSymbolNames!(`_`, `_`, Types);
static assert(is(Type == enum));
static assert(Type._byte_.stringof == "_byte_");
static assert(Type._short_.stringof == "_short_");
}


The `foreach` could be replaced with `map` and `joiner`, but I'm not 
sure if that would be an improvement.


`format` might be interesting:


import std.format;
import std.meta: staticMap;
enum stringOf(t...) = t[0].stringof;
mixin(format(
"enum makeEnumFromSymbolNames {%-(" ~ prefix ~ "%s" ~ suffix 
~"%|, %)}",

[staticMap!(stringOf, Es)]
));


That takes longer to compile, though. Probably needs more memory as well.


Re: Constructing an enum using the members of an AliasSeq as enumerator names

2016-04-27 Thread Nordlöw via Digitalmars-d-learn

On Wednesday, 27 April 2016 at 10:49:54 UTC, Nordlöw wrote:
What's the easiest way to create an `enum` using the symbol 
names of an `AliasSeq` as enumerator names?


/** Returns: a `string` containing the definition of an `enum` 
named `name` and
with enumerator names given by `Es`, optionally prepended 
with `prefix` and

appended with `suffix`.

TODO Move to Phobos std.typecons
*/
string makeEnumDefinitionString(string name,
string prefix = `_`,
string suffix = ``,
Es...)()
if (Es.length >= 1)
{
typeof(return) s = `enum ` ~ name ~ ` { `;
foreach (E; Es)
{
s ~= prefix ~ E.stringof ~ suffix ~ `, `;
}
s ~= `}`;
return s;
}

@safe pure nothrow @nogc unittest
{
import std.meta : AliasSeq;
alias Types = AliasSeq!(byte, short);
mixin(makeEnumDefinitionString!("Type", `_`, `_`, Types));
static assert(is(Type == enum));
static assert(Type._byte_.stringof == "_byte_");
static assert(Type._short_.stringof == "_short_");
}

Can it be made more elegant?

Destroy!


Constructing an enum using the members of an AliasSeq as enumerator names

2016-04-27 Thread Nordlöw via Digitalmars-d-learn
What's the easiest way to create an `enum` using the symbol names 
of an `AliasSeq` as enumerator names?


That is, given

alias Types = AliasSeq!(byte, short, int);

we need some compile-time type-constructor `makeEnum` called as

alias E = makeEnum!Types;

that should be equivalent to

enum E { _byte, _short, _int }

I guess a `mixin` is the way to go here, right?