quant
quant

Reputation: 2214

Forward operators in haxe

I'm trying to write my own boolean "abstract" with some additional functions.

@forward
abstract MyBool(Bool) {
  public inline function new(b:Bool) {
    this = b;
  }
  @:from
  public static inline function fromBool(b:Bool):MyBool {
    return new MyBool(b);
  }
  @:to
  public inline function toBool():Bool {
    return this;
  }
  // some additional functions
}

In principal this works fine:

var t:T = true;
if(t) {
  trace("1");
}
t.someStrangeMethod();

However @:forward does not forward basic boolean-operators like "!":

var f:T = false;
if(!f) { // fails here, because "!" is not defined as an operator for MyBool ...
  trace("2");
}

The error message is "MyBool should be Bool", which I find quite strange because MyBool is an abstract of a Bool with @:forward annotation and there is a @:to-method.

Of course there are some easy workarounds. One could either use:

if(!f.toBool()) {
  trace("2");
}

and/or add a function annotated with @:op(!A) to the abstract:

@:op(!A)
public inline function notOp():Bool {
  return !this;
}

However I do not like both methods:

So I was wondering if anyone has a better idea? Is there maybe another "@:forward"-like compiling metadata, I do not know about yet?

Upvotes: 4

Views: 719

Answers (2)

Gama11
Gama11

Reputation: 34138

There's an open feature request regarding this:

Can @:forward also forward underlying operator overloads? (#5035)

One way to make your code example work is to allow implicit conversions with to Bool. I'm not entirely sure why the equivalent @:to function doesn't work here, as the Haxe Manual states that "Class field casts have the same semantics".

abstract MyBool(Bool) to Bool {

Apart from that, I think the only options is to declare an @:op function for each operator you want to support. If declared without a body, the underlying type's operator will be forwarded:

@:op(!A) function notOp():MyBool;

Upvotes: 4

Kronocian
Kronocian

Reputation: 76

If your main goal is to just add methods to the Bool type, then perhaps avoid the problem altogether by instead creating a class that adds methods to Bool via static extension (documented in the Haxe manual). This method would eliminate the need for operator forwarding.

Upvotes: 2

Related Questions