pluginiter.h

Go to the documentation of this file.
00001 /**********************************************************************
00002 pluginiter.h - facilitates construction of plugin classes
00003  
00004 Copyright (C) 2006 by Chris Morley
00005  
00006 This file is part of the Open Babel project.
00007 For more information, see <http://openbabel.sourceforge.net/>
00008  
00009 This program is free software; you can redistribute it and/or modify
00010 it under the terms of the GNU General Public License as published by
00011 the Free Software Foundation version 2 of the License.
00012  
00013 This program is distributed in the hope that it will be useful, but
00014 WITHOUT ANY WARRANTY; without even the implied warranty of
00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016 General Public License for more details.
00017 ***********************************************************************/
00018 
00019 #ifndef OB_PLUGINITER_H
00020 #define OB_PLUGINITER_H
00021 
00022 #include <openbabel/babelconfig.h>
00023 
00024 namespace OpenBabel
00025 {
00026 
00030 template<typename T>
00031 class OBAPI PluginIter
00032 {
00033 private:
00034   typedef std::map<const std::string, T*> Maptype;
00035   Maptype _map;
00036   typename Maptype::iterator _itr;
00037   T* _default;
00038 
00039 public:
00043   void Register(T* pType, const std::string ID, bool IsDefault)
00044   {
00045     _map[ID] = pType;
00046     if(IsDefault || _map.empty())
00047       _default=pType;
00048   }
00049 
00052   T* FindType(const std::string& ID)
00053   {
00054     if(ID.empty())
00055       return _default;
00056     _itr = _map.find(ID);
00057     if(_itr==_map.end())
00058       return NULL;
00059     else
00060       return _itr->second;
00061   }
00062 
00064   T* FindDefaultType() const { return _default; }
00065 
00067   std::string ID() const { return _itr->first; }
00068   
00069 
00070 //The following function and operator* cause an linking error with SWIG,
00071 //perhaps because they are not used in the C++ code and, being templated,
00072 //are consequently not generated by the compiler. Temporarily they have been
00073 //commented out.
00074 
00076 //  std::string Description() const { return _itr->second->Description(); }
00077 
00079 
00080 
00082   void ToStart() { _itr = _map.begin(); }
00083   
00086   PluginIter& operator++()
00087   {
00088     ++_itr;
00089     return *this;
00090   }
00092   operator bool() const { return _itr != _map.end(); }
00094   T* operator->() const   { return _itr->second;  }
00096 //  T& operator*() const    { return *(_itr->second); }
00098 };
00099 
00100 //Macro to iterate over all sub-types
00101 #define FOR_EACH(plugintype, f)  for(PluginIter<plugintype>& f=plugintype::Iter(); f; ++f )
00102 
00103 //Macro to be added to definition of the base class
00104 #define MAKE_PLUGIN(BaseClass)\
00105 public:\
00106 BaseClass(std::string ID, bool IsDefault=false)\
00107 {Iter().Register(this, ID, IsDefault);}\
00108 static PluginIter<BaseClass>& Iter()\
00109 {static PluginIter<BaseClass>* p = NULL;\
00110 if(!p) p = new PluginIter<BaseClass>;\
00111 p->ToStart();\
00112 return *p;}\
00113 static BaseClass* FindDefaultType(){ return Iter().FindDefaultType();}\
00114   static BaseClass* FindType(const std::string& ID){ return Iter().FindType(ID);}
00115 
00116 } //namespace
00117 #endif //OB_PLUGINITER_H
00118