Show Changes Show Changes
Edit Edit
Print Print
Recent Changes Recent Changes
Subscriptions Subscriptions
Lost and Found Lost and Found
Find References Find References
Rename Rename
Administration Page Administration Page
Topic Locks Topic Locks

Search

History

2/22/2017 3:41:01 AM
-92.222.238.172
10/4/2007 8:45:06 PM
-192.167.22.24
7/5/2007 6:47:45 AM
-220.211.116.217
9/17/2006 1:56:25 AM
kawachi-210.132.210.20
8/10/2006 8:01:50 AM
-219.98.157.71
List all versions List all versions

RSS feed for the SquirrelWiki namespace

Sq Plus Function Overloading
.

rochie

Summary

(Added to snapshot 05/27/07 kkawachi)

This enables squirrel script to call overloaded functions/constructors of C++.

The code consists of 2 patches and 1 new file (http://www.liebes-jahreshoroskop.com/).

Patch for "sqplus/sqplus.h":

diff -ur SQUIRREL2_1_0_sqplus_22/sqplus/sqplus.h SQUIRREL2_1_0_sqplus_22_OVERLOAD/sqplus/sqplus.h
--- SQUIRREL2_1_0_sqplus_22/sqplus/sqplus.h		2006-08-20 18:47:40.000000000 +0900
+++ SQUIRREL2_1_0_sqplus_22_OVERLOAD/sqplus/sqplus.h		2006-09-17 17:33:06.375000000 +0900
@@ -18,6 +18,7 @@
   #include <malloc.h>
 #endif
 #include <memory.h>
+#include <memory>
 #if defined(_MSC_VER) || defined(__BORLANDC__) 
   #include <tchar.h>
   #ifndef UNICODE
@@ -75,6 +76,10 @@
 // Define SQPLUS_CONST_OPT before including SqPlus.h for constant argument + constant member function support.
 //#define SQPLUS_CONST_OPT
 
+// === Function overloading support ===
+// Define SQPLUS_OVERLOAD_OPT before including SqPlus.h for function overloading support
+//#define SQPLUS_OVERLOAD_OPT
+
 // === Uncomment to support std::string ===
 //#define SQPLUS_SUPPORT_STD_STRING
 
@@ -585,6 +590,11 @@
 #include "SqPlusConst.h"
 #endif
 
+#ifdef SQPLUS_OVERLOAD_OPT
+#define SQPLUS_OVERLOAD_DECLARATION
+#include "SqPlusOverload.h"
+#endif
+ 
 //////////////////////////////////////////////////////////////////////////
 //////////// END Generalized Class/Struct Instance Support ///////////////
 //////////////////////////////////////////////////////////////////////////
@@ -1808,8 +1818,17 @@
       return *this;
   } // enumInt
 
+#ifdef SQPLUS_OVERLOAD_OPT
+#define SQPLUS_OVERLOAD_IMPLEMENTATION
+#include "SqPlusOverload.h"    
+#endif
 };
 
+#ifdef SQPLUS_OVERLOAD_OPT
+#define SQPLUS_OVERLOAD_FUNCTIONS
+#include "SqPlusOverload.h"    
+#endif
+
 // === BEGIN Function Call Handlers ===
 
 inline void Push(HSQUIRRELVM v,char value)           { sq_pushinteger(v,value); }

Patch for "testSqPlus2/testSqPlus2.cpp":

diff -ur SQUIRREL2_1_0_sqplus_22/testSqPlus2/testSqPlus2.cpp SQUIRREL2_1_0_sqplus_22_OVERLOAD/testSqPlus2/testSqPlus2.cpp
--- SQUIRREL2_1_0_sqplus_22/testSqPlus2/testSqPlus2.cpp		2006-06-27 10:18:10.000000000 +0900
+++ SQUIRREL2_1_0_sqplus_22_OVERLOAD/testSqPlus2/testSqPlus2.cpp		2006-09-17 17:33:19.546875000 +0900
@@ -8,6 +8,7 @@
 #include <stdarg.h> 
 #include <stdio.h>
 //#define SQPLUS_CONST_OPT
