re-order MultiFact implementation to get it to compile

This commit is contained in:
Fischlurch 2009-10-29 22:00:17 +01:00
parent ee611224b6
commit 1dccd37c70
3 changed files with 66 additions and 38 deletions

View file

@ -41,7 +41,7 @@
#include "lib/multifact.hpp"
#include <tr1/functional>
#include "lib/meta/function.hpp"
@ -49,42 +49,63 @@ namespace lib {
namespace factory {
using lumiera::typelist::Types;
using lumiera::typelist::FunctionSignature;
using lumiera::typelist::FunctionTypedef;
using std::tr1::function;
template<typename TY, typename ARG>
struct FabTraits<TY(ARG)>
/**
* Extended MultiFact configuration for arbitrary fabrication functions.
* Contrary to the (simple) standard case, such fabrication functions
* take additional arguments on each invocation. These arguments need
* to be passed through by MultiFact. Moreover, the actual Wrapper
* used may require these fabrication functions to deliver their
* product in a specific form, e.g. as pointer or reference.
* Thus, we have to re-build the actual signature of the
* fabrication functions to be installed into MultiFact.
*/
template< typename SIG
, template<class> class Wrapper
>
struct FabWiring<function<SIG>, Wrapper>
: Wrapper<typename FunctionSignature<function<SIG> >::Ret>
{
typedef TY RawProduct;
typedef RawProduct FabSig(ARG);
typedef ARG Argument;
typedef typename FunctionSignature<function<SIG> >::Args Args;
typedef typename FunctionSignature<function<SIG> >::Ret Element;
typedef typename Wrapper<Element>::PType WrappedProduct;
typedef typename Wrapper<Element>::RType FabProduct;
typedef typename FunctionTypedef<FabProduct, Args>::Sig SIG_Fab;
};
/**
* 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
* Variant of MultiFact, accepting additional invocation argument.
* Similar to the (simple) standard case, this MultiFact specialisation
* allows to install suitable fabrication function(s) at runtime and
* will select the function to use on invocation based on the given ID.
* One additional argument will be passed on to this function.
* @todo with a bit more metaprogramming it would be possible to
* accept multiple arguments; maybe we'll need this later on.
*/
template< typename SIG
template< typename ELM, typename ARG
, typename ID
, template<class> class Wrapper
>
class MultiFact<function<SIG>, ID, Wrapper>
: public MultiFact<SIG,ID,Wrapper>
class MultiFact<ELM(ARG), ID, Wrapper>
: public MultiFact<function<ELM(ARG)>,ID,Wrapper>
{
typedef MultiFact<SIG,ID,Wrapper> _Base;
typedef typename FabTraits<SIG>::Argument ArgType;
typedef MultiFact<function<ELM(ARG)>,ID,Wrapper> _Base;
typedef typename _Base::Product Product;
typedef typename _Base::Creator Creator;
public:
typedef typename _Base::Product Product;
Product
operator() (ID const& id, ArgType arg)
operator() (ID const& id, ARG arg)
{
Creator& func = selectProducer (id);
return wrap (func(arg));

View file

@ -78,25 +78,16 @@ namespace lib {
template<typename TY>
struct FabTraits
{
typedef TY RawProduct;
typedef RawProduct FabSig(void);
};
/**
* Table of registered production functions for MultiFact.
* Each stored function can be accessed by ID and is able
* to fabricate a specific object, which is assignable to TY
* to fabricate a specific object, which is assignable to
* the nominal target type in the MultiFact definition.
*/
template<typename TY, typename ID>
template<typename SIG, typename ID>
struct Fab
{
typedef typename FabTraits<TY>::FabSig Signature;
typedef std::tr1::function<Signature> FactoryFunc;
typedef std::tr1::function<SIG> FactoryFunc;
FactoryFunc&
@ -126,6 +117,23 @@ namespace lib {
/**
* @internal configuration of the elements
* to be combined into a MultiFact instance
*/
template< typename TY
, template<class> class Wrapper
>
struct FabWiring
: Wrapper<TY>
{
typedef typename Wrapper<TY>::PType WrappedProduct;
typedef typename Wrapper<TY>::RType FabProduct;
typedef FabProduct SIG_Fab(void);
};
/**
* Factory for creating a family of objects by ID.
* The actual factory functions are to be installed
@ -141,20 +149,17 @@ namespace lib {
, template<class> class Wrapper
>
class MultiFact
: Wrapper<typename FabTraits<TY>::RawProduct>
: public FabWiring<TY,Wrapper>
{
typedef Wrapper<typename FabTraits<TY>::RawProduct> _Wrap;
typedef typename FabTraits<TY>::RawProduct RawType;
typedef typename _Wrap::PType WrappedProduct;
typedef typename _Wrap::RType FabProduct;
typedef Fab<FabProduct,ID> _Fab;
typedef FabWiring<TY,Wrapper> _Conf;
typedef typename _Conf::SIG_Fab SIG_Fab;
typedef Fab<SIG_Fab,ID> _Fab;
_Fab funcTable_;
protected:
typedef typename _Fab::FactoryFunc Creator;
typedef WrappedProduct Product;
Creator&
selectProducer (ID const& id)
@ -164,6 +169,8 @@ namespace lib {
public:
typedef typename _Conf::WrappedProduct Product;
Product
operator() (ID const& id)
{

View file

@ -77,7 +77,7 @@ namespace test{
/** the factory instantiation used for this test */
typedef factory::MultiFact< function<Num(int)> // nominal signature of fabrication
typedef factory::MultiFact< Num(int) // nominal signature of fabrication
, prodID // select factory function by prodID
, factory::BuildRefcountPtr // wrapper: manage product by smart-ptr
> TestFactory;