sharelib/sharelib.h

Go to the documentation of this file.
00001 #ifndef SHARELIB_H
00002 #define SHARELIB_H
00003 
00013 #ifdef _WIN32
00014   // Export symbols to .dll while using MS C++ compiler
00015 # define SHARE_EXPORT __declspec(dllexport)
00016 #else
00017   // There is no need to declare export on Linux
00018 # define SHARE_EXPORT
00019 #endif
00020 
00021 #include <new>            // Import std::bad_alloc exception
00022 #include <memory>         // Import std::allocator
00023 #include <iterator>       // Import std::random_access_iterator_tag
00024 #include <functional>
00025 #include <stddef.h>       // Import base set of system types (like size_t, ptrdiff_t, ...)
00026 
00031 namespace Share {
00035   template <bool> struct ERROR_CTAssert_failed__Unexpected_sizeof_char;
00039   template <> struct ERROR_CTAssert_failed__Unexpected_sizeof_char<true> { };
00040 
00045   class ShareException: public std::bad_alloc {
00046     public:
00051       SHARE_EXPORT ShareException (const char *message);
00052 
00056       SHARE_EXPORT ~ShareException () throw ();
00057 
00061       SHARE_EXPORT ShareException (const ShareException &);
00062 
00066       SHARE_EXPORT const char* message() const;
00067 
00068     private:
00069       void operator= (const ShareException &);
00070       char *message_;
00071   };
00072 
00079   class Relocator {
00080     public:
00081       typedef void* absolute_pointer;                 
00082       typedef const void* absolute_const_pointer;     
00083       typedef size_t relative_pointer;                
00084       typedef const size_t relative_const_pointer;    
00085 
00092       static relative_pointer absToRel (absolute_pointer abs, absolute_pointer base) {
00093         ERROR_CTAssert_failed__Unexpected_sizeof_char<sizeof(char)==1>();
00094         return
00095           (abs) ?
00096           static_cast<char *> (abs) - static_cast<char *> (base) :
00097           0;
00098        }
00099 
00104       static relative_const_pointer absToRel (absolute_const_pointer abs, absolute_pointer base) {
00105         return absToRel (const_cast<absolute_pointer>(abs), base);
00106       }
00107 
00114       static absolute_pointer relToAbs (relative_pointer rel, absolute_pointer base) {
00115         ERROR_CTAssert_failed__Unexpected_sizeof_char<sizeof(char)==1>();
00116         return
00117           (rel) ?
00118           static_cast<char *> (base) + rel :
00119           0;
00120       }
00121 
00122     private:
00126       Relocator ();
00127   };
00128 
00135   template <class T> struct TReference {
00136     typedef T& reference;                       
00137     typedef const T& const_reference;           
00138   };
00139 
00143   template <> struct TReference<void> {
00144     typedef void reference;                     
00145     typedef void const_reference;               
00146   };
00147 
00151   template <> struct TReference<const void> {
00152     typedef void reference;                     
00153     typedef void const_reference;               
00154   };
00155 
00162   template <class T> struct TVoidPointer {
00163     typedef void* void_pointer;                 
00164     typedef const void* const_void_pointer;     
00165   };
00166 
00170   template <class T> struct TVoidPointer<const T> {
00171     typedef const void* void_pointer;           
00172     typedef const void* const_void_pointer;     
00173   };
00174 
00175   class SharedSegment;          // Platform-independent shared segment representation
00176   class SegmentHeader;          // Object placed at begin of each shared segment
00177 
00184   class ShareManager {
00185     public:
00186       typedef Relocator::relative_pointer relative_pointer;               
00187       typedef Relocator::relative_const_pointer relative_const_pointer;   
00188 
00194       SHARE_EXPORT static ShareManager* instance();
00195 
00200       SHARE_EXPORT static void destroySelf();
00201 
00209       SHARE_EXPORT void createSegment (const char *name, size_t size) throw (ShareException);
00210 
00218       SHARE_EXPORT void attachSegment (const char *name) throw (ShareException);
00219 
00224       SHARE_EXPORT void detachSegment () throw ();
00225 
00232       SHARE_EXPORT void unlinkSegment () throw ();
00233 
00238       SHARE_EXPORT const char* name ();
00239 
00245       relative_pointer absToRel (void *abs) {
00246         return Relocator::absToRel (abs, atAddr_);
00247       }
00248 
00252       relative_const_pointer absToRel (const void *abs) {
00253         return Relocator::absToRel (abs, atAddr_);
00254       }
00255 
00259       template <class T> relative_pointer absToRel (T *abs) {
00260         typedef typename TVoidPointer<T>::void_pointer void_pointer;
00261         return absToRel(static_cast<void_pointer> (abs));
00262       }
00263 
00269       void* relToAbs (relative_pointer rel) {
00270         return Relocator::relToAbs (rel, atAddr_);
00271       }
00272 
00279       SHARE_EXPORT void* alloc (size_t size) throw (ShareException);
00280 
00286       void* alloc (size_t size, size_t count) throw (ShareException) {
00287         return this-> alloc (size * count);
00288       }
00289 
00295       SHARE_EXPORT void free (void *addr) throw ();
00296 
00301       void free (void *addr, size_t) throw () {
00302         this-> free (addr);
00303       }
00304 
00308       SHARE_EXPORT size_t available ();
00309 
00310     protected:
00316       SHARE_EXPORT void initDebugMode (SharedSegment *segment);
00317 
00322       SHARE_EXPORT void destroySegment ();
00323 
00327       friend class SharedSegmentWrapper;
00328 
00329     private:
00330       static ShareManager *instance_;                   
00331       SharedSegment *segment_;                          
00332       SegmentHeader *atAddr_;                           
00333 
00334     private:
00335       ShareManager ();
00336       ~ShareManager ();
00337       ShareManager (const ShareManager&);               
00338       ShareManager& operator= (const ShareManager&);    
00339   };
00340 
00346   class SharedObject {
00347   public:
00352     static void* operator new (size_t size) throw (ShareException)
00353     {
00354       return alloc(size);
00355     }
00356 
00361     static void* operator new[] (size_t size) throw (ShareException)
00362     {
00363       return alloc(size);
00364     }
00365 
00369     static void operator delete (void *addr, size_t) throw ()
00370     {
00371       free (addr);
00372     }
00373 
00377     static void operator delete[] (void *addr, size_t) throw()
00378     {
00379       free (addr);
00380     }
00381 
00388     static void* alloc (size_t size) throw (ShareException)
00389     {
00390       return ShareManager::instance()-> alloc (size);
00391     }
00392 
00398     static void* alloc (size_t size, size_t count) throw (ShareException) {
00399       return alloc (size * count);
00400     }
00401 
00407     static void free (void *addr) throw ()
00408     {
00409       ShareManager::instance()-> free (addr);
00410     }
00411 
00412   protected:
00413     SharedObject () { }           
00414     ~SharedObject () { }          
00415   };
00416 
00422   template <class T> class RelocPtr: public SharedObject {
00423     public:
00424       typedef T value_type;
00425       typedef size_t size_type;
00426       typedef ptrdiff_t difference_type;
00427       typedef T* pointer;
00428       typedef const T* const_pointer;
00429       typedef typename TVoidPointer<T>::void_pointer void_pointer;                  
00430       typedef typename TVoidPointer<T>::const_void_pointer const_void_pointer;      
00431       typedef typename TReference<T>::reference reference;                          
00432       typedef typename TReference<T>::const_reference const_reference;              
00433       typedef typename Relocator::relative_pointer relative_pointer;                
00434       typedef typename Relocator::relative_const_pointer relative_const_pointer;    
00435 
00439       typedef std::random_access_iterator_tag iterator_category;
00440 
00444       RelocPtr ():
00445         rel_ (0)
00446       {
00447       }
00448 
00453       RelocPtr (void_pointer abs):
00454         rel_ (ShareManager::instance()-> absToRel (abs))
00455       {
00456       }
00457 
00463       RelocPtr (void_pointer abs, void *base):
00464         rel_ (Relocator::absToRel (abs, base))
00465       {
00466       }
00467 
00471       RelocPtr (const RelocPtr &src):
00472         SharedObject(),
00473         rel_ (src.rel_)
00474       {
00475       }
00476 
00480       RelocPtr& operator= (const RelocPtr &src) {
00481         rel_= src.rel_;
00482         return *this;
00483       }
00484 
00488       RelocPtr& operator= (void_pointer abs) {
00489         rel_= ShareManager::instance()-> absToRel (abs);
00490         return *this;
00491       }
00492 
00497       pointer operator-> () const {
00498         return static_cast <T *> (ShareManager::instance()-> relToAbs (rel_));
00499       }
00500 
00506       operator pointer () const {
00507         return operator-> ();
00508       }
00509 
00514       reference operator[] (size_type i) {
00515         RelocPtr<T> tmp (*this);
00516         tmp+= i;
00517         return *(tmp.operator->());
00518       }
00519 
00523       relative_pointer toRel () const {
00524         return rel_;
00525       }
00526 
00530       static RelocPtr<T> fromRel (relative_pointer rel) {
00531         RelocPtr<T> tmp;
00532         tmp.rel_= rel;
00533         return tmp;
00534       }
00535 
00539       RelocPtr& operator++ () {
00540         rel_+= sizeof(T);
00541         return *this;
00542       }
00546       RelocPtr& operator-- () {
00547         rel_-= sizeof(T);
00548         return *this;
00549       }
00550 
00554       RelocPtr& operator+= (difference_type count) {
00555         rel_+= count * sizeof(T);
00556         return *this;
00557       }
00558 
00562       RelocPtr& operator-= (difference_type count) {
00563         rel_-= count * sizeof(T);
00564         return *this;
00565       }
00566 
00567     private:
00568       relative_pointer rel_;   
00569   };
00570 
00574   template <class T> RelocPtr<T> operator++ (RelocPtr<T> &ptr, int)
00575   {
00576     RelocPtr<T> tmp(ptr);
00577     ++ptr;
00578     return tmp;
00579   }
00580 
00584   template <class T> RelocPtr<T> operator-- (RelocPtr<T> &ptr, int)
00585   {
00586     RelocPtr<T> tmp(ptr);
00587     --ptr;
00588     return tmp;
00589   }
00590 
00594   template <class T> ptrdiff_t operator- (RelocPtr<T> &a, RelocPtr<T> &b)
00595   {
00596     return (a.toRel()-b.toRel())/sizeof(T);
00597   }
00598 
00602   template <class T> RelocPtr<T> operator+ (RelocPtr<T> ptr, ptrdiff_t diff)
00603   {
00604     ptr+= diff;
00605     return ptr;
00606   }
00607 
00611   template <class T> RelocPtr<T> operator- (RelocPtr<T> ptr, ptrdiff_t diff)
00612   {
00613     ptr-= diff;
00614     return ptr;
00615   }
00616 
00623   template <class T> class Allocator {
00624     public:
00625       typedef T value_type;
00626       typedef size_t size_type;
00627       typedef ptrdiff_t difference_type;
00628       typedef RelocPtr<T> pointer;                
00629       typedef RelocPtr<const T> const_pointer;    
00630       typedef T& reference;
00631       typedef const T& const_reference;
00632 
00636       Allocator() throw() { }
00637 
00641       ~Allocator() throw() { }
00642 
00646       template <class U> Allocator (const Allocator<U>&) throw() { }
00647 
00652       template <class U>
00653       struct rebind {
00654         typedef Allocator<U> other;
00655       };
00656 
00661       pointer address (reference obj) const {
00662         return &obj;
00663       }
00664 
00669       const_pointer address (const_reference obj) const {
00670         return &obj;
00671       }
00672 
00678       pointer allocate (size_type count) {
00679         return pointer (static_cast<T*>(ShareManager::instance()-> alloc (sizeof(T), count)));
00680       }
00681 
00688       void deallocate (pointer addr, size_type count) {
00689         ShareManager::instance()-> free (addr, count);
00690       }
00691 
00692       void construct (pointer p, const T& val) {
00693         ::new(p) T(val);
00694       }
00695 
00696       void destroy (pointer p) {
00697         p->~T();
00698       }
00699 
00700       size_type max_size () const throw() {
00701         return 
00702           (ShareManager::instance()-> available())
00703           /sizeof(T);
00704       }
00705   };
00706   template <class T1, class T2> bool operator== (const Allocator<T1>&, const Allocator<T2>&) throw() { return true; }
00707   template <class T1, class T2> bool operator!= (const Allocator<T1>&, const Allocator<T2>&) throw() { return false; }
00708 
00709   // Patch for Microsoft C++ compiler
00710 #ifdef _WIN32
00711   template <> void Allocator<char>::destroy(Allocator<char>::pointer) { }
00712 #endif // _WIN32
00713 
00721   template <
00722     class TItem,
00723     class TAllocator = std::allocator<TItem>
00724     >
00725   class Vector {
00729       static const size_t allocBase2Exp = 4;
00730 
00734       static const size_t allocDownFactor2Exp = 2;
00735 
00736       typedef typename TAllocator::size_type size_type;
00737       typedef typename TAllocator::difference_type difference_type;
00738       typedef typename TAllocator::pointer pointer;
00739       typedef typename TAllocator::const_pointer const_pointer;
00740       typedef typename TAllocator::reference reference;
00741       typedef typename TAllocator::const_reference const_reference;
00742 
00743     public:
00744       typedef pointer iterator;                   
00745       typedef const_pointer const_iterator;       
00746 
00750       Vector():
00751         size_ (0),
00752         capacity_ (0),
00753         data_ (0)
00754       {
00755         lowLevelResize(0);
00756       }
00757 
00758       Vector (size_type size):
00759         size_ (0),
00760         capacity_ (0),
00761         data_ (0)
00762       {
00763         lowLevelResize(size);
00764         size_ = size;
00765       }
00766 
00770       Vector (const Vector &other):
00771         size_ (0),
00772         capacity_ (0),
00773         data_ (0)
00774       {
00775         operator= (other);
00776       }
00777 
00781       Vector& operator= (const Vector &other) {
00782         size_type newSize = other.size();
00783         lowLevelResize(newSize);
00784         size_ = newSize;
00785         TItem *s1 = begin();
00786         const TItem *s2 = other.begin();
00787         const TItem *s2end = other.end();
00788         for (; s2!=s2end; s1++, s2++)
00789           alloc_.construct (s1, *s2);
00790 
00791         return *this;
00792       }
00793 
00794       ~Vector() {
00795         TItem *pEnd = end();
00796         for (TItem *i=begin(); i!=pEnd; i++)
00797           alloc_.destroy (i);
00798         alloc_.deallocate (data_, capacity_);
00799       }
00800 
00806       reference operator[] (size_type index) {
00807         return data_[index];
00808       }
00809 
00813       const_reference operator[] (size_type index) const {
00814         return data_[index];
00815       }
00816 
00820       bool operator== (const Vector &other) const {
00821         const TItem *s1 = begin();
00822         const TItem *s2 = other.begin();
00823         for (; s1!=end() && s2!=other.end(); s1++, s2++)
00824           if (*s1 != *s2)
00825             return false;
00826         return
00827           s1 == end() &&
00828           s2 == other.end();
00829       }
00830 
00834       bool operator!= (const Vector &other) const {
00835         return !operator== (other);
00836       }
00837 
00841       iterator begin() {
00842         return data_;
00843       }
00844 
00848       iterator end() {
00849         return data_ + static_cast<difference_type> (size_);
00850       }
00851 
00855       const_iterator begin() const {
00856         return static_cast<const_iterator>(data_);
00857       }
00858 
00862       const_iterator end() const {
00863         return static_cast<const_iterator>(data_ + static_cast<difference_type>(size_));
00864       }
00865 
00869       void clear() {
00870         for (TItem *i=begin(); i!=end(); i++)
00871           alloc_.destroy (i);
00872         lowLevelResize(0);
00873         size_ = 0;
00874       }
00875 
00879       bool empty() const {
00880         return size_==0;
00881       }
00882 
00888       void push_back (const_reference item) {
00889         lowLevelResize (size_ + 1, true);
00890         alloc_.construct (this + static_cast<difference_type>(size_), item);
00891         size_ ++;
00892       }
00893 
00898       void pop_back() {
00899         lowLevelResize(size_ - 1, true);
00900         size_ --;
00901       }
00902 
00906       size_type size() const {
00907         return size_;
00908       }
00909 
00915       void resize (size_type newSize, const_reference val= TItem()) {
00916         lowLevelResize(newSize, true);
00917         for (; size_ < newSize; size_++)
00918           data_[size_] = val;
00919 
00920         size_ = newSize;
00921       }
00922 
00923     private:
00924       TAllocator alloc_;
00925       size_type size_;
00926       size_type capacity_;
00927       iterator data_;
00928 
00929       void lowLevelCopy (TItem *dest, const TItem *src, size_type count) {
00930         for (size_type i=0; i<count; i++, dest++, src++)
00931           *dest = *src;
00932       }
00933 
00934       void lowLevelResize (size_type newSize, bool bCopyContent=false) {
00935         static const size_type allocBaseSize = 1 << allocBase2Exp;
00936         if (newSize < allocBaseSize)
00937           newSize = allocBaseSize;
00938 
00939         if (
00940             newSize <= capacity_ &&
00941             newSize >= (capacity_ >> allocDownFactor2Exp)
00942             )
00943           return;
00944 
00945         for (capacity_= allocBaseSize; capacity_<newSize; capacity_<<=1);
00946         TItem *newBlock = alloc_.allocate (capacity_);
00947 
00948         if (data_) {
00949           if (bCopyContent)
00950             lowLevelCopy (newBlock, static_cast<const_iterator>(data_), size_);
00951 
00952           alloc_.deallocate (data_, size_);
00953         }
00954 
00955         data_ = newBlock;
00956       }
00957   };
00958 
00965   template <class TAllocator = std::allocator<char> >
00966   class String {
00967       typedef char TItem;
00968       typedef Vector<TItem, TAllocator> TContainer;
00969       typedef typename TAllocator::size_type size_type;
00970       typedef typename TAllocator::difference_type difference_type;
00971       typedef typename TAllocator::pointer pointer;
00972       typedef typename TAllocator::const_pointer const_pointer;
00973       typedef typename TAllocator::reference reference;
00974       typedef typename TAllocator::const_reference const_reference;
00975 
00976     public:
00977       typedef typename TContainer::iterator iterator;                   
00978       typedef typename TContainer::const_iterator const_iterator;       
00979 
00983       String():
00984         array_ (1, '\0')
00985       {
00986       }
00987 
00993       String (size_type size, const_reference val):
00994         array_ (size+1, val)
00995       {
00996         array_ [size] = '\0';
00997       }
00998 
01003       String (const TItem *sz):
01004         array_ (szLength (sz)+1)
01005       {
01006         TItem *i = array_.begin();
01007         for (; *sz; sz++, i++)
01008           *i = *sz;
01009         *i = '\0';
01010       }
01011 
01015       String (const String &other):
01016         array_ (other.array_)
01017       {
01018       }
01019 
01023       String& operator= (const TItem *sz) {
01024         array_.resize (szLength (sz)+1);
01025         TItem *i = array_.begin();
01026         for (; *sz; sz++, i++)
01027           *i = *sz;
01028         *i = '\0';
01029 
01030         return *this;
01031       }
01032 
01036       String& operator= (const String &other) {
01037         array_ = other.array_;
01038         return *this;
01039       }
01040 
01045       reference operator[] (size_type index) {
01046         return array_[index];
01047       }
01048 
01052       const_reference operator[] (size_type index) const {
01053         return array_[index];
01054       }
01055 
01059       iterator begin() {
01060         return array_.begin();
01061       }
01062 
01066       iterator end() {
01067         return array_.end()-1;
01068       }
01069 
01073       const_iterator begin() const {
01074         return array_.begin();
01075       }
01076 
01080       const_iterator end() const {
01081         return array_.end()-1;
01082       }
01083 
01089       int compare (const String &other) const {
01090         const TItem *s1 = begin();
01091         const TItem *s2 = other.begin();
01092         const TItem *s1end = end();
01093         const TItem *s2end = other.end();
01094         for (; s1!=s1end && s2!=s2end; s1++, s2++) {
01095           if (*s1 < *s2)
01096             return -1;
01097           else if (*s1 > *s2)
01098             return 1;
01099         }
01100         if (s1 != end())
01101           return 1;
01102         else if (s2 != other.end())
01103           return -1;
01104         else
01105           return 0;
01106       }
01107       bool operator== (const String<TAllocator> &other) const { return 0==compare (other); }
01108       bool operator!= (const String<TAllocator> &other) const { return 0!=compare (other); }
01109       bool operator<= (const String<TAllocator> &other) const { return 0>=compare (other); }
01110       bool operator>= (const String<TAllocator> &other) const { return 0<=compare (other); }
01111       bool operator<  (const String<TAllocator> &other) const { return 0> compare (other); }
01112       bool operator>  (const String<TAllocator> &other) const { return 0< compare (other); }
01113 
01117       void append (const TItem *);
01118 
01122       void clear() {
01123         array_.clear();
01124       }
01125 
01129       bool empty() const {
01130         return array_.empty();
01131       }
01132 
01136       size_type length() const {
01137         return array_.size();
01138       }
01139 
01143       const TItem* c_str() const {
01144         return array_.begin();
01145       }
01146 
01147     private:
01148       TContainer array_;
01149       TAllocator alloc_;
01150 
01151     private:
01152       static size_type szLength (const TItem *sz) {
01153         int len = 0;
01154         while (*sz)
01155           len++, sz++;
01156         return len;
01157       }
01158   };
01159 
01163   template <class A> String<A> operator+ (String<A> s1, const String<A> &s2)
01164   {
01165     s1.append (s2);
01166     return s1;
01167   }
01168 
01174   template <
01175     class TFirst,
01176     class TSecond
01177     >
01178   struct Pair {
01179     TFirst first;
01180     TSecond second;
01181   };
01182 
01191   template <
01192     class TKey,
01193     class TValue,
01194     class TAllocator = std::allocator< Pair<TKey, TValue> >
01195     >
01196   class Map {
01200       static const size_t defaultHtSize = 1 << 12;
01201 
01202       typedef Pair<TKey, TValue> TData;
01203       typedef TData& TData_reference;
01204       typedef const TData* TData_const_pointer;
01205       typedef size_t size_type;
01206       typedef typename TAllocator::template rebind<Map>::other TMapAllocator;
01207       typedef typename TMapAllocator::const_pointer TMap_const_pointer;
01208 
01209     public:
01214       Map (size_type htSize= defaultHtSize):
01215         htSize_ (htSize)
01216       {
01217         htArray_ = pItemAlloc_.allocate (htSize_);
01218         for (size_type i=0; i<htSize_; i++)
01219           htArray_[i]=0;
01220       }
01221 
01222     private:
01223       struct Item;
01224       typedef typename TAllocator::template rebind<Item>::other TItemAllocator;
01225       typedef typename TItemAllocator::pointer TItem_pointer;
01226       typedef typename TItemAllocator::const_pointer TItem_const_pointer;
01227       typedef typename TItemAllocator::reference TItem_reference;
01228       struct Item {
01229         TData data;
01230         TItem_pointer next;
01231       };
01232       typedef typename TAllocator::template rebind<TItem_pointer>::other TPItemAllocator;
01233       typedef typename TPItemAllocator::pointer TPItem_pointer;
01234 
01235     public:
01240       class const_iterator {
01241         public:
01242           const_iterator():
01243             hTable_ (0),
01244             hashIndex_ (0),
01245             item_ (0)
01246           {
01247           }
01248 
01252           TData_const_pointer operator->() {
01253             if (!item_)
01254               return 0;
01255             else
01256               return &(item_-> data);
01257           }
01258 
01262           operator TData_const_pointer() {
01263             return operator->();
01264           }
01265 
01269           const_iterator& operator ++() {
01270             if (item_)
01271               item_ = item_-> next;
01272 
01273             if (!item_) {
01274               for (
01275                   hashIndex_++;
01276                   hashIndex_ < hTable_->htSize_ && hTable_->htArray_[hashIndex_] == 0;
01277                   hashIndex_ ++);
01278 
01279               if (hashIndex_ < hTable_->htSize_)
01280                 item_ = hTable_-> htArray_ [hashIndex_];
01281             }
01282 
01283             return *this;
01284           }
01285 
01289           const_iterator operator ++(int) {
01290             const_iterator tmp = *this;
01291             operator ++();
01292             return tmp;
01293           }
01294 
01298           bool operator== (const const_iterator &other) {
01299             return
01300               hTable_ == other.hTable_ &&
01301               item_ == other.item_;
01302           }
01303 
01307           bool operator!= (const const_iterator &other) {
01308             return !operator== (other);
01309           }
01310 
01311         private:
01312           const_iterator (TMap_const_pointer ht, size_type hashIndex, TItem_const_pointer item):
01313             hTable_ (ht),
01314             hashIndex_ (hashIndex),
01315             item_ (item)
01316           {
01317           }
01318 
01319         private:
01320           TMap_const_pointer hTable_;
01321           size_type hashIndex_;
01322           TItem_const_pointer item_;
01323           friend class Map;
01324       };  // (class const_iterator)
01325 
01326       ~Map() {
01327         clear();
01328         pItemAlloc_.deallocate (htArray_, htSize_);
01329       }
01330 
01334       void clear() {
01335         TItem_pointer *ppCurrent = htArray_;
01336         for (size_type hashIndex=0; hashIndex<htSize_; hashIndex++, ppCurrent++) {
01337           Item *pCurrent = *ppCurrent;
01338           while (pCurrent) {
01339             Item *pNext = pCurrent->next;
01340             itemAlloc_.destroy (pCurrent);
01341             itemAlloc_.deallocate (pCurrent, 1);
01342             pCurrent = pNext;
01343           }
01344           *ppCurrent = 0;
01345         }
01346       }
01347 
01353       const_iterator find (const TKey &key) {
01354         size_type hashIndex = hashFunction (key);
01355         TItem_pointer pCurrent = htArray_ [hashIndex];
01356 
01357         while (pCurrent && pCurrent->data.first != key)
01358           pCurrent = pCurrent->next;
01359 
01360         return const_iterator (this, hashIndex, pCurrent);
01361       }
01362 
01369       TValue& operator[] (const TKey &key) {
01370         size_type hashIndex = hashFunction (key);
01371         typedef typename TItemAllocator::difference_type TDiff;
01372         TItem_pointer *ppCurrent = htArray_ + static_cast<TDiff>(hashIndex);
01373 
01374         for (; *ppCurrent; ppCurrent = &((*ppCurrent)-> next)) {
01375           TData_reference current = (*ppCurrent)-> data;
01376           if (current.first == key)
01377             return current.second;
01378         }
01379 
01380         Item item = {
01381           { key, TValue() },
01382           0
01383         };
01384 
01385         *ppCurrent = itemAlloc_.allocate (1);
01386         itemAlloc_.construct (*ppCurrent, item);
01387 
01388         return (*ppCurrent)->data.second;
01389       }
01390 
01395       const_iterator begin() const {
01396         const_iterator iter (this, 0, 0);
01397         iter++;
01398         return iter;
01399       }
01400 
01405       const_iterator end() const {
01406         return const_iterator (this, 0, 0);
01407       }
01408 
01409     private:
01410       size_t htSize_;
01411       TPItem_pointer htArray_;
01412       TItemAllocator itemAlloc_;
01413       TPItemAllocator pItemAlloc_;
01414 
01418       template<class T> size_t hashFunction (const T &key) {
01419         typedef typename T::const_iterator Iterator;
01420         Iterator i= key.begin();
01421         unsigned int h=0;
01422         for (; i != key.end(); i++) {
01423           unsigned char p = static_cast<unsigned char> (*i);
01424           h = 31*h + p;
01425         }
01426         return h % htSize_;
01427       }
01428   };
01429 }
01430 
01431 #endif // SHARELIB_H

Generated on Sun Aug 26 17:42:59 2007 for ShareLibrary by  doxygen 1.5.2