diff --git a/src/common/meta/configflags.hpp b/src/common/meta/configflags.hpp index 7ffb79a70..fa24bfc97 100644 --- a/src/common/meta/configflags.hpp +++ b/src/common/meta/configflags.hpp @@ -55,6 +55,8 @@ namespace lumiera { namespace typelist { + const size_t CONFIG_FLAGS_MAX = 5; + template struct Flag { typedef Flag ID; }; template<> struct Flag<0> { typedef NullType ID; }; diff --git a/src/proc/engine/nodewiring.cpp b/src/proc/engine/nodewiring.cpp index 6a20f86e4..7d999aa48 100644 --- a/src/proc/engine/nodewiring.cpp +++ b/src/proc/engine/nodewiring.cpp @@ -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::CODE); size_t config = 13; /////////////////////////////////////////TODO -// return pImpl_->selector(config); +// return pImpl_->selector[config](); } // BlockAlloc > > >::fabricate(); diff --git a/src/proc/engine/nodewiringconfig.hpp b/src/proc/engine/nodewiringconfig.hpp index 0ebefd865..aac1ff7a1 100644 --- a/src/proc/engine/nodewiringconfig.hpp +++ b/src/proc/engine/nodewiringconfig.hpp @@ -51,7 +51,8 @@ #include "common/util.hpp" #include "common/meta/configflags.hpp" -#include +#include +#include #include @@ -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 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 FacFunction; - struct FacFunctor - { - virtual ~FacFunctor() {} - virtual RET invoke() =0; - }; template - 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(*this)) + { } }; - typedef std::tr1::shared_ptr PFunc; + typedef std::tr1::shared_ptr PFunc; typedef std::map ConfigTable; ConfigTable possibleConfig_; ///< Table of factories @@ -162,13 +161,14 @@ namespace engine { FlagInfo::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(configFlags)); + throw lumiera::error::Invalid("ConfigSelector: No preconfigured factory for config-bits=" + +std::bitset(configFlags).to_string()); } }; diff --git a/tests/50components.tests b/tests/50components.tests index 9b15ca3ee..90ab37569 100644 --- a/tests/50components.tests +++ b/tests/50components.tests @@ -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 diff --git a/tests/common/meta/configflagstest.cpp b/tests/common/meta/configflagstest.cpp index 1d1bad7db..34b54be48 100644 --- a/tests/common/meta/configflagstest.cpp +++ b/tests/common/meta/configflagstest.cpp @@ -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 Flags1; typedef Flags Flags2; @@ -186,7 +189,7 @@ namespace lumiera { << "? ---> " \ << Instantiation::Test::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::BITS <<"\n"; @@ -282,14 +285,14 @@ namespace lumiera { */ void check_ConfigSelector() { - DELIMITER (check_ConfigSelector()); + PRINT_DELIMITER (check_ConfigSelector()); typedef Apply ListAllConfigs; typedef Filter::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);