fixedsizearray.hpp

Go to the documentation of this file.
00001 /* $Id: fixedsizearray.hpp 15718 2009-03-15 00:32:18Z rubidium $ */
00002 
00005 #ifndef  FIXEDSIZEARRAY_HPP
00006 #define  FIXEDSIZEARRAY_HPP
00007 
00008 
00013 template <class Titem_, int Tcapacity_>
00014 struct CFixedSizeArrayT {
00017   Titem_ *m_items;
00018 
00020   struct CHdr
00021   {
00022     int    m_num_items; 
00023     int    m_ref_cnt;   
00024   };
00025 
00026   /* make types and constants visible from outside */
00027   typedef Titem_ Titem; // type of array item
00028 
00029   static const int Tcapacity = Tcapacity_;     // the array capacity (maximum size)
00030   static const int TitemSize = sizeof(Titem_); // size of item
00031   static const int ThdrSize  = sizeof(CHdr);   // size of header
00032 
00034   CFixedSizeArrayT()
00035   {
00036     /* allocate block for header + items (don't construct items) */
00037     m_items = (Titem*)((MallocT<int8>(ThdrSize + Tcapacity * sizeof(Titem))) + ThdrSize);
00038     SizeRef() = 0; // initial number of items
00039     RefCnt() = 1; // initial reference counter
00040   }
00041 
00043   CFixedSizeArrayT(const CFixedSizeArrayT<Titem_, Tcapacity_>& src)
00044   {
00045     /* share block (header + items) with the source array */
00046     m_items = src.m_items;
00047     RefCnt()++; // now we share block with the source
00048   }
00049 
00051   ~CFixedSizeArrayT()
00052   {
00053     /* release one reference to the shared block */
00054     if ((--RefCnt()) > 0) return; // and return if there is still some owner
00055 
00056     Clear();
00057     /* free the memory block occupied by items */
00058     free(((int8*)m_items) - ThdrSize);
00059     m_items = NULL;
00060   }
00061 
00063   FORCEINLINE void Clear()
00064   {
00065     /* walk through all allocated items backward and destroy them */
00066     for (Titem *pItem = &m_items[Size() - 1]; pItem >= m_items; pItem--) {
00067       pItem->~Titem_();
00068     }
00069     /* number of items become zero */
00070     SizeRef() = 0;
00071   }
00072 
00073 protected:
00075   FORCEINLINE CHdr& Hdr() { return *(CHdr*)(((int8*)m_items) - ThdrSize); }
00077   FORCEINLINE const CHdr& Hdr() const { return *(CHdr*)(((int8*)m_items) - ThdrSize); }
00079   FORCEINLINE int& RefCnt() { return Hdr().m_ref_cnt; }
00081   FORCEINLINE int& SizeRef() { return Hdr().m_num_items; }
00082 public:
00084   FORCEINLINE int Size() const { return Hdr().m_num_items; }
00086   FORCEINLINE bool IsFull() const { return Size() >= Tcapacity; };
00088   FORCEINLINE bool IsEmpty() const { return Size() <= 0; };
00090   FORCEINLINE void CheckIdx(int idx) const { assert(idx >= 0); assert(idx < Size()); }
00092   FORCEINLINE Titem& AddNC() { assert(!IsFull()); return m_items[SizeRef()++]; }
00094   FORCEINLINE Titem& Add() { Titem& item = AddNC(); new(&item)Titem; return item; }
00096   FORCEINLINE Titem& operator [] (int idx) { CheckIdx(idx); return m_items[idx]; }
00098   FORCEINLINE const Titem& operator [] (int idx) const { CheckIdx(idx); return m_items[idx]; }
00099 };
00100 
00101 #endif /* FIXEDSIZEARRAY_HPP */

Generated on Wed Apr 1 14:38:06 2009 for OpenTTD by  doxygen 1.5.6