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 >
|