| Thread overview | |||||||
|---|---|---|---|---|---|---|---|
|
February 24, 2007 this() member function? | ||||
|---|---|---|---|---|
| ||||
Attachments: | 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
| |||
February 24, 2007 Re: this() member function? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Wei Li | 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);
}
| |||
February 24, 2007 Re: this() member function? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Wei Li | 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/ ------------------------------------- | |||
February 24, 2007 Re: this() member function? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Wei Li | 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
| |||
February 24, 2007 Re: this() member function? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Bill Baxter | Bill Baxter wrote: > 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 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 c. There is ugly bug #8 which effectively makes boxer unusable under linux 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/ ------------------------------------- | |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply