From c6373f53f4690d667e553ed7258e13c3b45aa323 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sun, 7 Jul 2013 11:50:03 -0700 Subject: gras: created element factory --- include/gras/detail/factory.hpp | 151 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 include/gras/detail/factory.hpp (limited to 'include/gras/detail') diff --git a/include/gras/detail/factory.hpp b/include/gras/detail/factory.hpp new file mode 100644 index 0000000..0487e76 --- /dev/null +++ b/include/gras/detail/factory.hpp @@ -0,0 +1,151 @@ +// Copyright (C) by Josh Blum. See LICENSE.txt for licensing information. + +#ifndef INCLUDED_GRAS_DETAIL_FACTORY_HPP +#define INCLUDED_GRAS_DETAIL_FACTORY_HPP + +#include //PMCList + +namespace gras +{ + +/*********************************************************************** + * Factory entry base class + **********************************************************************/ +struct GRAS_API FactoryRegistryEntry +{ + FactoryRegistryEntry(void); + virtual ~FactoryRegistryEntry(void); + virtual Element *make(const PMCC &args) = 0; +}; + +/*********************************************************************** + * Templated registration - 0 args + **********************************************************************/ +template +struct FactoryRegistryEntryImpl0 : FactoryRegistryEntry +{ + typedef ReturnType(*Fcn)(void); + FactoryRegistryEntryImpl0(Fcn fcn):_fcn(fcn){} + Element *make(const PMCC &) + { + return _fcn(); + } + Fcn _fcn; +}; + +template +void Factory::register_make(const std::string &name, ReturnType(*fcn)(void)) +{ + void *r = new FactoryRegistryEntryImpl0(fcn); + Factory::_register_make(name, r); +} + +/*********************************************************************** + * Templated registration - 1 args + **********************************************************************/ +template +struct FactoryRegistryEntryImpl1 : FactoryRegistryEntry +{ + typedef ReturnType(*Fcn)(const Arg0 &); + FactoryRegistryEntryImpl1(Fcn fcn):_fcn(fcn){} + Element *make(const PMCC &args) + { + const PMCList &a = args.as(); + return _fcn(a[0].safe_as()); + } + Fcn _fcn; +}; + +template +void Factory::register_make(const std::string &name, ReturnType(*fcn)(const Arg0 &)) +{ + void *r = new FactoryRegistryEntryImpl1(fcn); + Factory::_register_make(name, r); +} + +/*********************************************************************** + * Templated registration - 2 args + **********************************************************************/ +template +struct FactoryRegistryEntryImpl2 : FactoryRegistryEntry +{ + typedef ReturnType(*Fcn)(const Arg0 &, const Arg1 &); + FactoryRegistryEntryImpl2(Fcn fcn):_fcn(fcn){} + Element *make(const PMCC &args) + { + const PMCList &a = args.as(); + return _fcn(a[0].safe_as(), a[1].safe_as()); + } + Fcn _fcn; +}; + +template +void Factory::register_make(const std::string &name, ReturnType(*fcn)(const Arg0 &, const Arg1 &)) +{ + void *r = new FactoryRegistryEntryImpl2(fcn); + Factory::_register_make(name, r); +} + +/*********************************************************************** + * Templated registration - 3 args + **********************************************************************/ +template +struct FactoryRegistryEntryImpl3 : FactoryRegistryEntry +{ + typedef ReturnType(*Fcn)(const Arg0 &, const Arg1 &, const Arg2 &); + FactoryRegistryEntryImpl3(Fcn fcn):_fcn(fcn){} + Element *make(const PMCC &args) + { + const PMCList &a = args.as(); + return _fcn(a[0].safe_as(), a[1].safe_as(), a[2].safe_as()); + } + Fcn _fcn; +}; + +template +void Factory::register_make(const std::string &name, ReturnType(*fcn)(const Arg0 &, const Arg1 &, const Arg2 &)) +{ + void *r = new FactoryRegistryEntryImpl3(fcn); + Factory::_register_make(name, r); +} + +/*********************************************************************** + * Templated make implementations + **********************************************************************/ +inline +Element *Factory::make(const std::string &name) +{ + PMCList args(0); + return Factory::_make(name, PMC_M(args)); +} + +template +Element *Factory::make(const std::string &name, const Arg0 &a0) +{ + PMCList args(1); + args[0] = PMC_M(a0); + return Factory::_make(name, PMC_M(args)); +} + +template +Element *Factory::make(const std::string &name, const Arg0 &a0, const Arg1 &a1) +{ + PMCList args(2); + args[0] = PMC_M(a0); + args[1] = PMC_M(a1); + return Factory::_make(name, PMC_M(args)); +} + +template +Element *Factory::make(const std::string &name, const Arg0 &a0, const Arg1 &a1, const Arg2 &a2) +{ + PMCList args(3); + args[0] = PMC_M(a0); + args[1] = PMC_M(a1); + args[2] = PMC_M(a2); + return Factory::_make(name, PMC_M(args)); +} + +} + +#endif /*INCLUDED_GRAS_DETAIL_FACTORY_HPP*/ -- cgit