00001 /* $Id: fixedsizearray.hpp 11597 2007-12-08 14:50:41Z 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 */