Extend pseudo-generics system used by maps to dynarrays

This commit is contained in:
Ricardo Luís Vaz Silva 2023-02-09 11:26:01 -03:00 committed by Christoph Oelckers
parent e29011ecde
commit 569263efe9
4 changed files with 121 additions and 87 deletions

View file

@ -187,6 +187,8 @@ xx(Exists)
xx(SetInvalid)
xx(SetNull)
xx(Key)
xx(Index)
xx(Find)
// color channels
xx(a)

View file

@ -8505,6 +8505,11 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
}
else
{
if (PFunction **Override; ctx.Version >= MakeVersion(4, 11, 0) && (Override = static_cast<PDynArray*>(Self->ValueType)->FnOverrides.CheckKey(MethodName)))
{
afd_override = *Override;
}
auto elementType = static_cast<PDynArray*>(Self->ValueType)->ElementType;
Self->ValueType = static_cast<PDynArray*>(Self->ValueType)->BackingType;
bool isDynArrayObj = elementType->isObjectPointer();

View file

@ -1985,12 +1985,114 @@ PStaticArray *NewStaticArray(PType *type)
//
//==========================================================================
enum OverrideFunctionRetType {
OFN_RET_VOID,
OFN_RET_VAL,
OFN_RET_KEY,
OFN_RET_BOOL,
OFN_RET_VAL_BOOL,
OFN_RET_INT,
};
enum OverrideFunctionArgType {
OFN_ARG_VOID,
OFN_ARG_KEY,
OFN_ARG_VAL,
OFN_ARG_KEY_VAL,
OFN_ARG_ELEM,
OFN_ARG_INT_ELEM,
};
template<OverrideFunctionRetType RetType, OverrideFunctionArgType ArgType , class MT>
void CreateOverrideFunction(MT *self, FName name)
{
auto Fn = Create<PFunction>(self->BackingType, name);
auto NativeFn = FindFunction(self->BackingType, name.GetChars());
assert(NativeFn);
assert(NativeFn->VMPointer);
TArray<PType*> ret;
TArray<PType*> args;
TArray<uint32_t> argflags;
TArray<FName> argnames;
if constexpr(RetType == OFN_RET_VAL)
{
ret.Push(self->ValueType);
}
else if constexpr(RetType == OFN_RET_KEY)
{
ret.Push(self->KeyType);
}
else if constexpr(RetType == OFN_RET_BOOL)
{
ret.Push(TypeBool);
}
else if constexpr(RetType == OFN_RET_VAL_BOOL)
{
ret.Push(self->ValueType);
ret.Push(TypeBool);
}
else if constexpr(RetType == OFN_RET_INT)
{
ret.Push(TypeSInt32);
}
args.Push(NewPointer(self->BackingType));
argnames.Push(NAME_self);
argflags.Push(VARF_Implicit | VARF_ReadOnly);
if constexpr(ArgType == OFN_ARG_KEY)
{
args.Push(self->KeyType);
argflags.Push(0);
argnames.Push(NAME_Key);
}
else if constexpr(ArgType == OFN_ARG_VAL)
{
args.Push(self->ValueType);
argflags.Push(0);
argnames.Push(NAME_Value);
}
else if constexpr(ArgType == OFN_ARG_KEY_VAL)
{
args.Push(self->KeyType);
args.Push(self->ValueType);
argflags.Push(0);
argflags.Push(0);
argnames.Push(NAME_Key);
argnames.Push(NAME_Value);
}
else if constexpr(ArgType == OFN_ARG_ELEM)
{
args.Push(self->ElementType);
argflags.Push(0);
argnames.Push(NAME_Item);
}
else if constexpr(ArgType == OFN_ARG_INT_ELEM)
{
args.Push(TypeSInt32);
args.Push(self->ElementType);
argflags.Push(0);
argflags.Push(0);
argnames.Push(NAME_Index);
argnames.Push(NAME_Item);
}
Fn->AddVariant(NewPrototype(ret, args), argflags, argnames, *NativeFn->VMPointer, VARF_Method | VARF_Native, SUF_ACTOR | SUF_OVERLAY | SUF_WEAPON | SUF_ITEM);
self->FnOverrides.Insert(name, Fn);
}
PDynArray::PDynArray(PType *etype,PStruct *backing)
: ElementType(etype), BackingType(backing)
{
mDescriptiveName.Format("DynArray<%s>", etype->DescriptiveName());
Size = sizeof(FArray);
Align = alignof(FArray);
CreateOverrideFunction<OFN_RET_INT , OFN_ARG_ELEM > (this, NAME_Find);
CreateOverrideFunction<OFN_RET_INT , OFN_ARG_ELEM > (this, NAME_Push);
CreateOverrideFunction<OFN_RET_VOID , OFN_ARG_INT_ELEM > (this, NAME_Insert);
}
//==========================================================================
@ -2226,96 +2328,19 @@ PDynArray *NewDynArray(PType *type)
//
//==========================================================================
enum OverrideFunctionRetType {
OFN_RET_VOID,
OFN_RET_VAL,
OFN_RET_KEY,
OFN_RET_BOOL,
OFN_RET_VAL_BOOL,
};
enum OverrideFunctionArgType {
OFN_ARG_VOID,
OFN_ARG_KEY,
OFN_ARG_VAL,
OFN_ARG_KEY_VAL,
};
template<class MT, OverrideFunctionRetType RetType, OverrideFunctionArgType ArgType >
void CreateOverrideFunction(MT *self, FName name)
{
auto Fn = Create<PFunction>(self->BackingType, name);
auto NativeFn = FindFunction(self->BackingType, name.GetChars());
assert(NativeFn);
assert(NativeFn->VMPointer);
TArray<PType*> ret;
TArray<PType*> args;
TArray<uint32_t> argflags;
TArray<FName> argnames;
if constexpr(RetType == OFN_RET_VAL)
{
ret.Push(self->ValueType);
}
else if constexpr(RetType == OFN_RET_KEY)
{
ret.Push(self->KeyType);
}
else if constexpr(RetType == OFN_RET_BOOL)
{
ret.Push(TypeBool);
}
else if constexpr(RetType == OFN_RET_VAL_BOOL)
{
ret.Push(self->ValueType);
ret.Push(TypeBool);
}
args.Push(NewPointer(self->BackingType));
argnames.Push(NAME_self);
argflags.Push(VARF_Implicit | VARF_ReadOnly);
if constexpr(ArgType == OFN_ARG_KEY)
{
args.Push(self->KeyType);
argflags.Push(0);
argnames.Push(NAME_Key);
}
else if constexpr(ArgType == OFN_ARG_VAL)
{
args.Push(self->ValueType);
argflags.Push(0);
argnames.Push(NAME_Value);
}
else if constexpr(ArgType == OFN_ARG_KEY_VAL)
{
args.Push(self->KeyType);
args.Push(self->ValueType);
argflags.Push(0);
argflags.Push(0);
argnames.Push(NAME_Key);
argnames.Push(NAME_Value);
}
Fn->AddVariant(NewPrototype(ret, args), argflags, argnames, *NativeFn->VMPointer, VARF_Method | VARF_Native,SUF_ACTOR | SUF_OVERLAY | SUF_WEAPON | SUF_ITEM);
self->FnOverrides.Insert(name, Fn);
}
PMap::PMap(PType *keytype, PType *valtype, PStruct *backing, int backing_class)
: KeyType(keytype), ValueType(valtype), BackingType(backing), BackingClass((decltype(BackingClass)) backing_class)
{
mDescriptiveName.Format("Map<%s, %s>", keytype->DescriptiveName(), valtype->DescriptiveName());
Size = sizeof(ZSFMap);
Align = alignof(ZSFMap);
CreateOverrideFunction<PMap, OFN_RET_VAL , OFN_ARG_KEY > (this, NAME_Get);
CreateOverrideFunction<PMap, OFN_RET_VAL , OFN_ARG_KEY > (this, NAME_GetIfExists);
CreateOverrideFunction<PMap, OFN_RET_BOOL , OFN_ARG_KEY > (this, NAME_CheckKey);
CreateOverrideFunction<PMap, OFN_RET_VAL_BOOL , OFN_ARG_KEY > (this, NAME_CheckValue);
CreateOverrideFunction<PMap, OFN_RET_VOID , OFN_ARG_KEY_VAL > (this, NAME_Insert);
CreateOverrideFunction<PMap, OFN_RET_VOID , OFN_ARG_KEY > (this, NAME_InsertNew);
CreateOverrideFunction<PMap, OFN_RET_VOID , OFN_ARG_KEY > (this, NAME_Remove);
CreateOverrideFunction< OFN_RET_VAL , OFN_ARG_KEY > (this, NAME_Get);
CreateOverrideFunction< OFN_RET_VAL , OFN_ARG_KEY > (this, NAME_GetIfExists);
CreateOverrideFunction< OFN_RET_BOOL , OFN_ARG_KEY > (this, NAME_CheckKey);
CreateOverrideFunction< OFN_RET_VAL_BOOL , OFN_ARG_KEY > (this, NAME_CheckValue);
CreateOverrideFunction< OFN_RET_VOID , OFN_ARG_KEY_VAL > (this, NAME_Insert);
CreateOverrideFunction< OFN_RET_VOID , OFN_ARG_KEY > (this, NAME_InsertNew);
CreateOverrideFunction< OFN_RET_VOID , OFN_ARG_KEY > (this, NAME_Remove);
}
//==========================================================================
@ -2777,9 +2802,9 @@ PMapIterator::PMapIterator(PType *keytype, PType *valtype, PStruct *backing, int
mDescriptiveName.Format("MapIterator<%s, %s>", keytype->DescriptiveName(), valtype->DescriptiveName());
Size = sizeof(ZSFMap);
Align = alignof(ZSFMap);
CreateOverrideFunction<PMapIterator, OFN_RET_KEY, OFN_ARG_VOID>(this, NAME_GetKey);
CreateOverrideFunction<PMapIterator, OFN_RET_VAL, OFN_ARG_VOID>(this, NAME_GetValue);
CreateOverrideFunction<PMapIterator, OFN_RET_VOID, OFN_ARG_VAL>(this, NAME_SetValue);
CreateOverrideFunction<OFN_RET_KEY, OFN_ARG_VOID>(this, NAME_GetKey);
CreateOverrideFunction<OFN_RET_VAL, OFN_ARG_VOID>(this, NAME_GetValue);
CreateOverrideFunction<OFN_RET_VOID, OFN_ARG_VAL>(this, NAME_SetValue);
}
//==========================================================================

View file

@ -512,6 +512,8 @@ public:
PType *ElementType;
PStruct *BackingType;
TMap<FName,PFunction*> FnOverrides;
bool IsMatch(intptr_t id1, intptr_t id2) const override;
void GetTypeIDs(intptr_t &id1, intptr_t &id2) const override;