diff options
Diffstat (limited to 'tmpl/factory_detail.tmpl.hpp')
-rw-r--r-- | tmpl/factory_detail.tmpl.hpp | 64 |
1 files changed, 64 insertions, 0 deletions
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*/ |