I would like to be able to abstractly coerce some generic type as a bool without altering how the underlying type may be used. The flag needs to be set and not a function of the type. The main application here is being able to pack a bool type with a return value whenever necessary. I specifically do not want this bool to be a part of the underlying type nor do I want to obfuscate accessibility with wrapper objects.
The results provided are targeting Linux 64.
I have this so far,
abstract Flag<T>({value:T,flag:Bool})
{
public function new(value:T,flag:Bool) this = {value:value,flag:flag};
@:to public inline function toFlag():Bool return this.flag;
@:to public inline function toValue():T return this.value;
}
But the odd thing is...
var a = new Flag<Int>(0,true);
var mc = function(a):Int return a;
trace(Std.is(a,Bool)); //false
trace(Std.is(a,Int)); //false
var j:Int;
j = a; //works
j = mc(a); //works
j = a + 0; //cannot add Flag<Int> and Int
j = Std.int(a)+0; //works
j = cast(a,Int); //invalid cast (runtime)
var i:Bool;
i = a; //works
i = i? true : false; //properly evaluates to true.
i = a? true : false; //always evaluates to false without error.
i = a < 0; //cannot compare Flag<Int> and Int
I'm confused on why some of these behaviors are doing what they're doing.
When I define a function that accepts or returns a sub-type of Flag, it works properly with the binary operators. However, the binary operators won't do the type coercion themselves, even though they are functions with parameters that accept their given type. Nonetheless, Oddly, casting doesn't work, even though assignment with a properly declared type does work.
The ternary operator is also rather bizarre. When using non-bool type, ternary-if throws an error- which would be consistent with the other operators, but here it arbitrarily works and evaluates to false.
What do I need to do to get the proper functionality?