CrystalSpace

Public API Reference

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