Exception if naryFun!visitors can't be called with provided arguments
Fuses algebraic types on return.
1 import std.exception: assertThrown; 2 static struct Asteroid { uint size; } 3 static struct Spaceship { uint size; } 4 alias SpaceObject = Variant!(Asteroid, Spaceship); 5 6 alias collideWith = tryMatch!( 7 (Asteroid x, Asteroid y) => "a/a", 8 // No visitor for A/S pair 9 // (Asteroid x, Spaceship y) => "a/s", 10 (Spaceship x, Asteroid y) => "s/a", 11 (Spaceship x, Spaceship y) => "s/s", 12 ); 13 14 import mir.utility: min; 15 // Direct access of a member in case of all algebraic types has this member 16 alias oops = (a, b) => (a.size + b.size) > 3 && min(a.size, b.size) > 1; 17 18 alias collide = (x, y) => oops(x, y) ? "big-boom" : collideWith(x, y); 19 20 auto ea = Asteroid(1); 21 auto es = Spaceship(2); 22 auto oa = SpaceObject(ea); 23 auto os = SpaceObject(es); 24 25 // Asteroid-Asteroid 26 assert(collide(ea, ea) == "a/a"); 27 assert(collide(ea, oa) == "a/a"); 28 assert(collide(oa, ea) == "a/a"); 29 assert(collide(oa, oa) == "a/a"); 30 31 // Asteroid-Spaceship 32 assertThrown!Exception(collide(ea, es)); 33 assertThrown!Exception(collide(ea, os)); 34 assertThrown!Exception(collide(oa, es)); 35 assertThrown!Exception(collide(oa, os)); 36 37 // can deduce the type based on other return values 38 static assert(is(typeof(collide(ea, os)) == string)); 39 static assert(is(typeof(collide(oa, es)) == string)); 40 static assert(is(typeof(collide(oa, os)) == string)); 41 42 // Also allows newer compilers to detect combinations which always throw an exception 43 static if (is(typeof(collideWith(ea, es)) == noreturn)) 44 { 45 static assert(is(typeof(collide(ea, es)) == string)); 46 } 47 else 48 { 49 // not enough information to deduce the type from (ea, es) pair 50 static assert(is(typeof(collide(ea, es)) == void)); 51 } 52 53 // Spaceship-Asteroid 54 assert(collide(es, ea) == "s/a"); 55 assert(collide(es, oa) == "s/a"); 56 assert(collide(os, ea) == "s/a"); 57 assert(collide(os, oa) == "s/a"); 58 59 // Spaceship-Spaceship 60 assert(collide(es, es) == "big-boom"); 61 assert(collide(es, os) == "big-boom"); 62 assert(collide(os, es) == "big-boom"); 63 assert(collide(os, os) == "big-boom");
Behaves as match but doesn't enforce at compile time that all types can be handled by the visiting functions.