summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/gras/callable.hpp136
-rw-r--r--include/gras/detail/callable.hpp685
-rw-r--r--include/gras/detail/factory.hpp325
-rw-r--r--include/gras/factory.hpp70
-rw-r--r--tmpl/callable.tmpl.hpp94
-rw-r--r--tmpl/callable_detail.tmpl.hpp100
-rw-r--r--tmpl/expand_template.py33
-rw-r--r--tmpl/factory.tmpl.hpp63
-rw-r--r--tmpl/factory_detail.tmpl.hpp64
-rwxr-xr-xtmpl/regen_all.sh19
10 files changed, 1468 insertions, 121 deletions
diff --git a/include/gras/callable.hpp b/include/gras/callable.hpp
index 60d0fb0..b5003c1 100644
--- a/include/gras/callable.hpp
+++ b/include/gras/callable.hpp
@@ -57,28 +57,70 @@ protected:
******************************************************************/
protected:
template <typename ClassType, typename ReturnType>
- void register_call(const std::string &name, ReturnType(ClassType::*fcn)(void));
+ void register_call(const std::string &name, ReturnType(ClassType::*fcn)());
template <typename ClassType>
- void register_call(const std::string &name, void(ClassType::*fcn)(void));
+ void register_call(const std::string &name, void(ClassType::*fcn)());
- template <typename ClassType, typename ReturnType, typename Arg0>
- void register_call(const std::string &name, ReturnType(ClassType::*fcn)(const Arg0 &));
+ template <typename ClassType, typename ReturnType, typename A0>
+ void register_call(const std::string &name, ReturnType(ClassType::*fcn)(const A0 &));
- template <typename ClassType, typename Arg0>
- void register_call(const std::string &name, void(ClassType::*fcn)(const Arg0 &));
+ template <typename ClassType, typename A0>
+ void register_call(const std::string &name, void(ClassType::*fcn)(const A0 &));
- template <typename ClassType, typename ReturnType, typename Arg0, typename Arg1>
- void register_call(const std::string &name, ReturnType(ClassType::*fcn)(const Arg0 &, const Arg1 &));
+ template <typename ClassType, typename ReturnType, typename A0, typename A1>
+ void register_call(const std::string &name, ReturnType(ClassType::*fcn)(const A0 &, const A1 &));
- template <typename ClassType, typename Arg0, typename Arg1>
- void register_call(const std::string &name, void(ClassType::*fcn)(const Arg0 &, const Arg1 &));
+ template <typename ClassType, typename A0, typename A1>
+ void register_call(const std::string &name, void(ClassType::*fcn)(const A0 &, const A1 &));
- template <typename ClassType, typename ReturnType, typename Arg0, typename Arg1, typename Arg2>
- void register_call(const std::string &name, ReturnType(ClassType::*fcn)(const Arg0 &, const Arg1 &, const Arg2 &));
+ template <typename ClassType, typename ReturnType, typename A0, typename A1, typename A2>
+ void register_call(const std::string &name, ReturnType(ClassType::*fcn)(const A0 &, const A1 &, const A2 &));
- template <typename ClassType, typename Arg0, typename Arg1, typename Arg2>
- void register_call(const std::string &name, void(ClassType::*fcn)(const Arg0 &, const Arg1 &, const Arg2 &));
+ template <typename ClassType, typename A0, typename A1, typename A2>
+ void register_call(const std::string &name, void(ClassType::*fcn)(const A0 &, const A1 &, const A2 &));
+
+ template <typename ClassType, typename ReturnType, typename A0, typename A1, typename A2, typename A3>
+ void register_call(const std::string &name, ReturnType(ClassType::*fcn)(const A0 &, const A1 &, const A2 &, const A3 &));
+
+ template <typename ClassType, typename A0, typename A1, typename A2, typename A3>
+ void register_call(const std::string &name, void(ClassType::*fcn)(const A0 &, const A1 &, const A2 &, const A3 &));
+
+ template <typename ClassType, typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4>
+ void register_call(const std::string &name, ReturnType(ClassType::*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &));
+
+ template <typename ClassType, typename A0, typename A1, typename A2, typename A3, typename A4>
+ void register_call(const std::string &name, void(ClassType::*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &));
+
+ template <typename ClassType, typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5>
+ void register_call(const std::string &name, ReturnType(ClassType::*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &));
+
+ template <typename ClassType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5>
+ void register_call(const std::string &name, void(ClassType::*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &));
+
+ template <typename ClassType, typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
+ void register_call(const std::string &name, ReturnType(ClassType::*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &));
+
+ template <typename ClassType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
+ void register_call(const std::string &name, void(ClassType::*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &));
+
+ template <typename ClassType, typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
+ void register_call(const std::string &name, ReturnType(ClassType::*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &));
+
+ template <typename ClassType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
+ void register_call(const std::string &name, void(ClassType::*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &));
+
+ template <typename ClassType, typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
+ void register_call(const std::string &name, ReturnType(ClassType::*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &, const A8 &));
+
+ template <typename ClassType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
+ void register_call(const std::string &name, void(ClassType::*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &, const A8 &));
+
+ template <typename ClassType, typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
+ void register_call(const std::string &name, ReturnType(ClassType::*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &, const A8 &, const A9 &));
+
+ template <typename ClassType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
+ void register_call(const std::string &name, void(ClassType::*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &, const A8 &, const A9 &));
/*******************************************************************
* Call API - don't look here, template magic, not helpful
@@ -90,23 +132,65 @@ public:
inline
void x(const std::string &name);
- template <typename ReturnType, typename Arg0>
- ReturnType x(const std::string &name, const Arg0 &);
+ template <typename ReturnType, typename A0>
+ ReturnType x(const std::string &name, const A0 &);
+
+ template <typename A0>
+ void x(const std::string &name, const A0 &);
+
+ template <typename ReturnType, typename A0, typename A1>
+ ReturnType x(const std::string &name, const A0 &, const A1 &);
+
+ template <typename A0, typename A1>
+ void x(const std::string &name, const A0 &, const A1 &);
+
+ template <typename ReturnType, typename A0, typename A1, typename A2>
+ ReturnType x(const std::string &name, const A0 &, const A1 &, const A2 &);
+
+ template <typename A0, typename A1, typename A2>
+ void x(const std::string &name, const A0 &, const A1 &, const A2 &);
+
+ template <typename ReturnType, typename A0, typename A1, typename A2, typename A3>
+ ReturnType x(const std::string &name, const A0 &, const A1 &, const A2 &, const A3 &);
+
+ template <typename A0, typename A1, typename A2, typename A3>
+ void x(const std::string &name, const A0 &, const A1 &, const A2 &, const A3 &);
+
+ template <typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4>
+ ReturnType x(const std::string &name, const A0 &, const A1 &, const A2 &, const A3 &, const A4 &);
+
+ template <typename A0, typename A1, typename A2, typename A3, typename A4>
+ void x(const std::string &name, const A0 &, const A1 &, const A2 &, const A3 &, const A4 &);
+
+ template <typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5>
+ ReturnType x(const std::string &name, const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &);
+
+ template <typename A0, typename A1, typename A2, typename A3, typename A4, typename A5>
+ void x(const std::string &name, const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &);
+
+ template <typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
+ ReturnType x(const std::string &name, const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &);
+
+ template <typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
+ void x(const std::string &name, const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &);
+
+ template <typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
+ ReturnType x(const std::string &name, const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &);
- template <typename Arg0>
- void x(const std::string &name, const Arg0 &);
+ template <typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
+ void x(const std::string &name, const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &);
- template <typename ReturnType, typename Arg0, typename Arg1>
- ReturnType x(const std::string &name, const Arg0 &, const Arg1 &);
+ template <typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
+ ReturnType x(const std::string &name, const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &, const A8 &);
- template <typename Arg0, typename Arg1>
- void x(const std::string &name, const Arg0 &, const Arg1 &);
+ template <typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
+ void x(const std::string &name, const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &, const A8 &);
- template <typename ReturnType, typename Arg0, typename Arg1, typename Arg2>
- ReturnType x(const std::string &name, const Arg0 &, const Arg1 &, const Arg2 &);
+ template <typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
+ ReturnType x(const std::string &name, const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &, const A8 &, const A9 &);
- template <typename Arg0, typename Arg1, typename Arg2>
- void x(const std::string &name, const Arg0 &, const Arg1 &, const Arg2 &);
+ template <typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
+ void x(const std::string &name, const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &, const A8 &, const A9 &);
/*******************************************************************
* Private registration hooks
diff --git a/include/gras/detail/callable.hpp b/include/gras/detail/callable.hpp
index 98fa29d..68766fe 100644
--- a/include/gras/detail/callable.hpp
+++ b/include/gras/detail/callable.hpp
@@ -24,18 +24,20 @@ struct GRAS_API CallableRegistryEntry
template <typename ClassType, typename ReturnType>
struct CallableRegistryEntryImpl0 : CallableRegistryEntry
{
- typedef ReturnType(ClassType::*Fcn)(void);
+ typedef ReturnType(ClassType::*Fcn)();
CallableRegistryEntryImpl0(ClassType *obj, Fcn fcn):
_obj(obj), _fcn(fcn){}
- PMCC call(const PMCC &)
+ PMCC call(const PMCC &args)
{
+ const PMCList &a = args.as<PMCList>();
+ if (a.size() < 0) throw a;
return PMC_M((_obj->*_fcn)());
}
ClassType *_obj; Fcn _fcn;
};
template <typename ClassType, typename ReturnType>
-void Callable::register_call(const std::string &name, ReturnType(ClassType::*fcn)(void))
+void Callable::register_call(const std::string &name, ReturnType(ClassType::*fcn)())
{
ClassType *obj = dynamic_cast<ClassType *>(this);
void *fr = new CallableRegistryEntryImpl0<ClassType, ReturnType>(obj, fcn);
@@ -45,18 +47,20 @@ void Callable::register_call(const std::string &name, ReturnType(ClassType::*fcn
template <typename ClassType>
struct CallableRegistryEntryImplVoid0 : CallableRegistryEntry
{
- typedef void(ClassType::*Fcn)(void);
+ typedef void(ClassType::*Fcn)();
CallableRegistryEntryImplVoid0(ClassType *obj, Fcn fcn):
_obj(obj), _fcn(fcn){}
- PMCC call(const PMCC &)
+ PMCC call(const PMCC &args)
{
+ const PMCList &a = args.as<PMCList>();
+ if (a.size() < 0) throw a;
(_obj->*_fcn)(); return PMCC();
}
ClassType *_obj; Fcn _fcn;
};
template <typename ClassType>
-void Callable::register_call(const std::string &name, void(ClassType::*fcn)(void))
+void Callable::register_call(const std::string &name, void(ClassType::*fcn)())
{
ClassType *obj = dynamic_cast<ClassType *>(this);
void *fr = new CallableRegistryEntryImplVoid0<ClassType>(obj, fcn);
@@ -66,141 +70,490 @@ void Callable::register_call(const std::string &name, void(ClassType::*fcn)(void
/***********************************************************************
* Registration for return with 1 args
**********************************************************************/
-template <typename ClassType, typename ReturnType, typename Arg0>
+template <typename ClassType, typename ReturnType, typename A0>
struct CallableRegistryEntryImpl1 : CallableRegistryEntry
{
- typedef ReturnType(ClassType::*Fcn)(const Arg0 &);
+ typedef ReturnType(ClassType::*Fcn)(const A0 &);
CallableRegistryEntryImpl1(ClassType *obj, Fcn fcn):
_obj(obj), _fcn(fcn){}
PMCC call(const PMCC &args)
{
const PMCList &a = args.as<PMCList>();
- return PMC_M((_obj->*_fcn)(a[0].safe_as<Arg0>()));
+ if (a.size() < 1) throw a;
+ return PMC_M((_obj->*_fcn)(a[0].safe_as<A0>()));
}
ClassType *_obj; Fcn _fcn;
};
-template <typename ClassType, typename ReturnType, typename Arg0>
-void Callable::register_call(const std::string &name, ReturnType(ClassType::*fcn)(const Arg0 &))
+template <typename ClassType, typename ReturnType, typename A0>
+void Callable::register_call(const std::string &name, ReturnType(ClassType::*fcn)(const A0 &))
{
ClassType *obj = dynamic_cast<ClassType *>(this);
- void *fr = new CallableRegistryEntryImpl1<ClassType, ReturnType, Arg0>(obj, fcn);
+ void *fr = new CallableRegistryEntryImpl1<ClassType, ReturnType, A0>(obj, fcn);
_register_call(name, fr);
}
-template <typename ClassType, typename Arg0>
+template <typename ClassType, typename A0>
struct CallableRegistryEntryImplVoid1 : CallableRegistryEntry
{
- typedef void(ClassType::*Fcn)(const Arg0 &);
+ typedef void(ClassType::*Fcn)(const A0 &);
CallableRegistryEntryImplVoid1(ClassType *obj, Fcn fcn):
_obj(obj), _fcn(fcn){}
PMCC call(const PMCC &args)
{
const PMCList &a = args.as<PMCList>();
- (_obj->*_fcn)(a[0].safe_as<Arg0>()); return PMCC();
+ if (a.size() < 1) throw a;
+ (_obj->*_fcn)(a[0].safe_as<A0>()); return PMCC();
}
ClassType *_obj; Fcn _fcn;
};
-template <typename ClassType, typename Arg0>
-void Callable::register_call(const std::string &name, void(ClassType::*fcn)(const Arg0 &))
+template <typename ClassType, typename A0>
+void Callable::register_call(const std::string &name, void(ClassType::*fcn)(const A0 &))
{
ClassType *obj = dynamic_cast<ClassType *>(this);
- void *fr = new CallableRegistryEntryImplVoid1<ClassType, Arg0>(obj, fcn);
+ void *fr = new CallableRegistryEntryImplVoid1<ClassType, A0>(obj, fcn);
_register_call(name, fr);
}
/***********************************************************************
* Registration for return with 2 args
**********************************************************************/
-template <typename ClassType, typename ReturnType, typename Arg0, typename Arg1>
+template <typename ClassType, typename ReturnType, typename A0, typename A1>
struct CallableRegistryEntryImpl2 : CallableRegistryEntry
{
- typedef ReturnType(ClassType::*Fcn)(const Arg0 &, const Arg1 &);
+ typedef ReturnType(ClassType::*Fcn)(const A0 &, const A1 &);
CallableRegistryEntryImpl2(ClassType *obj, Fcn fcn):
_obj(obj), _fcn(fcn){}
PMCC call(const PMCC &args)
{
const PMCList &a = args.as<PMCList>();
- return PMC_M((_obj->*_fcn)(a[0].safe_as<Arg0>(), a[1].safe_as<Arg1>()));
+ if (a.size() < 2) throw a;
+ return PMC_M((_obj->*_fcn)(a[0].safe_as<A0>(), a[1].safe_as<A1>()));
}
ClassType *_obj; Fcn _fcn;
};
-template <typename ClassType, typename ReturnType, typename Arg0, typename Arg1>
-void Callable::register_call(const std::string &name, ReturnType(ClassType::*fcn)(const Arg0 &, const Arg1 &))
+template <typename ClassType, typename ReturnType, typename A0, typename A1>
+void Callable::register_call(const std::string &name, ReturnType(ClassType::*fcn)(const A0 &, const A1 &))
{
ClassType *obj = dynamic_cast<ClassType *>(this);
- void *fr = new CallableRegistryEntryImpl2<ClassType, ReturnType, Arg0, Arg1>(obj, fcn);
+ void *fr = new CallableRegistryEntryImpl2<ClassType, ReturnType, A0, A1>(obj, fcn);
_register_call(name, fr);
}
-template <typename ClassType, typename Arg0, typename Arg1>
+template <typename ClassType, typename A0, typename A1>
struct CallableRegistryEntryImplVoid2 : CallableRegistryEntry
{
- typedef void(ClassType::*Fcn)(const Arg0 &, const Arg1 &);
+ typedef void(ClassType::*Fcn)(const A0 &, const A1 &);
CallableRegistryEntryImplVoid2(ClassType *obj, Fcn fcn):
_obj(obj), _fcn(fcn){}
PMCC call(const PMCC &args)
{
const PMCList &a = args.as<PMCList>();
- (_obj->*_fcn)(a[0].safe_as<Arg0>(), a[1].safe_as<Arg1>()); return PMCC();
+ if (a.size() < 2) throw a;
+ (_obj->*_fcn)(a[0].safe_as<A0>(), a[1].safe_as<A1>()); return PMCC();
}
ClassType *_obj; Fcn _fcn;
};
-template <typename ClassType, typename Arg0, typename Arg1>
-void Callable::register_call(const std::string &name, void(ClassType::*fcn)(const Arg0 &, const Arg1 &))
+template <typename ClassType, typename A0, typename A1>
+void Callable::register_call(const std::string &name, void(ClassType::*fcn)(const A0 &, const A1 &))
{
ClassType *obj = dynamic_cast<ClassType *>(this);
- void *fr = new CallableRegistryEntryImplVoid2<ClassType, Arg0, Arg1>(obj, fcn);
+ void *fr = new CallableRegistryEntryImplVoid2<ClassType, A0, A1>(obj, fcn);
_register_call(name, fr);
}
/***********************************************************************
* Registration for return with 3 args
**********************************************************************/
-template <typename ClassType, typename ReturnType, typename Arg0, typename Arg1, typename Arg2>
+template <typename ClassType, typename ReturnType, typename A0, typename A1, typename A2>
struct CallableRegistryEntryImpl3 : CallableRegistryEntry
{
- typedef ReturnType(ClassType::*Fcn)(const Arg0 &, const Arg1 &, const Arg2 &);
+ typedef ReturnType(ClassType::*Fcn)(const A0 &, const A1 &, const A2 &);
CallableRegistryEntryImpl3(ClassType *obj, Fcn fcn):
_obj(obj), _fcn(fcn){}
PMCC call(const PMCC &args)
{
const PMCList &a = args.as<PMCList>();
- return PMC_M((_obj->*_fcn)(a[0].safe_as<Arg0>(), a[1].safe_as<Arg1>(), a[2].safe_as<Arg2>()));
+ if (a.size() < 3) throw a;
+ return PMC_M((_obj->*_fcn)(a[0].safe_as<A0>(), a[1].safe_as<A1>(), a[2].safe_as<A2>()));
}
ClassType *_obj; Fcn _fcn;
};
-template <typename ClassType, typename ReturnType, typename Arg0, typename Arg1, typename Arg2>
-void Callable::register_call(const std::string &name, ReturnType(ClassType::*fcn)(const Arg0 &, const Arg1 &, const Arg2 &))
+template <typename ClassType, typename ReturnType, typename A0, typename A1, typename A2>
+void Callable::register_call(const std::string &name, ReturnType(ClassType::*fcn)(const A0 &, const A1 &, const A2 &))
{
ClassType *obj = dynamic_cast<ClassType *>(this);
- void *fr = new CallableRegistryEntryImpl3<ClassType, ReturnType, Arg0, Arg1, Arg2>(obj, fcn);
+ void *fr = new CallableRegistryEntryImpl3<ClassType, ReturnType, A0, A1, A2>(obj, fcn);
_register_call(name, fr);
}
-template <typename ClassType, typename Arg0, typename Arg1, typename Arg2>
+template <typename ClassType, typename A0, typename A1, typename A2>
struct CallableRegistryEntryImplVoid3 : CallableRegistryEntry
{
- typedef void(ClassType::*Fcn)(const Arg0 &, const Arg1 &, const Arg2 &);
+ typedef void(ClassType::*Fcn)(const A0 &, const A1 &, const A2 &);
CallableRegistryEntryImplVoid3(ClassType *obj, Fcn fcn):
_obj(obj), _fcn(fcn){}
PMCC call(const PMCC &args)
{
const PMCList &a = args.as<PMCList>();
- (_obj->*_fcn)(a[0].safe_as<Arg0>(), a[1].safe_as<Arg1>(), a[2].safe_as<Arg2>()); return PMCC();
+ if (a.size() < 3) throw a;
+ (_obj->*_fcn)(a[0].safe_as<A0>(), a[1].safe_as<A1>(), a[2].safe_as<A2>()); return PMCC();
+ }
+ ClassType *_obj; Fcn _fcn;
+};
+
+template <typename ClassType, typename A0, typename A1, typename A2>
+void Callable::register_call(const std::string &name, void(ClassType::*fcn)(const A0 &, const A1 &, const A2 &))
+{
+ ClassType *obj = dynamic_cast<ClassType *>(this);
+ void *fr = new CallableRegistryEntryImplVoid3<ClassType, A0, A1, A2>(obj, fcn);
+ _register_call(name, fr);
+}
+
+/***********************************************************************
+ * Registration for return with 4 args
+ **********************************************************************/
+template <typename ClassType, typename ReturnType, typename A0, typename A1, typename A2, typename A3>
+struct CallableRegistryEntryImpl4 : CallableRegistryEntry
+{
+ typedef ReturnType(ClassType::*Fcn)(const A0 &, const A1 &, const A2 &, const A3 &);
+ CallableRegistryEntryImpl4(ClassType *obj, Fcn fcn):
+ _obj(obj), _fcn(fcn){}
+ PMCC call(const PMCC &args)
+ {
+ const PMCList &a = args.as<PMCList>();
+ if (a.size() < 4) throw a;
+ return PMC_M((_obj->*_fcn)(a[0].safe_as<A0>(), a[1].safe_as<A1>(), a[2].safe_as<A2>(), a[3].safe_as<A3>()));
+ }
+ ClassType *_obj; Fcn _fcn;
+};
+
+template <typename ClassType, typename ReturnType, typename A0, typename A1, typename A2, typename A3>
+void Callable::register_call(const std::string &name, ReturnType(ClassType::*fcn)(const A0 &, const A1 &, const A2 &, const A3 &))
+{
+ ClassType *obj = dynamic_cast<ClassType *>(this);
+ void *fr = new CallableRegistryEntryImpl4<ClassType, ReturnType, A0, A1, A2, A3>(obj, fcn);
+ _register_call(name, fr);
+}
+
+template <typename ClassType, typename A0, typename A1, typename A2, typename A3>
+struct CallableRegistryEntryImplVoid4 : CallableRegistryEntry
+{
+ typedef void(ClassType::*Fcn)(const A0 &, const A1 &, const A2 &, const A3 &);
+ CallableRegistryEntryImplVoid4(ClassType *obj, Fcn fcn):
+ _obj(obj), _fcn(fcn){}
+ PMCC call(const PMCC &args)
+ {
+ const PMCList &a = args.as<PMCList>();
+ if (a.size() < 4) throw a;
+ (_obj->*_fcn)(a[0].safe_as<A0>(), a[1].safe_as<A1>(), a[2].safe_as<A2>(), a[3].safe_as<A3>()); return PMCC();
+ }
+ ClassType *_obj; Fcn _fcn;
+};
+
+template <typename ClassType, typename A0, typename A1, typename A2, typename A3>
+void Callable::register_call(const std::string &name, void(ClassType::*fcn)(const A0 &, const A1 &, const A2 &, const A3 &))
+{
+ ClassType *obj = dynamic_cast<ClassType *>(this);
+ void *fr = new CallableRegistryEntryImplVoid4<ClassType, A0, A1, A2, A3>(obj, fcn);
+ _register_call(name, fr);
+}
+
+/***********************************************************************
+ * Registration for return with 5 args
+ **********************************************************************/
+template <typename ClassType, typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4>
+struct CallableRegistryEntryImpl5 : CallableRegistryEntry
+{
+ typedef ReturnType(ClassType::*Fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &);
+ CallableRegistryEntryImpl5(ClassType *obj, Fcn fcn):
+ _obj(obj), _fcn(fcn){}
+ PMCC call(const PMCC &args)
+ {
+ const PMCList &a = args.as<PMCList>();
+ if (a.size() < 5) throw a;
+ return PMC_M((_obj->*_fcn)(a[0].safe_as<A0>(), a[1].safe_as<A1>(), a[2].safe_as<A2>(), a[3].safe_as<A3>(), a[4].safe_as<A4>()));
+ }
+ ClassType *_obj; Fcn _fcn;
+};
+
+template <typename ClassType, typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4>
+void Callable::register_call(const std::string &name, ReturnType(ClassType::*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &))
+{
+ ClassType *obj = dynamic_cast<ClassType *>(this);
+ void *fr = new CallableRegistryEntryImpl5<ClassType, ReturnType, A0, A1, A2, A3, A4>(obj, fcn);
+ _register_call(name, fr);
+}
+
+template <typename ClassType, typename A0, typename A1, typename A2, typename A3, typename A4>
+struct CallableRegistryEntryImplVoid5 : CallableRegistryEntry
+{
+ typedef void(ClassType::*Fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &);
+ CallableRegistryEntryImplVoid5(ClassType *obj, Fcn fcn):
+ _obj(obj), _fcn(fcn){}
+ PMCC call(const PMCC &args)
+ {
+ const PMCList &a = args.as<PMCList>();
+ if (a.size() < 5) throw a;
+ (_obj->*_fcn)(a[0].safe_as<A0>(), a[1].safe_as<A1>(), a[2].safe_as<A2>(), a[3].safe_as<A3>(), a[4].safe_as<A4>()); return PMCC();
}
ClassType *_obj; Fcn _fcn;
};
-template <typename ClassType, typename Arg0, typename Arg1, typename Arg2>
-void Callable::register_call(const std::string &name, void(ClassType::*fcn)(const Arg0 &, const Arg1 &, const Arg2 &))
+template <typename ClassType, typename A0, typename A1, typename A2, typename A3, typename A4>
+void Callable::register_call(const std::string &name, void(ClassType::*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &))
{
ClassType *obj = dynamic_cast<ClassType *>(this);
- void *fr = new CallableRegistryEntryImplVoid3<ClassType, Arg0, Arg1, Arg2>(obj, fcn);
+ void *fr = new CallableRegistryEntryImplVoid5<ClassType, A0, A1, A2, A3, A4>(obj, fcn);
+ _register_call(name, fr);
+}
+
+/***********************************************************************
+ * Registration for return with 6 args
+ **********************************************************************/
+template <typename ClassType, typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5>
+struct CallableRegistryEntryImpl6 : CallableRegistryEntry
+{
+ typedef ReturnType(ClassType::*Fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &);
+ CallableRegistryEntryImpl6(ClassType *obj, Fcn fcn):
+ _obj(obj), _fcn(fcn){}
+ PMCC call(const PMCC &args)
+ {
+ const PMCList &a = args.as<PMCList>();
+ if (a.size() < 6) throw a;
+ return PMC_M((_obj->*_fcn)(a[0].safe_as<A0>(), a[1].safe_as<A1>(), a[2].safe_as<A2>(), a[3].safe_as<A3>(), a[4].safe_as<A4>(), a[5].safe_as<A5>()));
+ }
+ ClassType *_obj; Fcn _fcn;
+};
+
+template <typename ClassType, typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5>
+void Callable::register_call(const std::string &name, ReturnType(ClassType::*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &))
+{
+ ClassType *obj = dynamic_cast<ClassType *>(this);
+ void *fr = new CallableRegistryEntryImpl6<ClassType, ReturnType, A0, A1, A2, A3, A4, A5>(obj, fcn);
+ _register_call(name, fr);
+}
+
+template <typename ClassType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5>
+struct CallableRegistryEntryImplVoid6 : CallableRegistryEntry
+{
+ typedef void(ClassType::*Fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &);
+ CallableRegistryEntryImplVoid6(ClassType *obj, Fcn fcn):
+ _obj(obj), _fcn(fcn){}
+ PMCC call(const PMCC &args)
+ {
+ const PMCList &a = args.as<PMCList>();
+ if (a.size() < 6) throw a;
+ (_obj->*_fcn)(a[0].safe_as<A0>(), a[1].safe_as<A1>(), a[2].safe_as<A2>(), a[3].safe_as<A3>(), a[4].safe_as<A4>(), a[5].safe_as<A5>()); return PMCC();
+ }
+ ClassType *_obj; Fcn _fcn;
+};
+
+template <typename ClassType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5>
+void Callable::register_call(const std::string &name, void(ClassType::*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &))
+{
+ ClassType *obj = dynamic_cast<ClassType *>(this);
+ void *fr = new CallableRegistryEntryImplVoid6<ClassType, A0, A1, A2, A3, A4, A5>(obj, fcn);
+ _register_call(name, fr);
+}
+
+/***********************************************************************
+ * Registration for return with 7 args
+ **********************************************************************/
+template <typename ClassType, typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
+struct CallableRegistryEntryImpl7 : CallableRegistryEntry
+{
+ typedef ReturnType(ClassType::*Fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &);
+ CallableRegistryEntryImpl7(ClassType *obj, Fcn fcn):
+ _obj(obj), _fcn(fcn){}
+ PMCC call(const PMCC &args)
+ {
+ const PMCList &a = args.as<PMCList>();
+ if (a.size() < 7) throw a;
+ return PMC_M((_obj->*_fcn)(a[0].safe_as<A0>(), a[1].safe_as<A1>(), a[2].safe_as<A2>(), a[3].safe_as<A3>(), a[4].safe_as<A4>(), a[5].safe_as<A5>(), a[6].safe_as<A6>()));
+ }
+ ClassType *_obj; Fcn _fcn;
+};
+
+template <typename ClassType, typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
+void Callable::register_call(const std::string &name, ReturnType(ClassType::*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &))
+{
+ ClassType *obj = dynamic_cast<ClassType *>(this);
+ void *fr = new CallableRegistryEntryImpl7<ClassType, ReturnType, A0, A1, A2, A3, A4, A5, A6>(obj, fcn);
+ _register_call(name, fr);
+}
+
+template <typename ClassType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
+struct CallableRegistryEntryImplVoid7 : CallableRegistryEntry
+{
+ typedef void(ClassType::*Fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &);
+ CallableRegistryEntryImplVoid7(ClassType *obj, Fcn fcn):
+ _obj(obj), _fcn(fcn){}
+ PMCC call(const PMCC &args)
+ {
+ const PMCList &a = args.as<PMCList>();
+ if (a.size() < 7) throw a;
+ (_obj->*_fcn)(a[0].safe_as<A0>(), a[1].safe_as<A1>(), a[2].safe_as<A2>(), a[3].safe_as<A3>(), a[4].safe_as<A4>(), a[5].safe_as<A5>(), a[6].safe_as<A6>()); return PMCC();
+ }
+ ClassType *_obj; Fcn _fcn;
+};
+
+template <typename ClassType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
+void Callable::register_call(const std::string &name, void(ClassType::*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &))
+{
+ ClassType *obj = dynamic_cast<ClassType *>(this);
+ void *fr = new CallableRegistryEntryImplVoid7<ClassType, A0, A1, A2, A3, A4, A5, A6>(obj, fcn);
+ _register_call(name, fr);
+}
+
+/***********************************************************************
+ * Registration for return with 8 args
+ **********************************************************************/
+template <typename ClassType, typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
+struct CallableRegistryEntryImpl8 : CallableRegistryEntry
+{
+ typedef ReturnType(ClassType::*Fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &);
+ CallableRegistryEntryImpl8(ClassType *obj, Fcn fcn):
+ _obj(obj), _fcn(fcn){}
+ PMCC call(const PMCC &args)
+ {
+ const PMCList &a = args.as<PMCList>();
+ if (a.size() < 8) throw a;
+ return PMC_M((_obj->*_fcn)(a[0].safe_as<A0>(), a[1].safe_as<A1>(), a[2].safe_as<A2>(), a[3].safe_as<A3>(), a[4].safe_as<A4>(), a[5].safe_as<A5>(), a[6].safe_as<A6>(), a[7].safe_as<A7>()));
+ }
+ ClassType *_obj; Fcn _fcn;
+};
+
+template <typename ClassType, typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
+void Callable::register_call(const std::string &name, ReturnType(ClassType::*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &))
+{
+ ClassType *obj = dynamic_cast<ClassType *>(this);
+ void *fr = new CallableRegistryEntryImpl8<ClassType, ReturnType, A0, A1, A2, A3, A4, A5, A6, A7>(obj, fcn);
+ _register_call(name, fr);
+}
+
+template <typename ClassType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
+struct CallableRegistryEntryImplVoid8 : CallableRegistryEntry
+{
+ typedef void(ClassType::*Fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &);
+ CallableRegistryEntryImplVoid8(ClassType *obj, Fcn fcn):
+ _obj(obj), _fcn(fcn){}
+ PMCC call(const PMCC &args)
+ {
+ const PMCList &a = args.as<PMCList>();
+ if (a.size() < 8) throw a;
+ (_obj->*_fcn)(a[0].safe_as<A0>(), a[1].safe_as<A1>(), a[2].safe_as<A2>(), a[3].safe_as<A3>(), a[4].safe_as<A4>(), a[5].safe_as<A5>(), a[6].safe_as<A6>(), a[7].safe_as<A7>()); return PMCC();
+ }
+ ClassType *_obj; Fcn _fcn;
+};
+
+template <typename ClassType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
+void Callable::register_call(const std::string &name, void(ClassType::*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &))
+{
+ ClassType *obj = dynamic_cast<ClassType *>(this);
+ void *fr = new CallableRegistryEntryImplVoid8<ClassType, A0, A1, A2, A3, A4, A5, A6, A7>(obj, fcn);
+ _register_call(name, fr);
+}
+
+/***********************************************************************
+ * Registration for return with 9 args
+ **********************************************************************/
+template <typename ClassType, typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
+struct CallableRegistryEntryImpl9 : CallableRegistryEntry
+{
+ typedef ReturnType(ClassType::*Fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &, const A8 &);
+ CallableRegistryEntryImpl9(ClassType *obj, Fcn fcn):
+ _obj(obj), _fcn(fcn){}
+ PMCC call(const PMCC &args)
+ {
+ const PMCList &a = args.as<PMCList>();
+ if (a.size() < 9) throw a;
+ return PMC_M((_obj->*_fcn)(a[0].safe_as<A0>(), a[1].safe_as<A1>(), a[2].safe_as<A2>(), a[3].safe_as<A3>(), a[4].safe_as<A4>(), a[5].safe_as<A5>(), a[6].safe_as<A6>(), a[7].safe_as<A7>(), a[8].safe_as<A8>()));
+ }
+ ClassType *_obj; Fcn _fcn;
+};
+
+template <typename ClassType, typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
+void Callable::register_call(const std::string &name, ReturnType(ClassType::*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &, const A8 &))
+{
+ ClassType *obj = dynamic_cast<ClassType *>(this);
+ void *fr = new CallableRegistryEntryImpl9<ClassType, ReturnType, A0, A1, A2, A3, A4, A5, A6, A7, A8>(obj, fcn);
+ _register_call(name, fr);
+}
+
+template <typename ClassType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
+struct CallableRegistryEntryImplVoid9 : CallableRegistryEntry
+{
+ typedef void(ClassType::*Fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &, const A8 &);
+ CallableRegistryEntryImplVoid9(ClassType *obj, Fcn fcn):
+ _obj(obj), _fcn(fcn){}
+ PMCC call(const PMCC &args)
+ {
+ const PMCList &a = args.as<PMCList>();
+ if (a.size() < 9) throw a;
+ (_obj->*_fcn)(a[0].safe_as<A0>(), a[1].safe_as<A1>(), a[2].safe_as<A2>(), a[3].safe_as<A3>(), a[4].safe_as<A4>(), a[5].safe_as<A5>(), a[6].safe_as<A6>(), a[7].safe_as<A7>(), a[8].safe_as<A8>()); return PMCC();
+ }
+ ClassType *_obj; Fcn _fcn;
+};
+
+template <typename ClassType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
+void Callable::register_call(const std::string &name, void(ClassType::*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &, const A8 &))
+{
+ ClassType *obj = dynamic_cast<ClassType *>(this);
+ void *fr = new CallableRegistryEntryImplVoid9<ClassType, A0, A1, A2, A3, A4, A5, A6, A7, A8>(obj, fcn);
+ _register_call(name, fr);
+}
+
+/***********************************************************************
+ * Registration for return with 10 args
+ **********************************************************************/
+template <typename ClassType, typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
+struct CallableRegistryEntryImpl10 : CallableRegistryEntry
+{
+ typedef ReturnType(ClassType::*Fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &, const A8 &, const A9 &);
+ CallableRegistryEntryImpl10(ClassType *obj, Fcn fcn):
+ _obj(obj), _fcn(fcn){}
+ PMCC call(const PMCC &args)
+ {
+ const PMCList &a = args.as<PMCList>();
+ if (a.size() < 10) throw a;
+ return PMC_M((_obj->*_fcn)(a[0].safe_as<A0>(), a[1].safe_as<A1>(), a[2].safe_as<A2>(), a[3].safe_as<A3>(), a[4].safe_as<A4>(), a[5].safe_as<A5>(), a[6].safe_as<A6>(), a[7].safe_as<A7>(), a[8].safe_as<A8>(), a[9].safe_as<A9>()));
+ }
+ ClassType *_obj; Fcn _fcn;
+};
+
+template <typename ClassType, typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
+void Callable::register_call(const std::string &name, ReturnType(ClassType::*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &, const A8 &, const A9 &))
+{
+ ClassType *obj = dynamic_cast<ClassType *>(this);
+ void *fr = new CallableRegistryEntryImpl10<ClassType, ReturnType, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9>(obj, fcn);
+ _register_call(name, fr);
+}
+
+template <typename ClassType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
+struct CallableRegistryEntryImplVoid10 : CallableRegistryEntry
+{
+ typedef void(ClassType::*Fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &, const A8 &, const A9 &);
+ CallableRegistryEntryImplVoid10(ClassType *obj, Fcn fcn):
+ _obj(obj), _fcn(fcn){}
+ PMCC call(const PMCC &args)
+ {
+ const PMCList &a = args.as<PMCList>();
+ if (a.size() < 10) throw a;
+ (_obj->*_fcn)(a[0].safe_as<A0>(), a[1].safe_as<A1>(), a[2].safe_as<A2>(), a[3].safe_as<A3>(), a[4].safe_as<A4>(), a[5].safe_as<A5>(), a[6].safe_as<A6>(), a[7].safe_as<A7>(), a[8].safe_as<A8>(), a[9].safe_as<A9>()); return PMCC();
+ }
+ ClassType *_obj; Fcn _fcn;
+};
+
+template <typename ClassType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
+void Callable::register_call(const std::string &name, void(ClassType::*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &, const A8 &, const A9 &))
+{
+ ClassType *obj = dynamic_cast<ClassType *>(this);
+ void *fr = new CallableRegistryEntryImplVoid10<ClassType, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9>(obj, fcn);
_register_call(name, fr);
}
@@ -225,8 +578,8 @@ void Callable::x(const std::string &name)
/***********************************************************************
* Call implementations with 1 args
**********************************************************************/
-template <typename ReturnType, typename Arg0>
-ReturnType Callable::x(const std::string &name, const Arg0 &a0)
+template <typename ReturnType, typename A0>
+ReturnType Callable::x(const std::string &name, const A0 &a0)
{
PMCList args(1);
args[0] = PMC_M(a0);
@@ -234,8 +587,8 @@ ReturnType Callable::x(const std::string &name, const Arg0 &a0)
return r.safe_as<ReturnType>();
}
-template <typename Arg0>
-void Callable::x(const std::string &name, const Arg0 &a0)
+template <typename A0>
+void Callable::x(const std::string &name, const A0 &a0)
{
PMCList args(1);
args[0] = PMC_M(a0);
@@ -245,8 +598,8 @@ void Callable::x(const std::string &name, const Arg0 &a0)
/***********************************************************************
* Call implementations with 2 args
**********************************************************************/
-template <typename ReturnType, typename Arg0, typename Arg1>
-ReturnType Callable::x(const std::string &name, const Arg0 &a0, const Arg1 &a1)
+template <typename ReturnType, typename A0, typename A1>
+ReturnType Callable::x(const std::string &name, const A0 &a0, const A1 &a1)
{
PMCList args(2);
args[0] = PMC_M(a0);
@@ -255,8 +608,8 @@ ReturnType Callable::x(const std::string &name, const Arg0 &a0, const Arg1 &a1)
return r.safe_as<ReturnType>();
}
-template <typename Arg0, typename Arg1>
-void Callable::x(const std::string &name, const Arg0 &a0, const Arg1 &a1)
+template <typename A0, typename A1>
+void Callable::x(const std::string &name, const A0 &a0, const A1 &a1)
{
PMCList args(2);
args[0] = PMC_M(a0);
@@ -267,8 +620,8 @@ void Callable::x(const std::string &name, const Arg0 &a0, const Arg1 &a1)
/***********************************************************************
* Call implementations with 3 args
**********************************************************************/
-template <typename ReturnType, typename Arg0, typename Arg1, typename Arg2>
-ReturnType Callable::x(const std::string &name, const Arg0 &a0, const Arg1 &a1, const Arg2 &a2)
+template <typename ReturnType, typename A0, typename A1, typename A2>
+ReturnType Callable::x(const std::string &name, const A0 &a0, const A1 &a1, const A2 &a2)
{
PMCList args(3);
args[0] = PMC_M(a0);
@@ -278,8 +631,8 @@ ReturnType Callable::x(const std::string &name, const Arg0 &a0, const Arg1 &a1,
return r.safe_as<ReturnType>();
}
-template <typename Arg0, typename Arg1, typename Arg2>
-void Callable::x(const std::string &name, const Arg0 &a0, const Arg1 &a1, const Arg2 &a2)
+template <typename A0, typename A1, typename A2>
+void Callable::x(const std::string &name, const A0 &a0, const A1 &a1, const A2 &a2)
{
PMCList args(3);
args[0] = PMC_M(a0);
@@ -288,6 +641,230 @@ void Callable::x(const std::string &name, const Arg0 &a0, const Arg1 &a1, const
_handle_call(name, PMC_M(args));
}
+/***********************************************************************
+ * Call implementations with 4 args
+ **********************************************************************/
+template <typename ReturnType, typename A0, typename A1, typename A2, typename A3>
+ReturnType Callable::x(const std::string &name, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3)
+{
+ PMCList args(4);
+ args[0] = PMC_M(a0);
+ args[1] = PMC_M(a1);
+ args[2] = PMC_M(a2);
+ args[3] = PMC_M(a3);
+ PMCC r = _handle_call(name, PMC_M(args));
+ return r.safe_as<ReturnType>();
+}
+
+template <typename A0, typename A1, typename A2, typename A3>
+void Callable::x(const std::string &name, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3)
+{
+ PMCList args(4);
+ args[0] = PMC_M(a0);
+ args[1] = PMC_M(a1);
+ args[2] = PMC_M(a2);
+ args[3] = PMC_M(a3);
+ _handle_call(name, PMC_M(args));
+}
+
+/***********************************************************************
+ * Call implementations with 5 args
+ **********************************************************************/
+template <typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4>
+ReturnType Callable::x(const std::string &name, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4)
+{
+ PMCList args(5);
+ args[0] = PMC_M(a0);
+ args[1] = PMC_M(a1);
+ args[2] = PMC_M(a2);
+ args[3] = PMC_M(a3);
+ args[4] = PMC_M(a4);
+ PMCC r = _handle_call(name, PMC_M(args));
+ return r.safe_as<ReturnType>();
+}
+
+template <typename A0, typename A1, typename A2, typename A3, typename A4>
+void Callable::x(const std::string &name, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4)
+{
+ PMCList args(5);
+ args[0] = PMC_M(a0);
+ args[1] = PMC_M(a1);
+ args[2] = PMC_M(a2);
+ args[3] = PMC_M(a3);
+ args[4] = PMC_M(a4);
+ _handle_call(name, PMC_M(args));
+}
+
+/***********************************************************************
+ * Call implementations with 6 args
+ **********************************************************************/
+template <typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5>
+ReturnType Callable::x(const std::string &name, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5)
+{
+ PMCList args(6);
+ args[0] = PMC_M(a0);
+ args[1] = PMC_M(a1);
+ args[2] = PMC_M(a2);
+ args[3] = PMC_M(a3);
+ args[4] = PMC_M(a4);
+ args[5] = PMC_M(a5);
+ PMCC r = _handle_call(name, PMC_M(args));
+ return r.safe_as<ReturnType>();
+}
+
+template <typename A0, typename A1, typename A2, typename A3, typename A4, typename A5>
+void Callable::x(const std::string &name, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5)
+{
+ PMCList args(6);
+ args[0] = PMC_M(a0);
+ args[1] = PMC_M(a1);
+ args[2] = PMC_M(a2);
+ args[3] = PMC_M(a3);
+ args[4] = PMC_M(a4);
+ args[5] = PMC_M(a5);
+ _handle_call(name, PMC_M(args));
+}
+
+/***********************************************************************
+ * Call implementations with 7 args
+ **********************************************************************/
+template <typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
+ReturnType Callable::x(const std::string &name, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6)
+{
+ PMCList args(7);
+ args[0] = PMC_M(a0);
+ args[1] = PMC_M(a1);
+ args[2] = PMC_M(a2);
+ args[3] = PMC_M(a3);
+ args[4] = PMC_M(a4);
+ args[5] = PMC_M(a5);
+ args[6] = PMC_M(a6);
+ PMCC r = _handle_call(name, PMC_M(args));
+ return r.safe_as<ReturnType>();
+}
+
+template <typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
+void Callable::x(const std::string &name, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6)
+{
+ PMCList args(7);
+ args[0] = PMC_M(a0);
+ args[1] = PMC_M(a1);
+ args[2] = PMC_M(a2);
+ args[3] = PMC_M(a3);
+ args[4] = PMC_M(a4);
+ args[5] = PMC_M(a5);
+ args[6] = PMC_M(a6);
+ _handle_call(name, PMC_M(args));
+}
+
+/***********************************************************************
+ * Call implementations with 8 args
+ **********************************************************************/
+template <typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
+ReturnType Callable::x(const std::string &name, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6, const A7 &a7)
+{
+ PMCList args(8);
+ args[0] = PMC_M(a0);
+ args[1] = PMC_M(a1);
+ args[2] = PMC_M(a2);
+ args[3] = PMC_M(a3);
+ args[4] = PMC_M(a4);
+ args[5] = PMC_M(a5);
+ args[6] = PMC_M(a6);
+ args[7] = PMC_M(a7);
+ PMCC r = _handle_call(name, PMC_M(args));
+ return r.safe_as<ReturnType>();
+}
+
+template <typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
+void Callable::x(const std::string &name, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6, const A7 &a7)
+{
+ PMCList args(8);
+ args[0] = PMC_M(a0);
+ args[1] = PMC_M(a1);
+ args[2] = PMC_M(a2);
+ args[3] = PMC_M(a3);
+ args[4] = PMC_M(a4);
+ args[5] = PMC_M(a5);
+ args[6] = PMC_M(a6);
+ args[7] = PMC_M(a7);
+ _handle_call(name, PMC_M(args));
+}
+
+/***********************************************************************
+ * Call implementations with 9 args
+ **********************************************************************/
+template <typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
+ReturnType Callable::x(const std::string &name, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8)
+{
+ PMCList args(9);
+ args[0] = PMC_M(a0);
+ args[1] = PMC_M(a1);
+ args[2] = PMC_M(a2);
+ args[3] = PMC_M(a3);
+ args[4] = PMC_M(a4);
+ args[5] = PMC_M(a5);
+ args[6] = PMC_M(a6);
+ args[7] = PMC_M(a7);
+ args[8] = PMC_M(a8);
+ PMCC r = _handle_call(name, PMC_M(args));
+ return r.safe_as<ReturnType>();
+}
+
+template <typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
+void Callable::x(const std::string &name, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8)
+{
+ PMCList args(9);
+ args[0] = PMC_M(a0);
+ args[1] = PMC_M(a1);
+ args[2] = PMC_M(a2);
+ args[3] = PMC_M(a3);
+ args[4] = PMC_M(a4);
+ args[5] = PMC_M(a5);
+ args[6] = PMC_M(a6);
+ args[7] = PMC_M(a7);
+ args[8] = PMC_M(a8);
+ _handle_call(name, PMC_M(args));
+}
+
+/***********************************************************************
+ * Call implementations with 10 args
+ **********************************************************************/
+template <typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
+ReturnType Callable::x(const std::string &name, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8, const A9 &a9)
+{
+ PMCList args(10);
+ args[0] = PMC_M(a0);
+ args[1] = PMC_M(a1);
+ args[2] = PMC_M(a2);
+ args[3] = PMC_M(a3);
+ args[4] = PMC_M(a4);
+ args[5] = PMC_M(a5);
+ args[6] = PMC_M(a6);
+ args[7] = PMC_M(a7);
+ args[8] = PMC_M(a8);
+ args[9] = PMC_M(a9);
+ PMCC r = _handle_call(name, PMC_M(args));
+ return r.safe_as<ReturnType>();
+}
+
+template <typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
+void Callable::x(const std::string &name, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8, const A9 &a9)
+{
+ PMCList args(10);
+ args[0] = PMC_M(a0);
+ args[1] = PMC_M(a1);
+ args[2] = PMC_M(a2);
+ args[3] = PMC_M(a3);
+ args[4] = PMC_M(a4);
+ args[5] = PMC_M(a5);
+ args[6] = PMC_M(a6);
+ args[7] = PMC_M(a7);
+ args[8] = PMC_M(a8);
+ args[9] = PMC_M(a9);
+ _handle_call(name, PMC_M(args));
+}
+
} //namespace gras
#endif /*INCLUDED_GRAS_DETAIL_CALLABLE_HPP*/
diff --git a/include/gras/detail/factory.hpp b/include/gras/detail/factory.hpp
index 632e09d..a2de116 100644
--- a/include/gras/detail/factory.hpp
+++ b/include/gras/detail/factory.hpp
@@ -24,17 +24,19 @@ struct GRAS_API FactoryRegistryEntry
template <typename ReturnType>
struct FactoryRegistryEntryImpl0 : FactoryRegistryEntry
{
- typedef ReturnType(*Fcn)(void);
+ typedef ReturnType(*Fcn)();
FactoryRegistryEntryImpl0(Fcn fcn):_fcn(fcn){}
- Element *make(const PMCC &)
+ Element *make(const PMCC &args)
{
+ const PMCList &a = args.as<PMCList>();
+ if (a.size() < 0) throw a;
return _fcn();
}
Fcn _fcn;
};
template <typename ReturnType>
-void Factory::register_make(const std::string &name, ReturnType(*fcn)(void))
+void Factory::register_make(const std::string &name, ReturnType(*fcn)())
{
void *r = new FactoryRegistryEntryImpl0<ReturnType>(fcn);
Factory::_register_make(name, r);
@@ -43,69 +45,240 @@ void Factory::register_make(const std::string &name, ReturnType(*fcn)(void))
/***********************************************************************
* Templated registration - 1 args
**********************************************************************/
-template <typename ReturnType, typename Arg0>
+template <typename ReturnType, typename A0>
struct FactoryRegistryEntryImpl1 : FactoryRegistryEntry
{
- typedef ReturnType(*Fcn)(const Arg0 &);
+ typedef ReturnType(*Fcn)(const A0 &);
FactoryRegistryEntryImpl1(Fcn fcn):_fcn(fcn){}
Element *make(const PMCC &args)
{
const PMCList &a = args.as<PMCList>();
- return _fcn(a[0].safe_as<Arg0>());
+ if (a.size() < 1) throw a;
+ return _fcn(a[0].safe_as<A0>());
}
Fcn _fcn;
};
-template <typename ReturnType, typename Arg0>
-void Factory::register_make(const std::string &name, ReturnType(*fcn)(const Arg0 &))
+template <typename ReturnType, typename A0>
+void Factory::register_make(const std::string &name, ReturnType(*fcn)(const A0 &))
{
- void *r = new FactoryRegistryEntryImpl1<ReturnType, Arg0>(fcn);
+ void *r = new FactoryRegistryEntryImpl1<ReturnType, A0>(fcn);
Factory::_register_make(name, r);
}
/***********************************************************************
* Templated registration - 2 args
**********************************************************************/
-template <typename ReturnType, typename Arg0, typename Arg1>
+template <typename ReturnType, typename A0, typename A1>
struct FactoryRegistryEntryImpl2 : FactoryRegistryEntry
{
- typedef ReturnType(*Fcn)(const Arg0 &, const Arg1 &);
+ typedef ReturnType(*Fcn)(const A0 &, const A1 &);
FactoryRegistryEntryImpl2(Fcn fcn):_fcn(fcn){}
Element *make(const PMCC &args)
{
const PMCList &a = args.as<PMCList>();
- return _fcn(a[0].safe_as<Arg0>(), a[1].safe_as<Arg1>());
+ if (a.size() < 2) throw a;
+ return _fcn(a[0].safe_as<A0>(), a[1].safe_as<A1>());
}
Fcn _fcn;
};
-template <typename ReturnType, typename Arg0, typename Arg1>
-void Factory::register_make(const std::string &name, ReturnType(*fcn)(const Arg0 &, const Arg1 &))
+template <typename ReturnType, typename A0, typename A1>
+void Factory::register_make(const std::string &name, ReturnType(*fcn)(const A0 &, const A1 &))
{
- void *r = new FactoryRegistryEntryImpl2<ReturnType, Arg0, Arg1>(fcn);
+ void *r = new FactoryRegistryEntryImpl2<ReturnType, A0, A1>(fcn);
Factory::_register_make(name, r);
}
/***********************************************************************
* Templated registration - 3 args
**********************************************************************/
-template <typename ReturnType, typename Arg0, typename Arg1, typename Arg2>
+template <typename ReturnType, typename A0, typename A1, typename A2>
struct FactoryRegistryEntryImpl3 : FactoryRegistryEntry
{
- typedef ReturnType(*Fcn)(const Arg0 &, const Arg1 &, const Arg2 &);
+ typedef ReturnType(*Fcn)(const A0 &, const A1 &, const A2 &);
FactoryRegistryEntryImpl3(Fcn fcn):_fcn(fcn){}
Element *make(const PMCC &args)
{
const PMCList &a = args.as<PMCList>();
- return _fcn(a[0].safe_as<Arg0>(), a[1].safe_as<Arg1>(), a[2].safe_as<Arg2>());
+ if (a.size() < 3) throw a;
+ return _fcn(a[0].safe_as<A0>(), a[1].safe_as<A1>(), a[2].safe_as<A2>());
+ }
+ Fcn _fcn;
+};
+
+template <typename ReturnType, typename A0, typename A1, typename A2>
+void Factory::register_make(const std::string &name, ReturnType(*fcn)(const A0 &, const A1 &, const A2 &))
+{
+ void *r = new FactoryRegistryEntryImpl3<ReturnType, A0, A1, A2>(fcn);
+ Factory::_register_make(name, r);
+}
+
+/***********************************************************************
+ * Templated registration - 4 args
+ **********************************************************************/
+template <typename ReturnType, typename A0, typename A1, typename A2, typename A3>
+struct FactoryRegistryEntryImpl4 : FactoryRegistryEntry
+{
+ typedef ReturnType(*Fcn)(const A0 &, const A1 &, const A2 &, const A3 &);
+ FactoryRegistryEntryImpl4(Fcn fcn):_fcn(fcn){}
+ Element *make(const PMCC &args)
+ {
+ const PMCList &a = args.as<PMCList>();
+ if (a.size() < 4) throw a;
+ return _fcn(a[0].safe_as<A0>(), a[1].safe_as<A1>(), a[2].safe_as<A2>(), a[3].safe_as<A3>());
+ }
+ Fcn _fcn;
+};
+
+template <typename ReturnType, typename A0, typename A1, typename A2, typename A3>
+void Factory::register_make(const std::string &name, ReturnType(*fcn)(const A0 &, const A1 &, const A2 &, const A3 &))
+{
+ void *r = new FactoryRegistryEntryImpl4<ReturnType, A0, A1, A2, A3>(fcn);
+ Factory::_register_make(name, r);
+}
+
+/***********************************************************************
+ * Templated registration - 5 args
+ **********************************************************************/
+template <typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4>
+struct FactoryRegistryEntryImpl5 : FactoryRegistryEntry
+{
+ typedef ReturnType(*Fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &);
+ FactoryRegistryEntryImpl5(Fcn fcn):_fcn(fcn){}
+ Element *make(const PMCC &args)
+ {
+ const PMCList &a = args.as<PMCList>();
+ if (a.size() < 5) throw a;
+ return _fcn(a[0].safe_as<A0>(), a[1].safe_as<A1>(), a[2].safe_as<A2>(), a[3].safe_as<A3>(), a[4].safe_as<A4>());
}
Fcn _fcn;
};
-template <typename ReturnType, typename Arg0, typename Arg1, typename Arg2>
-void Factory::register_make(const std::string &name, ReturnType(*fcn)(const Arg0 &, const Arg1 &, const Arg2 &))
+template <typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4>
+void Factory::register_make(const std::string &name, ReturnType(*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &))
{
- void *r = new FactoryRegistryEntryImpl3<ReturnType, Arg0, Arg1, Arg2>(fcn);
+ void *r = new FactoryRegistryEntryImpl5<ReturnType, A0, A1, A2, A3, A4>(fcn);
+ Factory::_register_make(name, r);
+}
+
+/***********************************************************************
+ * Templated registration - 6 args
+ **********************************************************************/
+template <typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5>
+struct FactoryRegistryEntryImpl6 : FactoryRegistryEntry
+{
+ typedef ReturnType(*Fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &);
+ FactoryRegistryEntryImpl6(Fcn fcn):_fcn(fcn){}
+ Element *make(const PMCC &args)
+ {
+ const PMCList &a = args.as<PMCList>();
+ if (a.size() < 6) throw a;
+ return _fcn(a[0].safe_as<A0>(), a[1].safe_as<A1>(), a[2].safe_as<A2>(), a[3].safe_as<A3>(), a[4].safe_as<A4>(), a[5].safe_as<A5>());
+ }
+ Fcn _fcn;
+};
+
+template <typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5>
+void Factory::register_make(const std::string &name, ReturnType(*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &))
+{
+ void *r = new FactoryRegistryEntryImpl6<ReturnType, A0, A1, A2, A3, A4, A5>(fcn);
+ Factory::_register_make(name, r);
+}
+
+/***********************************************************************
+ * Templated registration - 7 args
+ **********************************************************************/
+template <typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
+struct FactoryRegistryEntryImpl7 : FactoryRegistryEntry
+{
+ typedef ReturnType(*Fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &);
+ FactoryRegistryEntryImpl7(Fcn fcn):_fcn(fcn){}
+ Element *make(const PMCC &args)
+ {
+ const PMCList &a = args.as<PMCList>();
+ if (a.size() < 7) throw a;
+ return _fcn(a[0].safe_as<A0>(), a[1].safe_as<A1>(), a[2].safe_as<A2>(), a[3].safe_as<A3>(), a[4].safe_as<A4>(), a[5].safe_as<A5>(), a[6].safe_as<A6>());
+ }
+ Fcn _fcn;
+};
+
+template <typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
+void Factory::register_make(const std::string &name, ReturnType(*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &))
+{
+ void *r = new FactoryRegistryEntryImpl7<ReturnType, A0, A1, A2, A3, A4, A5, A6>(fcn);
+ Factory::_register_make(name, r);
+}
+
+/***********************************************************************
+ * Templated registration - 8 args
+ **********************************************************************/
+template <typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
+struct FactoryRegistryEntryImpl8 : FactoryRegistryEntry
+{
+ typedef ReturnType(*Fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &);
+ FactoryRegistryEntryImpl8(Fcn fcn):_fcn(fcn){}
+ Element *make(const PMCC &args)
+ {
+ const PMCList &a = args.as<PMCList>();
+ if (a.size() < 8) throw a;
+ return _fcn(a[0].safe_as<A0>(), a[1].safe_as<A1>(), a[2].safe_as<A2>(), a[3].safe_as<A3>(), a[4].safe_as<A4>(), a[5].safe_as<A5>(), a[6].safe_as<A6>(), a[7].safe_as<A7>());
+ }
+ Fcn _fcn;
+};
+
+template <typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
+void Factory::register_make(const std::string &name, ReturnType(*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &))
+{
+ void *r = new FactoryRegistryEntryImpl8<ReturnType, A0, A1, A2, A3, A4, A5, A6, A7>(fcn);
+ Factory::_register_make(name, r);
+}
+
+/***********************************************************************
+ * Templated registration - 9 args
+ **********************************************************************/
+template <typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
+struct FactoryRegistryEntryImpl9 : FactoryRegistryEntry
+{
+ typedef ReturnType(*Fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &, const A8 &);
+ FactoryRegistryEntryImpl9(Fcn fcn):_fcn(fcn){}
+ Element *make(const PMCC &args)
+ {
+ const PMCList &a = args.as<PMCList>();
+ if (a.size() < 9) throw a;
+ return _fcn(a[0].safe_as<A0>(), a[1].safe_as<A1>(), a[2].safe_as<A2>(), a[3].safe_as<A3>(), a[4].safe_as<A4>(), a[5].safe_as<A5>(), a[6].safe_as<A6>(), a[7].safe_as<A7>(), a[8].safe_as<A8>());
+ }
+ Fcn _fcn;
+};
+
+template <typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
+void Factory::register_make(const std::string &name, ReturnType(*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &, const A8 &))
+{
+ void *r = new FactoryRegistryEntryImpl9<ReturnType, A0, A1, A2, A3, A4, A5, A6, A7, A8>(fcn);
+ Factory::_register_make(name, r);
+}
+
+/***********************************************************************
+ * Templated registration - 10 args
+ **********************************************************************/
+template <typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
+struct FactoryRegistryEntryImpl10 : FactoryRegistryEntry
+{
+ typedef ReturnType(*Fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &, const A8 &, const A9 &);
+ FactoryRegistryEntryImpl10(Fcn fcn):_fcn(fcn){}
+ Element *make(const PMCC &args)
+ {
+ const PMCList &a = args.as<PMCList>();
+ if (a.size() < 10) throw a;
+ return _fcn(a[0].safe_as<A0>(), a[1].safe_as<A1>(), a[2].safe_as<A2>(), a[3].safe_as<A3>(), a[4].safe_as<A4>(), a[5].safe_as<A5>(), a[6].safe_as<A6>(), a[7].safe_as<A7>(), a[8].safe_as<A8>(), a[9].safe_as<A9>());
+ }
+ Fcn _fcn;
+};
+
+template <typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
+void Factory::register_make(const std::string &name, ReturnType(*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &, const A8 &, const A9 &))
+{
+ void *r = new FactoryRegistryEntryImpl10<ReturnType, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9>(fcn);
Factory::_register_make(name, r);
}
@@ -119,16 +292,16 @@ Element *Factory::make(const std::string &name)
return Factory::_handle_make(name, PMC_M(args));
}
-template <typename Arg0>
-Element *Factory::make(const std::string &name, const Arg0 &a0)
+template <typename A0>
+Element *Factory::make(const std::string &name, const A0 &a0)
{
PMCList args(1);
args[0] = PMC_M(a0);
return Factory::_handle_make(name, PMC_M(args));
}
-template <typename Arg0, typename Arg1>
-Element *Factory::make(const std::string &name, const Arg0 &a0, const Arg1 &a1)
+template <typename A0, typename A1>
+Element *Factory::make(const std::string &name, const A0 &a0, const A1 &a1)
{
PMCList args(2);
args[0] = PMC_M(a0);
@@ -136,8 +309,8 @@ Element *Factory::make(const std::string &name, const Arg0 &a0, const Arg1 &a1)
return Factory::_handle_make(name, PMC_M(args));
}
-template <typename Arg0, typename Arg1, typename Arg2>
-Element *Factory::make(const std::string &name, const Arg0 &a0, const Arg1 &a1, const Arg2 &a2)
+template <typename A0, typename A1, typename A2>
+Element *Factory::make(const std::string &name, const A0 &a0, const A1 &a1, const A2 &a2)
{
PMCList args(3);
args[0] = PMC_M(a0);
@@ -146,6 +319,104 @@ Element *Factory::make(const std::string &name, const Arg0 &a0, const Arg1 &a1,
return Factory::_handle_make(name, PMC_M(args));
}
+template <typename A0, typename A1, typename A2, typename A3>
+Element *Factory::make(const std::string &name, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3)
+{
+ PMCList args(4);
+ args[0] = PMC_M(a0);
+ args[1] = PMC_M(a1);
+ args[2] = PMC_M(a2);
+ args[3] = PMC_M(a3);
+ return Factory::_handle_make(name, PMC_M(args));
+}
+
+template <typename A0, typename A1, typename A2, typename A3, typename A4>
+Element *Factory::make(const std::string &name, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4)
+{
+ PMCList args(5);
+ args[0] = PMC_M(a0);
+ args[1] = PMC_M(a1);
+ args[2] = PMC_M(a2);
+ args[3] = PMC_M(a3);
+ args[4] = PMC_M(a4);
+ return Factory::_handle_make(name, PMC_M(args));
+}
+
+template <typename A0, typename A1, typename A2, typename A3, typename A4, typename A5>
+Element *Factory::make(const std::string &name, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5)
+{
+ PMCList args(6);
+ args[0] = PMC_M(a0);
+ args[1] = PMC_M(a1);
+ args[2] = PMC_M(a2);
+ args[3] = PMC_M(a3);
+ args[4] = PMC_M(a4);
+ args[5] = PMC_M(a5);
+ return Factory::_handle_make(name, PMC_M(args));
+}
+
+template <typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
+Element *Factory::make(const std::string &name, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6)
+{
+ PMCList args(7);
+ args[0] = PMC_M(a0);
+ args[1] = PMC_M(a1);
+ args[2] = PMC_M(a2);
+ args[3] = PMC_M(a3);
+ args[4] = PMC_M(a4);
+ args[5] = PMC_M(a5);
+ args[6] = PMC_M(a6);
+ return Factory::_handle_make(name, PMC_M(args));
+}
+
+template <typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
+Element *Factory::make(const std::string &name, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6, const A7 &a7)
+{
+ PMCList args(8);
+ args[0] = PMC_M(a0);
+ args[1] = PMC_M(a1);
+ args[2] = PMC_M(a2);
+ args[3] = PMC_M(a3);
+ args[4] = PMC_M(a4);
+ args[5] = PMC_M(a5);
+ args[6] = PMC_M(a6);
+ args[7] = PMC_M(a7);
+ return Factory::_handle_make(name, PMC_M(args));
+}
+
+template <typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
+Element *Factory::make(const std::string &name, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8)
+{
+ PMCList args(9);
+ args[0] = PMC_M(a0);
+ args[1] = PMC_M(a1);
+ args[2] = PMC_M(a2);
+ args[3] = PMC_M(a3);
+ args[4] = PMC_M(a4);
+ args[5] = PMC_M(a5);
+ args[6] = PMC_M(a6);
+ args[7] = PMC_M(a7);
+ args[8] = PMC_M(a8);
+ return Factory::_handle_make(name, PMC_M(args));
+}
+
+template <typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
+Element *Factory::make(const std::string &name, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8, const A9 &a9)
+{
+ PMCList args(10);
+ args[0] = PMC_M(a0);
+ args[1] = PMC_M(a1);
+ args[2] = PMC_M(a2);
+ args[3] = PMC_M(a3);
+ args[4] = PMC_M(a4);
+ args[5] = PMC_M(a5);
+ args[6] = PMC_M(a6);
+ args[7] = PMC_M(a7);
+ args[8] = PMC_M(a8);
+ args[9] = PMC_M(a9);
+ return Factory::_handle_make(name, PMC_M(args));
+}
+
}
#endif /*INCLUDED_GRAS_DETAIL_FACTORY_HPP*/
diff --git a/include/gras/factory.hpp b/include/gras/factory.hpp
index 52ed881..cffd4b1 100644
--- a/include/gras/factory.hpp
+++ b/include/gras/factory.hpp
@@ -37,31 +37,73 @@ struct GRAS_API Factory
* Register API - don't look here, template magic, not helpful
******************************************************************/
template <typename ReturnType>
- static void register_make(const std::string &name, ReturnType(*fcn)(void));
+ static void register_make(const std::string &name, ReturnType(*fcn)());
- template <typename ReturnType, typename Arg0>
- static void register_make(const std::string &name, ReturnType(*fcn)(const Arg0 &));
+ template <typename ReturnType, typename A0>
+ static void register_make(const std::string &name, ReturnType(*fcn)(const A0 &));
- template <typename ReturnType, typename Arg0, typename Arg1>
- static void register_make(const std::string &name, ReturnType(*fcn)(const Arg0 &, const Arg1 &));
+ template <typename ReturnType, typename A0, typename A1>
+ static void register_make(const std::string &name, ReturnType(*fcn)(const A0 &, const A1 &));
- template <typename ReturnType, typename Arg0, typename Arg1, typename Arg2>
- static void register_make(const std::string &name, ReturnType(*fcn)(const Arg0 &, const Arg1 &, const Arg2 &));
+ template <typename ReturnType, typename A0, typename A1, typename A2>
+ static void register_make(const std::string &name, ReturnType(*fcn)(const A0 &, const A1 &, const A2 &));
+
+ template <typename ReturnType, typename A0, typename A1, typename A2, typename A3>
+ static void register_make(const std::string &name, ReturnType(*fcn)(const A0 &, const A1 &, const A2 &, const A3 &));
+
+ template <typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4>
+ static void register_make(const std::string &name, ReturnType(*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &));
+
+ template <typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5>
+ static void register_make(const std::string &name, ReturnType(*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &));
+
+ template <typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
+ static void register_make(const std::string &name, ReturnType(*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &));
+
+ template <typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
+ static void register_make(const std::string &name, ReturnType(*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &));
+
+ template <typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
+ static void register_make(const std::string &name, ReturnType(*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &, const A8 &));
+
+ template <typename ReturnType, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
+ static void register_make(const std::string &name, ReturnType(*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &, const A8 &, const A9 &));
/*******************************************************************
* Make API - don't look here, template magic, not helpful
- ******************************************************************/
+ ******************************************************************/;
inline
static Element *make(const std::string &name);
- template <typename Arg0>
- static Element *make(const std::string &name, const Arg0 &a0);
+ template <typename A0>
+ static Element *make(const std::string &name, const A0 &);
+
+ template <typename A0, typename A1>
+ static Element *make(const std::string &name, const A0 &, const A1 &);
+
+ template <typename A0, typename A1, typename A2>
+ static Element *make(const std::string &name, const A0 &, const A1 &, const A2 &);
+
+ template <typename A0, typename A1, typename A2, typename A3>
+ static Element *make(const std::string &name, const A0 &, const A1 &, const A2 &, const A3 &);
+
+ template <typename A0, typename A1, typename A2, typename A3, typename A4>
+ static Element *make(const std::string &name, const A0 &, const A1 &, const A2 &, const A3 &, const A4 &);
+
+ template <typename A0, typename A1, typename A2, typename A3, typename A4, typename A5>
+ static Element *make(const std::string &name, const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &);
+
+ template <typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
+ static Element *make(const std::string &name, const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &);
+
+ template <typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
+ static Element *make(const std::string &name, const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &);
- template <typename Arg0, typename Arg1>
- static Element *make(const std::string &name, const Arg0 &a0, const Arg1 &a1);
+ template <typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
+ static Element *make(const std::string &name, const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &, const A8 &);
- template <typename Arg0, typename Arg1, typename Arg2>
- static Element *make(const std::string &name, const Arg0 &a0, const Arg1 &a1, const Arg2 &a2);
+ template <typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
+ static Element *make(const std::string &name, const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &, const A8 &, const A9 &);
/*******************************************************************
* Private registration hooks
diff --git a/tmpl/callable.tmpl.hpp b/tmpl/callable.tmpl.hpp
new file mode 100644
index 0000000..900bae4
--- /dev/null
+++ b/tmpl/callable.tmpl.hpp
@@ -0,0 +1,94 @@
+// Copyright (C) by Josh Blum. See LICENSE.txt for licensing information.
+
+#ifndef INCLUDED_GRAS_CALLABLE_HPP
+#define INCLUDED_GRAS_CALLABLE_HPP
+
+#include <gras/gras.hpp>
+#include <PMC/PMC.hpp>
+#include <boost/shared_ptr.hpp>
+#include <vector>
+#include <string>
+
+namespace gras
+{
+
+/*!
+ * The callable interface allows subclasses to export public methods,
+ * but without actually exporting traditional library symbols.
+ *
+ * Callable handles the template magic so you don't have to:
+ * - registering subclass methods is simple and easy on the user.
+ * - users call registered methods with natural code aesthetics.
+ *
+ * Register a method (in the constructor of MyClass):
+ * this->register_call("set_foo", &MyClass::set_foo);
+ *
+ * Call a method on a instance of MyClass:
+ * my_class->x("set_foo", new_foo_val);
+ *
+ * Why x for the call method?
+ * - The "x" is short, one character of screen width.
+ * - The "x" looks like "*", which is commonly used.
+ * - The overloaded () operator sucks with pointers.
+ * - The overloaded () operator has template issues.
+ */
+class GRAS_API Callable
+{
+public:
+
+ //! Default constructor
+ Callable(void);
+
+ //! Destructor (virtual for subclasses)
+ virtual ~Callable(void);
+
+ //! Get a list of names for registered calls
+ std::vector<std::string> get_registered_names(void) const;
+
+protected:
+ /*!
+ * Unregister a previously registered call.
+ * Throws if the name is not found in the registry.
+ */
+ void unregister_call(const std::string &name);
+
+ /*******************************************************************
+ * Register API - don't look here, template magic, not helpful
+ ******************************************************************/
+protected:
+ #for $NARGS in range($MAX_ARGS)
+ template <typename ClassType, typename ReturnType, $expand('typename A%d', $NARGS)>
+ void register_call(const std::string &name, ReturnType(ClassType::*fcn)($expand('const A%d &', $NARGS)));
+
+ template <typename ClassType, $expand('typename A%d', $NARGS)>
+ void register_call(const std::string &name, void(ClassType::*fcn)($expand('const A%d &', $NARGS)));
+
+ #end for
+ /*******************************************************************
+ * Call API - don't look here, template magic, not helpful
+ ******************************************************************/
+public:
+ #for $NARGS in range($MAX_ARGS)
+ template <typename ReturnType, $expand('typename A%d', $NARGS)>
+ ReturnType x(const std::string &name, $expand('const A%d &', $NARGS));
+
+ template <$expand('typename A%d', $NARGS)>
+ void x(const std::string &name, $expand('const A%d &', $NARGS));
+
+ #end for
+ /*******************************************************************
+ * Private registration hooks
+ ******************************************************************/
+protected:
+ void _register_call(const std::string &, void *);
+public:
+ virtual PMCC _handle_call(const std::string &, const PMCC &);
+private:
+ boost::shared_ptr<void> _call_registry;
+};
+
+} //namespace gras
+
+#include <gras/detail/callable.hpp>
+
+#endif /*INCLUDED_GRAS_CALLABLE_HPP*/
diff --git a/tmpl/callable_detail.tmpl.hpp b/tmpl/callable_detail.tmpl.hpp
new file mode 100644
index 0000000..65750e7
--- /dev/null
+++ b/tmpl/callable_detail.tmpl.hpp
@@ -0,0 +1,100 @@
+// Copyright (C) by Josh Blum. See LICENSE.txt for licensing information.
+
+#ifndef INCLUDED_GRAS_DETAIL_CALLABLE_HPP
+#define INCLUDED_GRAS_DETAIL_CALLABLE_HPP
+
+#include <PMC/Containers.hpp> //PMCList
+
+namespace gras
+{
+
+/***********************************************************************
+ * Registration entry base class
+ **********************************************************************/
+struct GRAS_API CallableRegistryEntry
+{
+ CallableRegistryEntry(void);
+ virtual ~CallableRegistryEntry(void);
+ virtual PMCC call(const PMCC &args) = 0;
+};
+
+#for $NARGS in range($MAX_ARGS)
+/***********************************************************************
+ * Registration for return with $NARGS args
+ **********************************************************************/
+template <typename ClassType, typename ReturnType, $expand('typename A%d', $NARGS)>
+struct CallableRegistryEntryImpl$(NARGS) : CallableRegistryEntry
+{
+ typedef ReturnType(ClassType::*Fcn)($expand('const A%d &', $NARGS));
+ CallableRegistryEntryImpl$(NARGS)(ClassType *obj, Fcn fcn):
+ _obj(obj), _fcn(fcn){}
+ PMCC call(const PMCC &args)
+ {
+ const PMCList &a = args.as<PMCList>();
+ if (a.size() < $NARGS) throw a;
+ return PMC_M((_obj->*_fcn)($expand('a[%d].safe_as<A%d>()', $NARGS)));
+ }
+ ClassType *_obj; Fcn _fcn;
+};
+
+template <typename ClassType, typename ReturnType, $expand('typename A%d', $NARGS)>
+void Callable::register_call(const std::string &name, ReturnType(ClassType::*fcn)($expand('const A%d &', $NARGS)))
+{
+ ClassType *obj = dynamic_cast<ClassType *>(this);
+ void *fr = new CallableRegistryEntryImpl$(NARGS)<ClassType, ReturnType, $expand('A%d', $NARGS)>(obj, fcn);
+ _register_call(name, fr);
+}
+
+template <typename ClassType, $expand('typename A%d', $NARGS)>
+struct CallableRegistryEntryImplVoid$(NARGS) : CallableRegistryEntry
+{
+ typedef void(ClassType::*Fcn)($expand('const A%d &', $NARGS));
+ CallableRegistryEntryImplVoid$(NARGS)(ClassType *obj, Fcn fcn):
+ _obj(obj), _fcn(fcn){}
+ PMCC call(const PMCC &args)
+ {
+ const PMCList &a = args.as<PMCList>();
+ if (a.size() < $NARGS) throw a;
+ (_obj->*_fcn)($expand('a[%d].safe_as<A%d>()', $NARGS)); return PMCC();
+ }
+ ClassType *_obj; Fcn _fcn;
+};
+
+template <typename ClassType, $expand('typename A%d', $NARGS)>
+void Callable::register_call(const std::string &name, void(ClassType::*fcn)($expand('const A%d &', $NARGS)))
+{
+ ClassType *obj = dynamic_cast<ClassType *>(this);
+ void *fr = new CallableRegistryEntryImplVoid$(NARGS)<ClassType, $expand('A%d', $NARGS)>(obj, fcn);
+ _register_call(name, fr);
+}
+
+#end for
+#for $NARGS in range($MAX_ARGS)
+/***********************************************************************
+ * Call implementations with $NARGS args
+ **********************************************************************/
+template <typename ReturnType, $expand('typename A%d', $NARGS)>
+ReturnType Callable::x(const std::string &name, $expand('const A%d &a%d', $NARGS))
+{
+ PMCList args($NARGS);
+ #for $i in range($NARGS):
+ args[$i] = PMC_M(a$i);
+ #end for
+ PMCC r = _handle_call(name, PMC_M(args));
+ return r.safe_as<ReturnType>();
+}
+
+template <$expand('typename A%d', $NARGS)>
+void Callable::x(const std::string &name, $expand('const A%d &a%d', $NARGS))
+{
+ PMCList args($NARGS);
+ #for $i in range($NARGS):
+ args[$i] = PMC_M(a$i);
+ #end for
+ _handle_call(name, PMC_M(args));
+}
+
+#end for
+} //namespace gras
+
+#endif /*INCLUDED_GRAS_DETAIL_CALLABLE_HPP*/
diff --git a/tmpl/expand_template.py b/tmpl/expand_template.py
new file mode 100644
index 0000000..3941fb2
--- /dev/null
+++ b/tmpl/expand_template.py
@@ -0,0 +1,33 @@
+# Copyright (C) by Josh Blum. See LICENSE.txt for licensing information.
+
+import os
+import sys
+from Cheetah.Template import Template
+
+MAX_ARGS = 11
+
+def expand(t, n):
+ out = list()
+ for i in range(n): out.append(t.replace('%d', str(i)))
+ return ', '.join(out)
+
+def cleanup(code):
+ code = code.replace('template <>', 'inline')
+ code = code.replace(', >', '>')
+ code = code.replace(', )', ')')
+ code = code.replace('\\#', '#')
+ return code
+
+if __name__ == '__main__':
+ in_path = sys.argv[1]
+ out_path = sys.argv[2]
+ tmpl = open(in_path, 'r').read()
+ for key in ['define', 'include', 'if', 'endif', 'else', 'ifdef', 'ifndef']:
+ tmpl = tmpl.replace('#%s'%key, '\\#%s'%key)
+ code = str(Template(tmpl, dict(
+ MAX_ARGS=MAX_ARGS, expand=expand,
+ )))
+ code = cleanup(code)
+ if not os.path.exists(out_path) or open(out_path, 'r').read() != code:
+ print 'write code to', out_path
+ open(out_path, 'w').write(code)
diff --git a/tmpl/factory.tmpl.hpp b/tmpl/factory.tmpl.hpp
new file mode 100644
index 0000000..a9c9820
--- /dev/null
+++ b/tmpl/factory.tmpl.hpp
@@ -0,0 +1,63 @@
+// Copyright (C) by Josh Blum. See LICENSE.txt for licensing information.
+
+#ifndef INCLUDED_GRAS_FACTORY_HPP
+#define INCLUDED_GRAS_FACTORY_HPP
+
+#include <gras/gras.hpp>
+#include <gras/element.hpp>
+#include <PMC/PMC.hpp>
+#include <string>
+
+/*!
+ * Register a block's factory function:
+ * Declare this macro at the global scope in a cpp file.
+ * The block will register at static initialization time.
+ */
+#define GRAS_REGISTER_FACTORY(name, fcn) \
+ GRAS_STATIC_BLOCK(fcn) \
+ {gras::Factory::register_make(name, &fcn);}
+
+namespace gras
+{
+
+/*!
+ * Element factory:
+ * - Register factory functions into the global factory.
+ * - Call make() to create element from global factory.
+ *
+ * Example register a factory function:
+ * gras::Factory::register_make("make_my_block", &make_my_block);
+ *
+ * Example call into the factory:
+ * gras::Element *my_block = gras::Factory::make("make_my_block", arg0, arg1);
+ */
+struct GRAS_API Factory
+{
+ /*******************************************************************
+ * Register API - don't look here, template magic, not helpful
+ ******************************************************************/
+ #for $NARGS in range($MAX_ARGS)
+ template <typename ReturnType, $expand('typename A%d', $NARGS)>
+ static void register_make(const std::string &name, ReturnType(*fcn)($expand('const A%d &', $NARGS)));
+
+ #end for
+ /*******************************************************************
+ * Make API - don't look here, template magic, not helpful
+ ******************************************************************/;
+ #for $NARGS in range($MAX_ARGS)
+ template <$expand('typename A%d', $NARGS)>
+ static Element *make(const std::string &name, $expand('const A%d &', $NARGS));
+
+ #end for
+ /*******************************************************************
+ * Private registration hooks
+ ******************************************************************/
+ static void _register_make(const std::string &, void *);
+ static Element *_handle_make(const std::string &, const PMCC &);
+};
+
+}
+
+#include <gras/detail/factory.hpp>
+
+#endif /*INCLUDED_GRAS_FACTORY_HPP*/
diff --git a/tmpl/factory_detail.tmpl.hpp b/tmpl/factory_detail.tmpl.hpp
new file mode 100644
index 0000000..87a0756
--- /dev/null
+++ b/tmpl/factory_detail.tmpl.hpp
@@ -0,0 +1,64 @@
+// Copyright (C) by Josh Blum. See LICENSE.txt for licensing information.
+
+#ifndef INCLUDED_GRAS_DETAIL_FACTORY_HPP
+#define INCLUDED_GRAS_DETAIL_FACTORY_HPP
+
+#include <PMC/Containers.hpp> //PMCList
+
+namespace gras
+{
+
+/***********************************************************************
+ * Factory entry base class
+ **********************************************************************/
+struct GRAS_API FactoryRegistryEntry
+{
+ FactoryRegistryEntry(void);
+ virtual ~FactoryRegistryEntry(void);
+ virtual Element *make(const PMCC &args) = 0;
+};
+
+#for $NARGS in range($MAX_ARGS)
+/***********************************************************************
+ * Templated registration - $NARGS args
+ **********************************************************************/
+template <typename ReturnType, $expand('typename A%d', $NARGS)>
+struct FactoryRegistryEntryImpl$(NARGS) : FactoryRegistryEntry
+{
+ typedef ReturnType(*Fcn)($expand('const A%d &', $NARGS));
+ FactoryRegistryEntryImpl$(NARGS)(Fcn fcn):_fcn(fcn){}
+ Element *make(const PMCC &args)
+ {
+ const PMCList &a = args.as<PMCList>();
+ if (a.size() < $NARGS) throw a;
+ return _fcn($expand('a[%d].safe_as<A%d>()', $NARGS));
+ }
+ Fcn _fcn;
+};
+
+template <typename ReturnType, $expand('typename A%d', $NARGS)>
+void Factory::register_make(const std::string &name, ReturnType(*fcn)($expand('const A%d &', $NARGS)))
+{
+ void *r = new FactoryRegistryEntryImpl$(NARGS)<ReturnType, $expand('A%d', $NARGS)>(fcn);
+ Factory::_register_make(name, r);
+}
+
+#end for
+/***********************************************************************
+ * Templated make implementations
+ **********************************************************************/
+#for $NARGS in range($MAX_ARGS)
+template <$expand('typename A%d', $NARGS)>
+Element *Factory::make(const std::string &name, $expand('const A%d &a%d', $NARGS))
+{
+ PMCList args($NARGS);
+ #for $i in range($NARGS):
+ args[$i] = PMC_M(a$i);
+ #end for
+ return Factory::_handle_make(name, PMC_M(args));
+}
+
+#end for
+}
+
+#endif /*INCLUDED_GRAS_DETAIL_FACTORY_HPP*/
diff --git a/tmpl/regen_all.sh b/tmpl/regen_all.sh
new file mode 100755
index 0000000..53886c9
--- /dev/null
+++ b/tmpl/regen_all.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+# This script generates the multi-argument template code
+# for the callable and factory interfaces.
+# This is the magic that makes the API calls
+# so natural to call into as a C++ client app.
+# This script is manually run when the source tmpl files are changed.
+# And the generated sources are checked in.
+# This way, the build system does not generate public headers.
+# And the build system does not depend on Cheetah templates.
+
+SCRIPT="`readlink -e $0`"
+SCRIPTPATH="`dirname $SCRIPT`"
+DEST=${SCRIPTPATH}/../include/gras
+
+python expand_template.py factory.tmpl.hpp ${DEST}/factory.hpp
+python expand_template.py factory_detail.tmpl.hpp ${DEST}/detail/factory.hpp
+python expand_template.py callable.tmpl.hpp ${DEST}/callable.hpp
+python expand_template.py callable_detail.tmpl.hpp ${DEST}/detail/callable.hpp