Menu

PointerMap.h

Go to the documentation of this file.
00001 /*******************************************************************************
00002  *
00003  * Copyright (c) 2010 Philipp Werner <philipp.werner@st.ovgu.de>
00004  * All rights reserved.
00005  *
00006  *    Redistribution and use in source and binary forms, with or without
00007  *    modification, are permitted provided that the following conditions
00008  *    are met:
00009  *
00010  *    * Redistributions of source code must retain the above copyright
00011  *      notice, this list of conditions and the following disclaimer.
00012  *
00013  *    * Redistributions in binary form must reproduce the above copyright
00014  *      notice, this list of conditions and the following disclaimer in
00015  *      the documentation and/or other materials provided with the
00016  *      distribution.
00017  *
00018  *    * Neither the name of the copyright holders nor the names of
00019  *      contributors may be used to endorse or promote products derived
00020  *      from this software without specific prior written permission.
00021  *
00022  *
00023  *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
00024  *    IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00025  *    TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00026  *    PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00027  *    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00028  *    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00029  *    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00030  *    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00031  *    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00032  *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00033  *    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034  *
00035  *
00036  * $Id$
00037  *
00038  ******************************************************************************/
00039 
00040 #ifndef __POINTERMAP_H_8DCAB52FEC8A52__
00041 #define __POINTERMAP_H_8DCAB52FEC8A52__
00042 
00043 #include "mw/afp/Config.h"
00044 #include <string.h>
00045 #if !defined(__NO_STL__)
00046 #include <map>
00047 #else
00048 #include "assert/staticerror.h"
00049 #endif
00050 
00051 
00052 namespace famouso {
00053     namespace mw {
00054         namespace afp {
00055             namespace defrag {
00056                 namespace detail {
00057 
00069                     template <class KeyT, class ItemT, unsigned int N>
00070                     class PointerMap {
00072                             ItemT * array[N];
00073 
00075                             ItemT ** get_next(ItemT ** i) {
00076                                 while (i != &array[N] && *i == 0) {
00077                                     i++;
00078                                 }
00079                                 return i;
00080                             }
00081 
00082                         public:
00083 
00085                             class iterator {
00086                                     PointerMap & pm;
00087                                     ItemT ** item;
00088                                 public:
00089                                     iterator(PointerMap & pm, ItemT ** item) :
00090                                             pm(pm), item(item) {
00091                                     }
00092 
00093                                     iterator operator = (const iterator & i) {
00094                                         pm = i.pm;
00095                                         item = i.item;
00096                                         return iterator(pm, item);
00097                                     }
00098 
00100                                     iterator & operator ++ () {
00101                                         item = pm.get_next(item + 1);
00102                                         return *this;
00103                                     }
00104 
00106                                     iterator operator ++ (int) {
00107                                         ItemT ** old = item;
00108                                         item = pm.get_next(item + 1);
00109                                         return iterator(pm, old);
00110                                     }
00111 
00113                                     bool operator == (const iterator& i) const {
00114                                         return item == i.item;
00115                                     }
00116 
00118                                     bool operator != (const iterator& i) const {
00119                                         return item != i.item;
00120                                     }
00121 
00123                                     ItemT *& operator * () {
00124                                         return *item;
00125                                     }
00126                             };
00127 
00129                             PointerMap() {
00130                                 memset(array, 0, sizeof(array));
00131                             }
00132 
00138                             bool insert(ItemT * item) {
00139                                 for (ItemT ** i = array; i != array + N; i++) {
00140                                     if (*i == 0) {
00141                                         *i = item;
00142                                         return true;
00143                                     }
00144                                 }
00145                                 return false;
00146                             }
00147 
00152                             void erase(iterator it) {
00153                                 *it = 0;
00154                             }
00155 
00160                             void erase(const KeyT & key) {
00161                                 ItemT ** end = array + N;
00162                                 for (ItemT ** i = array; i != end; i++) {
00163                                     if (*i != 0 && key == (*i)->get_key()) {
00164                                         *i = 0;
00165                                         return;
00166                                     }
00167                                 }
00168                             }
00169 
00176                             iterator find(const KeyT & key) {
00177                                 ItemT ** end = array + N;
00178                                 for (ItemT ** i = array; i != end; i++) {
00179                                     if (*i != 0 && key == (*i)->get_key()) {
00180                                         return iterator(*this, i);
00181                                     }
00182                                 }
00183                                 return this->end();
00184                             }
00185 
00187                             iterator begin() {
00188                                 return iterator(*this, get_next(&array[0]));
00189                             }
00190 
00192                             iterator end() {
00193                                 return iterator(*this, &array[N]);
00194                             }
00195                     };
00196 
00197 
00198 
00199 #if !defined(__NO_STL__)
00200 
00210                     template <class KeyT, class ItemT>
00211                     class PointerMap<KeyT, ItemT, dynamic> : private std::map<KeyT, ItemT *> {
00212 
00213                             typedef std::map<KeyT, ItemT *> Base;
00214 
00215                         public:
00216 
00218                             class iterator {
00219                                 public:
00220                                     typename Base::iterator it;
00221 
00222                                     iterator(const typename Base::iterator & it) :
00223                                             it(it) {
00224                                     }
00225 
00226                                     iterator operator = (const iterator & i) {
00227                                         it = i.it;
00228                                         return iterator(it);
00229                                     }
00230 
00232                                     iterator & operator ++ () {
00233                                         ++it;
00234                                         return *this;
00235                                     }
00236 
00238                                     iterator operator ++ (int) {
00239                                         typename Base::iterator old = it;
00240                                         ++it;
00241                                         return iterator(old);
00242                                     }
00243 
00245                                     bool operator == (const iterator& i) const {
00246                                         return it == i.it;
00247                                     }
00248 
00250                                     bool operator != (const iterator& i) const {
00251                                         return it != i.it;
00252                                     }
00253 
00255                                     ItemT *& operator * () {
00256                                         return it->second;
00257                                     }
00258                             };
00259 
00265                             bool insert(ItemT * item) {
00266                                 std::pair<iterator, bool> res = Base::insert(typename Base::value_type(item->get_key(), item));
00267                                 return res.second;
00268                             }
00269 
00274                             void erase(iterator it) {
00275                                 Base::erase(it.it);
00276                             }
00277 
00282                             void erase(const KeyT & key) {
00283                                 Base::erase(key);
00284                             }
00285 
00292                             iterator find(const KeyT & key) {
00293                                 return Base::find(key);
00294                             }
00295 
00297                             iterator begin() {
00298                                 return iterator(Base::begin());
00299                             }
00300 
00302                             iterator end() {
00303                                 return iterator(Base::end());
00304                             }
00305                     };
00306 
00307 #else
00308 
00309                     template <class KeyT, class ItemT>
00310                     class PointerMap<KeyT, ItemT, dynamic> {
00311                         FAMOUSO_STATIC_ASSERT_ERROR(false, dynamic_PointerMap_not_supported_on_this_platform, ());
00312                     };
00313 
00314 #endif
00315 
00316                 } // namespace detail
00317             } // namespace defrag
00318         } // namespace afp
00319     } // namespace mw
00320 } // namespace famouso
00321 
00322 
00323 #endif // __POINTERMAP_H_8DCAB52FEC8A52__
00324