User Manual, Developers Guide and API Documentation

Registry.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_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

Generated on Sun May 27 03:31:38 2012 for openWNS by  doxygen 1.5.5