00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef OVR_Array_h
00018 #define OVR_Array_h
00019
00020 #include "OVR_ContainerAllocator.h"
00021
00022 namespace OVR {
00023
00024
00025
00026
00027
00028
00029
00030
00031 struct ArrayDefaultPolicy
00032 {
00033 ArrayDefaultPolicy() : Capacity(0) {}
00034 ArrayDefaultPolicy(const ArrayDefaultPolicy&) : Capacity(0) {}
00035
00036 UPInt GetMinCapacity() const { return 0; }
00037 UPInt GetGranularity() const { return 4; }
00038 bool NeverShrinking() const { return 0; }
00039
00040 UPInt GetCapacity() const { return Capacity; }
00041 void SetCapacity(UPInt capacity) { Capacity = capacity; }
00042 private:
00043 UPInt Capacity;
00044 };
00045
00046
00047
00048
00049
00050
00051
00052 template<int MinCapacity=0, int Granularity=4, bool NeverShrink=false>
00053 struct ArrayConstPolicy
00054 {
00055 typedef ArrayConstPolicy<MinCapacity, Granularity, NeverShrink> SelfType;
00056
00057 ArrayConstPolicy() : Capacity(0) {}
00058 ArrayConstPolicy(const SelfType&) : Capacity(0) {}
00059
00060 UPInt GetMinCapacity() const { return MinCapacity; }
00061 UPInt GetGranularity() const { return Granularity; }
00062 bool NeverShrinking() const { return NeverShrink; }
00063
00064 UPInt GetCapacity() const { return Capacity; }
00065 void SetCapacity(UPInt capacity) { Capacity = capacity; }
00066 private:
00067 UPInt Capacity;
00068 };
00069
00070
00071
00072
00073
00074
00075 template<class T, class Allocator, class SizePolicy>
00076 struct ArrayDataBase
00077 {
00078 typedef T ValueType;
00079 typedef Allocator AllocatorType;
00080 typedef SizePolicy SizePolicyType;
00081 typedef ArrayDataBase<T, Allocator, SizePolicy> SelfType;
00082
00083 ArrayDataBase()
00084 : Data(0), Size(0), Policy() {}
00085
00086 ArrayDataBase(const SizePolicy& p)
00087 : Data(0), Size(0), Policy(p) {}
00088
00089 ~ArrayDataBase()
00090 {
00091 Allocator::DestructArray(Data, Size);
00092 Allocator::Free(Data);
00093 }
00094
00095 UPInt GetCapacity() const
00096 {
00097 return Policy.GetCapacity();
00098 }
00099
00100 void ClearAndRelease()
00101 {
00102 Allocator::DestructArray(Data, Size);
00103 Allocator::Free(Data);
00104 Data = 0;
00105 Size = 0;
00106 Policy.SetCapacity(0);
00107 }
00108
00109 void Reserve(UPInt newCapacity)
00110 {
00111 if (Policy.NeverShrinking() && newCapacity < GetCapacity())
00112 return;
00113
00114 if (newCapacity < Policy.GetMinCapacity())
00115 newCapacity = Policy.GetMinCapacity();
00116
00117
00118 if (newCapacity == 0)
00119 {
00120 if (Data)
00121 {
00122 Allocator::Free(Data);
00123 Data = 0;
00124 }
00125 Policy.SetCapacity(0);
00126 }
00127 else
00128 {
00129 UPInt gran = Policy.GetGranularity();
00130 newCapacity = (newCapacity + gran - 1) / gran * gran;
00131 if (Data)
00132 {
00133 if (Allocator::IsMovable())
00134 {
00135 Data = (T*)Allocator::Realloc(Data, sizeof(T) * newCapacity);
00136 }
00137 else
00138 {
00139 T* newData = (T*)Allocator::Alloc(sizeof(T) * newCapacity);
00140 UPInt i, s;
00141 s = (Size < newCapacity) ? Size : newCapacity;
00142 for (i = 0; i < s; ++i)
00143 {
00144 Allocator::Construct(&newData[i], Data[i]);
00145 Allocator::Destruct(&Data[i]);
00146 }
00147 for (i = s; i < Size; ++i)
00148 {
00149 Allocator::Destruct(&Data[i]);
00150 }
00151 Allocator::Free(Data);
00152 Data = newData;
00153 }
00154 }
00155 else
00156 {
00157 Data = (T*)Allocator::Alloc(sizeof(T) * newCapacity);
00158
00159 }
00160 Policy.SetCapacity(newCapacity);
00161
00162 }
00163 }
00164
00165
00166
00167
00168 void ResizeNoConstruct(UPInt newSize)
00169 {
00170 UPInt oldSize = Size;
00171
00172 if (newSize < oldSize)
00173 {
00174 Allocator::DestructArray(Data + newSize, oldSize - newSize);
00175 if (newSize < (Policy.GetCapacity() >> 1))
00176 {
00177 Reserve(newSize);
00178 }
00179 }
00180 else if(newSize >= Policy.GetCapacity())
00181 {
00182 Reserve(newSize + (newSize >> 2));
00183 }
00185
00186
00187 Size = newSize;
00188 }
00189
00190 ValueType* Data;
00191 UPInt Size;
00192 SizePolicy Policy;
00193 };
00194
00195
00196
00197
00198
00199
00200
00201
00202 template<class T, class Allocator, class SizePolicy>
00203 struct ArrayData : ArrayDataBase<T, Allocator, SizePolicy>
00204 {
00205 typedef T ValueType;
00206 typedef Allocator AllocatorType;
00207 typedef SizePolicy SizePolicyType;
00208 typedef ArrayDataBase<T, Allocator, SizePolicy> BaseType;
00209 typedef ArrayData <T, Allocator, SizePolicy> SelfType;
00210
00211 ArrayData()
00212 : BaseType() { }
00213
00214 ArrayData(int size)
00215 : BaseType() { Resize(size); }
00216
00217 ArrayData(const SelfType& a)
00218 : BaseType(a.Policy) { Append(a.Data, a.Size); }
00219
00220
00221 void Resize(UPInt newSize)
00222 {
00223 UPInt oldSize = this->Size;
00224 BaseType::ResizeNoConstruct(newSize);
00225 if(newSize > oldSize)
00226 Allocator::ConstructArray(this->Data + oldSize, newSize - oldSize);
00227 }
00228
00229 void PushBack(const ValueType& val)
00230 {
00231 BaseType::ResizeNoConstruct(this->Size + 1);
00232 Allocator::Construct(this->Data + this->Size - 1, val);
00233 }
00234
00235 template<class S>
00236 void PushBackAlt(const S& val)
00237 {
00238 BaseType::ResizeNoConstruct(this->Size + 1);
00239 Allocator::ConstructAlt(this->Data + this->Size - 1, val);
00240 }
00241
00242
00243 void Append(const ValueType other[], UPInt count)
00244 {
00245 if (count)
00246 {
00247 UPInt oldSize = this->Size;
00248 BaseType::ResizeNoConstruct(this->Size + count);
00249 Allocator::ConstructArray(this->Data + oldSize, count, other);
00250 }
00251 }
00252 };
00253
00254
00255
00256
00257
00258
00259
00260
00261 template<class T, class Allocator, class SizePolicy>
00262 struct ArrayDataCC : ArrayDataBase<T, Allocator, SizePolicy>
00263 {
00264 typedef T ValueType;
00265 typedef Allocator AllocatorType;
00266 typedef SizePolicy SizePolicyType;
00267 typedef ArrayDataBase<T, Allocator, SizePolicy> BaseType;
00268 typedef ArrayDataCC <T, Allocator, SizePolicy> SelfType;
00269
00270 ArrayDataCC(const ValueType& defval)
00271 : BaseType(), DefaultValue(defval) { }
00272
00273 ArrayDataCC(const ValueType& defval, int size)
00274 : BaseType(), DefaultValue(defval) { Resize(size); }
00275
00276 ArrayDataCC(const SelfType& a)
00277 : BaseType(a.Policy), DefaultValue(a.DefaultValue) { Append(a.Data, a.Size); }
00278
00279
00280 void Resize(UPInt newSize)
00281 {
00282 UPInt oldSize = this->Size;
00283 BaseType::ResizeNoConstruct(newSize);
00284 if(newSize > oldSize)
00285 Allocator::ConstructArray(this->Data + oldSize, newSize - oldSize, DefaultValue);
00286 }
00287
00288 void PushBack(const ValueType& val)
00289 {
00290 BaseType::ResizeNoConstruct(this->Size + 1);
00291 Allocator::Construct(this->Data + this->Size - 1, val);
00292 }
00293
00294 template<class S>
00295 void PushBackAlt(const S& val)
00296 {
00297 BaseType::ResizeNoConstruct(this->Size + 1);
00298 Allocator::ConstructAlt(this->Data + this->Size - 1, val);
00299 }
00300
00301
00302 void Append(const ValueType other[], UPInt count)
00303 {
00304 if (count)
00305 {
00306 UPInt oldSize = this->Size;
00307 BaseType::ResizeNoConstruct(this->Size + count);
00308 Allocator::ConstructArray(this->Data + oldSize, count, other);
00309 }
00310 }
00311
00312 ValueType DefaultValue;
00313 };
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331 template<class ArrayData>
00332 class ArrayBase
00333 {
00334 public:
00335 typedef typename ArrayData::ValueType ValueType;
00336 typedef typename ArrayData::AllocatorType AllocatorType;
00337 typedef typename ArrayData::SizePolicyType SizePolicyType;
00338 typedef ArrayBase<ArrayData> SelfType;
00339
00340
00341 #undef new
00342 OVR_MEMORY_REDEFINE_NEW(ArrayBase)
00343
00344 #if defined(OVR_DEFINE_NEW)
00345 #define new OVR_DEFINE_NEW
00346 #endif
00347
00348
00349 ArrayBase()
00350 : Data() {}
00351 ArrayBase(int size)
00352 : Data(size) {}
00353 ArrayBase(const SelfType& a)
00354 : Data(a.Data) {}
00355
00356 ArrayBase(const ValueType& defval)
00357 : Data(defval) {}
00358 ArrayBase(const ValueType& defval, int size)
00359 : Data(defval, size) {}
00360
00361 SizePolicyType* GetSizePolicy() const { return Data.Policy; }
00362 void SetSizePolicy(const SizePolicyType& p) { Data.Policy = p; }
00363
00364 bool NeverShrinking()const { return Data.Policy.NeverShrinking(); }
00365 UPInt GetSize() const { return Data.Size; }
00366 bool IsEmpty() const { return Data.Size == 0; }
00367 UPInt GetCapacity() const { return Data.GetCapacity(); }
00368 UPInt GetNumBytes() const { return Data.GetCapacity() * sizeof(ValueType); }
00369
00370 void ClearAndRelease() { Data.ClearAndRelease(); }
00371 void Clear() { Data.Resize(0); }
00372 void Resize(UPInt newSize) { Data.Resize(newSize); }
00373
00374
00375 void Reserve(UPInt newCapacity)
00376 {
00377 if (newCapacity > Data.GetCapacity())
00378 Data.Reserve(newCapacity);
00379 }
00380
00381
00382 ValueType& At(UPInt index)
00383 {
00384 OVR_ASSERT(index < Data.Size);
00385 return Data.Data[index];
00386 }
00387 const ValueType& At(UPInt index) const
00388 {
00389 OVR_ASSERT(index < Data.Size);
00390 return Data.Data[index];
00391 }
00392
00393 ValueType ValueAt(UPInt index) const
00394 {
00395 OVR_ASSERT(index < Data.Size);
00396 return Data.Data[index];
00397 }
00398
00399
00400 ValueType& operator [] (UPInt index)
00401 {
00402 OVR_ASSERT(index < Data.Size);
00403 return Data.Data[index];
00404 }
00405 const ValueType& operator [] (UPInt index) const
00406 {
00407 OVR_ASSERT(index < Data.Size);
00408 return Data.Data[index];
00409 }
00410
00411
00412 const ValueType* GetDataPtr() const { return Data.Data; }
00413 ValueType* GetDataPtr() { return Data.Data; }
00414
00415
00416 void PushBack(const ValueType& val)
00417 {
00418
00419
00420
00421
00422 Data.PushBack(val);
00423 }
00424
00425 template<class S>
00426 void PushBackAlt(const S& val)
00427 {
00428 Data.PushBackAlt(val);
00429 }
00430
00431
00432 void PopBack(UPInt count = 1)
00433 {
00434 OVR_ASSERT(Data.Size >= count);
00435 Data.Resize(Data.Size - count);
00436 }
00437
00438 ValueType& PushDefault()
00439 {
00440 Data.PushBack(ValueType());
00441 return Back();
00442 }
00443
00444 ValueType Pop()
00445 {
00446 ValueType t = Back();
00447 PopBack();
00448 return t;
00449 }
00450
00451
00452
00453 ValueType& Front() { return At(0); }
00454 const ValueType& Front() const { return At(0); }
00455
00456
00457 ValueType& Back() { return At(Data.Size - 1); }
00458 const ValueType& Back() const { return At(Data.Size - 1); }
00459
00460
00461 const SelfType& operator = (const SelfType& a)
00462 {
00463 Resize(a.GetSize());
00464 for (UPInt i = 0; i < Data.Size; i++) {
00465 *(Data.Data + i) = a[i];
00466 }
00467 return *this;
00468 }
00469
00470
00471 void RemoveMultipleAt(UPInt index, UPInt num)
00472 {
00473 OVR_ASSERT(index + num <= Data.Size);
00474 if (Data.Size == num)
00475 {
00476 Clear();
00477 }
00478 else
00479 {
00480 AllocatorType::DestructArray(Data.Data + index, num);
00481 AllocatorType::CopyArrayForward(
00482 Data.Data + index,
00483 Data.Data + index + num,
00484 Data.Size - num - index);
00485 Data.Size -= num;
00486 }
00487 }
00488
00489
00490
00491 void RemoveAt(UPInt index)
00492 {
00493 OVR_ASSERT(index < Data.Size);
00494 if (Data.Size == 1)
00495 {
00496 Clear();
00497 }
00498 else
00499 {
00500 AllocatorType::Destruct(Data.Data + index);
00501 AllocatorType::CopyArrayForward(
00502 Data.Data + index,
00503 Data.Data + index + 1,
00504 Data.Size - 1 - index);
00505 --Data.Size;
00506 }
00507 }
00508
00509
00510 void InsertAt(UPInt index, const ValueType& val = ValueType())
00511 {
00512 OVR_ASSERT(index <= Data.Size);
00513
00514 Data.Resize(Data.Size + 1);
00515 if (index < Data.Size - 1)
00516 {
00517 AllocatorType::CopyArrayBackward(
00518 Data.Data + index + 1,
00519 Data.Data + index,
00520 Data.Size - 1 - index);
00521 }
00522 AllocatorType::Construct(Data.Data + index, val);
00523 }
00524
00525
00526 void InsertMultipleAt(UPInt index, UPInt num, const ValueType& val = ValueType())
00527 {
00528 OVR_ASSERT(index <= Data.Size);
00529
00530 Data.Resize(Data.Size + num);
00531 if (index < Data.Size - num)
00532 {
00533 AllocatorType::CopyArrayBackward(
00534 Data.Data + index + num,
00535 Data.Data + index,
00536 Data.Size - num - index);
00537 }
00538 for (UPInt i = 0; i < num; ++i)
00539 AllocatorType::Construct(Data.Data + index + i, val);
00540 }
00541
00542
00543 void Append(const SelfType& other)
00544 {
00545 Append(other.Data.Data, other.GetSize());
00546 }
00547
00548
00549 void Append(const ValueType other[], UPInt count)
00550 {
00551 Data.Append(other, count);
00552 }
00553
00554 class Iterator
00555 {
00556 SelfType* pArray;
00557 SPInt CurIndex;
00558
00559 public:
00560 Iterator() : pArray(0), CurIndex(-1) {}
00561 Iterator(SelfType* parr, SPInt idx = 0) : pArray(parr), CurIndex(idx) {}
00562
00563 bool operator==(const Iterator& it) const { return pArray == it.pArray && CurIndex == it.CurIndex; }
00564 bool operator!=(const Iterator& it) const { return pArray != it.pArray || CurIndex != it.CurIndex; }
00565
00566 Iterator& operator++()
00567 {
00568 if (pArray)
00569 {
00570 if (CurIndex < (SPInt)pArray->GetSize())
00571 ++CurIndex;
00572 }
00573 return *this;
00574 }
00575 Iterator operator++(int)
00576 {
00577 Iterator it(*this);
00578 operator++();
00579 return it;
00580 }
00581 Iterator& operator--()
00582 {
00583 if (pArray)
00584 {
00585 if (CurIndex >= 0)
00586 --CurIndex;
00587 }
00588 return *this;
00589 }
00590 Iterator operator--(int)
00591 {
00592 Iterator it(*this);
00593 operator--();
00594 return it;
00595 }
00596 Iterator operator+(int delta) const
00597 {
00598 return Iterator(pArray, CurIndex + delta);
00599 }
00600 Iterator operator-(int delta) const
00601 {
00602 return Iterator(pArray, CurIndex - delta);
00603 }
00604 SPInt operator-(const Iterator& right) const
00605 {
00606 OVR_ASSERT(pArray == right.pArray);
00607 return CurIndex - right.CurIndex;
00608 }
00609 ValueType& operator*() const { OVR_ASSERT(pArray); return (*pArray)[CurIndex]; }
00610 ValueType* operator->() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; }
00611 ValueType* GetPtr() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; }
00612
00613 bool IsFinished() const { return !pArray || CurIndex < 0 || CurIndex >= (int)pArray->GetSize(); }
00614
00615 void Remove()
00616 {
00617 if (!IsFinished())
00618 pArray->RemoveAt(CurIndex);
00619 }
00620
00621 SPInt GetIndex() const { return CurIndex; }
00622 };
00623
00624 Iterator Begin() { return Iterator(this); }
00625 Iterator End() { return Iterator(this, (SPInt)GetSize()); }
00626 Iterator Last() { return Iterator(this, (SPInt)GetSize() - 1); }
00627
00628 class ConstIterator
00629 {
00630 const SelfType* pArray;
00631 SPInt CurIndex;
00632
00633 public:
00634 ConstIterator() : pArray(0), CurIndex(-1) {}
00635 ConstIterator(const SelfType* parr, SPInt idx = 0) : pArray(parr), CurIndex(idx) {}
00636
00637 bool operator==(const ConstIterator& it) const { return pArray == it.pArray && CurIndex == it.CurIndex; }
00638 bool operator!=(const ConstIterator& it) const { return pArray != it.pArray || CurIndex != it.CurIndex; }
00639
00640 ConstIterator& operator++()
00641 {
00642 if (pArray)
00643 {
00644 if (CurIndex < (int)pArray->GetSize())
00645 ++CurIndex;
00646 }
00647 return *this;
00648 }
00649 ConstIterator operator++(int)
00650 {
00651 ConstIterator it(*this);
00652 operator++();
00653 return it;
00654 }
00655 ConstIterator& operator--()
00656 {
00657 if (pArray)
00658 {
00659 if (CurIndex >= 0)
00660 --CurIndex;
00661 }
00662 return *this;
00663 }
00664 ConstIterator operator--(int)
00665 {
00666 ConstIterator it(*this);
00667 operator--();
00668 return it;
00669 }
00670 ConstIterator operator+(int delta) const
00671 {
00672 return ConstIterator(pArray, CurIndex + delta);
00673 }
00674 ConstIterator operator-(int delta) const
00675 {
00676 return ConstIterator(pArray, CurIndex - delta);
00677 }
00678 SPInt operator-(const ConstIterator& right) const
00679 {
00680 OVR_ASSERT(pArray == right.pArray);
00681 return CurIndex - right.CurIndex;
00682 }
00683 const ValueType& operator*() const { OVR_ASSERT(pArray); return (*pArray)[CurIndex]; }
00684 const ValueType* operator->() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; }
00685 const ValueType* GetPtr() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; }
00686
00687 bool IsFinished() const { return !pArray || CurIndex < 0 || CurIndex >= (int)pArray->GetSize(); }
00688
00689 SPInt GetIndex() const { return CurIndex; }
00690 };
00691 ConstIterator Begin() const { return ConstIterator(this); }
00692 ConstIterator End() const { return ConstIterator(this, (SPInt)GetSize()); }
00693 ConstIterator Last() const { return ConstIterator(this, (SPInt)GetSize() - 1); }
00694
00695 protected:
00696 ArrayData Data;
00697 };
00698
00699
00700
00701
00702
00703
00704
00705
00706 template<class T, class SizePolicy=ArrayDefaultPolicy>
00707 class Array : public ArrayBase<ArrayData<T, ContainerAllocator<T>, SizePolicy> >
00708 {
00709 public:
00710 typedef T ValueType;
00711 typedef ContainerAllocator<T> AllocatorType;
00712 typedef SizePolicy SizePolicyType;
00713 typedef Array<T, SizePolicy> SelfType;
00714 typedef ArrayBase<ArrayData<T, ContainerAllocator<T>, SizePolicy> > BaseType;
00715
00716 Array() : BaseType() {}
00717 Array(int size) : BaseType(size) {}
00718 Array(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); }
00719 Array(const SelfType& a) : BaseType(a) {}
00720 const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
00721 };
00722
00723
00724
00725
00726
00727
00728 template<class T, class SizePolicy=ArrayDefaultPolicy>
00729 class ArrayPOD : public ArrayBase<ArrayData<T, ContainerAllocator_POD<T>, SizePolicy> >
00730 {
00731 public:
00732 typedef T ValueType;
00733 typedef ContainerAllocator_POD<T> AllocatorType;
00734 typedef SizePolicy SizePolicyType;
00735 typedef ArrayPOD<T, SizePolicy> SelfType;
00736 typedef ArrayBase<ArrayData<T, ContainerAllocator_POD<T>, SizePolicy> > BaseType;
00737
00738 ArrayPOD() : BaseType() {}
00739 ArrayPOD(int size) : BaseType(size) {}
00740 ArrayPOD(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); }
00741 ArrayPOD(const SelfType& a) : BaseType(a) {}
00742 const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
00743 };
00744
00745
00746
00747
00748
00749
00750 template<class T, class SizePolicy=ArrayDefaultPolicy>
00751 class ArrayCPP : public ArrayBase<ArrayData<T, ContainerAllocator_CPP<T>, SizePolicy> >
00752 {
00753 public:
00754 typedef T ValueType;
00755 typedef ContainerAllocator_CPP<T> AllocatorType;
00756 typedef SizePolicy SizePolicyType;
00757 typedef ArrayCPP<T, SizePolicy> SelfType;
00758 typedef ArrayBase<ArrayData<T, ContainerAllocator_CPP<T>, SizePolicy> > BaseType;
00759
00760 ArrayCPP() : BaseType() {}
00761 ArrayCPP(int size) : BaseType(size) {}
00762 ArrayCPP(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); }
00763 ArrayCPP(const SelfType& a) : BaseType(a) {}
00764 const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
00765 };
00766
00767
00768
00769
00770
00771
00772
00773
00774 template<class T, class SizePolicy=ArrayDefaultPolicy>
00775 class ArrayCC : public ArrayBase<ArrayDataCC<T, ContainerAllocator<T>, SizePolicy> >
00776 {
00777 public:
00778 typedef T ValueType;
00779 typedef ContainerAllocator<T> AllocatorType;
00780 typedef SizePolicy SizePolicyType;
00781 typedef ArrayCC<T, SizePolicy> SelfType;
00782 typedef ArrayBase<ArrayDataCC<T, ContainerAllocator<T>, SizePolicy> > BaseType;
00783
00784 ArrayCC(const ValueType& defval) : BaseType(defval) {}
00785 ArrayCC(const ValueType& defval, int size) : BaseType(defval, size) {}
00786 ArrayCC(const ValueType& defval, const SizePolicyType& p) : BaseType(defval) { SetSizePolicy(p); }
00787 ArrayCC(const SelfType& a) : BaseType(a) {}
00788 const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
00789 };
00790
00791 }
00792
00793 #endif