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.

Reply via email to