WIP try to create an extension point to MultiFact, allowing to accept argument(s)
sketch of an idea how to add an extension possibility without messing up the basic MultiFact template
This commit is contained in:
parent
6dc09e66dc
commit
2530e8c1a1
3 changed files with 130 additions and 10 deletions
100
src/lib/multifact-arg.hpp
Normal file
100
src/lib/multifact-arg.hpp
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
MULTIFACT-ARG.hpp - variant of family-of-object factory, accepting fabrication arguments
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2009, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
||||
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
|
||||
** Extension allowing the MultiFact to pass arguments to the fabrication.
|
||||
** This extension is implemented by template specialisations and thus kicks in
|
||||
** when specifying a function \em signature as factory "product type". The resulting
|
||||
** factory class exposes a function call operator matching this signature, additionally
|
||||
** expecting the ID (to select the specific fabrication function) as first parameter.
|
||||
**
|
||||
** @todo WIP-WIP-WIP ... does this work out as intended?? TICKET #377
|
||||
**
|
||||
** @see multifact-argument-test.cpp
|
||||
** @see query-resolver.cpp usage example
|
||||
** @see multifact.hpp standard case
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LIB_MULTIFACT_ARG_H
|
||||
#define LIB_MULTIFACT_ARG_H
|
||||
|
||||
|
||||
#include "lib/multifact.hpp"
|
||||
|
||||
|
||||
|
||||
namespace lib {
|
||||
namespace factory {
|
||||
|
||||
|
||||
using std::tr1::function;
|
||||
|
||||
|
||||
template<typename TY, typename ARG>
|
||||
struct FabTraits<TY(ARG)>
|
||||
{
|
||||
typedef TY RawProduct;
|
||||
typedef RawProduct FacSig(ARG);
|
||||
typedef ARG Argument;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Variant of MultiFact, selecting a creator function by ID
|
||||
* with the ability to pass additional argument(s) to this
|
||||
* creator function on invocation.
|
||||
* TODO type comment
|
||||
*/
|
||||
template< typename SIG,
|
||||
, typename ID
|
||||
, template<class> class Wrapper
|
||||
>
|
||||
class MultiFact<function<SIG>, ID, Wrapper>
|
||||
: public MultiFact<SIG,ID,Wrapper>
|
||||
{
|
||||
|
||||
typedef typename FabTraits<SIG>::Argument ArgType;
|
||||
|
||||
public:
|
||||
Product
|
||||
operator() (ID const& id, ArgType arg)
|
||||
{
|
||||
Creator& func = selectProducer (id);
|
||||
return wrap (func(arg));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // namespace factory
|
||||
|
||||
|
||||
|
||||
// TODO is there some suitable standard configuration we could provide here??
|
||||
|
||||
|
||||
} // namespace lib
|
||||
#endif
|
||||
|
|
@ -25,6 +25,7 @@
|
|||
**
|
||||
** @todo WIP-WIP-WIP ... currently collecting various bits of implementation here. TICKET #277
|
||||
**
|
||||
** @see multifact-test.cpp
|
||||
** @see SingletonFactory
|
||||
** @see lib::factory::Factory
|
||||
*/
|
||||
|
|
@ -60,6 +61,15 @@ namespace lib {
|
|||
};
|
||||
|
||||
|
||||
template<typename TY>
|
||||
struct FabTraits
|
||||
{
|
||||
typedef TY RawProduct;
|
||||
typedef RawProduct FacSig(void);
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Table of registered production functions for MultiFact.
|
||||
* Each stored function can be accessed by ID and is able
|
||||
|
|
@ -68,12 +78,12 @@ namespace lib {
|
|||
template<typename TY, typename ID>
|
||||
struct Fab
|
||||
{
|
||||
typedef TY& RawProduct;
|
||||
typedef std::tr1::function<RawProduct(void)> FactoryFunc;
|
||||
typedef typename FabTraits<TY>::FacSig Signature;
|
||||
typedef std::tr1::function<Signature> FactoryFunc;
|
||||
|
||||
|
||||
FactoryFunc&
|
||||
select (ID id)
|
||||
select (ID const& id)
|
||||
{
|
||||
if (!contains (id))
|
||||
throw lumiera::error::Invalid("unknown factory product requested.");
|
||||
|
|
@ -82,7 +92,7 @@ namespace lib {
|
|||
}
|
||||
|
||||
void
|
||||
defineProduction (ID id, FactoryFunc fun)
|
||||
defineProduction (ID const& id, FactoryFunc fun)
|
||||
{
|
||||
producerTable_[id] = fun;
|
||||
}
|
||||
|
|
@ -114,20 +124,30 @@ namespace lib {
|
|||
, template<class> class Wrapper
|
||||
>
|
||||
class MultiFact
|
||||
: Wrapper<TY>
|
||||
: Wrapper<typename FabTraits<TY>::RawProduct>
|
||||
{
|
||||
typedef Fab<TY,ID> _Fab;
|
||||
typedef typename _Fab::FactoryFunc Creator;
|
||||
typedef typename Wrapper<TY>::PType Product;
|
||||
|
||||
_Fab funcTable_;
|
||||
|
||||
protected:
|
||||
typedef typename FabTraits<TY>::RawProduct RawType;
|
||||
typedef typename Wrapper<RawType>::PType Product;
|
||||
typedef typename _Fab::FactoryFunc Creator;
|
||||
|
||||
|
||||
Creator&
|
||||
selectProducer (ID const& id)
|
||||
{
|
||||
return funcTable_.select(id);
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
Product
|
||||
operator() (ID id)
|
||||
operator() (ID const& id)
|
||||
{
|
||||
Creator& func = funcTable_.select(id);
|
||||
Creator& func = selectProducer (id);
|
||||
return wrap (func());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ namespace test{
|
|||
|
||||
cout << showSizeof (theFact) << endl;
|
||||
|
||||
typedef TestFactory::PType PP;
|
||||
typedef TestFactory::Product PP;
|
||||
|
||||
DummyID id1 = {ONE, 2};
|
||||
DummyID id1 = {TWO, 3};
|
||||
|
|
|
|||
Loading…
Reference in a new issue