![]() |
User Manual, Developers Guide and API Documentation |
![]() |
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
1.5.5