From: stephan b. <sg...@us...> - 2004-12-26 06:02:00
|
Update of /cvsroot/pclasses/pclasses2/include/pclasses In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17821/include/pclasses Modified Files: Factory.h Log Message: Added factory aliasing support. Allows mapping multiple names to one factory. Index: Factory.h =================================================================== RCS file: /cvsroot/pclasses/pclasses2/include/pclasses/Factory.h,v retrieving revision 1.11 retrieving revision 1.12 diff -u -d -r1.11 -r1.12 --- Factory.h 25 Dec 2004 19:56:39 -0000 1.11 +++ Factory.h 26 Dec 2004 06:01:52 -0000 1.12 @@ -198,6 +198,7 @@ typedef InterfaceT * ResultType; + /** A typedef for the KeyType used by this class. */ @@ -206,6 +207,68 @@ /** Same as ContextType */ typedef ContextT ContextType; + typedef std::map<key_type,key_type> AliasMap; + + /** + Returns the map of classname aliases. + */ + AliasMap & aliases() + { + return m_alias; + } + + /** + Returns the map of classname aliases. + */ + const AliasMap & aliases() const + { + return m_alias; + } + + /** + Aliases 'alias' as an equivalent of 'isthesameas'. + + This can be used to register multiple named via a + single factory. + */ + void alias( const key_type & alias, const key_type & isthesameas ) + { + this->aliases()[alias] = isthesameas; + } + + /** + Expands the given alias recursively. If a recursive alias is detected, + the last expansion is returned - i.e., the same as _alias. + */ + key_type expandAliases( const key_type & _alias ) const + { + //CERR << "expandAlias("<<_alias<<")\n"; + typename AliasMap::const_iterator cit = this->aliases().find( _alias ), + cet = this->aliases().end(); + if( cet == cit ) + { + //CERR << "No alias found for "<<_alias<<"\n"; + return _alias; + } + key_type exp = (*cit).second; + while( cit != cet ) + { + cit = this->aliases().find( exp ); + if( cet == cit ) + { + // CERR << "Returning '"<<_alias<<"' unaliased: " << exp<<"\n"; + return exp; + } + exp = (*cit).second; + if( exp == _alias ) + { // circular aliasing + // CERR << "Warning: circular alias '"<<_alias<<"'."; + return exp; + } + } + return exp; + } + /** Convenience typedef. */ @@ -238,8 +301,9 @@ Subtypes are free to implement, e.g., DLL lookups. */ - virtual ResultType create( const key_type & key ) + virtual ResultType create( const key_type & _key ) { + key_type key = this->expandAliases( _key ); typename FactoryMap::const_iterator it = factoryMap().find( key ); if ( it != factoryMap().end() ) // found a factory? { @@ -286,7 +350,7 @@ */ virtual void registerFactory( const key_type & key, FactoryFuncType fp ) { - // CERR << "registerFactory("<<key<<",facfunc)\n"; + //CERR << "registerFactory("<<key<<",facfunc)\n"; factoryMap().insert( FactoryMap::value_type( key, fp ) ); } @@ -329,6 +393,9 @@ return Hook::FactoryInstanceHook<ThisType>::instance(); } + + private: + AliasMap m_alias; }; // class Factory @@ -338,6 +405,9 @@ expected that this will be the most-used factory implementation, as non-string-keyed factories are rare in practice (but sometimes very useful). + + A note to doxygen users: for some reason the parent class + isn't showing up via doxygen. :/ See Factory<InterfaceT>. */ template <typename InterfaceT> struct NamedTypeFactory : public Factory< InterfaceT, Sharing::FactoryContext, std::string > |