+//#define SQPLUS_OVERLOAD_OPT
 #include "sqplus.h"
 
 using namespace SqPlus;
@@ -30,6 +31,17 @@
   return _T("Returned String");
 }
 
+#ifdef SQPLUS_OVERLOAD_OPT
+void overloadTest(void) {scprintf(_T("void overloadTest(void)\n"));}
+void overloadTest(int) {scprintf(_T("void overloadTest(int)\n"));}
+void overloadTest(float) {scprintf(_T("void overloadTest(float)\n"));}
+
+static SQInteger releaseVector3(SQUserPointer up, SQInteger s) {
+  scprintf(_T("releaseVector3() called.\n"));
+  return 0;
+}
+#endif
+
 struct Vector3 {
   static float staticVar;
   float x,y,z;
@@ -48,6 +60,13 @@
   Vector3 operator+(Vector3 & v) {
     return Vector3(x+v.x,y+v.y,z+v.z);
   }
+#ifdef SQPLUS_OVERLOAD_OPT
+  void set(const Vector3 &src) {x = src.x; y = src.y; z = src.z;} 
+  float set(float xyz) {x = y = z = xyz; return xyz;}
+  void set(float x_, float y_, float z_) {x = x_; y = y_; z = z_;}
+  static void setStaticVar(void) {staticVar = 0.0;}
+  static void setStaticVar(float f) {staticVar = f;}
+#endif
 };
 
 
@@ -796,6 +815,17 @@
         func(&Vector3::operator+,_T("_add")).
         staticFunc(&Add2,_T("Add2")).
         staticFuncVarArgs(&Add,_T("Add")).
+# ifdef SQPLUS_OVERLOAD_OPT
+        overloadConstructor<Vector3(*)(void)>().
+        overloadConstructor<Vector3(*)(float, float, float)>().
+        overloadConstructor<Vector3(*)(Vector3&)>().
+        overloadFunc<void(Vector3::*)(const Vector3&)>(&Vector3::set, _T("set")).
+        overloadFunc<float(Vector3::*)(float)>(&Vector3::set, _T("set")).
+        overloadFunc<void(Vector3::*)(float, float, float)>(&Vector3::set, _T("set")).
+        overloadStaticFunc<void(*)(void)>(&Vector3::setStaticVar, _T("setStaticVar")).
+        overloadStaticFunc<void(*)(float)>(&Vector3::setStaticVar, _T("setStaticVar")).
+        releaseHook(&releaseVector3).
+# endif
 #if 1
         staticVar(&Vector3::staticVar,_T("staticVar")).
 #else
@@ -820,6 +850,12 @@
       BindConstant(SQ_10*2,_T("SQ_10_2"));
       BindConstant(_T("Global String"),_T("GLOBAL_STRING"));
 
+#ifdef SQPLUS_OVERLOAD_OPT
+      OverloadGlobal<void(*)(void)>(&overloadTest, _T("overloadTest"));
+      OverloadGlobal<void(*)(int)>(&overloadTest, _T("overloadTest"));
+      OverloadGlobal<void(*)(float)>(&overloadTest, _T("overloadTest"));
+#endif
+      
       SquirrelObject testStaticVars = SquirrelVM::CompileBuffer(_T(" local v = Vector3(); local v2 = Vector3(); local v3 = v+v2; v3 += v2; print(\"v3.x: \"+v3.x); print(\"Vector3::staticVar: \"+v.staticVar+\" Vector3::globalVar: \"+v.globalVar); v.staticVar = 0; "));
       SquirrelVM::RunScript(testStaticVars);
 
@@ -930,7 +966,35 @@
       SquirrelObject testRegV = SquirrelVM::CompileBuffer(_T(" local vec = Vector3(); print(vec.x); vec = vec.Add(vec); print(vec.x); vec = vec.Add(vec); print(vec.x); vec = vec.Add2(vec,vec); print(vec.x); local v2 = Vector3(); vec = v2.Inc(vec); print(vec.x); print(v2.x); "));
       SquirrelVM::RunScript(testRegV);
 
