00001 #ifndef SHARELIB_H
00002 #define SHARELIB_H
00003
00013 #ifdef _WIN32
00014
00015 # define SHARE_EXPORT __declspec(dllexport)
00016 #else
00017
00018 # define SHARE_EXPORT
00019 #endif
00020
00021 #include <new>
00022 #include <memory>
00023 #include <iterator>
00024 #include <functional>
00025 #include <stddef.h>
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;
00176 class SegmentHeader;
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
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 };
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