# fixedsizearray.hpp

Go to the documentation of this file.

    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 */