if (use_generic) {
r = engine->RegisterGlobalFunction("void print(string & in)", WRAP_FN(print), asCALL_GENERIC); assert(r >= 0);
} else {
r = engine->RegisterGlobalFunction("void print(string & in)", asFUNCTION(print), asCALL_CDECL); assert(r >= 0);
}
Similarly WRAP_MFN() can be used instead of asMETHOD() and asCALL_THISCALL, WRAP_OBJ_FIRST() instead of asCALL_CDECL_OBJFIRST and WRAP_OBJ_LAST() instead of asCALL_CDECL_OBJLAST. There are also PR versions of the macros for overloads. (The PR macros are actually more straightforward than the regular ones; the mechanism I originally wanted for the non-PR macros ended up crashing MSVC 2010.)
The one major limitation with this is the variable parameter type, e.g.: (?&in). Since AngelScript passes variable parameters to generic and non-generic functions in fundamentally different ways, I can't think of a reasonable mechanism to map one to the other.
While I was at it, I also worked on automatic wrappers for use with smart pointers as value types. This includes creating getters and setters as well as functions to automatically invoke member functions. They can be used to generate either generic or native functions.
An example file demonstrating both at work:
#include "angelscript.h"
#include "scriptstdstring.h"
#include "as_smart_ptr_wrapper.h"
#include "as_gen_wrapper.h"
#include <iostream>
#include <cassert>
#include <cstdio>
#include <memory>
// Types to export
struct Base {
virtual ~Base() {}
void moo(void) const { std::cout << "Moo." << std::endl; }
};
struct Derived : Base {
int x;
int y;
void moo(void) const { std::cout << "Moo!" << std::endl; }
void add(int value) { x += value; y += value; }
int & getter(void) { return x; }
};
typedef std::shared_ptr<Base> BasePtr;
typedef std::shared_ptr<Derived> DerivedPtr;
// Helper functions
template <typename T>
void construct(void * address) {
new (address) T;
}
template <typename T>
void destroy(T * object) {
object->~T();
}
template <typename T>
void copy_construct(void * address, T * other) {
new (address) T(*other);
}
template <typename T>
void assign(T * lhs, T* rhs) {
*lhs = *rhs;
}
void MessageCallback(const asSMessageInfo *msg, void *param)
{
const char *type = "ERR ";
if (msg->type == asMSGTYPE_WARNING) {
type = "WARN";
} else if (msg->type == asMSGTYPE_INFORMATION) {
type = "INFO";
}
printf("%s (%d, %d) : %s : %s\n", msg->section, msg->row, msg->col, type, msg->message);
}
void __cdecl print(const std::string & str) {
std::cout << str;
}
template <typename T>
T foo(T);
int main(int, char **) {
asIScriptEngine * engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
engine->SetMessageCallback(asFUNCTION(MessageCallback), 0, asCALL_CDECL);
RegisterStdString(engine);
bool use_generic = strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY");
int r;
if (use_generic) {
r = engine->RegisterGlobalFunction("void print(string & in)", WRAP_FN(print), asCALL_GENERIC); assert(r >= 0);
} else {
r = engine->RegisterGlobalFunction("void print(string & in)", asFUNCTION(print), asCALL_CDECL); assert(r >= 0);
}
// Base
r = engine->RegisterObjectType("Base", sizeof(BasePtr), asOBJ_VALUE | asOBJ_APP_CLASS_CDAK); assert(r >= 0);
if (use_generic) {
r = engine->RegisterObjectBehaviour("Base", asBEHAVE_CONSTRUCT, "void f()", WRAP_OBJ_FIRST(construct<BasePtr>), asCALL_GENERIC); assert(r >= 0);
r = engine->RegisterObjectBehaviour("Base", asBEHAVE_CONSTRUCT, "void f(const Base & in)", WRAP_OBJ_FIRST(copy_construct<BasePtr>), asCALL_GENERIC); assert(r >= 0);
r = engine->RegisterObjectBehaviour("Base", asBEHAVE_DESTRUCT, "void f()", WRAP_OBJ_FIRST(destroy<BasePtr>), asCALL_GENERIC); assert(r >= 0);
r = engine->RegisterObjectMethod("Base", "Base &opAssign(const Base &in)", WRAP_OBJ_FIRST(assign<BasePtr>), asCALL_GENERIC); assert(r >= 0);
r = engine->RegisterObjectMethod("Base", "void moo(void) const", GEN_CALLER(Base, moo), asCALL_GENERIC); assert(r >= 0);
} else {
r = engine->RegisterObjectBehaviour("Base", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(construct<BasePtr>), asCALL_CDECL_OBJFIRST); assert(r >= 0);
r = engine->RegisterObjectBehaviour("Base", asBEHAVE_CONSTRUCT, "void f(const Base & in)", asFUNCTION(copy_construct<BasePtr>), asCALL_CDECL_OBJFIRST); assert(r >= 0);
r = engine->RegisterObjectBehaviour("Base", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(destroy<BasePtr>), asCALL_CDECL_OBJFIRST); assert(r >= 0);
r = engine->RegisterObjectMethod("Base", "Base &opAssign(const Base &in)", asFUNCTION(assign<BasePtr>), asCALL_CDECL_OBJFIRST); assert(r >= 0);
r = engine->RegisterObjectMethod("Base", "void moo(void) const", CALLER(Base, moo), asCALL_CDECL_OBJFIRST); assert(r >= 0);
}
// Derived
r = engine->RegisterObjectType("Derived", sizeof(DerivedPtr), asOBJ_VALUE | asOBJ_APP_CLASS_CDAK); assert(r >= 0);
if (use_generic) {
r = engine->RegisterObjectBehaviour("Derived", asBEHAVE_CONSTRUCT, "void f()", WRAP_OBJ_FIRST(construct<DerivedPtr>), asCALL_GENERIC); assert(r >= 0);
r = engine->RegisterObjectBehaviour("Derived", asBEHAVE_CONSTRUCT, "void f(const Derived & in)", WRAP_OBJ_FIRST(copy_construct<DerivedPtr>), asCALL_GENERIC); assert(r >= 0);
r = engine->RegisterObjectBehaviour("Derived", asBEHAVE_DESTRUCT, "void f()", WRAP_OBJ_FIRST(destroy<DerivedPtr>), asCALL_GENERIC); assert(r >= 0);
r = engine->RegisterObjectMethod("Derived", "Derived &opAssign(const Derived & in)", WRAP_OBJ_FIRST(assign<DerivedPtr>), asCALL_GENERIC); assert(r >= 0);
r = engine->RegisterObjectMethod("Derived", "const int & get_x() const", REF_GETTER_GEN(Derived, x), asCALL_GENERIC); assert(r >= 0);
r = engine->RegisterObjectMethod("Derived", "void set_x(const int & in)", REF_SETTER_GEN(Derived, x), asCALL_GENERIC); assert(r >= 0);
r = engine->RegisterObjectMethod("Derived", "int get_y() const", GETTER_GEN(Derived, y), asCALL_GENERIC); assert(r >= 0);
r = engine->RegisterObjectMethod("Derived", "void set_y(int)", SETTER_GEN(Derived, y), asCALL_GENERIC); assert(r >= 0);
r = engine->RegisterObjectMethod("Derived", "void moo(void) const", GEN_CALLER(Derived, moo), asCALL_GENERIC); assert(r >= 0);
r = engine->RegisterObjectMethod("Derived", "void add(int)", GEN_CALLER(Derived, add), asCALL_GENERIC); assert(r >= 0);
r = engine->RegisterObjectMethod("Derived", "int & getter(void)", GEN_CALLER(Derived, getter), asCALL_GENERIC); assert(r >= 0);
} else {
r = engine->RegisterObjectBehaviour("Derived", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(construct<DerivedPtr>), asCALL_CDECL_OBJFIRST); assert(r >= 0);
r = engine->RegisterObjectBehaviour("Derived", asBEHAVE_CONSTRUCT, "void f(const Derived & in)", asFUNCTION(copy_construct<DerivedPtr>), asCALL_CDECL_OBJFIRST); assert(r >= 0);
r = engine->RegisterObjectBehaviour("Derived", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(destroy<DerivedPtr>), asCALL_CDECL_OBJFIRST); assert(r >= 0);
r = engine->RegisterObjectMethod("Derived", "Derived &opAssign(const Derived & in)", asFUNCTION(assign<DerivedPtr>), asCALL_CDECL_OBJFIRST); assert(r >= 0);
r = engine->RegisterObjectMethod("Derived", "const int & get_x() const", REF_GETTER(Derived, x), asCALL_CDECL_OBJFIRST); assert(r >= 0);
r = engine->RegisterObjectMethod("Derived", "void set_x(const int & in)", REF_SETTER(Derived, x), asCALL_CDECL_OBJFIRST); assert(r >= 0);
r = engine->RegisterObjectMethod("Derived", "int get_y() const", GETTER(Derived, y), asCALL_CDECL_OBJFIRST); assert(r >= 0);
r = engine->RegisterObjectMethod("Derived", "void set_y(int)", SETTER(Derived, y), asCALL_CDECL_OBJFIRST); assert(r >= 0);
r = engine->RegisterObjectMethod("Derived", "void moo(void) const", CALLER(Derived, moo), asCALL_CDECL_OBJFIRST); assert(r >= 0);
r = engine->RegisterObjectMethod("Derived", "void add(int)", CALLER(Derived, add), asCALL_CDECL_OBJFIRST); assert(r >= 0);
r = engine->RegisterObjectMethod("Derived", "int & getter(void)", CALLER(Derived, getter), asCALL_CDECL_OBJFIRST); assert(r >= 0);
}
// conversions
if (use_generic) {
r = engine->RegisterObjectBehaviour("Base", asBEHAVE_VALUE_CAST, "Derived f() const", WRAP_OBJ_FIRST((std::dynamic_pointer_cast<Derived, Base>)), asCALL_GENERIC); assert(r >= 0);
r = engine->RegisterObjectBehaviour("Derived", asBEHAVE_IMPLICIT_VALUE_CAST, "Base f() const", WRAP_OBJ_FIRST((std::static_pointer_cast<Base, Derived>)), asCALL_GENERIC); assert(r >= 0);
} else {
r = engine->RegisterObjectBehaviour("Base", asBEHAVE_VALUE_CAST, "Derived f() const", asFUNCTION((std::dynamic_pointer_cast<Derived, Base>)), asCALL_CDECL_OBJFIRST); assert(r >= 0);
r = engine->RegisterObjectBehaviour("Derived", asBEHAVE_IMPLICIT_VALUE_CAST, "Base f() const", asFUNCTION((std::static_pointer_cast<Base, Derived>)), asCALL_CDECL_OBJFIRST); assert(r >= 0);
}
const char script[] =
"void foo(const Base & in ptr) {\n"
" ptr.moo();\n"
" Derived d = Derived(ptr);\n"
" print(d.x + \"\\n\");\n"
" print(d.y + \"\\n\");\n"
" d.getter() = 3;\n"
" d.y = 4;\n"
" d.moo();\n"
" d.add(1);\n"
"}\n"
;
asIScriptModule * mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
r = mod->AddScriptSection("script", script, sizeof(script) - 1); assert(r >= 0);
r = mod->Build(); assert(r >= 0);
int func_id = mod->GetFunctionIdByDecl("void foo(const Base & in)");
Derived * d = new Derived;
d->x = 1;
d->y = 2;
BasePtr base(d);
asIScriptContext * ctx = engine->CreateContext();
ctx->Prepare(func_id);
ctx->SetArgObject(0, &base);
ctx->Execute();
ctx->Release();
engine->Release();
std::cout << d->x << std::endl;
std::cout << d->y << std::endl;
}
A header for the generic wrappers good for up to four arguments:
#ifndef AS_GEN_WRAPPER_H
#define AS_GEN_WRAPPER_H
#include "angelscript.h"
#include <new>
namespace gw {
template <typename T> class Proxy {
public:
T value;
Proxy(T value) : value(value) {}
static T cast(void * ptr) {
return reinterpret_cast<Proxy<T> *>(&ptr)->value;
}
private:
Proxy(const Proxy &);
Proxy & operator=(const Proxy &);
};
template <typename T> struct Wrapper {};
template <typename T> struct ObjFirst {};
template <typename T> struct ObjLast {};
template <>
struct Wrapper<void (*)(void)> {
template <void (*fp)(void)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
((fp)());
}
};
template <typename R>
struct Wrapper<R (*)(void)> {
template <R (*fp)(void)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)());
}
};
template <typename T>
struct Wrapper<void (T::*)(void)> {
template <void (T::*fp)(void)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
((static_cast<T *>(gen->GetObject())->*fp)());
}
};
template <typename T, typename R>
struct Wrapper<R (T::*)(void)> {
template <R (T::*fp)(void)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
new (gen->GetAddressOfReturnLocation()) Proxy<R>((static_cast<T *>(gen->GetObject())->*fp)());
}
};
template <typename T>
struct Wrapper<void (T::*)(void) const> {
template <void (T::*fp)(void) const>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
((static_cast<T *>(gen->GetObject())->*fp)());
}
};
template <typename T, typename R>
struct Wrapper<R (T::*)(void) const> {
template <R (T::*fp)(void) const>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
new (gen->GetAddressOfReturnLocation()) Proxy<R>((static_cast<T *>(gen->GetObject())->*fp)());
}
};
template <typename T>
struct ObjFirst<void (*)(T)> {
template <void (*fp)(T)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
((fp)(
Proxy<T>::cast(gen->GetObject())));
}
};
template <typename T, typename R>
struct ObjFirst<R (*)(T)> {
template <R (*fp)(T)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
Proxy<T>::cast(gen->GetObject())));
}
};
template <typename T>
struct ObjLast<void (*)(T)> {
template <void (*fp)(T)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
((fp)(
Proxy<T>::cast(gen->GetObject())));
}
};
template <typename T, typename R>
struct ObjLast<R (*)(T)> {
template <R (*fp)(T)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
Proxy<T>::cast(gen->GetObject())));
}
};
template <typename A0>
struct Wrapper<void (*)(A0)> {
template <void (*fp)(A0)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
((fp)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value));
}
};
template <typename R, typename A0>
struct Wrapper<R (*)(A0)> {
template <R (*fp)(A0)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value));
}
};
template <typename T, typename A0>
struct Wrapper<void (T::*)(A0)> {
template <void (T::*fp)(A0)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
((static_cast<T *>(gen->GetObject())->*fp)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value));
}
};
template <typename T, typename R, typename A0>
struct Wrapper<R (T::*)(A0)> {
template <R (T::*fp)(A0)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
new (gen->GetAddressOfReturnLocation()) Proxy<R>((static_cast<T *>(gen->GetObject())->*fp)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value));
}
};
template <typename T, typename A0>
struct Wrapper<void (T::*)(A0) const> {
template <void (T::*fp)(A0) const>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
((static_cast<T *>(gen->GetObject())->*fp)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value));
}
};
template <typename T, typename R, typename A0>
struct Wrapper<R (T::*)(A0) const> {
template <R (T::*fp)(A0) const>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
new (gen->GetAddressOfReturnLocation()) Proxy<R>((static_cast<T *>(gen->GetObject())->*fp)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value));
}
};
template <typename T, typename A0>
struct ObjFirst<void (*)(T, A0)> {
template <void (*fp)(T, A0)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
((fp)(
Proxy<T>::cast(gen->GetObject()),
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value));
}
};
template <typename T, typename R, typename A0>
struct ObjFirst<R (*)(T, A0)> {
template <R (*fp)(T, A0)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
Proxy<T>::cast(gen->GetObject()),
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value));
}
};
template <typename T, typename A0>
struct ObjLast<void (*)(A0, T)> {
template <void (*fp)(A0, T)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
((fp)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
Proxy<T>::cast(gen->GetObject())));
}
};
template <typename T, typename R, typename A0>
struct ObjLast<R (*)(A0, T)> {
template <R (*fp)(A0, T)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
Proxy<T>::cast(gen->GetObject())));
}
};
template <typename A0, typename A1>
struct Wrapper<void (*)(A0, A1)> {
template <void (*fp)(A0, A1)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
((fp)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value));
}
};
template <typename R, typename A0, typename A1>
struct Wrapper<R (*)(A0, A1)> {
template <R (*fp)(A0, A1)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value));
}
};
template <typename T, typename A0, typename A1>
struct Wrapper<void (T::*)(A0, A1)> {
template <void (T::*fp)(A0, A1)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
((static_cast<T *>(gen->GetObject())->*fp)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value));
}
};
template <typename T, typename R, typename A0, typename A1>
struct Wrapper<R (T::*)(A0, A1)> {
template <R (T::*fp)(A0, A1)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
new (gen->GetAddressOfReturnLocation()) Proxy<R>((static_cast<T *>(gen->GetObject())->*fp)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value));
}
};
template <typename T, typename A0, typename A1>
struct Wrapper<void (T::*)(A0, A1) const> {
template <void (T::*fp)(A0, A1) const>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
((static_cast<T *>(gen->GetObject())->*fp)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value));
}
};
template <typename T, typename R, typename A0, typename A1>
struct Wrapper<R (T::*)(A0, A1) const> {
template <R (T::*fp)(A0, A1) const>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
new (gen->GetAddressOfReturnLocation()) Proxy<R>((static_cast<T *>(gen->GetObject())->*fp)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value));
}
};
template <typename T, typename A0, typename A1>
struct ObjFirst<void (*)(T, A0, A1)> {
template <void (*fp)(T, A0, A1)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
((fp)(
Proxy<T>::cast(gen->GetObject()),
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value));
}
};
template <typename T, typename R, typename A0, typename A1>
struct ObjFirst<R (*)(T, A0, A1)> {
template <R (*fp)(T, A0, A1)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
Proxy<T>::cast(gen->GetObject()),
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value));
}
};
template <typename T, typename A0, typename A1>
struct ObjLast<void (*)(A0, A1, T)> {
template <void (*fp)(A0, A1, T)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
((fp)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
Proxy<T>::cast(gen->GetObject())));
}
};
template <typename T, typename R, typename A0, typename A1>
struct ObjLast<R (*)(A0, A1, T)> {
template <R (*fp)(A0, A1, T)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
Proxy<T>::cast(gen->GetObject())));
}
};
template <typename A0, typename A1, typename A2>
struct Wrapper<void (*)(A0, A1, A2)> {
template <void (*fp)(A0, A1, A2)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
((fp)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value));
}
};
template <typename R, typename A0, typename A1, typename A2>
struct Wrapper<R (*)(A0, A1, A2)> {
template <R (*fp)(A0, A1, A2)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value));
}
};
template <typename T, typename A0, typename A1, typename A2>
struct Wrapper<void (T::*)(A0, A1, A2)> {
template <void (T::*fp)(A0, A1, A2)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
((static_cast<T *>(gen->GetObject())->*fp)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value));
}
};
template <typename T, typename R, typename A0, typename A1, typename A2>
struct Wrapper<R (T::*)(A0, A1, A2)> {
template <R (T::*fp)(A0, A1, A2)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
new (gen->GetAddressOfReturnLocation()) Proxy<R>((static_cast<T *>(gen->GetObject())->*fp)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value));
}
};
template <typename T, typename A0, typename A1, typename A2>
struct Wrapper<void (T::*)(A0, A1, A2) const> {
template <void (T::*fp)(A0, A1, A2) const>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
((static_cast<T *>(gen->GetObject())->*fp)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value));
}
};
template <typename T, typename R, typename A0, typename A1, typename A2>
struct Wrapper<R (T::*)(A0, A1, A2) const> {
template <R (T::*fp)(A0, A1, A2) const>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
new (gen->GetAddressOfReturnLocation()) Proxy<R>((static_cast<T *>(gen->GetObject())->*fp)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value));
}
};
template <typename T, typename A0, typename A1, typename A2>
struct ObjFirst<void (*)(T, A0, A1, A2)> {
template <void (*fp)(T, A0, A1, A2)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
((fp)(
Proxy<T>::cast(gen->GetObject()),
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value));
}
};
template <typename T, typename R, typename A0, typename A1, typename A2>
struct ObjFirst<R (*)(T, A0, A1, A2)> {
template <R (*fp)(T, A0, A1, A2)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
Proxy<T>::cast(gen->GetObject()),
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value));
}
};
template <typename T, typename A0, typename A1, typename A2>
struct ObjLast<void (*)(A0, A1, A2, T)> {
template <void (*fp)(A0, A1, A2, T)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
((fp)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
Proxy<T>::cast(gen->GetObject())));
}
};
template <typename T, typename R, typename A0, typename A1, typename A2>
struct ObjLast<R (*)(A0, A1, A2, T)> {
template <R (*fp)(A0, A1, A2, T)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
Proxy<T>::cast(gen->GetObject())));
}
};
template <typename A0, typename A1, typename A2, typename A3>
struct Wrapper<void (*)(A0, A1, A2, A3)> {
template <void (*fp)(A0, A1, A2, A3)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
((fp)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value));
}
};
template <typename R, typename A0, typename A1, typename A2, typename A3>
struct Wrapper<R (*)(A0, A1, A2, A3)> {
template <R (*fp)(A0, A1, A2, A3)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value));
}
};
template <typename T, typename A0, typename A1, typename A2, typename A3>
struct Wrapper<void (T::*)(A0, A1, A2, A3)> {
template <void (T::*fp)(A0, A1, A2, A3)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
((static_cast<T *>(gen->GetObject())->*fp)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value));
}
};
template <typename T, typename R, typename A0, typename A1, typename A2, typename A3>
struct Wrapper<R (T::*)(A0, A1, A2, A3)> {
template <R (T::*fp)(A0, A1, A2, A3)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
new (gen->GetAddressOfReturnLocation()) Proxy<R>((static_cast<T *>(gen->GetObject())->*fp)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value));
}
};
template <typename T, typename A0, typename A1, typename A2, typename A3>
struct Wrapper<void (T::*)(A0, A1, A2, A3) const> {
template <void (T::*fp)(A0, A1, A2, A3) const>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
((static_cast<T *>(gen->GetObject())->*fp)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value));
}
};
template <typename T, typename R, typename A0, typename A1, typename A2, typename A3>
struct Wrapper<R (T::*)(A0, A1, A2, A3) const> {
template <R (T::*fp)(A0, A1, A2, A3) const>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
new (gen->GetAddressOfReturnLocation()) Proxy<R>((static_cast<T *>(gen->GetObject())->*fp)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value));
}
};
template <typename T, typename A0, typename A1, typename A2, typename A3>
struct ObjFirst<void (*)(T, A0, A1, A2, A3)> {
template <void (*fp)(T, A0, A1, A2, A3)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
((fp)(
Proxy<T>::cast(gen->GetObject()),
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value));
}
};
template <typename T, typename R, typename A0, typename A1, typename A2, typename A3>
struct ObjFirst<R (*)(T, A0, A1, A2, A3)> {
template <R (*fp)(T, A0, A1, A2, A3)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
Proxy<T>::cast(gen->GetObject()),
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value));
}
};
template <typename T, typename A0, typename A1, typename A2, typename A3>
struct ObjLast<void (*)(A0, A1, A2, A3, T)> {
template <void (*fp)(A0, A1, A2, A3, T)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
((fp)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value,
Proxy<T>::cast(gen->GetObject())));
}
};
template <typename T, typename R, typename A0, typename A1, typename A2, typename A3>
struct ObjLast<R (*)(A0, A1, A2, A3, T)> {
template <R (*fp)(A0, A1, A2, A3, T)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
new (gen->GetAddressOfReturnLocation()) Proxy<R>((fp)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value,
Proxy<T>::cast(gen->GetObject())));
}
};
template <typename T>
struct Id {
template <T fn_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr f(void) { return asFUNCTION(&(Wrapper<T>::f<fn_ptr>)); }
template <T fn_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr of(void) { return asFUNCTION(&(ObjFirst<T>::f<fn_ptr>)); }
template <T fn_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr ol(void) { return asFUNCTION(&(ObjLast<T>::f<fn_ptr>)); }
};
template <typename T>
Id<T> id(T fn_ptr) { return Id<T>(); }
#define WRAP_FN(name) (::gw::id(name).f< name >())
#define WRAP_MFN(ClassType, name) (::gw::id(&ClassType::name).f< &ClassType::name >())
#define WRAP_OBJ_FIRST(name) (::gw::id(name).of< name >())
#define WRAP_OBJ_LAST(name) (::gw::id(name).ol< name >())
#define WRAP_FN_PR(name, Parameters, ReturnType) asFUNCTION((::gw::Wrapper<ReturnType (*)Parameters>::f< name >))
#define WRAP_MFN_PR(ClassType, name, Parameters, ReturnType) asFUNCTION((::gw::Wrapper<ReturnType (ClassType::*)Parameters>::f< &ClassType::name >))
#define WRAP_OBJ_FIRST_PR(name, Parameters, ReturnType) asFUNCTION((::gw::ObjFirst<ReturnType (*)Parameters>::f< name >))
#define WRAP_OBJ_LAST_PR(name, Parameters, ReturnType) asFUNCTION((::gw::ObjLast<ReturnType (*)Parameters>::f< name >))
} // end namespace gw
#endif
A python script to regenerate the file in case four arguments aren't enough for you:
max_args = 4 # the maximum number of parameters to be processed
print """#ifndef AS_GEN_WRAPPER_H
#define AS_GEN_WRAPPER_H
#include "angelscript.h"
#include <new>
namespace gw {
template <typename T> class Proxy {
public:
T value;
Proxy(T value) : value(value) {}
static T cast(void * ptr) {
return reinterpret_cast<Proxy<T> *>(&ptr)->value;
}
private:
Proxy(const Proxy &);
Proxy & operator=(const Proxy &);
};
template <typename T> struct Wrapper {};
template <typename T> struct ObjFirst {};
template <typename T> struct ObjLast {};
"""
typename_list = "typename A0"
type_list = "A0"
arg_list = "\n static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value"
new_exp = "new (gen->GetAddressOfReturnLocation()) Proxy<R>"
obj_exp = "static_cast<T *>(gen->GetObject())->*"
obj_arg_exp = "\n Proxy<T>::cast(gen->GetObject())"
template = """template <{0}{1}>
struct {9}<{2} ({3}*)({7}){4}> {{
template <{2} ({3}*fp)({7}){4}>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {{
{5}(({6}fp)({8}));
}}
}};
"""
print template.format("", "", "void", "", "", "", "", "void", "", "Wrapper")
print template.format("typename R", "", "R", "", "", new_exp, "", "void", "", "Wrapper")
print template.format("typename T", "", "void", "T::", "", "", obj_exp, "void", "", "Wrapper")
print template.format("typename T, typename R", "", "R", "T::", "", new_exp, obj_exp, "void", "", "Wrapper")
print template.format("typename T", "", "void", "T::", " const", "", obj_exp, "void", "", "Wrapper")
print template.format("typename T, typename R", "", "R", "T::", " const", new_exp, obj_exp, "void", "", "Wrapper")
print template.format("typename T", "", "void", "", "", "", "", "T", obj_arg_exp, "ObjFirst")
print template.format("typename T, typename R", "", "R", "", "", new_exp, "", "T", obj_arg_exp, "ObjFirst")
print template.format("typename T", "", "void", "", "", "", "", "T", obj_arg_exp, "ObjLast")
print template.format("typename T, typename R", "", "R", "", "", new_exp, "", "T", obj_arg_exp, "ObjLast")
for i in range(0, max_args):
print template.format("", typename_list, "void", "", "", "", "", type_list, arg_list, "Wrapper")
print template.format("typename R, ", typename_list, "R", "", "", new_exp, "", type_list, arg_list, "Wrapper")
print template.format("typename T, ", typename_list, "void", "T::", "", "", obj_exp, type_list, arg_list, "Wrapper")
print template.format("typename T, typename R, ", typename_list, "R", "T::", "", new_exp, obj_exp, type_list, arg_list, "Wrapper")
print template.format("typename T, ", typename_list, "void", "T::", " const", "", obj_exp, type_list, arg_list, "Wrapper")
print template.format("typename T, typename R, ", typename_list, "R", "T::", " const", new_exp, obj_exp, type_list, arg_list, "Wrapper")
print template.format("typename T, ", typename_list, "void", "", "", "", "", "T, " + type_list, obj_arg_exp + "," + arg_list, "ObjFirst")
print template.format("typename T, typename R, ", typename_list, "R", "", "", new_exp, "", "T, " + type_list, obj_arg_exp + "," + arg_list, "ObjFirst")
print template.format("typename T, ", typename_list, "void", "", "", "", "", type_list + ", T", arg_list + "," + obj_arg_exp, "ObjLast")
print template.format("typename T, typename R, ", typename_list, "R", "", "", new_exp, "", type_list + ", T", arg_list + "," + obj_arg_exp, "ObjLast")
typename_list += ", typename A{0}".format(i + 1)
type_list += ", A{0}".format(i + 1)
arg_list += ",\n static_cast<Proxy <A{0}> *>(gen->GetAddressOfArg({0}))->value".format(i + 1)
print """template <typename T>
struct Id {
template <T fn_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr f(void) { return asFUNCTION(&(Wrapper<T>::f<fn_ptr>)); }
template <T fn_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr of(void) { return asFUNCTION(&(ObjFirst<T>::f<fn_ptr>)); }
template <T fn_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr ol(void) { return asFUNCTION(&(ObjLast<T>::f<fn_ptr>)); }
};
template <typename T>
Id<T> id(T fn_ptr) { return Id<T>(); }
#define WRAP_FN(name) (::gw::id(name).f< name >())
#define WRAP_MFN(ClassType, name) (::gw::id(&ClassType::name).f< &ClassType::name >())
#define WRAP_OBJ_FIRST(name) (::gw::id(name).of< name >())
#define WRAP_OBJ_LAST(name) (::gw::id(name).ol< name >())
#define WRAP_FN_PR(name, Parameters, ReturnType) asFUNCTION((::gw::Wrapper<ReturnType (*)Parameters>::f< name >))
#define WRAP_MFN_PR(ClassType, name, Parameters, ReturnType) asFUNCTION((::gw::Wrapper<ReturnType (ClassType::*)Parameters>::f< &ClassType::name >))
#define WRAP_OBJ_FIRST_PR(name, Parameters, ReturnType) asFUNCTION((::gw::ObjFirst<ReturnType (*)Parameters>::f< name >))
#define WRAP_OBJ_LAST_PR(name, Parameters, ReturnType) asFUNCTION((::gw::ObjLast<ReturnType (*)Parameters>::f< name >))
} // end namespace gw
#endif"""
A smart pointer header also good for up to four arguments:
#ifndef AS_SMART_POINTER_WRAPPER
#define AS_SMART_POINTER_WRAPPER
#include <new>
#include "angelscript.h"
#include <memory>
namespace spw {
template <typename T> struct Default {
static T f(void) { return T(); }
};
template <typename T> struct Default<T &> {
static T & f(void) { return *static_cast<T *>(0); }
};
template <typename T> class Proxy {
public:
T value;
Proxy(T value) : value(value) {}
private:
Proxy(const Proxy &);
Proxy & operator=(const Proxy &);
};
template <typename T, typename U, U T::*member_ptr>
U getter(const std::shared_ptr<T> & ptr) {
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to access member of a null pointer");
return Default<U>::f();
}
return (ptr.get())->*member_ptr;
}
template <typename T, typename U, U T::*member_ptr>
const U & ref_getter(const std::shared_ptr<T> & ptr) {
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to access member of a null pointer");
return Default<U &>::f();
}
return (ptr.get())->*member_ptr;
}
template <typename T, typename U, U T::*member_ptr>
void getter_gen(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
std::shared_ptr<T> & ptr = *static_cast<std::shared_ptr<T> *>(gen->GetObject());
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to access member of a null pointer");
} else {
new (gen->GetAddressOfReturnLocation()) Proxy<U>((ptr.get())->*member_ptr);
}
}
template <typename T, typename U, U T::*member_ptr>
void ref_getter_gen(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
std::shared_ptr<T> & ptr = *static_cast<std::shared_ptr<T> *>(gen->GetObject());
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to access member of a null pointer");
} else {
new (gen->GetAddressOfReturnLocation()) Proxy<U &>((ptr.get())->*member_ptr);
}
}
template <typename T, typename U, U T::*member_ptr>
void setter(const std::shared_ptr<T> & ptr, U value) {
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to access member of a null pointer");
} else {
(ptr.get())->*member_ptr = value;
}
}
template <typename T, typename U, U T::*member_ptr>
void ref_setter(const std::shared_ptr<T> & ptr, const U & value) {
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to access member of a null pointer");
} else {
(ptr.get())->*member_ptr = value;
}
}
template <typename T, typename U, U T::*member_ptr>
void setter_gen(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
std::shared_ptr<T> & ptr = *static_cast<std::shared_ptr<T> *>(gen->GetObject());
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to access member of a null pointer");
} else {
(ptr.get())->*member_ptr = static_cast<Proxy<U> *>(gen->GetAddressOfArg(0))->value;
}
}
template <typename T, typename U, U T::*member_ptr>
void ref_setter_gen(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
std::shared_ptr<T> & ptr = *static_cast<std::shared_ptr<T> *>(gen->GetObject());
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to access member of a null pointer");
} else {
(ptr.get())->*member_ptr = static_cast<Proxy<U &> *>(gen->GetAddressOfArg(0))->value;
}
}
template <typename T> struct Caller {};
template <typename T> struct GenCaller {};
template <typename T, typename R>
struct Caller<R (T::*)(void)> {
template <R (T::*fn)(void)>
static R f(std::shared_ptr<T> & ptr) {
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
return Default<R>::f();
} else {
return ((ptr.get())->*fn)();
}
}
};
template <typename T, typename R>
struct Caller<R (T::*)(void) const> {
template <R (T::*fn)(void) const>
static R f(std::shared_ptr<T> & ptr) {
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
return Default<R>::f();
} else {
return ((ptr.get())->*fn)();
}
}
};
template <typename T>
struct GenCaller<void (T::*)(void)> {
template <void (T::*fn)(void)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
std::shared_ptr<T> & ptr = *static_cast<std::shared_ptr<T> *>(gen->GetObject());
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
} else {
((ptr.get())->*fn)();
}
}
};
template <typename T, typename R>
struct GenCaller<R (T::*)(void)> {
template <R (T::*fn)(void)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
std::shared_ptr<T> & ptr = *static_cast<std::shared_ptr<T> *>(gen->GetObject());
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
} else {
new (gen->GetAddressOfReturnLocation()) Proxy<R>(((ptr.get())->*fn)());
}
}
};
template <typename T>
struct GenCaller<void (T::*)(void) const> {
template <void (T::*fn)(void) const>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
std::shared_ptr<T> & ptr = *static_cast<std::shared_ptr<T> *>(gen->GetObject());
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
} else {
((ptr.get())->*fn)();
}
}
};
template <typename T, typename R>
struct GenCaller<R (T::*)(void) const> {
template <R (T::*fn)(void) const>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
std::shared_ptr<T> & ptr = *static_cast<std::shared_ptr<T> *>(gen->GetObject());
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
} else {
new (gen->GetAddressOfReturnLocation()) Proxy<R>(((ptr.get())->*fn)());
}
}
};
template <typename T, typename R, typename A0>
struct Caller<R (T::*)(A0)> {
template <R (T::*fn)(A0)>
static R f(std::shared_ptr<T> & ptr, A0 a0) {
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
return Default<R>::f();
} else {
return ((ptr.get())->*fn)(a0);
}
}
};
template <typename T, typename R, typename A0>
struct Caller<R (T::*)(A0) const> {
template <R (T::*fn)(A0) const>
static R f(std::shared_ptr<T> & ptr, A0 a0) {
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
return Default<R>::f();
} else {
return ((ptr.get())->*fn)(a0);
}
}
};
template <typename T, typename A0>
struct GenCaller<void (T::*)(A0)> {
template <void (T::*fn)(A0)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
std::shared_ptr<T> & ptr = *static_cast<std::shared_ptr<T> *>(gen->GetObject());
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
} else {
((ptr.get())->*fn)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value);
}
}
};
template <typename T, typename R, typename A0>
struct GenCaller<R (T::*)(A0)> {
template <R (T::*fn)(A0)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
std::shared_ptr<T> & ptr = *static_cast<std::shared_ptr<T> *>(gen->GetObject());
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
} else {
new (gen->GetAddressOfReturnLocation()) Proxy<R>(((ptr.get())->*fn)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value));
}
}
};
template <typename T, typename A0>
struct GenCaller<void (T::*)(A0) const> {
template <void (T::*fn)(A0) const>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
std::shared_ptr<T> & ptr = *static_cast<std::shared_ptr<T> *>(gen->GetObject());
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
} else {
((ptr.get())->*fn)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value);
}
}
};
template <typename T, typename R, typename A0>
struct GenCaller<R (T::*)(A0) const> {
template <R (T::*fn)(A0) const>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
std::shared_ptr<T> & ptr = *static_cast<std::shared_ptr<T> *>(gen->GetObject());
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
} else {
new (gen->GetAddressOfReturnLocation()) Proxy<R>(((ptr.get())->*fn)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value));
}
}
};
template <typename T, typename R, typename A0, typename A1>
struct Caller<R (T::*)(A0, A1)> {
template <R (T::*fn)(A0, A1)>
static R f(std::shared_ptr<T> & ptr, A0 a0, A1 a1) {
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
return Default<R>::f();
} else {
return ((ptr.get())->*fn)(a0, a1);
}
}
};
template <typename T, typename R, typename A0, typename A1>
struct Caller<R (T::*)(A0, A1) const> {
template <R (T::*fn)(A0, A1) const>
static R f(std::shared_ptr<T> & ptr, A0 a0, A1 a1) {
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
return Default<R>::f();
} else {
return ((ptr.get())->*fn)(a0, a1);
}
}
};
template <typename T, typename A0, typename A1>
struct GenCaller<void (T::*)(A0, A1)> {
template <void (T::*fn)(A0, A1)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
std::shared_ptr<T> & ptr = *static_cast<std::shared_ptr<T> *>(gen->GetObject());
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
} else {
((ptr.get())->*fn)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value);
}
}
};
template <typename T, typename R, typename A0, typename A1>
struct GenCaller<R (T::*)(A0, A1)> {
template <R (T::*fn)(A0, A1)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
std::shared_ptr<T> & ptr = *static_cast<std::shared_ptr<T> *>(gen->GetObject());
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
} else {
new (gen->GetAddressOfReturnLocation()) Proxy<R>(((ptr.get())->*fn)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value));
}
}
};
template <typename T, typename A0, typename A1>
struct GenCaller<void (T::*)(A0, A1) const> {
template <void (T::*fn)(A0, A1) const>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
std::shared_ptr<T> & ptr = *static_cast<std::shared_ptr<T> *>(gen->GetObject());
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
} else {
((ptr.get())->*fn)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value);
}
}
};
template <typename T, typename R, typename A0, typename A1>
struct GenCaller<R (T::*)(A0, A1) const> {
template <R (T::*fn)(A0, A1) const>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
std::shared_ptr<T> & ptr = *static_cast<std::shared_ptr<T> *>(gen->GetObject());
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
} else {
new (gen->GetAddressOfReturnLocation()) Proxy<R>(((ptr.get())->*fn)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value));
}
}
};
template <typename T, typename R, typename A0, typename A1, typename A2>
struct Caller<R (T::*)(A0, A1, A2)> {
template <R (T::*fn)(A0, A1, A2)>
static R f(std::shared_ptr<T> & ptr, A0 a0, A1 a1, A2 a2) {
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
return Default<R>::f();
} else {
return ((ptr.get())->*fn)(a0, a1, a2);
}
}
};
template <typename T, typename R, typename A0, typename A1, typename A2>
struct Caller<R (T::*)(A0, A1, A2) const> {
template <R (T::*fn)(A0, A1, A2) const>
static R f(std::shared_ptr<T> & ptr, A0 a0, A1 a1, A2 a2) {
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
return Default<R>::f();
} else {
return ((ptr.get())->*fn)(a0, a1, a2);
}
}
};
template <typename T, typename A0, typename A1, typename A2>
struct GenCaller<void (T::*)(A0, A1, A2)> {
template <void (T::*fn)(A0, A1, A2)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
std::shared_ptr<T> & ptr = *static_cast<std::shared_ptr<T> *>(gen->GetObject());
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
} else {
((ptr.get())->*fn)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value);
}
}
};
template <typename T, typename R, typename A0, typename A1, typename A2>
struct GenCaller<R (T::*)(A0, A1, A2)> {
template <R (T::*fn)(A0, A1, A2)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
std::shared_ptr<T> & ptr = *static_cast<std::shared_ptr<T> *>(gen->GetObject());
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
} else {
new (gen->GetAddressOfReturnLocation()) Proxy<R>(((ptr.get())->*fn)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value));
}
}
};
template <typename T, typename A0, typename A1, typename A2>
struct GenCaller<void (T::*)(A0, A1, A2) const> {
template <void (T::*fn)(A0, A1, A2) const>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
std::shared_ptr<T> & ptr = *static_cast<std::shared_ptr<T> *>(gen->GetObject());
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
} else {
((ptr.get())->*fn)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value);
}
}
};
template <typename T, typename R, typename A0, typename A1, typename A2>
struct GenCaller<R (T::*)(A0, A1, A2) const> {
template <R (T::*fn)(A0, A1, A2) const>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
std::shared_ptr<T> & ptr = *static_cast<std::shared_ptr<T> *>(gen->GetObject());
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
} else {
new (gen->GetAddressOfReturnLocation()) Proxy<R>(((ptr.get())->*fn)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value));
}
}
};
template <typename T, typename R, typename A0, typename A1, typename A2, typename A3>
struct Caller<R (T::*)(A0, A1, A2, A3)> {
template <R (T::*fn)(A0, A1, A2, A3)>
static R f(std::shared_ptr<T> & ptr, A0 a0, A1 a1, A2 a2, A3 a3) {
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
return Default<R>::f();
} else {
return ((ptr.get())->*fn)(a0, a1, a2, a3);
}
}
};
template <typename T, typename R, typename A0, typename A1, typename A2, typename A3>
struct Caller<R (T::*)(A0, A1, A2, A3) const> {
template <R (T::*fn)(A0, A1, A2, A3) const>
static R f(std::shared_ptr<T> & ptr, A0 a0, A1 a1, A2 a2, A3 a3) {
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
return Default<R>::f();
} else {
return ((ptr.get())->*fn)(a0, a1, a2, a3);
}
}
};
template <typename T, typename A0, typename A1, typename A2, typename A3>
struct GenCaller<void (T::*)(A0, A1, A2, A3)> {
template <void (T::*fn)(A0, A1, A2, A3)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
std::shared_ptr<T> & ptr = *static_cast<std::shared_ptr<T> *>(gen->GetObject());
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
} else {
((ptr.get())->*fn)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value);
}
}
};
template <typename T, typename R, typename A0, typename A1, typename A2, typename A3>
struct GenCaller<R (T::*)(A0, A1, A2, A3)> {
template <R (T::*fn)(A0, A1, A2, A3)>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
std::shared_ptr<T> & ptr = *static_cast<std::shared_ptr<T> *>(gen->GetObject());
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
} else {
new (gen->GetAddressOfReturnLocation()) Proxy<R>(((ptr.get())->*fn)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value));
}
}
};
template <typename T, typename A0, typename A1, typename A2, typename A3>
struct GenCaller<void (T::*)(A0, A1, A2, A3) const> {
template <void (T::*fn)(A0, A1, A2, A3) const>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
std::shared_ptr<T> & ptr = *static_cast<std::shared_ptr<T> *>(gen->GetObject());
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
} else {
((ptr.get())->*fn)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value);
}
}
};
template <typename T, typename R, typename A0, typename A1, typename A2, typename A3>
struct GenCaller<R (T::*)(A0, A1, A2, A3) const> {
template <R (T::*fn)(A0, A1, A2, A3) const>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {
std::shared_ptr<T> & ptr = *static_cast<std::shared_ptr<T> *>(gen->GetObject());
if (!ptr) {
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
} else {
new (gen->GetAddressOfReturnLocation()) Proxy<R>(((ptr.get())->*fn)(
static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value,
static_cast<Proxy <A1> *>(gen->GetAddressOfArg(1))->value,
static_cast<Proxy <A2> *>(gen->GetAddressOfArg(2))->value,
static_cast<Proxy <A3> *>(gen->GetAddressOfArg(3))->value));
}
}
};
template <typename T, typename U>
struct GetSet {
template <U T::* member_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr g(void) { return asFUNCTION(( &getter <T, U, member_ptr>)); }
template <U T::* member_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr rg(void) { return asFUNCTION((&ref_getter <T, U, member_ptr>)); }
template <U T::* member_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr gg(void) { return asFUNCTION(( &getter_gen<T, U, member_ptr>)); }
template <U T::* member_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr rgg(void) { return asFUNCTION((&ref_getter_gen<T, U, member_ptr>)); }
template <U T::* member_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr s(void) { return asFUNCTION((&setter <T, U, member_ptr>)); }
template <U T::* member_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr rs(void) { return asFUNCTION((&ref_setter <T, U, member_ptr>)); }
template <U T::* member_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr sg(void) { return asFUNCTION(( &setter_gen<T, U, member_ptr>)); }
template <U T::* member_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr rsg(void) { return asFUNCTION((&ref_setter_gen<T, U, member_ptr>)); }
};
template <typename T, typename U>
GetSet<T, U> gs_id(U T::*) { return GetSet<T, U>(); }
#define GETTER(ClassName, member_name) (::spw::gs_id(&ClassName::member_name).g<&ClassName::member_name>())
#define REF_GETTER(ClassName, member_name) (::spw::gs_id(&ClassName::member_name).rg<&ClassName::member_name>())
#define GETTER_GEN(ClassName, member_name) (::spw::gs_id(&ClassName::member_name).gg<&ClassName::member_name>())
#define REF_GETTER_GEN(ClassName, member_name) (::spw::gs_id(&ClassName::member_name).rgg<&ClassName::member_name>())
#define SETTER(ClassName, member_name) (::spw::gs_id(&ClassName::member_name).s<&ClassName::member_name>())
#define REF_SETTER(ClassName, member_name) (::spw::gs_id(&ClassName::member_name).rs<&ClassName::member_name>())
#define SETTER_GEN(ClassName, member_name) (::spw::gs_id(&ClassName::member_name).sg<&ClassName::member_name>())
#define REF_SETTER_GEN(ClassName, member_name) (::spw::gs_id(&ClassName::member_name).rsg<&ClassName::member_name>())
template <typename T>
struct CCaller {
template <T ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr c(void) { return asFUNCTION(&(Caller<T>::f<ptr>)); }
template <T ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr g(void) { return asFUNCTION(&(GenCaller<T>::f<ptr>)); }
};
template <typename T>
CCaller<T> caller_id(T) { return CCaller<T>(); }
#define CALLER(ClassName, member_name) (::spw::caller_id(&ClassName::member_name).c< &ClassName::member_name >())
#define GEN_CALLER(ClassName, member_name) (::spw::caller_id(&ClassName::member_name).g< &ClassName::member_name >())
#define CALLER_PR(ClassName, member_name, Args, Return) asFUNCTION((::spw::Caller<Return (ClassName::*)Args>::f< &ClassName::member_name >))
#define GEN_CALLER_PR(ClassName, member_name, Args, Return) asFUNCTION((::spw::GenCaller<Return (ClassName::*)Args>::f< &ClassName::member_name >))
} // end namespace spw
#endif
Another python script, again, if four arguments aren't enough:
pointer_header = "<memory>" # which C++ header should be included
pointer_type = "std::shared_ptr<T>" # the name of the smart pointer parameterized on T
get_pointer = "(ptr.get())" # an expression that converts a smart pointer named ptr to T *
max_args = 4 # the maximum number of parameters to be processed
print """#ifndef AS_SMART_POINTER_WRAPPER
#define AS_SMART_POINTER_WRAPPER
#include <new>
#include "angelscript.h"
#include {0}
""".format(pointer_header)
print """namespace spw {
template <typename T> struct Default {
static T f(void) { return T(); }
};
template <typename T> struct Default<T &> {
static T & f(void) { return *static_cast<T *>(0); }
};
template <typename T> class Proxy {
public:
T value;
Proxy(T value) : value(value) {}
private:
Proxy(const Proxy &);
Proxy & operator=(const Proxy &);
};
"""
print """template <typename T, typename U, U T::*member_ptr>
U getter(const {0} & ptr) {{
if (!ptr) {{
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to access member of a null pointer");
return Default<U>::f();
}}
return {1}->*member_ptr;
}}
template <typename T, typename U, U T::*member_ptr>
const U & ref_getter(const {0} & ptr) {{
if (!ptr) {{
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to access member of a null pointer");
return Default<U &>::f();
}}
return {1}->*member_ptr;
}}
template <typename T, typename U, U T::*member_ptr>
void getter_gen(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {{
{0} & ptr = *static_cast<{0} *>(gen->GetObject());
if (!ptr) {{
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to access member of a null pointer");
}} else {{
new (gen->GetAddressOfReturnLocation()) Proxy<U>({1}->*member_ptr);
}}
}}
template <typename T, typename U, U T::*member_ptr>
void ref_getter_gen(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {{
{0} & ptr = *static_cast<{0} *>(gen->GetObject());
if (!ptr) {{
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to access member of a null pointer");
}} else {{
new (gen->GetAddressOfReturnLocation()) Proxy<U &>({1}->*member_ptr);
}}
}}
template <typename T, typename U, U T::*member_ptr>
void setter(const {0} & ptr, U value) {{
if (!ptr) {{
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to access member of a null pointer");
}} else {{
{1}->*member_ptr = value;
}}
}}
template <typename T, typename U, U T::*member_ptr>
void ref_setter(const {0} & ptr, const U & value) {{
if (!ptr) {{
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to access member of a null pointer");
}} else {{
{1}->*member_ptr = value;
}}
}}
template <typename T, typename U, U T::*member_ptr>
void setter_gen(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {{
{0} & ptr = *static_cast<{0} *>(gen->GetObject());
if (!ptr) {{
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to access member of a null pointer");
}} else {{
{1}->*member_ptr = static_cast<Proxy<U> *>(gen->GetAddressOfArg(0))->value;
}}
}}
template <typename T, typename U, U T::*member_ptr>
void ref_setter_gen(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {{
{0} & ptr = *static_cast<{0} *>(gen->GetObject());
if (!ptr) {{
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to access member of a null pointer");
}} else {{
{1}->*member_ptr = static_cast<Proxy<U &> *>(gen->GetAddressOfArg(0))->value;
}}
}}
""".format(pointer_type, get_pointer)
print """template <typename T> struct Caller {};
template <typename T> struct GenCaller {};
"""
typename_list = ", typename A0"
type_list = "A0"
parameter_list = ", A0 a0"
arg_list = "a0"
gen_arg_list = "\n static_cast<Proxy <A0> *>(gen->GetAddressOfArg(0))->value"
caller = """template <typename T, typename R{0}>
struct Caller<R (T::*)({1}){6}> {{
template <R (T::*fn)({1}){6}>
static R f({2} & ptr{3}) {{
if (!ptr) {{
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
return Default<R>::f();
}} else {{
return ({4}->*fn)({5});
}}
}}
}};
"""
gen_caller = """template <typename T{0}>
struct GenCaller<void (T::*)({1}){6}> {{
template <void (T::*fn)({1}){6}>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {{
{2} & ptr = *static_cast<{2} *>(gen->GetObject());
if (!ptr) {{
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
}} else {{
({4}->*fn)({5});
}}
}}
}};
template <typename T, typename R{0}>
struct GenCaller<R (T::*)({1}){6}> {{
template <R (T::*fn)({1}){6}>
static void f(AS_NAMESPACE_QUALIFIER asIScriptGeneric * gen) {{
{2} & ptr = *static_cast<{2} *>(gen->GetObject());
if (!ptr) {{
AS_NAMESPACE_QUALIFIER asIScriptContext * ctx = AS_NAMESPACE_QUALIFIER asGetActiveContext();
ctx->SetException("Attempting to call member function of a null pointer");
}} else {{
new (gen->GetAddressOfReturnLocation()) Proxy<R>(({4}->*fn)({5}));
}}
}}
}};
"""
print caller.format("", "void", pointer_type, "", get_pointer, "", "")
print caller.format("", "void", pointer_type, "", get_pointer, "", " const")
print gen_caller.format("", "void", pointer_type, "", get_pointer, "", "")
print gen_caller.format("", "void", pointer_type, "", get_pointer, "", " const")
print caller.format(typename_list, type_list, pointer_type, parameter_list, get_pointer, arg_list, "")
print caller.format(typename_list, type_list, pointer_type, parameter_list, get_pointer, arg_list, " const")
print gen_caller.format(typename_list, type_list, pointer_type, parameter_list, get_pointer, gen_arg_list, "")
print gen_caller.format(typename_list, type_list, pointer_type, parameter_list, get_pointer, gen_arg_list, " const")
for i in range(1, max_args):
typename_list += ", typename A{0}".format(i)
type_list += ", A{0}".format(i)
parameter_list += ", A{0} a{0}".format(i)
arg_list += ", a{0}".format(i)
gen_arg_list += ",\n static_cast<Proxy <A{0}> *>(gen->GetAddressOfArg({0}))->value".format(i)
print caller.format(typename_list, type_list, pointer_type, parameter_list, get_pointer, arg_list, "")
print caller.format(typename_list, type_list, pointer_type, parameter_list, get_pointer, arg_list, " const")
print gen_caller.format(typename_list, type_list, pointer_type, parameter_list, get_pointer, gen_arg_list, "")
print gen_caller.format(typename_list, type_list, pointer_type, parameter_list, get_pointer, gen_arg_list, " const")
print """template <typename T, typename U>
struct GetSet {
template <U T::* member_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr g(void) { return asFUNCTION(( &getter <T, U, member_ptr>)); }
template <U T::* member_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr rg(void) { return asFUNCTION((&ref_getter <T, U, member_ptr>)); }
template <U T::* member_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr gg(void) { return asFUNCTION(( &getter_gen<T, U, member_ptr>)); }
template <U T::* member_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr rgg(void) { return asFUNCTION((&ref_getter_gen<T, U, member_ptr>)); }
template <U T::* member_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr s(void) { return asFUNCTION((&setter <T, U, member_ptr>)); }
template <U T::* member_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr rs(void) { return asFUNCTION((&ref_setter <T, U, member_ptr>)); }
template <U T::* member_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr sg(void) { return asFUNCTION(( &setter_gen<T, U, member_ptr>)); }
template <U T::* member_ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr rsg(void) { return asFUNCTION((&ref_setter_gen<T, U, member_ptr>)); }
};
template <typename T, typename U>
GetSet<T, U> gs_id(U T::*) { return GetSet<T, U>(); }
#define GETTER(ClassName, member_name) (::spw::gs_id(&ClassName::member_name).g<&ClassName::member_name>())
#define REF_GETTER(ClassName, member_name) (::spw::gs_id(&ClassName::member_name).rg<&ClassName::member_name>())
#define GETTER_GEN(ClassName, member_name) (::spw::gs_id(&ClassName::member_name).gg<&ClassName::member_name>())
#define REF_GETTER_GEN(ClassName, member_name) (::spw::gs_id(&ClassName::member_name).rgg<&ClassName::member_name>())
#define SETTER(ClassName, member_name) (::spw::gs_id(&ClassName::member_name).s<&ClassName::member_name>())
#define REF_SETTER(ClassName, member_name) (::spw::gs_id(&ClassName::member_name).rs<&ClassName::member_name>())
#define SETTER_GEN(ClassName, member_name) (::spw::gs_id(&ClassName::member_name).sg<&ClassName::member_name>())
#define REF_SETTER_GEN(ClassName, member_name) (::spw::gs_id(&ClassName::member_name).rsg<&ClassName::member_name>())
template <typename T>
struct CCaller {
template <T ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr c(void) { return asFUNCTION(&(Caller<T>::f<ptr>)); }
template <T ptr> AS_NAMESPACE_QUALIFIER asSFuncPtr g(void) { return asFUNCTION(&(GenCaller<T>::f<ptr>)); }
};
template <typename T>
CCaller<T> caller_id(T) { return CCaller<T>(); }
#define CALLER(ClassName, member_name) (::spw::caller_id(&ClassName::member_name).c< &ClassName::member_name >())
#define GEN_CALLER(ClassName, member_name) (::spw::caller_id(&ClassName::member_name).g< &ClassName::member_name >())
#define CALLER_PR(ClassName, member_name, Args, Return) asFUNCTION((::spw::Caller<Return (ClassName::*)Args>::f< &ClassName::member_name >))
#define GEN_CALLER_PR(ClassName, member_name, Args, Return) asFUNCTION((::spw::GenCaller<Return (ClassName::*)Args>::f< &ClassName::member_name >))
} // end namespace spw
#endif"""
Python code was developed on CPython 2.6.