change ConfigSelector to accept arbitrary factory function signatures

This commit is contained in:
Fischlurch 2008-08-05 03:46:06 +02:00
parent 29e33e4eb4
commit 07975e520f
5 changed files with 46 additions and 40 deletions

View file

@ -55,6 +55,8 @@
namespace lumiera {
namespace typelist {
const size_t CONFIG_FLAGS_MAX = 5;
template<char bit> struct Flag { typedef Flag ID; };
template<> struct Flag<0> { typedef NullType ID; };

View file

@ -89,9 +89,10 @@ namespace engine {
}
};
typedef WiringDescriptor& (FunctionType)(void);
typedef ConfigSelector< WiringDescriptorFactory ///< Factory template
, WiringDescriptor& ///< type of the product
, FunctionType ///< function signature of the Factory
, Alloc& ///< allocator fed to all factories
> WiringSelector;
@ -129,7 +130,7 @@ namespace engine {
// Bits config (FlagInfo<Config>::CODE);
size_t config = 13; /////////////////////////////////////////TODO
// return pImpl_->selector(config);
// return pImpl_->selector[config]();
}
// BlockAlloc<NodeWiring< StateAdapter< Config<cache, process, inplace> > > >::fabricate();

View file

@ -51,7 +51,8 @@
#include "common/util.hpp"
#include "common/meta/configflags.hpp"
#include <boost/lexical_cast.hpp>
#include <boost/function.hpp>
#include <bitset>
#include <map>
@ -59,10 +60,10 @@ namespace engine {
namespace config {
using lumiera::typelist::FlagInfo;
using boost::lexical_cast;
using util::contains;
using lumiera::typelist::CONFIG_FLAGS_MAX;
/**
* Helper for fabricating ProcNode Wiring configurations.
@ -99,28 +100,26 @@ namespace engine {
* heap allocated.
*/
template< template<class CONF> class Factory
, typename RET ///< common base class of the Factory's products
, typename FUNC ///< common function type of all Factory instances
, typename PAR ///< ctor parameter of the Factories
>
class ConfigSelector
{
typedef boost::function<FUNC> FacFunction;
struct FacFunctor
{
virtual ~FacFunctor() {}
virtual RET invoke() =0;
};
template<class FAC>
struct FactoryHolder : FacFunctor
struct FactoryHolder
: private FAC,
public FacFunction
{
FAC factory_;
FactoryHolder(PAR p) : factory_(p) {}
virtual RET invoke () { return factory_(); }
FactoryHolder(PAR p)
: FAC(p),
FacFunction( static_cast<FAC&>(*this))
{ }
};
typedef std::tr1::shared_ptr<FacFunctor> PFunc;
typedef std::tr1::shared_ptr<FacFunction> PFunc;
typedef std::map<size_t, PFunc> ConfigTable;
ConfigTable possibleConfig_; ///< Table of factories
@ -162,13 +161,14 @@ namespace engine {
FlagInfo<CONFS>::accept (buildTable);
}
RET
operator() (size_t configFlags) ///< invoke the factory corresponding to the given config
FacFunction&
operator[] (size_t configFlags) ///< retrieve the factory corresponding to the given config
{
if (contains (possibleConfig_, configFlags))
return possibleConfig_[configFlags]->invoke();
return *possibleConfig_[configFlags];
else
throw lumiera::error::Invalid("ConfigSelector: No preconfigured factory for config-bits="+lexical_cast<std::string>(configFlags));
throw lumiera::error::Invalid("ConfigSelector: No preconfigured factory for config-bits="
+std::bitset<CONFIG_FLAGS_MAX>(configFlags).to_string());
}
};

View file

@ -57,22 +57,22 @@ out: Conf2 :-<2>-
out: Conf3 :-<3>-
out: Conf4 :-<2>-<4>-
out: AllFlags :-<1>-<2>-<3>-<4>-
out: ______
out: ______ check_flags()
out: __________________________
out: __________________________ check_flags()
out: Flags1 :-<2>-<4>-
out: Flags2 :-<2>-<4>-
out: SimpleConfig_defined_by_Typelist :-<1>-
out: AnotherConfig_defined_by_Typelist :-<1>-<2>-<3>-<4>-
out: ______
out: ______ check_instantiation()
out: __________________________
out: __________________________ check_instantiation()
out: defined Conf0? ---> 0
out: defined Conf1? ---> 1
out: defined Conf2? ---> 1
out: defined Conf3? ---> 1
out: defined Conf4? ---> 1
out: defined Trash? ---> 0
out: ______
out: ______ check_filter()
out: __________________________
out: __________________________ check_filter()
out: SomeFlagsets :
out: +---<1>-<3>-+
out: +---<2>-<4>-+-
@ -121,8 +121,8 @@ out: +-Conf-[-<2>-<3>-]
out: +-Conf-[-<2>-<4>-]
out: +-Conf-[-<2>-]
out: +-Conf-[-<3>-]-
out: ______
out: ______ check_FlagInfo()
out: __________________________
out: __________________________ check_FlagInfo()
out: Flags1 :-<1>-<3>-
out: max bit : 3
out: binary code: 10
@ -135,8 +135,8 @@ out: visit(code=10) -->
out: +-Conf-[-<1>-<3>-]-
out: visit(code=20) -->
out: +-Conf-[-<2>-<4>-]-
out: ______
out: ______ check_ConfigSelector()
out: __________________________
out: __________________________ check_ConfigSelector()
out: Possible_Configs :
out: +-Conf-[-<1>-]
out: +-Conf-[-<2>-<3>-]
@ -148,7 +148,7 @@ out: Flag-code = 12 ConfigSelector() ---> 1023
out: Flag-code = 20 ConfigSelector() ---> 1024
out: Flag-code = 4 ConfigSelector() ---> 1020
out: Flag-code = 8 ConfigSelector() ---> 1030
out: LUMIERA_ERROR_INVALID:invalid input or parameters (ConfigSelector: No preconfigured factory for config-bits=23).
out: LUMIERA_ERROR_INVALID:invalid input or parameters (ConfigSelector: No preconfigured factory for config-bits=10111).
return: 0
END

View file

@ -112,7 +112,10 @@ namespace lumiera {
} // (End) internal defs
#define DELIMITER(TITLE) cout << "______\n______ " << STRINGIFY(TITLE) << "\n";
#define PRINT_DELIMITER(TITLE) \
cout << "__________________________\n" \
"__________________________ " \
<< STRINGIFY(TITLE) << "\n";
@ -155,7 +158,7 @@ namespace lumiera {
/** @test conversion between list-of-flags and a config-type in both directions */
void check_flags ()
{
DELIMITER (check_flags());
PRINT_DELIMITER (check_flags());
typedef Config<TWO,FOU> Flags1;
typedef Flags<TWO,FOU> Flags2;
@ -186,7 +189,7 @@ namespace lumiera {
<< "? ---> " \
<< Instantiation<Maybe>::Test<NAME>::value << "\n";
DELIMITER (check_instantiation());
PRINT_DELIMITER (check_instantiation());
CAN_INSTANTIATE (Conf0);
CAN_INSTANTIATE (Conf1);
@ -204,7 +207,7 @@ namespace lumiera {
*/
void check_filter ()
{
DELIMITER (check_filter());
PRINT_DELIMITER (check_filter());
DISPLAY (SomeFlagsets);
@ -250,7 +253,7 @@ namespace lumiera {
*/
void check_FlagInfo()
{
DELIMITER (check_FlagInfo());
PRINT_DELIMITER (check_FlagInfo());
DISPLAY (Flags1);
cout << "max bit : " << FlagInfo<Flags1>::BITS <<"\n";
@ -282,14 +285,14 @@ namespace lumiera {
*/
void check_ConfigSelector()
{
DELIMITER (check_ConfigSelector());
PRINT_DELIMITER (check_ConfigSelector());
typedef Apply<AllFlagCombinations::List, DefineConfigByFlags> ListAllConfigs;
typedef Filter<ListAllConfigs::List,Instantiation<Maybe>::Test> Possible_Configs;
DISPLAY (Possible_Configs);
typedef engine::config::ConfigSelector< TestFactory // Factory template
, uint // product type
, uint(void) // Factory function type
, long // common ctor argument
> TestFactorySelector;
@ -300,7 +303,7 @@ namespace lumiera {
#define INVOKE_CONFIG_SELECTOR(CODE) \
cout << " Flag-code = " << CODE \
<< " ConfigSelector() ---> " \
<< testConfigSelector (CODE) << "\n";
<< testConfigSelector[CODE] () << "\n";
INVOKE_CONFIG_SELECTOR (2);
INVOKE_CONFIG_SELECTOR (12);