diff --git a/src/lib/multifact.hpp b/src/lib/multifact.hpp new file mode 100644 index 000000000..d7595565c --- /dev/null +++ b/src/lib/multifact.hpp @@ -0,0 +1,120 @@ +/* + MULTIFACT.hpp - flexible family-of-object factory template + + Copyright (C) Lumiera.org + 2009, Hermann Vosseler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +/** @file multifact.hpp + ** Building blocks of a configurable factory, generating families of related objects. + ** + ** @todo WIP-WIP-WIP ... currently collecting various bits of implementation here. TICKET #277 + ** + ** @see SingletonFactory + ** @see lib::factory::Factory + */ + + +#ifndef LIB_MULTIFACT_H +#define LIB_MULTIFACT_H + + +#include "lib/error.hpp" +//#include + +#include + + + +namespace lib { + namespace factory { + + /** + * Repository of registered production lines. + * @todo write type comment + */ + template + class Fab + { + typedef TY& RawProduct; + typedef std::tr1::function & FactoryFunc; + + public: + static FactoryFunc + select (ID id) + { + UNIMPLEMENTED ("how to store/select the production line"); + } + + static void + defineProduction (ID id, FactoryFunc fun) + { + UNIMPLEMENTED ("how to store/select the production line"); + } + }; + + + + /** + * @todo write type comment + */ + template< typename TY + , typename ID + , template class Wrapper + > + class MultiFact + : Wrapper + { + typedef Fab _Fab; + typedef typename _Fab::FactoryFunc Creator; + typedef typename WR::PType Product; + + public: + Product + operator() (ID id) + { + Creator func = _Fab::select(id); + return wrap (func()); + } + + /** + * to set up a production line, + * associated with a specific ID + */ + struct Produce + : Creator + { + template + Produce (ID id, FUNC fun) + : Creator(fun) + { + _Fab::defineProduction (id, *this); + } + }; + + }; + + + + } // namespace factory + +//using factory::Factory; + + +} // namespace lib +#endif diff --git a/tests/40components.tests b/tests/40components.tests index c7efedcf3..2da0e1e44 100644 --- a/tests/40components.tests +++ b/tests/40components.tests @@ -284,6 +284,16 @@ return: 0 END +PLANNED "configurable Factory" MultiFact_test < + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + + +#include "lib/test/run.hpp" +#include "lib/multifact.hpp" +#include "lib/util.hpp" + +#include +#include +#include + + + +namespace lib { +namespace test{ + + using boost::lexical_cast; + //using util::isnil; + using util::isSameObject; + using std::string; + using std::cout; + + + namespace { // hierarchy of test dummy objects + + struct Interface + { + virtual ~Interface() {}; + virtual operator string (); + }; + + enum theID + { ONE = 1 + , TWO + , THR + , FOU + }; + + typedef MultiFact TestFactory; + + + template + class Implementation + : public Interface + { + operator string() + { + return "Impl-"+lexical_cast (ii); + } + }; + + TestFactory::ProduceSingleton > _register_for_fabrication_ONE; + TestFactory::ProduceSingleton > _register_for_fabrication_TWO; + TestFactory::ProduceSingleton > _register_for_fabrication_THR; + TestFactory::ProduceSingleton > _register_for_fabrication_FOU; + } + + + + + + /******************************************************************* + * @test verify simple setup of the MultiFact template. + * Define a hierarchy of test dummy objects, such as to + * register them automatically for creation through a suitable + * instantiation of MultiFact. Verify we get the correct product + * when invoking this MultiFac flavour. + * @see lib::MultiFact + */ + class MultiFact_test : public Test + { + void + run (Arg) + { + TestFactory theFact; + cout << theFact(ONE) << endl; + cout << theFact(TWO) << endl; + cout << theFact(THR) << endl; + cout << theFact(FOU) << endl; + cout << showSizeof (theFact) << endl; + + Interface & o1 = theFact(ONE); + Interface & o2 = theFact(ONE); + ASSERT (isSameObject(o1,o2)); + + TestFactory anotherFact; + Interface & o3 = anotherFact(ONE); + ASSERT (isSameObject(o2,o3)); + } + }; + + + /** Register this test class... */ + LAUNCHER (MultiFact_test, "unit common"); + + + +}} // namespace lib::test