Menu

ConstantSizeList.h

Go to the documentation of this file.
00001 /*******************************************************************************
00002  *
00003  * Copyright (c) 2008-2010 Michael Schulze <mschulze@ivs.cs.uni-magdeburg.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  *    $Id$
00036  *
00037  ******************************************************************************/
00038 #ifndef __ConstantSizeList_h__
00039 #define __ConstantSizeList_h__
00040 
00041 #include <stdint.h>
00042 #include "object/Array.h"
00043 #include "object/Uninitialized.h"
00044 
00045 namespace object {
00046 
00069     template < typename T,
00070                unsigned int N,
00071                bool callDestructor = true >
00072     class ConstantSizeList {
00073 
00075             Array< Uninitialized<T>, N > content;
00076 
00078             enum {
00079                 used_space = (N / 8) + ((N % 8) ? 1 : 0)
00080             };
00081 
00085             uint8_t used[used_space];
00086 
00087         public:
00089             typedef T value_type;
00090 
00092             typedef T* pointer;
00093 
00095             typedef T& reference;
00096 
00098             struct ConstantSizeListIterator;
00099             typedef ConstantSizeListIterator iterator;
00100 
00101             ConstantSizeList () {
00102                 for (uint8_t i = 0;i < used_space;++i) {
00103                     used[i] = 0;
00104                 }
00105             }
00106 
00107             ~ConstantSizeList () {
00108                 if (callDestructor) {
00109                     iterator i = begin();
00110                     while (i != end()) {
00111                         delElement (&*i);
00112                         ++i;
00113                     }
00114                 }
00115             }
00116 
00117         public:
00119             iterator begin () {
00120                 return iterator(*this, getFirstElement());
00121             }
00122 
00124             iterator end () {
00125                 return iterator(*this, N);
00126             }
00127 
00129             class ConstantSizeListIterator {
00131                     ConstantSizeList&  _storage;
00133                     uint8_t _currentPos;
00134 
00135                 public:
00137                     typedef typename ConstantSizeList::value_type value_type;
00138 
00140                     typedef typename ConstantSizeList::pointer pointer;
00141 
00143                     typedef typename ConstantSizeList::reference reference;
00144 
00145                     ConstantSizeListIterator (ConstantSizeList& s, const uint8_t pos) :
00146                             _storage(s), _currentPos(pos) {
00147                     }
00148 
00149                     ConstantSizeListIterator operator = (const ConstantSizeListIterator& i) {
00150                         _storage = i._storage;
00151                         _currentPos = i._currentPos;
00152                         return ConstantSizeListIterator(_storage, _currentPos);
00153                     }
00154 
00159                     ConstantSizeListIterator operator ++ () {
00160                         _currentPos = _storage.getNextElement(_currentPos + 1);
00161                         return ConstantSizeListIterator(_storage, _currentPos);
00162                     }
00163 
00168                     ConstantSizeListIterator operator ++ (int) {
00169                         _currentPos = _storage.getNextElement(_currentPos + 1);
00170                         return ConstantSizeListIterator(_storage, _currentPos);
00171                     }
00172 
00177                     bool operator == (const ConstantSizeListIterator& i) const {
00178                         return _currentPos == i._currentPos;
00179                     }
00180 
00185                     bool operator != (const ConstantSizeListIterator& i) const {
00186                         return _currentPos != i._currentPos;
00187                     }
00188 
00194                     value_type& operator * () const {
00195                         return reinterpret_cast<value_type&>(_storage.content[_currentPos]);
00196                     }
00197 
00198             };
00199 
00201             void delElement (const T* value) {
00202                 for (uint8_t i = 0; i < N;++i)
00203                     if ( value == reinterpret_cast<T*>(&content[i]) ) {
00204                         reinterpret_cast<T*>(&content[i])->~T();
00205                         used[i/8] = used[i/8] & (~(0x80 >> (i % 8)));
00206                         return;
00207                     }
00208             }
00209 
00215             T* newElement () {
00216                 for (uint8_t i = 0;i < used_space;++i)
00217                     if ( used[i] != 0xff ) {
00218                         uint8_t mask = 0x80;
00219                         for (uint8_t j = 0;j < 8 ; ++j)
00220                             if (!(used[i] & mask)) {
00221                                 used[i] |= mask;
00222                                 return new(&content[(i*8+j)]) T();
00223                             } else
00224                                 mask >>= 1;
00225                     }
00226                 return 0;
00227             }
00228 
00229         private:
00230 
00235             uint8_t getFirstElement () {
00236                 return getNextElement(0);
00237             }
00238 
00246             uint8_t getNextElement (uint8_t t) {
00247                 uint8_t start = t % 8;
00248                 for (uint8_t i = t / 8;i < used_space;++i) {
00249                     if ( used[i] ) {
00250                         uint8_t mask = 0x80 >> start;
00251                         for (uint8_t j = start;j < 8 ; ++j) {
00252                             if ((used[i] & mask)) {
00253                                 return (i*8 + j);
00254                             } else {
00255                                 mask >>= 1;
00256                             }
00257                         }
00258                         start = 0;
00259                     }
00260                 }
00261                 return N;
00262             }
00263     };
00264 
00265 } /* namespace object */
00266 
00267 #endif
00268