diff --git a/src/lib/multifact.hpp b/src/lib/multifact.hpp index 002b09d95..c24648bd7 100644 --- a/src/lib/multifact.hpp +++ b/src/lib/multifact.hpp @@ -36,7 +36,7 @@ #include "lib/error.hpp" #include "lib/singleton.hpp" -//#include +#include "util.hpp" #include #include @@ -46,6 +46,8 @@ namespace lib { namespace factory { + using util::contains; + /** * Dummy "wrapper", * just returning a target-ref @@ -69,14 +71,17 @@ namespace lib { typedef std::tr1::function FactoryFunc; - static FactoryFunc& + FactoryFunc& select (ID id) { + if (!contains (producerTable_,id)) + throw lumiera::error::Invalid("unknown factory product requested."); + return producerTable_[id]; } - static void - defineProduction (ID id, FactoryFunc& fun) + void + defineProduction (ID id, FactoryFunc fun) { producerTable_[id] = fun; } @@ -101,28 +106,25 @@ namespace lib { typedef typename _Fab::FactoryFunc Creator; typedef typename Wrapper::PType Product; + _Fab funcTable_; + public: Product operator() (ID id) { - Creator& func = _Fab::select(id); + Creator& func = funcTable_.select(id); return wrap (func()); } - /** - * to set up a production line, - * associated with a specific ID + /** to set up a production line, + * associated with a specific ID */ - struct Produce - : Creator + template + void + defineProduction (ID id, FUNC fun) { - template - Produce (ID id, FUNC fun) - : Creator(fun) - { - _Fab::defineProduction (id, *this); - } - }; + funcTable_.defineProduction (id, fun); + } /** * Convenience shortcut for automatically setting up @@ -130,49 +132,27 @@ namespace lib { * of the given target type (TAR) */ template - class ProduceSingleton - : Singleton - , Produce + class Singleton + : lib::Singleton { - typedef std::tr1::function AccessSingleton_Func; + typedef lib::Singleton SingFac; +// typedef std::tr1::function AccessSingleton_Func; - AccessSingleton_Func - createSingleton_accessFunction(Singleton* theFactory) + Creator + createSingleton_accessFunction() { - return std::tr1::bind (&Singleton::operator(), theFactory); + return std::tr1::bind (&SingFac::operator() + , static_cast(this)); } public: - ProduceSingleton() - : Produce ( TAR::getTypeID() // required within target type! - , createSingleton_accessFunction(this)) + Singleton (MultiFact& factory, ID id) { - INFO (test, "zoing"); + factory.defineProduction(id, createSingleton_accessFunction()); } }; }; - template - struct AutoInstantiation - { - static X autoRegistration; - }; - - template - X AutoInstantiation::autoRegistration; - -// /** 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 diff --git a/tests/40components.tests b/tests/40components.tests index 2da0e1e44..0292330ab 100644 --- a/tests/40components.tests +++ b/tests/40components.tests @@ -289,7 +289,7 @@ out: Impl-1 out: Impl-2 out: Impl-3 out: Impl-4 -out: sizeof\( .+ \) = 1 +out: sizeof\( .+MultiFact.+Interface.+theID.+PassReference.+ \) = return: 0 END diff --git a/tests/lib/multifact-test.cpp b/tests/lib/multifact-test.cpp index 164311faf..8669b188d 100644 --- a/tests/lib/multifact-test.cpp +++ b/tests/lib/multifact-test.cpp @@ -44,6 +44,7 @@ namespace test{ using std::cout; using std::endl; + using lumiera::error::LUMIERA_ERROR_INVALID; namespace { // hierarchy of test dummy objects @@ -79,10 +80,12 @@ namespace test{ static theID getTypeID() { return ii; } }; - TestFactory::ProduceSingleton > singletonInstantiation_ONE; - TestFactory::ProduceSingleton > singletonInstantiation_TWO; - TestFactory::ProduceSingleton > singletonInstantiation_THR; - TestFactory::ProduceSingleton > singletonInstantiation_FOU; + TestFactory theFact; + + TestFactory::Singleton > holder1 (theFact,ONE); + TestFactory::Singleton > holder2 (theFact,TWO); + TestFactory::Singleton > holder3 (theFact,THR); + TestFactory::Singleton > holder4 (theFact,FOU); } @@ -102,7 +105,6 @@ namespace test{ void run (Arg) { - TestFactory theFact; cout << theFact(ONE) << endl; cout << theFact(TWO) << endl; cout << theFact(THR) << endl; @@ -114,6 +116,9 @@ namespace test{ ASSERT (isSameObject(o1,o2)); TestFactory anotherFact; + VERIFY_ERROR (INVALID, anotherFact(ONE) ); + + TestFactory::Singleton > anotherSingletonHolder (anotherFact,ONE); Interface & o3 = anotherFact(ONE); ASSERT (isSameObject(o2,o3)); }