Shameless autopromotion : type safe tagged union in D
deadalnix
deadalnix at gmail.com
Fri May 10 08:18:23 PDT 2013
On Friday, 10 May 2013 at 15:12:01 UTC, Artur Skawina wrote:
> On 05/10/13 14:32, deadalnix wrote:
>> http://www.deadalnix.me/2013/05/10/type-safe-tagged-union-in-d-programming-language/
>>
>> A trick that I used to use more and more, so I ended up
>> creating a generic solution and wrote an article about it.
>
> Nothing 'shameless' about it.
>
> But Real Programmers don't use mixins...
>
> struct TU(TYPES...) {
> union { TYPES data; }
> ubyte type;
> static assert(TYPES.length<=typeof(type).max);
>
> T opAssign(T)(T a) {
> foreach(N, TYPE; TYPES)
> static if (is(T==TYPE)) {
> type = N;
> return data[N] = a;
> }
> assert(0);
> }
> this(T)(T a) { this = a; }
>
> DT as(DT)() @property {
> foreach(N, TYPE; TYPES)
> static if (is(DT==TYPE)) {
> if (type==N)
> return data[N];
> else
> assert(0, "Cannot access a
> '"~typeString(type)~"' as "~DT.stringof);
> }
> assert(0);
> }
>
> auto ref apply(alias f)() {
> foreach(N, TYPE; TYPES)
> static if (is(typeof(f(data[N])))) // Comment this
> line out for strict CT checks.
> if (N==type)
> return f(data[N]);
> assert(0, "Could not apply '"~typeof(f).stringof~"' to
> "~typeString(type));
> }
>
> static string typeString()(typeof(type) n) {
> foreach(N, TYPE; TYPES)
> if (N==n)
> return TYPE.stringof;
> assert(0);
> }
> }
>
> double sqr(double a) { return a*a; }
> int sqr(int a) { return a*a; }
>
> void main() {
> import std.stdio;
> TU!(int, double, string) u;
> u = 257;
> writeln(u);
> writeln(u.data[0], ", ", u.data[1]);
> writeln(u.as!int);
> //writeln(u.as!double); // RT error
> writeln(u.apply!sqr());
> u = 3.14;
> writeln(u.apply!sqr());
> u = "blah";
> //writeln(u.apply!sqr()); // CT error in 'strict' mode,
> RT error otherwise.
>
> // Not currently accepted:
> //writeln(u.apply!(function(a){return a*a;})());
> //writeln(u.apply!(a=>a*a)());
> }
>
> Something that wasn't obvious from your examples is that
> templates are not necessary
> when implementing the 'processing' functions - overloading is
> enough.
>
> The interesting aspect of this is what improvements to the
> language would help to
> make this code both a) simpler and more readable, and b) even
> more efficient.
> Manual optimizations, such as 'if-sequnences'->'switch', should
> /not/ result in
> harder to read code. The
> locals-can't-be-parms-to-local-templates restriction
> should only apply when really necessary (for example: static
> functions/lambdas can
> be allowed). Etc.
>
> artur
Nice improvement, especially the opAssign.
To be 100% fait, I didn't implemented it as I didn't needed it,
but destruction is also something that can go wrong. I sure like
the absence of mixins !
More information about the Digitalmars-d-announce
mailing list