digitalmars.D - this() member function?
- Wei Li (78/78) Feb 24 2007 Hi:
- Wei Li (75/75) Feb 24 2007 The fixed version:
- Marcin Kuszczak (12/18) Feb 24 2007 Very nice!
- Bill Baxter (4/11) Feb 24 2007 So now we have std.boxer, and there's a port of boost::Any floating
- Marcin Kuszczak (20/35) Feb 24 2007 Let me comment on this:
Hi: The following code is a quick and dirty variant implemention inspired by boost.variant. It works, but why is the constructor(this(T)()) cannot to be a template function? //variant.d module variant; import std.stdio; import std.metastrings; import std.typetuple; private template MixinMembers(int L, T, V...) { mixin(Format!("%s var%s;", T.stringof, L - 1 - V.length)); static if(V.length > 0) mixin MixinMembers!(L, V); } //catenate strings at compile time.... private template MixinThisFunc(char[] S, T, V...) { public const char[] Result = S ~ Format!("public this(%s v) { assign!(%s)(v); } ", T.stringof, T.stringof); pragma(msg, Result ~ "\n"); static if(V.length > 0) mixin MixinThisFunc!(Result, V); } class Variant(TList...) { public alias TList TypeList; public alias Variant!(TList) SelfType; private union Holder { mixin MixinMembers!(TList.length, TList); } private Holder m_holder; private int m_which = -1; public mixin(MixinThisFunc!("",TypeList).Result); public this() { m_holder.var0 = m_holder.var0.init; m_which = 0; } public SelfType assign(T)(T rhs) { enum { index = IndexOf!(T, TypeList) } static assert( index >= 0); mixin(Format!("m_holder.var%s = rhs;", index)); m_which = index; return this; } public SelfType opAssign(T)(T rhs) { return assign(rhs); } public int which() { return m_which; } public T get(T)() { enum { index = IndexOf!(T, TypeList) } static assert(index >= 0); assert(index == which()); mixin(Format!("return m_holder.var%s;", index)); } } void main() { scope auto v = new Variant!(int, double, char, char[])(1000); writefln("which: %d", v.which()); v = 100.0; v = 'A'; writefln("which: %d", v.which()); char[] str = "foobar"; v = str; writefln("which: %d", v.which()); str = ""; str = v.get!(char[]); writefln(str); } - Wei Li
Feb 24 2007
The fixed version: import std.stdio; import std.metastrings; import std.typetuple; private template MixinMembers(int I, T, V...) { mixin(Format!("T var%s;", I)); static if(V.length > 0) mixin MixinMembers!(I + 1, V); } //catenate strings at compile time.... private template MixinThisFunc(char[] S, T, V...) { public const char[] Result = S ~ Format!("public this(%s v) { assign!(%s)(v); } ", T.stringof, T.stringof); pragma(msg, Result ~ "\n"); static if(V.length > 0) mixin MixinThisFunc!(Result, V); } class Variant(TList...) { public alias TList TypeList; public alias Variant!(TList) SelfType; // no union.tupleof? private union Holder { mixin MixinMembers!(0, TList); } private Holder m_holder; private int m_which = -1; public mixin(MixinThisFunc!("",TypeList).Result); public this() { m_holder.var0 = m_holder.var0.init; m_which = 0; } public SelfType assign(T)(T rhs) { enum { index = IndexOf!(T, TypeList) } static assert( index >= 0); mixin(Format!("m_holder.var%s = rhs;", index)); m_which = index; return this; } public SelfType opAssign(T)(T rhs) { return assign(rhs); } public int which() { return m_which; } public T get(T)() { enum { index = IndexOf!(T, TypeList) } static assert(index >= 0); assert(index == which()); mixin(Format!("return m_holder.var%s;", index)); } } void main() { scope auto v = new Variant!(int, double, char, char[])(1000); writefln("which: %d", v.which()); v = 100.0; v = 'A'; writefln("which: %d", v.which()); char[] str = "foobar"; v = str; writefln("which: %d", v.which()); str = ""; str = v.get!(char[]); writefln(str); }
Feb 24 2007
Wei Li wrote:Hi: The following code is a quick and dirty variant implemention inspired by boost.variant. It works, but why is the constructor(this(T)()) cannot to be a template function?Very nice! You just did not mentioned that your implementation is about 80 times more compact than Boost version :-) I had same experience when porting from boost... -- Regards Marcin Kuszczak (Aarti_pl) ------------------------------------- Ask me why I believe in Jesus - http://zapytaj.dlajezusa.pl (en/pl) Doost (port of few Boost libraries) - http://www.dsource.org/projects/doost/ -------------------------------------
Feb 24 2007
Wei Li wrote:Hi: The following code is a quick and dirty variant implemention inspired by boost.variant. It works, but why is the constructor(this(T)()) cannot to be a template function? //variant.d module variant; ...So now we have std.boxer, and there's a port of boost::Any floating around. How do all those differ from one another? --bb
Feb 24 2007
Bill Baxter wrote:Wei Li wrote:Let me comment on this: Boxer - this is done on struct so it is very fast. I would say if it would be fixed it should be still standard implementation. But there should be few issues fixed in this implementation: a. to get information that container is empty you have check if type is null. There should be really method empty() to check this b. I would also suggest to add method clear() for consistency Any - universal and clean implementation. Unfortunatelly about 10 times slower than boxer for 'int's... Variant - Similar to any but you can limit data types stored inside container to few choosen types. -- Regards Marcin Kuszczak (Aarti_pl) ------------------------------------- Ask me why I believe in Jesus - http://zapytaj.dlajezusa.pl (en/pl) Doost (port of few Boost libraries) - http://www.dsource.org/projects/doost/ -------------------------------------Hi: The following code is a quick and dirty variant implemention inspired by boost.variant. It works, but why is the constructor(this(T)()) cannot to be a template function? //variant.d module variant; ...So now we have std.boxer, and there's a port of boost::Any floating around. How do all those differ from one another? --bb
Feb 24 2007