summaryrefslogtreecommitdiff
path: root/include/gras/detail
diff options
context:
space:
mode:
authorJosh Blum2013-07-05 16:10:49 -0700
committerJosh Blum2013-07-05 16:10:49 -0700
commitaa2c285ac86e5671fa418d336920c1c300cf9737 (patch)
tree33dfab03ddb43b4865ce59b89f421741460d6c24 /include/gras/detail
parente23e5f43a97c72f1bf0dd240376bf89ff19f356c (diff)
downloadsandhi-aa2c285ac86e5671fa418d336920c1c300cf9737.tar.gz
sandhi-aa2c285ac86e5671fa418d336920c1c300cf9737.tar.bz2
sandhi-aa2c285ac86e5671fa418d336920c1c300cf9737.zip
gras: serious template insanity
Diffstat (limited to 'include/gras/detail')
-rw-r--r--include/gras/detail/callable.hpp255
1 files changed, 210 insertions, 45 deletions
diff --git a/include/gras/detail/callable.hpp b/include/gras/detail/callable.hpp
index 5e7854a..23e3ab6 100644
--- a/include/gras/detail/callable.hpp
+++ b/include/gras/detail/callable.hpp
@@ -8,112 +8,277 @@
namespace gras
{
+/***********************************************************************
+ * Registration entry base class
+ **********************************************************************/
struct GRAS_API CallableRegistryEntry
{
CallableRegistryEntry(void);
virtual ~CallableRegistryEntry(void);
- virtual PMCC call(const std::vector<PMCC> &args) = 0;
+ virtual PMCC call(const PMCC *args) = 0;
};
-template <typename ClassType, typename ReturnType, typename Arg0, typename Arg1>
-class CallableRegistryEntryImpl : public CallableRegistryEntry
+/***********************************************************************
+ * Registration for return with 0 args
+ **********************************************************************/
+template <typename ClassType, typename ReturnType>
+struct CallableRegistryEntryImpl0 : CallableRegistryEntry
{
-public:
-
- typedef ReturnType(ClassType::*Fcn0)(void);
- typedef ReturnType(ClassType::*Fcn1)(const Arg0 &);
- typedef ReturnType(ClassType::*Fcn2)(const Arg0 &, const Arg1 &);
-
- CallableRegistryEntryImpl(ClassType *obj, Fcn0 fcn0, Fcn1 fcn1 = NULL, Fcn2 fcn2 = NULL):
- _obj(obj), _fcn0(fcn0), _fcn1(fcn1), _fcn2(fcn2)
- {}
- virtual ~CallableRegistryEntryImpl(void){}
-
- PMCC call(const std::vector<PMCC> &args)
+ typedef ReturnType(ClassType::*Fcn)(void);
+ CallableRegistryEntryImpl0(ClassType *obj, Fcn fcn):
+ _obj(obj), _fcn(fcn){}
+ PMCC call(const PMCC *args)
{
- if (_fcn0) return PMC_M((_obj->*_fcn0)());
- if (_fcn1) return PMC_M((_obj->*_fcn1)(args[0].safe_as<Arg0>()));
- if (_fcn2) return PMC_M((_obj->*_fcn2)(args[0].safe_as<Arg0>(), args[1].safe_as<Arg1>()));
- return PMCC();//should not get here
+ return PMC_M((_obj->*_fcn)());
}
-
-private:
- ClassType *_obj;
- Fcn0 _fcn0; Fcn1 _fcn1; Fcn2 _fcn2;
+ ClassType *_obj; Fcn _fcn;
};
template <typename ClassType, typename ReturnType>
void Callable::register_call(const std::string &key, ReturnType(ClassType::*fcn)(void))
{
ClassType *obj = dynamic_cast<ClassType *>(this);
- void *fr = new CallableRegistryEntryImpl<ClassType, ReturnType, int, int>(obj, fcn);
+ void *fr = new CallableRegistryEntryImpl0<ClassType, ReturnType>(obj, fcn);
_register_call(key, fr);
}
+template <typename ClassType>
+struct CallableRegistryEntryImplVoid0 : CallableRegistryEntry
+{
+ typedef void(ClassType::*Fcn)(void);
+ CallableRegistryEntryImplVoid0(ClassType *obj, Fcn fcn):
+ _obj(obj), _fcn(fcn){}
+ PMCC call(const PMCC *args)
+ {
+ (_obj->*_fcn)(); return PMCC();
+ }
+ ClassType *_obj; Fcn _fcn;
+};
+
+template <typename ClassType>
+void Callable::register_call(const std::string &key, void(ClassType::*fcn)(void))
+{
+ ClassType *obj = dynamic_cast<ClassType *>(this);
+ void *fr = new CallableRegistryEntryImplVoid0<ClassType>(obj, fcn);
+ _register_call(key, fr);
+}
+
+/***********************************************************************
+ * Registration for return with 1 args
+ **********************************************************************/
+template <typename ClassType, typename ReturnType, typename Arg0>
+struct CallableRegistryEntryImpl1 : CallableRegistryEntry
+{
+ typedef ReturnType(ClassType::*Fcn)(const Arg0 &);
+ CallableRegistryEntryImpl1(ClassType *obj, Fcn fcn):
+ _obj(obj), _fcn(fcn){}
+ PMCC call(const PMCC *args)
+ {
+ return PMC_M((_obj->*_fcn)(args[0].safe_as<Arg0>()));
+ }
+ ClassType *_obj; Fcn _fcn;
+};
+
template <typename ClassType, typename ReturnType, typename Arg0>
void Callable::register_call(const std::string &key, ReturnType(ClassType::*fcn)(const Arg0 &))
{
ClassType *obj = dynamic_cast<ClassType *>(this);
- void *fr = new CallableRegistryEntryImpl<ClassType, ReturnType, Arg0, int>(obj, NULL, fcn);
+ void *fr = new CallableRegistryEntryImpl1<ClassType, ReturnType, Arg0>(obj, fcn);
+ _register_call(key, fr);
+}
+
+template <typename ClassType, typename Arg0>
+struct CallableRegistryEntryImplVoid1 : CallableRegistryEntry
+{
+ typedef void(ClassType::*Fcn)(const Arg0 &);
+ CallableRegistryEntryImplVoid1(ClassType *obj, Fcn fcn):
+ _obj(obj), _fcn(fcn){}
+ PMCC call(const PMCC *args)
+ {
+ (_obj->*_fcn)(args[0].safe_as<Arg0>()); return PMCC();
+ }
+ ClassType *_obj; Fcn _fcn;
+};
+
+template <typename ClassType, typename Arg0>
+void Callable::register_call(const std::string &key, void(ClassType::*fcn)(const Arg0 &))
+{
+ ClassType *obj = dynamic_cast<ClassType *>(this);
+ void *fr = new CallableRegistryEntryImplVoid1<ClassType, Arg0>(obj, fcn);
_register_call(key, fr);
}
+/***********************************************************************
+ * Registration for return with 2 args
+ **********************************************************************/
+template <typename ClassType, typename ReturnType, typename Arg0, typename Arg1>
+struct CallableRegistryEntryImpl2 : CallableRegistryEntry
+{
+ typedef ReturnType(ClassType::*Fcn)(const Arg0 &, const Arg1 &);
+ CallableRegistryEntryImpl2(ClassType *obj, Fcn fcn):
+ _obj(obj), _fcn(fcn){}
+ PMCC call(const PMCC *args)
+ {
+ return PMC_M((_obj->*_fcn)(args[0].safe_as<Arg0>(), args[1].safe_as<Arg1>()));
+ }
+ ClassType *_obj; Fcn _fcn;
+};
+
template <typename ClassType, typename ReturnType, typename Arg0, typename Arg1>
void Callable::register_call(const std::string &key, ReturnType(ClassType::*fcn)(const Arg0 &, const Arg1 &))
{
ClassType *obj = dynamic_cast<ClassType *>(this);
- void *fr = new CallableRegistryEntryImpl<ClassType, ReturnType, Arg0, Arg1>(obj, NULL, NULL, fcn);
+ void *fr = new CallableRegistryEntryImpl2<ClassType, ReturnType, Arg0, Arg1>(obj, fcn);
_register_call(key, fr);
}
+template <typename ClassType, typename Arg0, typename Arg1>
+struct CallableRegistryEntryImplVoid2 : CallableRegistryEntry
+{
+ typedef void(ClassType::*Fcn)(const Arg0 &, const Arg1 &);
+ CallableRegistryEntryImplVoid2(ClassType *obj, Fcn fcn):
+ _obj(obj), _fcn(fcn){}
+ PMCC call(const PMCC *args)
+ {
+ (_obj->*_fcn)(args[0].safe_as<Arg0>(), args[1].safe_as<Arg1>()); return PMCC();
+ }
+ ClassType *_obj; Fcn _fcn;
+};
+
+template <typename ClassType, typename Arg0, typename Arg1>
+void Callable::register_call(const std::string &key, void(ClassType::*fcn)(const Arg0 &, const Arg1 &))
+{
+ ClassType *obj = dynamic_cast<ClassType *>(this);
+ void *fr = new CallableRegistryEntryImplVoid2<ClassType, Arg0, Arg1>(obj, fcn);
+ _register_call(key, fr);
+}
+
+/***********************************************************************
+ * Registration for return with 3 args
+ **********************************************************************/
+template <typename ClassType, typename ReturnType, typename Arg0, typename Arg1, typename Arg2>
+struct CallableRegistryEntryImpl3 : CallableRegistryEntry
+{
+ typedef ReturnType(ClassType::*Fcn)(const Arg0 &, const Arg1 &, const Arg2 &);
+ CallableRegistryEntryImpl3(ClassType *obj, Fcn fcn):
+ _obj(obj), _fcn(fcn){}
+ PMCC call(const PMCC *args)
+ {
+ return PMC_M((_obj->*_fcn)(args[0].safe_as<Arg0>(), args[1].safe_as<Arg1>(), args[2].safe_as<Arg2>()));
+ }
+ ClassType *_obj; Fcn _fcn;
+};
+
+template <typename ClassType, typename ReturnType, typename Arg0, typename Arg1, typename Arg2>
+void Callable::register_call(const std::string &key, ReturnType(ClassType::*fcn)(const Arg0 &, const Arg1 &, const Arg2 &))
+{
+ ClassType *obj = dynamic_cast<ClassType *>(this);
+ void *fr = new CallableRegistryEntryImpl3<ClassType, ReturnType, Arg0, Arg1, Arg2>(obj, fcn);
+ _register_call(key, fr);
+}
+
+template <typename ClassType, typename Arg0, typename Arg1, typename Arg2>
+struct CallableRegistryEntryImplVoid3 : CallableRegistryEntry
+{
+ typedef void(ClassType::*Fcn)(const Arg0 &, const Arg1 &, const Arg2 &);
+ CallableRegistryEntryImplVoid3(ClassType *obj, Fcn fcn):
+ _obj(obj), _fcn(fcn){}
+ PMCC call(const PMCC *args)
+ {
+ (_obj->*_fcn)(args[0].safe_as<Arg0>(), args[1].safe_as<Arg1>(), args[2].safe_as<Arg2>()); return PMCC();
+ }
+ ClassType *_obj; Fcn _fcn;
+};
+
+template <typename ClassType, typename Arg0, typename Arg1, typename Arg2>
+void Callable::register_call(const std::string &key, void(ClassType::*fcn)(const Arg0 &, const Arg1 &, const Arg2 &))
+{
+ ClassType *obj = dynamic_cast<ClassType *>(this);
+ void *fr = new CallableRegistryEntryImplVoid3<ClassType, Arg0, Arg1, Arg2>(obj, fcn);
+ _register_call(key, fr);
+}
+
+/***********************************************************************
+ * Call implementations with 0 args
+ **********************************************************************/
template <typename ReturnType>
ReturnType Callable::call(const std::string &key)
{
- std::vector<PMCC> args;
+ PMCC args[0];
PMCC r = _handle_call(key, args);
return r.safe_as<ReturnType>();
}
+inline
+void Callable::call(const std::string &key)
+{
+ PMCC args[0];
+ _handle_call(key, args);
+}
+
+/***********************************************************************
+ * Call implementations with 1 args
+ **********************************************************************/
template <typename ReturnType, typename Arg0>
ReturnType Callable::call(const std::string &key, const Arg0 &a0)
{
- std::vector<PMCC> args;
- args.push_back(PMC_M(a0));
+ PMCC args[1];
+ args[0] = PMC_M(a0);
PMCC r = _handle_call(key, args);
return r.safe_as<ReturnType>();
}
+template <typename Arg0>
+void Callable::call(const std::string &key, const Arg0 &a0)
+{
+ PMCC args[1];
+ args[0] = PMC_M(a0);
+ _handle_call(key, args);
+}
+
+/***********************************************************************
+ * Call implementations with 2 args
+ **********************************************************************/
template <typename ReturnType, typename Arg0, typename Arg1>
ReturnType Callable::call(const std::string &key, const Arg0 &a0, const Arg1 &a1)
{
- std::vector<PMCC> args;
- args.push_back(PMC_M(a0));
- args.push_back(PMC_M(a1));
+ PMCC args[2];
+ args[0] = PMC_M(a0);
+ args[1] = PMC_M(a1);
PMCC r = _handle_call(key, args);
return r.safe_as<ReturnType>();
}
-inline
-void Callable::call(const std::string &key)
+template <typename Arg0, typename Arg1>
+void Callable::call(const std::string &key, const Arg0 &a0, const Arg1 &a1)
{
- std::vector<PMCC> args;
+ PMCC args[2];
+ args[0] = PMC_M(a0);
+ args[1] = PMC_M(a1);
_handle_call(key, args);
}
-template <typename Arg0>
-void Callable::call(const std::string &key, const Arg0 &a0)
+/***********************************************************************
+ * Call implementations with 3 args
+ **********************************************************************/
+template <typename ReturnType, typename Arg0, typename Arg1, typename Arg2>
+ReturnType Callable::call(const std::string &key, const Arg0 &a0, const Arg1 &a1, const Arg2 &a2)
{
- std::vector<PMCC> args;
- args.push_back(PMC_M(a0));
- _handle_call(key, args);
+ PMCC args[3];
+ args[0] = PMC_M(a0);
+ args[1] = PMC_M(a1);
+ args[2] = PMC_M(a2);
+ PMCC r = _handle_call(key, args);
+ return r.safe_as<ReturnType>();
}
-template <typename Arg0, typename Arg1>
-void Callable::call(const std::string &key, const Arg0 &a0, const Arg1 &a1)
+template <typename Arg0, typename Arg1, typename Arg2>
+void Callable::call(const std::string &key, const Arg0 &a0, const Arg1 &a1, const Arg2 &a2)
{
- std::vector<PMCC> args;
- args.push_back(PMC_M(a0));
- args.push_back(PMC_M(a1));
+ PMCC args[3];
+ args[0] = PMC_M(a0);
+ args[1] = PMC_M(a1);
+ args[2] = PMC_M(a2);
_handle_call(key, args);
}