first draft impl regarding automatic installation of a singleton facotry into MultiFact

This commit is contained in:
Fischlurch 2009-09-30 18:18:30 +02:00
parent 8ee76b1bfd
commit 5910f21383
2 changed files with 71 additions and 12 deletions

View file

@ -35,6 +35,7 @@
#include "lib/error.hpp"
#include "lib/singleton.hpp"
//#include <tr1/memory>
#include <tr1/functional>
@ -44,6 +45,18 @@
namespace lib {
namespace factory {
/**
* Dummy "wrapper",
* just returning a target-ref
*/
template<typename TAR>
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<RawProduct(void)> & FactoryFunc;
public:
static FactoryFunc
typedef std::tr1::function<RawProduct(void)> FactoryFunc;
static FactoryFunc&
select (ID id)
{
UNIMPLEMENTED ("how to store/select the production line");
@ -82,13 +96,13 @@ namespace lib {
{
typedef Fab<TY,ID> _Fab;
typedef typename _Fab::FactoryFunc Creator;
typedef typename WR::PType Product;
typedef typename Wrapper<TY>::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 TAR>
class ProduceSingleton
{
static Produce autoRegistration;
typedef std::tr1::function<TAR&(void)> AccessSingleton_Func;
static AccessSingleton_Func
createSingleton_accessFunction()
{
static Singleton<TAR> 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<TAR>::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> class Wrapper>
template< class TAR>
typename MultiFact<TY,ID,Wrapper>::Produce
MultiFact<TY,ID,Wrapper>::ProduceSingleton<TAR>::autoRegistration ( TY::getID() // required within target type!
, createSingleton_accessFunction());
} // namespace factory
//using factory::Factory;

View file

@ -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<Interface, theID, PassReference> TestFactory;
typedef factory::MultiFact<Interface, theID, factory::PassReference> TestFactory;
template<theID ii>
class Implementation
: public Interface
, TestFactory::ProduceSingleton<Implementation<ii> >
{
operator string()
{
@ -69,10 +77,10 @@ namespace test{
}
};
TestFactory::ProduceSingleton<Implementation<ONE> > _register_for_fabrication_ONE;
TestFactory::ProduceSingleton<Implementation<TWO> > _register_for_fabrication_TWO;
TestFactory::ProduceSingleton<Implementation<THR> > _register_for_fabrication_THR;
TestFactory::ProduceSingleton<Implementation<FOU> > _register_for_fabrication_FOU;
template class Implementation<ONE>;
template class Implementation<TWO>;
template class Implementation<THR>;
template class Implementation<FOU>;
}