csutil/array.h
Go to the documentation of this file.00001 /* 00002 Crystal Space Generic Array Template 00003 Copyright (C) 2003 by Matze Braun 00004 Copyright (C) 2003 by Jorrit Tyberghein 00005 Copyright (C) 2003,2004 by Eric Sunshine 00006 00007 This library is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU Library General Public 00009 License as published by the Free Software Foundation; either 00010 version 2 of the License, or (at your option) any later version. 00011 00012 This library is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 Library General Public License for more details. 00016 00017 You should have received a copy of the GNU Library General Public 00018 License along with this library; if not, write to the Free 00019 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00020 */ 00021 #ifndef __CSUTIL_ARRAY_H__ 00022 #define __CSUTIL_ARRAY_H__ 00023 00028 #include "csutil/allocator.h" 00029 #include "csutil/comparator.h" 00030 #include "csutil/customallocated.h" 00031 00032 #include "csutil/custom_new_disable.h" 00033 00034 #if defined(CS_MEMORY_TRACKER) 00035 #include "csutil/memdebug.h" 00036 #include "csutil/snprintf.h" 00037 #include <typeinfo> 00038 #endif 00039 00052 template <class T, class K> 00053 class csArrayCmp 00054 { 00055 public: 00061 typedef int(*CF)(T const&, K const&); 00063 csArrayCmp(K const& k, CF c = DefaultCompare) : key(k), cmp(c) {} 00065 csArrayCmp(csArrayCmp const& o) : key(o.key), cmp(o.cmp) {} 00067 csArrayCmp& operator=(csArrayCmp const& o) 00068 { key = o.key; cmp = o.cmp; return *this; } 00077 int operator()(T const& r) const { return cmp(r, key); } 00079 operator CF() const { return cmp; } 00081 operator K const&() const { return key; } 00092 static int DefaultCompare(T const& r, K const& k) 00093 { return csComparator<T,K>::Compare(r,k); } 00094 private: 00095 K key; 00096 CF cmp; 00097 }; 00098 00102 template <class T> 00103 class csArrayElementHandler 00104 { 00105 public: 00107 static void Construct (T* address) 00108 { 00109 new (static_cast<void*> (address)) T(); 00110 } 00111 00113 static void Construct (T* address, T const& src) 00114 { 00115 new (static_cast<void*> (address)) T(src); 00116 } 00117 00119 static void Destroy (T* address) 00120 { 00121 address->~T(); 00122 } 00123 00125 static void InitRegion (T* address, size_t count) 00126 { 00127 for (size_t i = 0 ; i < count ; i++) 00128 Construct (address + i); 00129 } 00130 00132 template<typename Allocator> 00133 static T* ResizeRegion (Allocator& alloc, T* mem, size_t relevantcount, 00134 size_t oldcount, size_t newcount) 00135 { 00136 (void)relevantcount; (void)oldcount; 00137 return (T*)alloc.Realloc (mem, newcount * sizeof(T)); 00138 } 00139 00141 static void MoveElements (T* mem, size_t dest, size_t src, size_t count) 00142 { 00143 memmove (mem + dest, mem + src, count * sizeof(T)); 00144 } 00145 }; 00146 00155 template <class T> 00156 class csArraySafeCopyElementHandler 00157 { 00158 public: 00159 static void Construct (T* address) 00160 { 00161 new (static_cast<void*> (address)) T(); 00162 } 00163 00164 static void Construct (T* address, T const& src) 00165 { 00166 new (static_cast<void*> (address)) T(src); 00167 } 00168 00169 static void Destroy (T* address) 00170 { 00171 address->~T(); 00172 } 00173 00174 static void InitRegion (T* address, size_t count) 00175 { 00176 for (size_t i = 0 ; i < count ; i++) 00177 Construct (address + i); 00178 } 00179 00185 template<typename Allocator> 00186 static T* ResizeRegion (Allocator& alloc, T* mem, size_t relevantcount, 00187 size_t oldcount, size_t newcount) 00188 { 00189 if (newcount <= oldcount) 00190 { 00191 // Realloc is safe. 00192 T* newmem = (T*)alloc.Realloc (mem, newcount * sizeof (T)); 00193 CS_ASSERT (newmem == mem); 00194 return newmem; 00195 } 00196 00197 T* newmem = (T*)alloc.Alloc (newcount * sizeof (T)); 00198 size_t i; 00199 for (i = 0 ; i < relevantcount ; i++) 00200 { 00201 Construct (newmem + i, mem[i]); 00202 Destroy (mem + i); 00203 } 00204 alloc.Free (mem); 00205 return newmem; 00206 } 00207 00213 static void MoveElements (T* mem, size_t dest, size_t src, size_t count) 00214 { 00215 size_t i; 00216 if (dest < src) 00217 { 00218 for (i = 0 ; i < count ; i++) 00219 { 00220 Construct (mem + dest + i, mem[src + i]); 00221 Destroy (mem + src + i); 00222 } 00223 } 00224 else 00225 { 00226 i = count; 00227 while (i > 0) 00228 { 00229 i--; 00230 Construct (mem + dest + i, mem[src + i]); 00231 Destroy (mem + src + i); 00232 } 00233 } 00234 } 00235 }; 00236 00237 00242 class csArrayThresholdVariable 00243 { 00244 size_t threshold; 00245 public: 00247 csArrayThresholdVariable (size_t in_threshold = 0) 00248 { threshold = (in_threshold > 0 ? in_threshold : 16); } 00250 size_t GetThreshold() const { return threshold; } 00251 }; 00252 00257 template<int N> 00258 class csArrayThresholdFixed 00259 { 00260 public: 00262 csArrayThresholdFixed (size_t x = 0) 00263 { (void)x; } 00265 size_t GetThreshold() const { return N; } 00266 // Work around VC7 bug apparently incorrectly copying this empty class 00267 csArrayThresholdFixed& operator= (const csArrayThresholdFixed&) 00268 { return *this; } 00269 }; 00270 00278 template<typename Threshold = csArrayThresholdVariable> 00279 class csArrayCapacityLinear : public Threshold 00280 { 00281 public: 00283 00284 csArrayCapacityLinear () : Threshold () {} 00285 csArrayCapacityLinear (const Threshold& threshold) : Threshold (threshold) 00286 {} 00288 00294 csArrayCapacityLinear (const size_t x) : Threshold (x) 00295 {} 00296 00302 bool IsCapacityExcessive (size_t capacity, size_t count) const 00303 { 00304 return (capacity > this->GetThreshold() 00305 && count < capacity - this->GetThreshold()); 00306 } 00312 size_t GetCapacity (size_t count) const 00313 { 00314 return ((count + this->GetThreshold() - 1) / this->GetThreshold()) * 00315 this->GetThreshold(); 00316 } 00317 }; 00318 00319 // Alias for csArrayCapacityLinear<csArrayThresholdVariable> to keep 00320 // SWIG generated Java classes (and thus filenames) short enough for Windows. 00321 // Note that a typedef wont work because SWIG would expand it. 00322 struct csArrayCapacityDefault : 00323 public csArrayCapacityLinear<csArrayThresholdVariable> 00324 { 00325 csArrayCapacityDefault () : 00326 csArrayCapacityLinear<csArrayThresholdVariable> () {} 00327 csArrayCapacityDefault (const csArrayThresholdVariable& threshold) : 00328 csArrayCapacityLinear<csArrayThresholdVariable> (threshold) {} 00329 csArrayCapacityDefault (const size_t x) : 00330 csArrayCapacityLinear<csArrayThresholdVariable> (x) {} 00331 } ; 00332 00337 const size_t csArrayItemNotFound = (size_t)-1; 00338 00347 template <class T, 00348 class ElementHandler = csArrayElementHandler<T>, 00349 class MemoryAllocator = CS::Memory::AllocatorMalloc, 00350 class CapacityHandler = csArrayCapacityDefault> 00351 class csArray : public CS::Memory::CustomAllocated 00352 { 00353 public: 00354 typedef csArray<T, ElementHandler, MemoryAllocator, CapacityHandler> ThisType; 00355 typedef T ValueType; 00356 typedef ElementHandler ElementHandlerType; 00357 typedef MemoryAllocator AllocatorType; 00358 typedef CapacityHandler CapacityHandlerType; 00359 00360 private: 00361 size_t count; 00366 struct ArrayCapacity : public CapacityHandler 00367 { 00368 size_t c; 00369 ArrayCapacity (size_t in_capacity) 00370 { c = (in_capacity > 0 ? in_capacity : 0); } 00371 ArrayCapacity (size_t in_capacity, const CapacityHandler& ch) : 00372 CapacityHandler (ch) 00373 { c = (in_capacity > 0 ? in_capacity : 0); } 00374 void CopyFrom (const CapacityHandler& source) 00375 { 00376 CapacityHandler::operator= (source); 00377 } 00378 }; 00379 ArrayCapacity capacity; 00380 CS::Memory::AllocatorPointerWrapper<T, MemoryAllocator> root; 00381 00382 protected: 00387 void InitRegion (size_t start, size_t count) 00388 { 00389 ElementHandler::InitRegion (root.p+start, count); 00390 } 00391 00396 void SetData (T* data) { root.p = data; } 00397 private: 00399 void CopyFrom (const csArray& source) 00400 { 00401 capacity.CopyFrom (source.capacity); 00402 SetSizeUnsafe (source.GetSize ()); 00403 for (size_t i=0 ; i<source.GetSize () ; i++) 00404 ElementHandler::Construct (root.p + i, source[i]); 00405 } 00406 00408 void InternalSetCapacity (size_t n) 00409 { 00410 if (root.p == 0) 00411 { 00412 root.p = (T*)root.Alloc (n * sizeof (T)); 00413 } 00414 else 00415 { 00416 root.p = ElementHandler::ResizeRegion (root, root.p, count, capacity.c, n); 00417 } 00418 capacity.c = n; 00419 } 00420 00425 void AdjustCapacity (size_t n) 00426 { 00427 if (n > capacity.c || capacity.IsCapacityExcessive (capacity.c, n)) 00428 { 00429 InternalSetCapacity (capacity.GetCapacity (n)); 00430 } 00431 } 00432 00439 void SetSizeUnsafe (size_t n) 00440 { 00441 if (n > capacity.c) 00442 AdjustCapacity (n); 00443 count = n; 00444 } 00445 00446 public: 00458 static int DefaultCompare(T const& r1, T const& r2) 00459 { 00460 return csComparator<T,T>::Compare(r1,r2); 00461 } 00462 00469 csArray (size_t in_capacity = 0, 00470 const CapacityHandler& ch = CapacityHandler()) : count (0), 00471 capacity (in_capacity, ch) 00472 { 00473 #ifdef CS_MEMORY_TRACKER 00474 root.SetMemTrackerInfo (typeid(*this).name()); 00475 #endif 00476 if (capacity.c != 0) 00477 { 00478 root.p = (T*)root.Alloc (capacity.c * sizeof (T)); 00479 } 00480 else 00481 { 00482 root.p = 0; 00483 } 00484 } 00489 csArray (size_t in_capacity, 00490 const MemoryAllocator& alloc, 00491 const CapacityHandler& ch) : count (0), 00492 capacity (in_capacity, ch), root (alloc) 00493 { 00494 #ifdef CS_MEMORY_TRACKER 00495 root.SetMemTrackerInfo (typeid(*this).name()); 00496 #endif 00497 if (capacity.c != 0) 00498 { 00499 root.p = (T*)root.Alloc (capacity.c * sizeof (T)); 00500 } 00501 else 00502 { 00503 root.p = 0; 00504 } 00505 } 00506 00508 ~csArray () 00509 { 00510 DeleteAll (); 00511 } 00512 00514 csArray (const csArray& source) : count (0), capacity (0), root (0) 00515 { 00516 #ifdef CS_MEMORY_TRACKER 00517 root.SetMemTrackerInfo (typeid(*this).name()); 00518 #endif 00519 CopyFrom (source); 00520 } 00521 00523 csArray<T,ElementHandler,MemoryAllocator,CapacityHandler>& operator= ( 00524 const csArray& other) 00525 { 00526 if (&other != this) 00527 { 00528 DeleteAll (); 00529 CopyFrom (other); 00530 } 00531 return *this; 00532 } 00533 00535 size_t GetSize () const 00536 { 00537 return count; 00538 } 00539 00541 size_t Capacity () const 00542 { 00543 return capacity.c; 00544 } 00545 00552 // @@@ FIXME: What about custom allocators? 00553 void TransferTo (csArray& destination) 00554 { 00555 if (&destination != this) 00556 { 00557 destination.DeleteAll (); 00558 destination.root.p = root.p; 00559 destination.count = count; 00560 destination.capacity = capacity; 00561 root.p = 0; 00562 capacity.c = count = 0; 00563 } 00564 } 00565 00575 void SetSize (size_t n, T const& what) 00576 { 00577 if (n <= count) 00578 { 00579 Truncate (n); 00580 } 00581 else 00582 { 00583 size_t old_len = GetSize (); 00584 SetSizeUnsafe (n); 00585 for (size_t i = old_len ; i < n ; i++) 00586 ElementHandler::Construct (root.p + i, what); 00587 } 00588 } 00589 00597 void SetSize (size_t n) 00598 { 00599 if (n <= count) 00600 { 00601 Truncate (n); 00602 } 00603 else 00604 { 00605 size_t old_len = GetSize (); 00606 SetSizeUnsafe (n); 00607 ElementHandler::InitRegion (root.p + old_len, n-old_len); 00608 } 00609 } 00610 00611 00613 T& Get (size_t n) 00614 { 00615 CS_ASSERT (n < count); 00616 return root.p[n]; 00617 } 00618 00620 T const& Get (size_t n) const 00621 { 00622 CS_ASSERT (n < count); 00623 return root.p[n]; 00624 } 00625 00631 T& GetExtend (size_t n) 00632 { 00633 if (n >= count) 00634 SetSize (n+1); 00635 return root.p[n]; 00636 } 00637 00643 T& GetExtend (size_t n, T const& what) 00644 { 00645 if (n >= count) 00646 SetSize (n+1, what); 00647 return root.p[n]; 00648 } 00649 00651 T& operator [] (size_t n) 00652 { 00653 return Get(n); 00654 } 00655 00657 T const& operator [] (size_t n) const 00658 { 00659 return Get(n); 00660 } 00661 00663 void Put (size_t n, T const& what) 00664 { 00665 if (n >= count) 00666 SetSize (n+1); 00667 ElementHandler::Destroy (root.p + n); 00668 ElementHandler::Construct (root.p + n, what); 00669 } 00670 00678 template <class K> 00679 size_t FindKey (csArrayCmp<T,K> comparekey) const 00680 { 00681 for (size_t i = 0 ; i < GetSize () ; i++) 00682 if (comparekey (root.p[i]) == 0) 00683 return i; 00684 return csArrayItemNotFound; 00685 } 00686 00691 size_t Push (T const& what) 00692 { 00693 if (((&what >= root.p) && (&what < root.p + GetSize())) && 00694 (capacity.c < count + 1)) 00695 { 00696 /* 00697 Special case: An element from this very array is pushed, and a 00698 reallocation is needed. This could cause the passed ref to the 00699 element to be pushed to be read from deleted memory. Work 00700 around this. 00701 */ 00702 size_t whatIndex = &what - root.p; 00703 SetSizeUnsafe (count + 1); 00704 ElementHandler::Construct (root.p + count - 1, root.p[whatIndex]); 00705 } 00706 else 00707 { 00708 SetSizeUnsafe (count + 1); 00709 ElementHandler::Construct (root.p + count - 1, what); 00710 } 00711 return count - 1; 00712 } 00713 00718 size_t PushSmart (T const& what) 00719 { 00720 size_t const n = Find (what); 00721 return (n == csArrayItemNotFound) ? Push (what) : n; 00722 } 00723 00725 T Pop () 00726 { 00727 CS_ASSERT (count > 0); 00728 T ret(root.p [count - 1]); 00729 ElementHandler::Destroy (root.p + count - 1); 00730 SetSizeUnsafe (count - 1); 00731 return ret; 00732 } 00733 00735 T const& Top () const 00736 { 00737 CS_ASSERT (count > 0); 00738 return root.p [count - 1]; 00739 } 00740 00742 T& Top () 00743 { 00744 CS_ASSERT (count > 0); 00745 return root.p [count - 1]; 00746 } 00747 00749 bool Insert (size_t n, T const& item) 00750 { 00751 if (n <= count) 00752 { 00753 SetSizeUnsafe (count + 1); // Increments 'count' as a side-effect. 00754 size_t const nmove = (count - n - 1); 00755 if (nmove > 0) 00756 ElementHandler::MoveElements (root.p, n+1, n, nmove); 00757 ElementHandler::Construct (root.p + n, item); 00758 return true; 00759 } 00760 else 00761 return false; 00762 } 00763 00767 csArray<T> Section (size_t low, size_t high) const 00768 { 00769 CS_ASSERT (high < count && high >= low); 00770 csArray<T> sect (high - low + 1); 00771 for (size_t i = low; i <= high; i++) sect.Push (root.p[i]); 00772 return sect; 00773 } 00774 00780 template <class K> 00781 size_t FindSortedKey (csArrayCmp<T,K> comparekey, 00782 size_t* candidate = 0) const 00783 { 00784 size_t m = 0, l = 0, r = GetSize (); 00785 while (l < r) 00786 { 00787 m = (l + r) / 2; 00788 int cmp = comparekey (root.p[m]); 00789 if (cmp == 0) 00790 { 00791 if (candidate) *candidate = csArrayItemNotFound; 00792 return m; 00793 } 00794 else if (cmp < 0) 00795 l = m + 1; 00796 else 00797 r = m; 00798 } 00799 if ((m + 1) == r) 00800 m++; 00801 if (candidate) *candidate = m; 00802 return csArrayItemNotFound; 00803 } 00804 00815 size_t InsertSorted (const T& item, 00816 int (*compare)(T const&, T const&) = DefaultCompare, 00817 size_t* equal_index = 0) 00818 { 00819 size_t m = 0, l = 0, r = GetSize (); 00820 while (l < r) 00821 { 00822 m = (l + r) / 2; 00823 int cmp = compare (root.p [m], item); 00824 00825 if (cmp == 0) 00826 { 00827 if (equal_index) *equal_index = m; 00828 Insert (++m, item); 00829 return m; 00830 } 00831 else if (cmp < 0) 00832 l = m + 1; 00833 else 00834 r = m; 00835 } 00836 if ((m + 1) == r) 00837 m++; 00838 if (equal_index) *equal_index = csArrayItemNotFound; 00839 Insert (m, item); 00840 return m; 00841 } 00842 00849 size_t Find (T const& which) const 00850 { 00851 for (size_t i = 0 ; i < GetSize () ; i++) 00852 if (root.p[i] == which) 00853 return i; 00854 return csArrayItemNotFound; 00855 } 00856 00858 size_t Contains(T const& which) const 00859 { return Find(which); } 00860 00867 size_t GetIndex (const T* which) const 00868 { 00869 CS_ASSERT (which >= root.p); 00870 CS_ASSERT (which < (root.p + count)); 00871 return which-root.p; 00872 } 00873 00877 void Sort (int (*compare)(T const&, T const&) = DefaultCompare) 00878 { 00879 qsort (root.p, GetSize (), sizeof(T), 00880 (int (*)(void const*, void const*))compare); 00881 } 00882 00886 void DeleteAll () 00887 { 00888 if (root.p) 00889 { 00890 size_t i; 00891 for (i = 0 ; i < count ; i++) 00892 ElementHandler::Destroy (root.p + i); 00893 root.Free (root.p); 00894 root.p = 0; 00895 capacity.c = count = 0; 00896 } 00897 } 00898 00910 void Truncate (size_t n) 00911 { 00912 CS_ASSERT(n <= count); 00913 if (n < count) 00914 { 00915 for (size_t i = n; i < count; i++) 00916 ElementHandler::Destroy (root.p + i); 00917 SetSizeUnsafe(n); 00918 } 00919 } 00920 00926 void Empty () 00927 { 00928 Truncate (0); 00929 } 00930 00936 bool IsEmpty() const 00937 { 00938 return GetSize() == 0; 00939 } 00940 00947 void SetCapacity (size_t n) 00948 { 00949 if (n > GetSize ()) 00950 InternalSetCapacity (n); 00951 } 00952 00960 void SetMinimalCapacity (size_t n) 00961 { 00962 if (n < Capacity ()) return; 00963 if (n > GetSize ()) 00964 InternalSetCapacity (n); 00965 } 00966 00972 void ShrinkBestFit () 00973 { 00974 if (count == 0) 00975 { 00976 DeleteAll (); 00977 } 00978 else if (count != capacity.c) 00979 { 00980 root.p = ElementHandler::ResizeRegion (root, root.p, count, capacity.c, count); 00981 capacity.c = count; 00982 } 00983 } 00984 00993 bool DeleteIndex (size_t n) 00994 { 00995 if (n < count) 00996 { 00997 size_t const ncount = count - 1; 00998 size_t const nmove = ncount - n; 00999 ElementHandler::Destroy (root.p + n); 01000 if (nmove > 0) 01001 ElementHandler::MoveElements (root.p, n, n+1, nmove); 01002 SetSizeUnsafe (ncount); 01003 return true; 01004 } 01005 else 01006 return false; 01007 } 01008 01018 bool DeleteIndexFast (size_t n) 01019 { 01020 if (n < count) 01021 { 01022 size_t const ncount = count - 1; 01023 size_t const nmove = ncount - n; 01024 ElementHandler::Destroy (root.p + n); 01025 if (nmove > 0) 01026 ElementHandler::MoveElements (root.p, n, ncount, 1); 01027 SetSizeUnsafe (ncount); 01028 return true; 01029 } 01030 else 01031 return false; 01032 } 01033 01040 bool DeleteRange (size_t start, size_t end) 01041 { 01042 if (start >= count) return false; 01043 // Treat 'csArrayItemNotFound' as invalid indices, do nothing. 01044 if (end == csArrayItemNotFound) return false; 01045 if (start == csArrayItemNotFound) return false;//start = 0; 01046 if (end >= count) end = count - 1; 01047 size_t i; 01048 for (i = start ; i <= end ; i++) 01049 ElementHandler::Destroy (root.p + i); 01050 01051 size_t const range_size = end - start + 1; 01052 size_t const ncount = count - range_size; 01053 size_t const nmove = count - end - 1; 01054 if (nmove > 0) 01055 ElementHandler::MoveElements (root.p, start, start + range_size, nmove); 01056 SetSizeUnsafe (ncount); 01057 return true; 01058 } 01059 01065 bool Delete (T const& item) 01066 { 01067 size_t const n = Find (item); 01068 if (n != csArrayItemNotFound) 01069 return DeleteIndex (n); 01070 return false; 01071 } 01072 01074 class Iterator 01075 { 01076 public: 01078 Iterator(Iterator const& r) : 01079 currentelem(r.currentelem), array(r.array) {} 01080 01082 Iterator& operator=(Iterator const& r) 01083 { currentelem = r.currentelem; array = r.array; return *this; } 01084 01086 bool HasNext() const 01087 { return currentelem < array.GetSize (); } 01088 01090 T& Next() 01091 { return array.Get(currentelem++); } 01092 01094 void Reset() 01095 { currentelem = 0; } 01096 01097 protected: 01098 Iterator(csArray<T, ElementHandler, MemoryAllocator, CapacityHandler>& newarray) 01099 : currentelem(0), array(newarray) {} 01100 friend class csArray<T, ElementHandler, MemoryAllocator, CapacityHandler>; 01101 01102 private: 01103 size_t currentelem; 01104 csArray<T, ElementHandler, MemoryAllocator, CapacityHandler>& array; 01105 }; 01106 01108 class ConstIterator 01109 { 01110 public: 01112 ConstIterator(ConstIterator const& r) : 01113 currentelem(r.currentelem), array(r.array) {} 01114 01116 ConstIterator& operator=(ConstIterator const& r) 01117 { currentelem = r.currentelem; array = r.array; return *this; } 01118 01120 bool HasNext() const 01121 { return currentelem < array.GetSize (); } 01122 01124 const T& Next() 01125 { return array.Get(currentelem++); } 01126 01128 void Reset() 01129 { currentelem = 0; } 01130 01131 protected: 01132 ConstIterator(const csArray<T, ElementHandler, MemoryAllocator, CapacityHandler>& newarray) 01133 : currentelem(0), array(newarray) {} 01134 friend class csArray<T, ElementHandler, MemoryAllocator, CapacityHandler>; 01135 01136 private: 01137 size_t currentelem; 01138 const csArray<T, ElementHandler, MemoryAllocator, CapacityHandler>& array; 01139 }; 01140 01142 Iterator GetIterator() 01143 { return Iterator(*this); } 01144 01146 ConstIterator GetIterator() const 01147 { return ConstIterator(*this); } 01148 01150 bool operator== (const csArray& other) const 01151 { 01152 if (other.GetSize() != GetSize()) return false; 01153 for (size_t i = 0; i < GetSize(); i++) 01154 if (Get (i) != other[i]) return false; 01155 return true; 01156 } 01157 01158 bool operator!= (const csArray& other) const { return !(*this==other); } 01159 01161 const MemoryAllocator& GetAllocator() const 01162 { 01163 return root; 01164 } 01165 01170 CS_DEPRECATED_METHOD_MSG("Use GetSize() instead.") 01171 size_t Length () const 01172 { 01173 return GetSize(); 01174 } 01175 01181 CS_DEPRECATED_METHOD_MSG("Use SetSize() instead.") 01182 void SetLength (size_t n, T const& what) { SetSize(n, what); } 01183 CS_DEPRECATED_METHOD_MSG("Use SetSize() instead.") 01184 void SetLength (size_t n) { SetSize(n); } 01187 }; 01188 01194 template <class T> 01195 class csSafeCopyArray 01196 : public csArray<T, 01197 csArraySafeCopyElementHandler<T> > 01198 { 01199 public: 01204 csSafeCopyArray (size_t limit = 0, size_t threshold = 0) 01205 : csArray<T, csArraySafeCopyElementHandler<T> > (limit, threshold) 01206 { 01207 } 01208 }; 01209 01210 #include "csutil/custom_new_enable.h" 01211 01214 #endif
Generated for Crystal Space 1.2.1 by doxygen 1.5.3