diff --git a/src/lib/multifact.hpp b/src/lib/multifact.hpp index d7595565c..85b63fea8 100644 --- a/src/lib/multifact.hpp +++ b/src/lib/multifact.hpp @@ -35,6 +35,7 @@ #include "lib/error.hpp" +#include "lib/singleton.hpp" //#include #include @@ -44,6 +45,18 @@ namespace lib { namespace factory { + /** + * Dummy "wrapper", + * just returning a target-ref + */ + template + struct PassReference + { + typedef TAR& PType; + + PType wrap (TAR& object) { return object; } + }; + /** * Repository of registered production lines. * @todo write type comment @@ -52,10 +65,11 @@ namespace lib { class Fab { typedef TY& RawProduct; - typedef std::tr1::function & FactoryFunc; public: - static FactoryFunc + typedef std::tr1::function FactoryFunc; + + static FactoryFunc& select (ID id) { UNIMPLEMENTED ("how to store/select the production line"); @@ -82,13 +96,13 @@ namespace lib { { typedef Fab _Fab; typedef typename _Fab::FactoryFunc Creator; - typedef typename WR::PType Product; + typedef typename Wrapper::PType Product; public: Product operator() (ID id) { - Creator func = _Fab::select(id); + Creator& func = _Fab::select(id); return wrap (func()); } @@ -107,10 +121,47 @@ namespace lib { } }; + /** + * Convenience shortcut for automatically setting up + * a production line, fabricating a singleton instance + * of the given target type (TAR) + */ + template + class ProduceSingleton + { + static Produce autoRegistration; + + typedef std::tr1::function AccessSingleton_Func; + + static AccessSingleton_Func + createSingleton_accessFunction() + { + static Singleton theSingletonFactory; + // using this static singleton factory for + // "fabricating" the TAR instance. Consequently, + // the created TAR object lives within this static + // allocated memory. + return std::tr1::bind (&Singleton::operator(), theSingletonFactory); + } + }; + }; - - - + + + /** define a static instance variable + * to trigger the sideeffect of automatic registration. + * This templated definition actually happens, when the + * ProduceSingleton template gets instantiated. This may be + * triggered explicitly, or by inheriting from ProduceSingleton. + */ + template< typename TY, typename ID + , template class Wrapper> + template< class TAR> + typename MultiFact::Produce + MultiFact::ProduceSingleton::autoRegistration ( TY::getID() // required within target type! + , createSingleton_accessFunction()); + + } // namespace factory //using factory::Factory; diff --git a/tests/lib/multifact-test.cpp b/tests/lib/multifact-test.cpp index e91ba71f6..9cb2e0cc8 100644 --- a/tests/lib/multifact-test.cpp +++ b/tests/lib/multifact-test.cpp @@ -22,6 +22,7 @@ #include "lib/test/run.hpp" +#include "lib/test/test-helper.hpp" #include "lib/multifact.hpp" #include "lib/util.hpp" @@ -35,10 +36,13 @@ namespace lib { namespace test{ using boost::lexical_cast; + using lib::test::showSizeof; //using util::isnil; using util::isSameObject; + using std::ostream; using std::string; using std::cout; + using std::endl; namespace { // hierarchy of test dummy objects @@ -49,6 +53,9 @@ namespace test{ virtual operator string (); }; + inline ostream& operator<< (ostream& os, Interface& ifa) { return os << string(ifa); } + + enum theID { ONE = 1 , TWO @@ -56,12 +63,13 @@ namespace test{ , FOU }; - typedef MultiFact TestFactory; + typedef factory::MultiFact TestFactory; template class Implementation : public Interface + , TestFactory::ProduceSingleton > { operator string() { @@ -69,10 +77,10 @@ namespace test{ } }; - TestFactory::ProduceSingleton > _register_for_fabrication_ONE; - TestFactory::ProduceSingleton > _register_for_fabrication_TWO; - TestFactory::ProduceSingleton > _register_for_fabrication_THR; - TestFactory::ProduceSingleton > _register_for_fabrication_FOU; + template class Implementation; + template class Implementation; + template class Implementation; + template class Implementation; }