![]() |
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_CONTAINER_REGISTRY_HPP 00029 #define WNS_CONTAINER_REGISTRY_HPP 00030 00031 #include <WNS/Assure.hpp> 00032 #include <WNS/TypeInfo.hpp> 00033 #include <WNS/Exception.hpp> 00034 00035 #include <map> 00036 #include <list> 00037 00038 namespace wns { namespace container { 00039 00043 namespace registry { 00047 class NoneOnErase 00048 { 00049 public: 00050 00051 template <typename ANY> 00052 void 00053 operator()(ANY&) const 00054 { 00055 } 00056 }; 00057 00063 class DeleteOnErase 00064 { 00065 public: 00066 00067 template <typename ANY> 00068 void 00069 operator()(ANY any) const 00070 { 00071 delete any; 00072 } 00073 }; 00074 } 00075 00104 template< 00105 typename KEY, 00106 typename ELEMENT, 00107 typename CLEANUPPOLICY = registry::NoneOnErase, 00108 typename SORTINGPOLICY = std::less<KEY> > 00109 class Registry: 00110 public IOutputStreamable 00111 { 00112 00116 typedef std::map<KEY, ELEMENT, SORTINGPOLICY> ElementContainer; 00117 typedef typename ElementContainer::iterator iterator; 00118 00119 public: 00120 typedef KEY KeyType; 00121 typedef ELEMENT ElementType; 00122 typedef std::list<KEY> KeyList; 00123 00127 class DuplicateKeyValue : 00128 public Exception 00129 { 00130 public: 00131 explicit 00132 DuplicateKeyValue(const KeyType& key) : 00133 Exception("Duplicate key in registry detected.\n") 00134 { 00135 (*this) << TypeInfo::create<ElementType>() 00136 << " with this key already registered.\n" 00137 << "Key: " << key; 00138 } 00139 00140 virtual 00141 ~DuplicateKeyValue() throw() 00142 { 00143 } 00144 }; 00145 00150 class UnknownKeyValue : 00151 public Exception 00152 { 00153 public: 00154 UnknownKeyValue(const KeyType& key, const Registry& reg) : 00155 Exception() 00156 { 00157 (*this) << "No " << TypeInfo::create<ElementType>() 00158 << " with this key registered.\n" 00159 << "Key: " << key << "\n" 00160 << reg; 00161 } 00162 00163 virtual 00164 ~UnknownKeyValue() throw() 00165 { 00166 } 00167 }; 00168 00172 typedef typename ElementContainer::const_iterator const_iterator; 00173 00177 Registry() : 00178 elements_() 00179 { 00180 } 00181 00187 virtual 00188 ~Registry() 00189 throw() 00190 { 00191 this->clear(); 00192 } 00193 00197 virtual void 00198 clear() 00199 { 00200 CLEANUPPOLICY cleanup; 00201 while (this->elements_.empty() == false) 00202 { 00203 cleanup(this->elements_.begin()->second); 00204 this->elements_.erase(this->elements_.begin()); 00205 } 00206 } 00207 00213 virtual void 00214 insert(const KeyType& key, ElementType element) 00215 throw(DuplicateKeyValue) 00216 { 00217 // Store size of map before potentially adding 00218 size_t sizeBeforeInserting = this->size(); 00219 // This should add an element, if not the key was 00220 // already used 00221 ElementType& slotInContainer = this->elements_[key]; 00222 // Store size of map after potentially adding 00223 size_t sizeAfterInserting = this->size(); 00224 00225 if (sizeAfterInserting - sizeBeforeInserting == 0) 00226 { 00227 // The key was already in use 00228 throw DuplicateKeyValue(key); 00229 } 00230 slotInContainer = element; 00231 } 00232 00233 00243 virtual void 00244 update(const KeyType& key, ElementType element) 00245 throw(UnknownKeyValue) 00246 { 00247 iterator itr = this->elements_.find(key); 00248 if (itr == this->elements_.end()) 00249 { 00250 throw UnknownKeyValue(key, *this); 00251 } 00252 CLEANUPPOLICY cleanup; 00253 cleanup(itr->second); 00254 itr->second = element; 00255 00256 } 00257 00269 virtual void 00270 erase(const KeyType& key) 00271 throw(UnknownKeyValue) 00272 { 00273 iterator itr = this->elements_.find(key); 00274 if (itr == this->elements_.end()) 00275 { 00276 throw UnknownKeyValue(key,*this); 00277 } 00278 00279 CLEANUPPOLICY cleanup; 00280 cleanup(itr->second); 00281 this->elements_.erase(itr); 00282 } 00283 00294 virtual const ElementType& 00295 find(const KeyType& key) const 00296 throw(UnknownKeyValue) 00297 { 00298 const_iterator itr = this->elements_.find(key); 00299 if (itr == this->elements_.end()) 00300 { 00301 throw UnknownKeyValue(key, *this); 00302 } 00303 return itr->second; 00304 } 00305 00316 virtual ElementType& 00317 find(const KeyType& key) 00318 throw(UnknownKeyValue) 00319 { 00320 iterator itr = this->elements_.find(key); 00321 if (itr == this->elements_.end()) 00322 { 00323 throw UnknownKeyValue(key, *this); 00324 } 00325 return itr->second; 00326 } 00327 00331 virtual const_iterator 00332 begin() const 00333 throw() 00334 { 00335 return this->elements_.begin(); 00336 } 00337 00341 virtual const_iterator 00342 end() const 00343 throw() 00344 { 00345 return this->elements_.end(); 00346 } 00347 00351 virtual bool 00352 knows(const KeyType& key) const 00353 throw() 00354 { 00355 return this->elements_.find(key) != elements_.end(); 00356 } 00357 00361 virtual bool 00362 empty() const 00363 throw() 00364 { 00365 return this->elements_.empty(); 00366 } 00367 00371 virtual size_t 00372 size() const 00373 throw() 00374 { 00375 return this->elements_.size(); 00376 } 00377 00381 virtual KeyList 00382 keys() const 00383 throw() 00384 { 00385 KeyList retVal; 00386 for (const_iterator iter = begin(); iter != end(); ++iter) 00387 { 00388 retVal.push_back(iter->first); 00389 } 00390 return retVal; 00391 } 00392 00393 private: 00394 std::string 00395 doToString() const 00396 { 00397 std::stringstream repr; 00398 00399 repr << "Elements with the following keys are registered:\n"; 00400 00401 for (typename Registry::const_iterator itr = elements_.begin(); 00402 itr != elements_.end(); 00403 ++itr) 00404 { 00405 repr << " - " << itr->first << "\n"; 00406 } 00407 00408 return repr.str(); 00409 } 00410 00414 ElementContainer elements_; 00415 }; // Registry 00416 } // container 00417 } // wns 00418 00419 #endif // NOT defined WNS_REGISTRY_HPP
1.5.5