add implicit capabilities to jsvar opend

This commit is contained in:
Adam D. Ruppe 2024-05-26 12:19:39 -04:00
parent e5441e5f35
commit c6399a517b
1 changed files with 42 additions and 2 deletions

44
jsvar.d
View File

@ -82,6 +82,8 @@
+/
module arsd.jsvar;
import arsd.core;
version=new_std_json;
static import std.array;
@ -545,9 +547,43 @@ private var _op(alias _this, alias this2, string op, T)(T t) if(op != "~") {
assert(0);
}
// a plain `compiles(T(var))` check can be triggered by an implicit cast
// which we don't want due to endless recursion so this more specific check
// are better than that anyway
private template hasVarConstructor(T) {
bool helper() {
static if(is(T == struct) || is(T == class))
static if(__traits(hasMember, T, "__ctor"))
foreach(overload; __traits(getOverloads, T, "__ctor"))
static if(is(typeof(overload) Params == __parameters))
static if(Params.length == 1)
static if(is(Params[0] == var))
return true;
return false;
}
enum bool hasVarConstructor = helper();
}
unittest {
assert(hasVarConstructor!string == false);
static struct A {
this(var a) {}
}
static struct B {
this(int a) {}
}
assert(hasVarConstructor!A == true);
assert(hasVarConstructor!B == false);
}
///
struct var {
@implicit
public this(T)(T t) {
static if(is(T == var))
this = t;
@ -555,6 +591,10 @@ struct var {
this.opAssign(t);
}
T opImplicitCast(T)() {
return this.get!T;
}
// used by the script interpreter... does a .dup on array, new on class if possible, otherwise copies members.
public var _copy_new() {
if(payloadType() == Type.Object) {
@ -990,9 +1030,9 @@ struct var {
return this;
} else static if(__traits(compiles, T.fromJsVar(var.init))) {
return T.fromJsVar(this);
} else static if(__traits(compiles, T(this))) {
} else static if(hasVarConstructor!T && __traits(compiles, T(this))) {
return T(this);
} else static if(__traits(compiles, new T(this))) {
} else static if(hasVarConstructor!T && __traits(compiles, new T(this))) {
return new T(this);
} else static if(is(T == Nullable!N, N)) {
if(payloadType == Type.Object && this._payload._object is null)