+#ifdef SQPLUS_OVERLOAD_OPT
+      SquirrelObject testOverload = SquirrelVM::CompileBuffer(
+          _T(" print(\"=== BEGIN OVERLOAD ===\");")
+          _T(" local vec3v = Vector3();")
+          _T(" print(\"constructed by void: \" + vec3v.x + \" \" + vec3v.y + \" \" + vec3v.z);")
+          _T(" local vec3f = Vector3(-11.0, 22.0, -33.0);")
+          _T(" print(\"constructed by 3 floats: \" + vec3f.x + \" \" + vec3f.y + \" \" + vec3f.z);")
+          _T(" local vec3c = Vector3(vec3f);")
+          _T(" print(\"constructed by copy: \" + vec3c.x + \" \" + vec3c.y + \" \" + vec3c.z);")
+          _T(" vec3v.set(333.0);")
+          _T(" print(\"modified by set(float): \" + vec3v.x + \" \" + vec3v.y + \" \" + vec3v.z);")
+          _T(" vec3v.set(444.0, 555.0, 666.0);")
+          _T(" print(\"modified by set(float, float, float): \" + vec3v.x + \" \" + vec3v.y + \" \" + vec3v.z);")
+          _T(" vec3v.set(vec3f);")
+          _T(" print(\"modified by set(Vector3&): \" + vec3v.x + \" \" + vec3v.y + \" \" + vec3v.z);")
+          _T(" vec3v.setStaticVar();")
+          _T(" print(\"staticVar: \" + vec3c.staticVar);")
+          _T(" vec3f.setStaticVar(2.0);")
+          _T(" print(\"staticVar: \" + vec3c.staticVar);")
+          _T(" overloadTest();")
+          _T(" overloadTest(100);")
+          _T(" overloadTest(2.0);")
+          _T(" print(\"=== END OVERLOAD ===\");")
+            );
+      SquirrelVM::RunScript(testOverload);
+#endif
 
+      
+      
 #ifdef SQ_USE_CLASS_INHERITANCE
       SquirrelObject testReg0 = SquirrelVM::CompileBuffer(_T(" co <- CustomTestObj(\"hello\",123,true); co.varArgTypes(\"str\",123,123,\"str\"); co.varArgTypes(123,\"str\",\"str\",123); "));
       SquirrelVM::RunScript(testReg0);
Files SQUIRREL2_1_0_sqplus_22/testSqPlus2/testSqPlus2.exe and SQUIRREL2_1_0_sqplus_22_OVERLOAD/testSqPlus2/testSqPlus2.exe differ

New File "sqplus/SqPlusOverload.h":

// SqPlusOverload.h
// SqPlus function overloading support created by Katsuaki Kawachi.

