diff options
Diffstat (limited to 'squirrel_3_0_1_stable/sqplus/SqPlusOverload.h')
-rw-r--r-- | squirrel_3_0_1_stable/sqplus/SqPlusOverload.h | 819 |
1 files changed, 819 insertions, 0 deletions
diff --git a/squirrel_3_0_1_stable/sqplus/SqPlusOverload.h b/squirrel_3_0_1_stable/sqplus/SqPlusOverload.h new file mode 100644 index 000000000..e205de366 --- /dev/null +++ b/squirrel_3_0_1_stable/sqplus/SqPlusOverload.h @@ -0,0 +1,819 @@ +// SqPlusOverload.h +// SqPlus function overloading support created by Katsuaki Kawachi. +// +// Const member function fixed Tegan +// from http://squirrel-lang.org/forums/thread/2160.aspx + +#ifdef SQPLUS_OVERLOAD_RELEASE_HOOK +#undef SQPLUS_OVERLOAD_RELEASE_HOOK + + // These end up int ClassType<T> now + static inline int destruct(SQUserPointer up, SQInteger size) { + if (up) { + static_cast<T*>(up)->~T(); + sq_free(up, size); + } + return 0; + } + + static inline SQRELEASEHOOK &release(void) { + static SQRELEASEHOOK hook = ClassType<T>::destruct; + return hook; + } + + void releaseHook(SQRELEASEHOOK releaseHook) { + release() = releaseHook; + //return *this; + } + + static inline SQRELEASEHOOK &getReleaseHook(void) { + return release(); + } + +#endif // SQPLUS_OVERLOAD_RELEASE_HOOK + + +#ifdef SQPLUS_OVERLOAD_DECLARATION +#undef SQPLUS_OVERLOAD_DECLARATION + +template<typename Func> struct Arg; + +#endif // SQPLUS_OVERLOAD_DECLARATION + + +#ifdef SQPLUS_OVERLOAD_IMPLEMENTATION +#undef SQPLUS_OVERLOAD_IMPLEMENTATION +private: + class SQFuncHolder { + private: + template<typename T> + class FlexArray { + protected: + SquirrelObject array; + public: + FlexArray(int size = 0) { + this->resize(size); + } + int size(void) const { + return array.Len(); + } + void resize(int newSize) { + if (this->size() == 0) { + array = SquirrelVM::CreateArray(newSize); + } else { + array.ArrayResize(newSize); + } + } + void push_back(const T &t) { + this->set(this->size(), t); + } + void set(int index, const T &t) { + get(index) = t; + } + T &get(int index) { + if (index >= array.Len()) { + resize(index + 1); + } + SQUserPointer up = array.GetUserPointer(index); + if (!up) { + up = sq_newuserdata(SquirrelVM::GetVMPtr(), sizeof(T)); + new(static_cast<T*>(up)) T; + array.SetUserPointer(index, up); + } + return *static_cast<T*>(up); + } + }; + /* + storage of wrapped C++ functions + */ + typedef SQInteger(*WrappedFunction)(HSQUIRRELVM, bool, int); + typedef FlexArray<WrappedFunction> SQWrappedFuncArray; + typedef FlexArray<SQWrappedFuncArray> SQWrappedFuncArray2 ; + typedef FlexArray<SQWrappedFuncArray2> SQWrappedFuncArray3 ; + + struct MemberHolder { + static SQWrappedFuncArray &funcs(int functionIndex, + int paramCount) { + static SQWrappedFuncArray3 funcs; + return funcs.get(paramCount).get(functionIndex); + } + }; + struct StaticHolder { + static SQWrappedFuncArray &funcs(int functionIndex, + int paramCount) { + static SQWrappedFuncArray3 funcs; + return funcs.get(paramCount).get(functionIndex); + } + }; + struct ConstructorHolder { + static SQWrappedFuncArray &funcs(int paramCount) { + static SQWrappedFuncArray2 funcs; + return funcs.get(paramCount); + } + }; + + /* + wrapper for C++ functions + */ + template<typename Mfunc> struct MemberDispatcher { + static inline FlexArray<Mfunc> &mfunc(void) { + static FlexArray<Mfunc> mfunc; + return mfunc; + } + static inline SQInteger + dispatch(HSQUIRRELVM v, bool execute, int functionIndex) { + return execute ? + Call(*GetInstance<TClassType, true>(v, 1), + mfunc().get(functionIndex), v, 2) : + Arg<Mfunc>::argTypeDistance(v); + } + }; + template<typename Sfunc> struct StaticDispatcher { + static inline FlexArray<Sfunc> &sfunc(void) { + static FlexArray<Sfunc> sfunc; + return sfunc; + } + static inline SQInteger + dispatch(HSQUIRRELVM v, bool execute, int functionIndex) { + return execute ? + Call(sfunc().get(functionIndex), v, 2) : + Arg<Sfunc>::argTypeDistance(v); + } + }; + template<typename Cfunc> struct Constructor { + static inline Cfunc &cfunc(void) { + static Cfunc cfunc = 0; + return cfunc; + } + static inline SQInteger + construct(HSQUIRRELVM v, bool execute, int) { + return execute ? + Call(cfunc(), v, 2) : + Arg<Cfunc>::argTypeDistance(v); + } + }; + + // search and call an overloaded function on runtime + static inline SQInteger + call(SQWrappedFuncArray &funcs, HSQUIRRELVM v, int functionIndex = 0) { + bool ambiguous = false; + int imin = -1; + int dmin = INT_MAX; + for (int i = 0, size = funcs.size(); i < size; ++i) { + // FIXME: to be refactored + const int d = (**funcs.get(i))(v, false, functionIndex); + if (d == 0) { // complete match + imin = i; + ambiguous = false; + goto SQPLUS_OVERLOAD_CALL_IMMEDIATE_EXECUTION; + } else if (0 < d && d < dmin) { + dmin = d; + imin = i; + ambiguous = false; + } else if (d == dmin) { + ambiguous = true; + } + } + + if (ambiguous) { + return sq_throwerror( + v, _SC("Call of overloaded function is ambiguous") + ); + } else if (imin == -1) { + return sq_throwerror( + v, _SC("No match for given arguments") + ); + } + + SQPLUS_OVERLOAD_CALL_IMMEDIATE_EXECUTION: + // FIXME: to be refactored + return (**funcs.get(imin))(v, true, functionIndex); + } + + public: + template<typename Mfunc> static inline void + addMemberFunc(int functionIndex, Mfunc mfunc) { + MemberHolder::funcs(functionIndex, Arg<Mfunc>::num()).push_back( + &MemberDispatcher<Mfunc>::dispatch + ); + MemberDispatcher<Mfunc>::mfunc().set(functionIndex, mfunc); + } + template<typename Sfunc> static inline void + addStaticFunc(int functionIndex, Sfunc sfunc) { + StaticHolder::funcs(functionIndex, Arg<Sfunc>::num()).push_back( + &StaticDispatcher<Sfunc>::dispatch + ); + StaticDispatcher<Sfunc>::sfunc().set(functionIndex, sfunc); + } + template<typename Cfunc> static inline void + addConstructor(Cfunc cfunc) { + ConstructorHolder::funcs(Arg<Cfunc>::num()).push_back( + &Constructor<Cfunc>::construct + ); + Constructor<Cfunc>::cfunc() = cfunc; + } + + static inline SQInteger + memberCall(int paramCount, HSQUIRRELVM v, int functionIndex) { + return call(MemberHolder::funcs(functionIndex, paramCount), + v, functionIndex); + } + static inline SQInteger + staticCall(int paramCount, HSQUIRRELVM v, int functionIndex) { + return call(StaticHolder::funcs(functionIndex, paramCount), + v, functionIndex); + } + static inline SQInteger + constructorCall(int paramCount, HSQUIRRELVM v, int) { + return call(ConstructorHolder::funcs(paramCount), v); + } + }; // class SQFuncHolder + + + struct FunctionNameEnumerator { + SquirrelObject names; + FunctionNameEnumerator(void) : names(SquirrelVM::CreateTable()) {} + int index(const SQChar *n) { + int i; + SquirrelObject v = names.GetValue(n); + if (v.IsNull()) { + i = names.Len(); + names.SetValue(n, i); + } else { + i = v.ToInteger(); + } + return i; + } + }; + + FunctionNameEnumerator overloadedMemberNames; + FunctionNameEnumerator overloadedStaticMemberNames; + + static SquirrelObject & + functionIndexHolders(HSQUIRRELVM v) { + static SquirrelObject indexHolders; + if (indexHolders.IsNull()) { + sq_newtable(v); + indexHolders.AttachToStackObject(-1); + sq_pop(v, 1); + } + return indexHolders; + } + + template<int N> + static SquirrelObject & + indexHolder(HSQUIRRELVM v) { + static SquirrelObject holder; + if (holder.IsNull()) { + sq_pushobject(v, functionIndexHolders(v).GetObjectHandle()); + sq_pushinteger(v, N); + if (SQ_OK == sq_rawget(v, -2)) { + holder.AttachToStackObject(-1); + sq_pop(v, 3); + } else { + sq_pushinteger(v, N); + sq_newtable(v); + holder.AttachToStackObject(-1); + sq_rawset(v, -3); + sq_pop(v, 1); + } + } + return holder; + } + + template<typename Func> + class SQOverloader { + private: + static inline SQInteger switcher(HSQUIRRELVM v, + int(*caller)(int, HSQUIRRELVM, int), + int fidx) { + return (*caller)(StackHandler(v).GetParamCount() - 1, + v, + fidx); + } + + static inline SQInteger memberSwitcher(HSQUIRRELVM v) { + SQInteger fidx; + sq_pushobject(v, indexHolder<0>(v).GetObjectHandle()); + sq_push(v, 0); // native closure + sq_rawget(v, -2); + sq_getinteger(v, -1, &fidx); + sq_pop(v, 2); + return switcher(v, SQFuncHolder::memberCall, fidx); + } + static inline SQInteger staticSwitcher(HSQUIRRELVM v) { + SQInteger fidx; + sq_pushobject(v, indexHolder<1>(v).GetObjectHandle()); + sq_push(v, 0); // native closure + sq_rawget(v, -2); + sq_getinteger(v, -1, &fidx); + sq_pop(v, 2); + return switcher(v, SQFuncHolder::staticCall, fidx); + } + static inline SQInteger constructorSwitcher(HSQUIRRELVM v) { + return switcher(v, SQFuncHolder::constructorCall, 0); + } + + public: + static inline void addMemberFunc(SQClassDefBase<TClassType,TClassBase> *def, + Func mfunc, + const SQChar *name) { + const int fidx = def->overloadedMemberNames.index(name); + SQFuncHolder::addMemberFunc(fidx, mfunc); + def->staticFuncVarArgs(memberSwitcher, name); + + HSQUIRRELVM v = def->v; + // get closure + sq_pushobject(v, def->newClass.GetObjectHandle()); + sq_pushstring(v, name, -1); + sq_rawget(v, -2); + // holder[closure] = fidx + sq_pushobject(v, indexHolder<0>(v).GetObjectHandle()); + sq_push(v, -2); + sq_pushinteger(v, fidx); + sq_rawset(v, -3); + // + sq_pop(v, 3); + } + + static inline void addOperatorFunc(SQClassDefBase<TClassType,TClassBase> *def, + Func ofunc, + const SQChar *name) { + if (Arg<Func>::num() != 1) { + //assert(false && + // "Cannot add this function as operator (argc != 1)"); + abort(); + } + SQChar proxy[256]; + scsprintf(proxy, _SC("overloaded%s"), name); + + addMemberFunc(def, ofunc, proxy); + + SQChar script[512]; + scsprintf(script, _SC("%s.%s<-function(o){return %s.%s(o);}"), + def->name, name, def->name, proxy); + SquirrelVM::RunScript(SquirrelVM::CompileBuffer(script)); + } + + static inline void addStaticFunc(SQClassDefBase<TClassType,TClassBase> *def, + Func sfunc, + const SQChar *name) { + const int fidx = def->overloadedStaticMemberNames.index(name); + SQFuncHolder::addStaticFunc(fidx, sfunc); + def->staticFuncVarArgs(staticSwitcher, name); + + HSQUIRRELVM v = def->v; + // get closure + sq_pushobject(v, def->newClass.GetObjectHandle()); + sq_pushstring(v, name, -1); + sq_rawget(v, -2); + + // holder[closure] = fidx + sq_pushobject(v, indexHolder<1>(v).GetObjectHandle()); + sq_push(v, -2); + sq_pushinteger(v, fidx); + sq_rawset(v, -3); + // + sq_pop(v, 3); + } + template<typename Cfunc> + static inline void addConstructor(SQClassDefBase<TClassType,TClassBase> *def, + Cfunc cfunc) { + SQFuncHolder::addConstructor(cfunc); + def->staticFuncVarArgs(constructorSwitcher, _SC("constructor")); + } + static inline void addGlobalFunc(SQClassDefBase<TClassType,TClassBase> *def, + Func gfunc, + const SQChar *name) { + const int fidx = def->overloadedStaticMemberNames.index(name); + SQFuncHolder::addStaticFunc(fidx, gfunc); + SquirrelVM::CreateFunctionGlobal(staticSwitcher, name, _SC("*")); + + HSQUIRRELVM v = def->v; + // get closure + sq_pushroottable(v); + sq_pushstring(v, name, -1); + sq_rawget(v, -2); + + // holder[closure] = fidx + sq_pushobject(v, indexHolder<1>(v).GetObjectHandle()); + sq_push(v, -2); + sq_pushinteger(v, fidx); + sq_rawset(v, -3); + // + sq_pop(v, 3); + } + }; + +public: + template<typename Mfunc> + SQClassDefBase<TClassType,TClassBase> &overloadFunc(Mfunc mfunc, const SQChar *n) { + SQOverloader<Mfunc>::addMemberFunc(this, mfunc, n); + return *this; + } + template<typename Ofunc> + SQClassDefBase<TClassType,TClassBase> &overloadOperator(Ofunc ofunc, const SQChar *n){ + SQOverloader<Ofunc>::addOperatorFunc(this, ofunc, n); + return *this; + } + template<typename Sfunc> + SQClassDefBase<TClassType,TClassBase> &overloadStaticFunc(Sfunc sfunc, + const SQChar *n) { + SQOverloader<Sfunc>::addStaticFunc(this, sfunc, n); + return *this; + } + template<typename Cmetafunc> + SQClassDefBase<TClassType,TClassBase> &overloadConstructor(void) { + SQOverloader<Cmetafunc>::addConstructor(this, &Arg<Cmetafunc>::create); + return *this; + } + template<typename Cfunc> + SQClassDefBase<TClassType,TClassBase> &overloadConstructor(Cfunc cfunc) { + SQOverloader<Cfunc>::addConstructor(this, cfunc); + return *this; + } + template<typename Gfunc> + SQClassDefBase<TClassType,TClassBase> &overloadGlobalFunc(Gfunc gfunc, + const SQChar *n) { + SQOverloader<Gfunc>::addGlobalFunc(this, gfunc, n); + return *this; + } + + +#endif // SQPLUS_OVERLOAD_IMPLEMENTATION + + + +#ifdef SQPLUS_OVERLOAD_FUNCTIONS +#undef SQPLUS_OVERLOAD_FUNCTIONS + +struct GlobalFuncOverloader {}; +static inline SQClassDefBase<GlobalFuncOverloader,SQNoBaseClass> &globalFuncOverloader(void) +{ + static SQClassDefBase<GlobalFuncOverloader,SQNoBaseClass> fo(_SC("GlobalFuncOverloader")); + return fo; +} + +template<typename Gfunc> void +OverloadGlobal(Gfunc gfunc, const SQChar *n) +{ + globalFuncOverloader().overloadGlobalFunc(gfunc, n); +} + +template<typename TYPE> struct CheckInstance { + template<typename T> struct unref {typedef T type;}; + template<typename T> struct unref<T&> {typedef T type;}; + template<typename T> struct unref<T*> {typedef T type;}; + template<typename T> struct unref<const T&> {typedef T type;}; + template<typename T> struct unref<const T*> {typedef T type;}; + + /* + d = -1 : not in hierarchy + d = 0 : same + d > 0 : similar (o is d-th subclass of TYPE) + */ + static inline int distance(HSQUIRRELVM v, int index) { + HSQOBJECT o; + sq_resetobject(&o); + sq_getstackobj(v, index, &o); + + const int top = sq_gettop(v); + sq_pushroottable(v); + + // Check plain object type + int d = -1; + if (Match(TypeWrapper<TYPE>(), v, index)) { + d = 0; + + // Check instance type hierarchy + if (sq_type(o) == OT_INSTANCE) { + SQUserPointer dsttype = + ClassType<typename unref<TYPE>::type>::type(); + + SQUserPointer argtype; + for (sq_getclass(v, index); + sq_gettypetag(v, -1, &argtype) == SQ_OK; + sq_getbase(v, -1)) { + if (argtype == dsttype) { + goto SQPLUS_OVERLOAD_DISTANCE_IMMEDIATE_RETURN; + } + ++d; + } + d = -1; // no matching type found + } + } + SQPLUS_OVERLOAD_DISTANCE_IMMEDIATE_RETURN: + sq_settop(v, top); + return d; + } +}; + + +template<typename T, typename R> +struct Arg<R(T::*)(void)> { + static inline int num(void) {return 0;} + static inline int argTypeDistance(HSQUIRRELVM) { + return 0; + } +}; + +template<typename T, typename R, typename A1> +struct Arg<R(T::*)(A1)> { + static inline int num(void) {return 1;} + static inline int argTypeDistance(HSQUIRRELVM v) { + return Arg<R(*)(A1)>::argTypeDistance(v); + } +}; + +template<typename T, typename R, typename A1, typename A2> +struct Arg<R(T::*)(A1, A2)> { + static inline int num(void) {return 2;} + static inline int argTypeDistance(HSQUIRRELVM v) { + return Arg<R(*)(A1, A2)>::argTypeDistance(v); + } +}; + +template<typename T, typename R, typename A1, typename A2, typename A3> +struct Arg<R(T::*)(A1, A2, A3)> { + static inline int num(void) {return 3;} + static inline int argTypeDistance(HSQUIRRELVM v) { + return Arg<R(*)(A1, A2, A3)>::argTypeDistance(v); + } +}; + +template<typename T, typename R, typename A1, typename A2, typename A3, typename A4> +struct Arg<R(T::*)(A1, A2, A3, A4)> { + static inline int num(void) {return 4;} + static inline int argTypeDistance(HSQUIRRELVM v) { + return Arg<R(*)(A1, A2, A3, A4)>::argTypeDistance(v); + } +}; + +template<typename T, typename R, typename A1, typename A2, typename A3, typename A4, typename A5> +struct Arg<R(T::*)(A1, A2, A3, A4, A5)> { + static inline int num(void) {return 5;} + static inline int argTypeDistance(HSQUIRRELVM v) { + return Arg<R(*)(A1, A2, A3, A4, A5)>::argTypeDistance(v); + } +}; + +template<typename T, typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6> +struct Arg<R(T::*)(A1, A2, A3, A4, A5, A6)> { + static inline int num(void) {return 6;} + static inline int argTypeDistance(HSQUIRRELVM v) { + return Arg<R(*)(A1, A2, A3, A4, A5, A6)>::argTypeDistance(v); + } +}; + +template<typename T, typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7> +struct Arg<R(T::*)(A1, A2, A3, A4, A5, A6, A7)> { + static inline int num(void) {return 7;} + static inline int argTypeDistance(HSQUIRRELVM v) { + return Arg<R(*)(A1, A2, A3, A4, A5, A6, A7)>::argTypeDistance(v); + } +}; + +#ifdef SQPLUS_CONST_OPT +template<typename T, typename R> +struct Arg<R(T::*)(void) const> { + static inline int num(void) {return 0;} + static inline int argTypeDistance(HSQUIRRELVM) { + return 0; + } +}; + +template<typename T, typename R, typename A1> +struct Arg<R(T::*)(A1) const> { + static inline int num(void) {return 1;} + static inline int argTypeDistance(HSQUIRRELVM v) { + return Arg<R(*)(A1)>::argTypeDistance(v); + } +}; + +template<typename T, typename R, typename A1, typename A2> +struct Arg<R(T::*)(A1, A2) const> { + static inline int num(void) {return 2;} + static inline int argTypeDistance(HSQUIRRELVM v) { + return Arg<R(*)(A1, A2)>::argTypeDistance(v); + } +}; + +template<typename T, typename R, typename A1, typename A2, typename A3> +struct Arg<R(T::*)(A1, A2, A3) const> { + static inline int num(void) {return 3;} + static inline int argTypeDistance(HSQUIRRELVM v) { + return Arg<R(*)(A1, A2, A3)>::argTypeDistance(v); + } +}; + +template<typename T, typename R, typename A1, typename A2, typename A3, typename A4> +struct Arg<R(T::*)(A1, A2, A3, A4) const> { + static inline int num(void) {return 4;} + static inline int argTypeDistance(HSQUIRRELVM v) { + return Arg<R(*)(A1, A2, A3, A4)>::argTypeDistance(v); + } +}; + +template<typename T, typename R, typename A1, typename A2, typename A3, typename A4, typename A5> +struct Arg<R(T::*)(A1, A2, A3, A4, A5) const> { + static inline int num(void) {return 5;} + static inline int argTypeDistance(HSQUIRRELVM v) { + return Arg<R(*)(A1, A2, A3, A4, A5)>::argTypeDistance(v); + } +}; + +template<typename T, typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6> +struct Arg<R(T::*)(A1, A2, A3, A4, A5, A6) const> { + static inline int num(void) {return 6;} + static inline int argTypeDistance(HSQUIRRELVM v) { + return Arg<R(*)(A1, A2, A3, A4, A5, A6)>::argTypeDistance(v); + } +}; + +template<typename T, typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7> +struct Arg<R(T::*)(A1, A2, A3, A4, A5, A6, A7) const> { + static inline int num(void) {return 7;} + static inline int argTypeDistance(HSQUIRRELVM v) { + return Arg<R(*)(A1, A2, A3, A4, A5, A6, A7)>::argTypeDistance(v); + } +}; +#endif + +static inline int classAllocationError(HSQUIRRELVM v) { + return sq_throwerror(v, _SC("Failed to allocate memory")); +} + +template<typename R> +struct Arg<R(*)(void)> { + static inline int num(void) {return 0;} + static inline int argTypeDistance(HSQUIRRELVM) {return 0;} + static inline int create(void) { + HSQUIRRELVM v = SquirrelVM::GetVMPtr(); + R *r = static_cast<R*>(sq_malloc(sizeof(R))); + return r ? + PostConstruct<R>(v, new(r) R, + ClassType<R>::getReleaseHook()) : + classAllocationError(v); + } +}; + +template<typename R, typename A1> +struct Arg<R(*)(A1)> { + static inline int num(void) {return 1;} + static inline int argTypeDistance(HSQUIRRELVM v) { + int s, r; + r = 0; + s = CheckInstance<A1>::distance(v, 2); if (s < 0) {return -1;} r += s; + return r; + } + static inline int create(A1 a1) { + HSQUIRRELVM v = SquirrelVM::GetVMPtr(); + R *r = static_cast<R*>(sq_malloc(sizeof(R))); + return r ? + PostConstruct<R>(v, new(r) R(a1), + ClassType<R>::getReleaseHook()) : + classAllocationError(v); + } +}; + +template<typename R, typename A1, typename A2> +struct Arg<R(*)(A1, A2)> { + static inline int num(void) {return 2;} + static inline int argTypeDistance(HSQUIRRELVM v) { + int s, r; + r = 0; + s = CheckInstance<A1>::distance(v, 2); if (s < 0) {return -1;} r += s; + s = CheckInstance<A2>::distance(v, 3); if (s < 0) {return -1;} r += s; + return r; + } + static inline int create(A1 a1, A2 a2) { + HSQUIRRELVM v = SquirrelVM::GetVMPtr(); + R *r = static_cast<R*>(sq_malloc(sizeof(R))); + return r ? + PostConstruct<R>(v, new(r) R(a1, a2), + ClassType<R>::getReleaseHook()) : + classAllocationError(v); + } +}; + +template<typename R, typename A1, typename A2, typename A3> +struct Arg<R(*)(A1, A2, A3)> { + static inline int num(void) {return 3;} + static inline int argTypeDistance(HSQUIRRELVM v) { + int s, r; + r = 0; + s = CheckInstance<A1>::distance(v, 2); if (s < 0) {return -1;} r += s; + s = CheckInstance<A2>::distance(v, 3); if (s < 0) {return -1;} r += s; + s = CheckInstance<A3>::distance(v, 4); if (s < 0) {return -1;} r += s; + return r; + } + static inline int create(A1 a1, A2 a2, A3 a3) { + HSQUIRRELVM v = SquirrelVM::GetVMPtr(); + R *r = static_cast<R*>(sq_malloc(sizeof(R))); + return r ? + PostConstruct<R>(v, new(r) R(a1, a2, a3), + ClassType<R>::getReleaseHook()) : + classAllocationError(v); + } +}; + +template<typename R, typename A1, typename A2, typename A3, typename A4> +struct Arg<R(*)(A1, A2, A3, A4)> { + static inline int num(void) {return 4;} + static inline int argTypeDistance(HSQUIRRELVM v) { + int s, r; + r = 0; + s = CheckInstance<A1>::distance(v, 2); if (s < 0) {return -1;} r += s; + s = CheckInstance<A2>::distance(v, 3); if (s < 0) {return -1;} r += s; + s = CheckInstance<A3>::distance(v, 4); if (s < 0) {return -1;} r += s; + s = CheckInstance<A4>::distance(v, 5); if (s < 0) {return -1;} r += s; + return r; + } + static inline int create(A1 a1, A2 a2, A3 a3, A4 a4) { + HSQUIRRELVM v = SquirrelVM::GetVMPtr(); + R *r = static_cast<R*>(sq_malloc(sizeof(R))); + return r ? + PostConstruct<R>(v, new(r) R(a1, a2, a3, a4), + ClassType<R>::getReleaseHook()) : + classAllocationError(v); + } +}; + +template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5> +struct Arg<R(*)(A1, A2, A3, A4, A5)> { + static inline int num(void) {return 5;} + static inline int argTypeDistance(HSQUIRRELVM v) { + int s, r; + r = 0; + s = CheckInstance<A1>::distance(v, 2); if (s < 0) {return -1;} r += s; + s = CheckInstance<A2>::distance(v, 3); if (s < 0) {return -1;} r += s; + s = CheckInstance<A3>::distance(v, 4); if (s < 0) {return -1;} r += s; + s = CheckInstance<A4>::distance(v, 5); if (s < 0) {return -1;} r += s; + s = CheckInstance<A5>::distance(v, 6); if (s < 0) {return -1;} r += s; + return r; + } + static inline int create(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + HSQUIRRELVM v = SquirrelVM::GetVMPtr(); + R *r = static_cast<R*>(sq_malloc(sizeof(R))); + return r ? + PostConstruct<R>(v, new(r) R(a1, a2, a3, a4, a5), + ClassType<R>::getReleaseHook()) : + classAllocationError(v); + } +}; + +template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6> +struct Arg<R(*)(A1, A2, A3, A4, A5, A6)> { + static inline int num(void) {return 6;} + static inline int argTypeDistance(HSQUIRRELVM v) { + int s, r; + r = 0; + s = CheckInstance<A1>::distance(v, 2); if (s < 0) {return -1;} r += s; + s = CheckInstance<A2>::distance(v, 3); if (s < 0) {return -1;} r += s; + s = CheckInstance<A3>::distance(v, 4); if (s < 0) {return -1;} r += s; + s = CheckInstance<A4>::distance(v, 5); if (s < 0) {return -1;} r += s; + s = CheckInstance<A5>::distance(v, 6); if (s < 0) {return -1;} r += s; + s = CheckInstance<A6>::distance(v, 7); if (s < 0) {return -1;} r += s; + return r; + } + static inline int create(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) { + HSQUIRRELVM v = SquirrelVM::GetVMPtr(); + R *r = static_cast<R*>(sq_malloc(sizeof(R))); + return r ? + PostConstruct<R>(v, new(r) R(a1, a2, a3, a4, a5, a6), + ClassType<R>::getReleaseHook()) : + classAllocationError(v); + } +}; + +template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7> +struct Arg<R(*)(A1, A2, A3, A4, A5, A6, A7)> { + static inline int num(void) {return 7;} + static inline int argTypeDistance(HSQUIRRELVM v) { + int s, r; + r = 0; + s = CheckInstance<A1>::distance(v, 2); if (s < 0) {return -1;} r += s; + s = CheckInstance<A2>::distance(v, 3); if (s < 0) {return -1;} r += s; + s = CheckInstance<A3>::distance(v, 4); if (s < 0) {return -1;} r += s; + s = CheckInstance<A4>::distance(v, 5); if (s < 0) {return -1;} r += s; + s = CheckInstance<A5>::distance(v, 6); if (s < 0) {return -1;} r += s; + s = CheckInstance<A6>::distance(v, 7); if (s < 0) {return -1;} r += s; + s = CheckInstance<A7>::distance(v, 8); if (s < 0) {return -1;} r += s; + return r; + } + static inline int create(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) { + HSQUIRRELVM v = SquirrelVM::GetVMPtr(); + R *r = static_cast<R*>(sq_malloc(sizeof(R))); + return r ? + PostConstruct<R>(v, new(r) R(a1, a2, a3, a4, a5, a6, a7), + ClassType<R>::getReleaseHook()) : + classAllocationError(v); + } +}; +#endif // SQPLUS_OVERLOAD_FUNCTIONS + +// SqPlusOverload.h + +// Local Variables: +// mode: c++ +// End: |