Recursive discriminated unions [Phobos2]

Chris Nicholson-Sauls ibisbasenji at gmail.com
Wed Feb 11 16:10:15 PST 2009


Andrei Alexandrescu wrote:
> Ok, I have a solution now. I'm not checking it in yet because I have a 
> brazillion other changes in my tree and I don't want to break something. 
> But I attach it to this message and it contains the following unittest:
> 
> unittest
> {
>     alias Algebraic!(real, This[], This[int], This[This]) A;
>     A v1, v2, v3;
>     v2 = 5.0L;
>     v3 = 42.0L;
>     v1 = [ v2 ][];
>     auto v = v1.peek!(A[]);
>     writeln(v[0]);
>     v1 = [ 9 : v3 ];
>     writeln(v1);
>     v1 = [ v3 : v3 ];
>     writeln(v1);
> }
> 
> The patterns This[], This*, This[U], U[This], and This[This] are 
> detected, but alas, no general solution yet (I don't know how to). 
> Anyhow, std.variant is starting to get interesting with this feature in 
> tow.
> 
> 
> Andrei
> 

I've noticed a shortcoming that I somehow hadn't come across before. 
The same issue exists in the current Phobos2, so it isn't anything new. 
  Apparently (and this may be known to all but me already) in order to 
use an array type, you must also use its element type.  Doing otherwise 
results in tripping a static assert.

Example:

	module test2;

	import std.variant;

	alias Algebraic!(void, string) var_t;

	void main () {
	    var_t foo = "quux";
	}

Shows: ../bin/../src/phobos/std/variant.d(418): static assert  "Cannot 
store a immutable(char) in a VariantN!(maxSize,void,immutable(char)[])"

Add invariant(char) to the list and all works fine, though.  The 
offending code is seemingly in VariantN.handler!(A):

         case OpID.index:
             auto me = cast(A*) pStore;
             static if (isArray!(A))
             {
                 // array type; input and output are the same VariantN
                 auto result = cast(VariantN*) parm;
                 size_t index = result.convertsTo!(int)
                     ? result.get!(int) : result.get!(size_t);
                 *result = (*me)[index];

	break;
             }

Specifically the statement (*result = (*me)[index];) triggers it, by 
spawning an opAssign!(elem_type).  I'm not sure how to cleanly alter it 
right off the top of my head.

----------

On the other hand, the new form This[] works fine, so far.  The only 
missing feature is an opApply().

The form This[This]... Using 'foo.get!(table_t)[k] = v;' results in a 
range violation.  For the moment, they are essentially immutable hashes. 
  Could actually be fine for a number of purposes.

----------

If I get some extra free time this weekend (assuming V-day isn't the 
death of me) I'll hack away at it some and see if I can't figure some 
things out, on all counts above.

Oh, and THANKS.  :)

-- Chris Nicholson-Sauls



More information about the Digitalmars-d mailing list