#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) {
                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, _T("Call of overloaded function")
                                     _T(" is ambiguous"));
            } else if (imin == -1) {
                return sq_throwerror(v, _T("No match for given arguments"));
            }

          SQPLUS_OVERLOAD_CALL_IMMEDIATE_EXECUTION:
            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;

    template<typename Func>
    class SQOverloader {
    private:
        static inline int &functionIndex(void) {
            static int index;
            return index;
        }
        
        static inline SQInteger switcher(HSQUIRRELVM v,
                                         int(*caller)(int, HSQUIRRELVM, int)) {
            return (*caller)(StackHandler(v).GetParamCount() - 1,
                             v,
                             functionIndex());
        }
        
        static inline SQInteger memberSwitcher(HSQUIRRELVM v) {
            return switcher(v, SQFuncHolder::memberCall);
        }
        static inline SQInteger staticSwitcher(HSQUIRRELVM v) {
            return switcher(v, SQFuncHolder::staticCall);
        }
        static inline SQInteger constructorSwitcher(HSQUIRRELVM v) {
            return switcher(v, SQFuncHolder::constructorCall);
        }
        
    public:
        static inline void addMemberFunc(SQClassDef<TClassType> *def,
                                         Func mfunc,
                                         const SQChar *name) {
            functionIndex() = def->overloadedMemberNames.index(name);
            SQFuncHolder::addMemberFunc(functionIndex(), mfunc);
            def->staticFuncVarArgs(memberSwitcher, name);
        }
        static inline void addStaticFunc(SQClassDef<TClassType> *def,
                                         Func sfunc,
                                         const SQChar *name) {
            functionIndex() = def->overloadedStaticMemberNames.index(name);
            SQFuncHolder::addStaticFunc(functionIndex(), sfunc);
            def->staticFuncVarArgs(staticSwitcher, name);
        }
        template<typename Cfunc>
        static inline void addConstructor(SQClassDef<TClassType> *def,
                                          Cfunc cfunc) {
            SQFuncHolder::addConstructor(cfunc);
            def->staticFuncVarArgs(constructorSwitcher, _T("constructor"));
        }
        static inline void addGlobalFunc(SQClassDef<TClassType> *def,
                                         Func gfunc,
                                         const SQChar *name) {
            functionIndex() = def->overloadedStaticMemberNames.index(name);
            SQFuncHolder::addStaticFunc(functionIndex(), gfunc);
            SquirrelVM::CreateFunctionGlobal(staticSwitcher, name, _T("*"));
        }
    };

    static inline SQRELEASEHOOK &release(void) {
        static SQRELEASEHOOK hook = ReleaseClassPtr<TClassType>::release;
        return hook;
    }

public:
    template<typename Mfunc>
    SQClassDef<TClassType> &overloadFunc(Mfunc mfunc, const SQChar *n) {
        SQOverloader<Mfunc>::addMemberFunc(this, mfunc, n);
        return *this;
    }
    template<typename Sfunc>
    SQClassDef<TClassType> &overloadStaticFunc(Sfunc sfunc, const SQChar *n) {
        SQOverloader<Sfunc>::addStaticFunc(this, sfunc, n);
        return *this;
    }
    template<typename Cmetafunc>
    SQClassDef<TClassType> &overloadConstructor(void) {
        SQOverloader<Cmetafunc>::addConstructor(this, &Arg<Cmetafunc>::create);
        return *this;
    }
    template<typename Cfunc>
    SQClassDef<TClassType> &overloadConstructor(Cfunc cfunc) {
        SQOverloader<Cfunc>::addConstructor(this, cfunc);
        return *this;
    }
    template<typename Gfunc>
    SQClassDef<TClassType> &overloadGlobalFunc(Gfunc gfunc, const SQChar *n) {
        SQOverloader<Gfunc>::addGlobalFunc(this, gfunc, n);
        return *this;
    }

    SQClassDef<TClassType> &releaseHook(SQRELEASEHOOK releaseHook) {
        release() = releaseHook;
        return *this;
    }
    static inline SQRELEASEHOOK &getReleaseHook(void) {
        return release();
    }


#endif // SQPLUS_OVERLOAD_IMPLEMENTATION



#ifdef SQPLUS_OVERLOAD_FUNCTIONS
#undef SQPLUS_OVERLOAD_FUNCTIONS

struct GlobalFuncOverloader {};
static inline SQClassDef<GlobalFuncOverloader> &globalFuncOverloader(void)
{
    static SQClassDef<GlobalFuncOverloader> ffo(_T("GlobalFuncOverloader"));
    return ffo;
}

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);
    }
};

static inline int classAllocationError(HSQUIRRELVM v) {
    return sq_throwerror(v, _T("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,
                             SQClassDef<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),
                             SQClassDef<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),
                             SQClassDef<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),
                             SQClassDef<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),
                             SQClassDef<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),
                             SQClassDef<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),
                             SQClassDef<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),
                             SQClassDef<R>::getReleaseHook()) :
            classAllocationError(v);
    }
};
#endif // SQPLUS_OVERLOAD_FUNCTIONS

// SqPlusOverload.h

// Local Variables: 
// mode: c++
// End:
Not logged in. Log in

squirrel's community wiki

This is FlexWiki, an open source wiki engine.

Change Style

Recent Topics