January 28, 2012
On 01/26/2012 12:55 PM, Michel Fortin wrote:
> On 2012-01-26 01:12:40 +0000, Jonathan M Davis <jmdavisProg@gmx.com> said:
>
>> On Thursday, January 26, 2012 02:06:45 Trass3r wrote:
>>> When writing C bindings I usually create lots of aliases via a
>>> string mixin to pull enum members into the enclosing scope so
>>> it's compatible to C.
>>> Would it be wise to let the compiler do this automatically for
>>> extern(C) enums?
>>
>> Why? You're using them in D code, not C code. What difference does it
>> make if
>> the enum is one that's used in C code or not? Why would you use such
>> aliases
>> with enums from C but not those from D/ What makes enums from C
>> different?
>
> Often C enum value naming takes into account that they'll live in the
> outer scope. For instance:
>
> enum UITableViewRowAnimation {
> UITableViewRowAnimationFade,
> UITableViewRowAnimationRight,
> UITableViewRowAnimationLeft,
> UITableViewRowAnimationTop,
> UITableViewRowAnimationBottom,
> UITableViewRowAnimationNone,
> UITableViewRowAnimationMiddle,
> UITableViewRowAnimationAutomatic = 100
> }
>
> So if you're doing direct bindings where you don't want to change the
> names, how do you use that in D?
>
> UITableViewRowAnimation.UITableViewRowAnimationFade
>

I would probably use:

enum UITableViewRowAnimation {
	Fade,
	Right,
	Left,
	Top,
	Bottom,
	None,
	Middle,
	Automatic = 100
}

Then you can use it like so:

UITableViewRowAnimation.Fade

-- 
Mike Wey
January 28, 2012
On 1/27/12, Daniel Murphy <yebblies@nospamgmail.com> wrote:
> (could be mixin(exposeEnumMembers!UITableViewRowAnimation); )

I don't think that's possible without passing the name of the enum. Once you pass the type to the "expose" template it won't know the enum is named "UITableViewRowAnimation". You /could/ use typeid() to get the mangled name and try to demangle that, but lo' and behold core.demangle doesn't work at compile-time. :/
January 28, 2012
On 1/28/12, Andrej Mitrovic <andrej.mitrovich@gmail.com> wrote:
> I don't think that's possible without passing the name of the enum.

Nevermind, I was wrong. It appears typeid() returns a mangled name only when used in a *pragma* call, otherwise you do get the proper name.
January 28, 2012
import std.conv;
import std.traits;

string exposeEnumMembersImpl(T)()
{
    string result;
    foreach (member; EnumMembers!UITableViewRowAnimation)
        result ~= "alias " ~ to!string(T.stringof) ~ "." ~
to!string(member) ~ " " ~ to!string(member) ~ ";\n";
    return result;
}

template exposeEnumMembers(T)
{
    enum exposeEnumMembers = exposeEnumMembersImpl!T();
}

mixin( exposeEnumMembers!UITableViewRowAnimation );

I did notice something about mixins, they hide existing aliases. If you already had those aliases listed and you added this mixin, the newly mixed in aliases will not conflict with the old ones. I find this behavior rather odd, even if it's defined this way..
January 28, 2012
"Andrej Mitrovic" <andrej.mitrovich@gmail.com> wrote in message news:mailman.101.1327757271.25230.digitalmars-d@puremagic.com...
> I did notice something about mixins, they hide existing aliases. If you already had those aliases listed and you added this mixin, the newly mixed in aliases will not conflict with the old ones. I find this behavior rather odd, even if it's defined this way..

Are you sure?  I thought it was the other way around, mixed-in members did not override existing ones...


January 28, 2012
On 1/28/12, Daniel Murphy <yebblies@nospamgmail.com> wrote:
> "Andrej Mitrovic" <andrej.mitrovich@gmail.com> wrote in message news:mailman.101.1327757271.25230.digitalmars-d@puremagic.com...
>> I did notice something about mixins, they hide existing aliases. If you already had those aliases listed and you added this mixin, the newly mixed in aliases will not conflict with the old ones. I find this behavior rather odd, even if it's defined this way..
>
> Are you sure?  I thought it was the other way around, mixed-in members did not override existing ones...

int foo, bar;
alias foo target;
alias bar target;  // error
mixin("alias bar target;");  // but use this instead and no problem..
January 28, 2012
"Andrej Mitrovic" <andrej.mitrovich@gmail.com> wrote in message
> int foo, bar;
> alias foo target;
> alias bar target;  // error
> mixin("alias bar target;");  // but use this instead and no problem..

Yes, but does target end up referenceing foo or bar?


January 28, 2012
> import std.conv;
> import std.traits;
>
> string exposeEnumMembersImpl(T)()
> {
>     string result;
>     foreach (member; EnumMembers!UITableViewRowAnimation)
>         result ~= "alias " ~ to!string(T.stringof) ~ "." ~
> to!string(member) ~ " " ~ to!string(member) ~ ";\n";
>     return result;
> }
>
> template exposeEnumMembers(T)
> {
>     enum exposeEnumMembers = exposeEnumMembersImpl!T();
> }
>
> mixin( exposeEnumMembers!UITableViewRowAnimation );


The extra template is senseless.
And no imports are needed.

string bringToCurrentScope(alias EnumType)()
{
	string res = "";
	foreach (e; __traits(allMembers, EnumType))
	{
		res ~= "alias " ~ EnumType.stringof ~ "." ~ e ~ " " ~ e ~ ";\n";
	}
    return res;
}

mixin(bringToCurrentScope!EnumName);


Anyway the whole point of this thread is to get rid of a crappy mixin(blabla); after each enum I define!
January 28, 2012
> The following is a better solution, and should probably be in the standard library.
..
> (could be mixin(exposeEnumMembers!UITableViewRowAnimation); )

That's what I already do.
The whole point of the thread is to get rid of that crap after each enum.
January 28, 2012
On 1/28/12, Trass3r <un@known.com> wrote:
> The extra template is senseless.

No it's not. Your sample won't compile with -property. That's why I've wrapped it into a template, to avoid having to use parens.

> And no imports are needed.

Fair enough. But if we're going to be anal about it you should add a constraint `if (is(EnumType == enum))`. Otherwise your sample will compile for non-enum types, which may or may not be what you want. You probably don't want to end up with static method imported into the local scope by accident. For classes it will generate:

alias MyClass.toString toString;
alias MyClass.toHash toHash;
alias MyClass.opCmp opCmp;
alias MyClass.opEquals opEquals;
alias MyClass.Monitor Monitor;
alias MyClass.factory factory;

Fun! :)