User Manual, Developers Guide and API Documentation

StaticFactory.hpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002  * This file is part of openWNS (open Wireless Network Simulator)
00003  * _____________________________________________________________________________
00004  *
00005  * Copyright (C) 2004-2007
00006  * Chair of Communication Networks (ComNets)
00007  * Kopernikusstr. 16, D-52074 Aachen, Germany
00008  * phone: ++49-241-80-27910,
00009  * fax: ++49-241-80-22242
00010  * email: info@openwns.org
00011  * www: http://www.openwns.org
00012  * _____________________________________________________________________________
00013  *
00014  * openWNS is free software; you can redistribute it and/or modify it under the
00015  * terms of the GNU Lesser General Public License version 2 as published by the
00016  * Free Software Foundation;
00017  *
00018  * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY
00019  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
00020  * A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00021  * details.
00022  *
00023  * You should have received a copy of the GNU Lesser General Public License
00024  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00025  *
00026  ******************************************************************************/
00027 
00028 #ifndef WNS_STATICFACTORY_HPP
00029 #define WNS_STATICFACTORY_HPP
00030 
00031 #include <WNS/Exception.hpp>
00032 #include <WNS/TypeInfo.hpp>
00033 
00034 #include <sstream>
00035 #include <string>
00036 
00037 #include <map>
00038 #include <vector>
00039 
00040 namespace wns {
00137     template <typename CREATOR>
00138     class StaticFactory {
00139     public:
00140 
00147         static void reg(std::string name, CREATOR* creator);
00148         typedef void (*RegisterFunction)(std::string name, CREATOR* creator);
00149 
00156         static CREATOR* creator(std::string name);
00157 
00162         static bool knows(std::string name);
00163 
00169         typedef std::map<std::string, CREATOR*> CreateMap;
00170 
00176         static CreateMap* getMap();
00177     };
00178 
00179 
00180     template <typename CREATOR>
00181     typename StaticFactory<CREATOR>::CreateMap*
00182     StaticFactory<CREATOR>::getMap()
00183     {
00184         static CreateMap plugins = CreateMap();
00185 
00186         return &plugins;
00187     } // getMap
00188 
00189 
00190     template <typename CREATOR>
00191     CREATOR*
00192     StaticFactory<CREATOR>::creator(std::string name)
00193     {
00194         if(getMap()->find(name) == getMap()->end()) {
00195             std::stringstream ss;
00196             ss << "StaticFactory<" << wns::TypeInfo::create<CREATOR>() << "> says:\n"
00197                << "You tried to create a '" << name << "' instance.\n"
00198                << "Valid choices are:\n\n";
00199             for(typename CreateMap::iterator i = getMap()->begin();
00200                 i != getMap()->end();
00201                 ++i) {
00202                 ss << "  * " << i->first << std::endl;
00203             }
00204             throw Exception(ss.str().c_str());
00205         }
00206 
00207         return (*getMap())[name];
00208     } // create
00209 
00210 
00211     template <typename CREATOR>
00212     void
00213     StaticFactory<CREATOR>::reg(std::string name, CREATOR* creator)
00214     {
00215         if(StaticFactory<CREATOR>::knows(name)) {
00216             Exception e;
00217             e << "there is already a plugin registered with name '"
00218               << name << "', what is probably not what you want.";
00219             throw e;
00220         }
00221 
00222         (*getMap())[name] = creator;
00223     } // reg
00224 
00225 
00226     template <typename CREATOR>
00227     bool
00228     StaticFactory<CREATOR>::knows(std::string name)
00229     {
00230         return getMap()->count(name) == 1;
00231     } // knows
00232 
00233 
00254     template <typename T, typename KIND = T>
00255     class Creator :
00256         public Creator<KIND, KIND>
00257     {
00258     public:
00259         virtual KIND* create()
00260         {
00261             return new T;
00262         }
00263     };
00264 
00265 
00266     template <typename KIND>
00267     class Creator<KIND, KIND>
00268     {
00269     public:
00270         virtual KIND* create() = 0;
00271 
00272         virtual ~Creator()
00273         {};
00274     };
00275 
00276 
00282     template <typename T, typename KIND,
00283           template <typename, typename> class CREATOR = Creator >
00284     class StaticFactoryRegister :
00285         public CREATOR<T, KIND>
00286     {
00287     public:
00288         StaticFactoryRegister(std::string name)
00289         {
00290             StaticFactory<CREATOR<KIND, KIND> >::reg(name, this);
00291         }
00292     };
00293 
00294 // this was taken from cppunit
00295 #define STATIC_FACTORY_JOIN(SYMBOL1, SYMBOL2) STATIC_FACTORY_DO_JOIN(SYMBOL1, SYMBOL2)
00296 #define STATIC_FACTORY_DO_JOIN(SYMBOL1, SYMBOL2) STATIC_FACTORY_DO_JOIN2(SYMBOL1, SYMBOL2)
00297 #define STATIC_FACTORY_DO_JOIN2(SYMBOL1, SYMBOL2) SYMBOL1##SYMBOL2
00298 
00299 #define STATIC_FACTORY_UNIQUE_NAME(PREFIX) \
00300     STATIC_FACTORY_JOIN(PREFIX,__LINE__)
00301 
00302 
00315 #define STATIC_FACTORY_REGISTER(CLASS, INTERFACE, NAME) \
00316     namespace { \
00317     static wns::StaticFactoryRegister<CLASS, INTERFACE> STATIC_FACTORY_UNIQUE_NAME(_)(NAME); \
00318     } \
00319     class StaticFactoryRegisterDummy
00320 
00333 #define STATIC_FACTORY_REGISTER_WITH_CREATOR(CLASS, INTERFACE, NAME, CREATOR) \
00334     namespace { \
00335     static wns::StaticFactoryRegister<CLASS, INTERFACE, CREATOR> STATIC_FACTORY_UNIQUE_NAME(_)(NAME); \
00336     } \
00337     class StaticFactoryRegisterDummy
00338 }
00339 
00340 #endif // NOT defined WNS_STATICFACTORY_HPP
00341 
00342 #define STATIC_FACTORY_DEFINE(INTERFACE, CREATOR) \
00343     typedef CREATOR<INTERFACE> INTERFACE ## Creator;\
00344     typedef wns::StaticFactory<INTERFACE ## Creator> INTERFACE ## Factory;
00345 
00346 #define STATIC_FACTORY_NEW_INSTANCE(INTERFACE, CREATOR, VIEW, ARGS...) \
00347     wns::StaticFactory< CREATOR<INTERFACE> >::creator(VIEW.get<std::string>("nameInStaticFactory"))->create(ARGS)
00348 

Generated on Sat May 26 03:31:53 2012 for openWNS by  doxygen 1.5.5