fixedsizearray.hpp

Go to the documentation of this file.
00001 /* $Id: fixedsizearray.hpp 17248 2009-08-21 20:21:05Z rubidium $ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
00008  */
00009 
00012 #ifndef  FIXEDSIZEARRAY_HPP
00013 #define  FIXEDSIZEARRAY_HPP
00014 
00015 
00020 template <class Titem_, int Tcapacity_>
00021 struct CFixedSizeArrayT {
00024   Titem_ *m_items;
00025 
00027   struct CHdr
00028   {
00029     int    m_num_items; 
00030     int    m_ref_cnt;   
00031   };
00032 
00033   /* make types and constants visible from outside */
00034   typedef Titem_ Titem; // type of array item
00035 
00036   static const int Tcapacity = Tcapacity_;     // the array capacity (maximum size)
00037   static const int TitemSize = sizeof(Titem_); // size of item
00038   static const int ThdrSize  = sizeof(CHdr);   // size of header
00039 
00041   CFixedSizeArrayT()
00042   {
00043     /* allocate block for header + items (don't construct items) */
00044     m_items = (Titem*)((MallocT<int8>(ThdrSize + Tcapacity * sizeof(Titem))) + ThdrSize);
00045     SizeRef() = 0; // initial number of items
00046     RefCnt() = 1; // initial reference counter
00047   }
00048 
00050   CFixedSizeArrayT(const CFixedSizeArrayT<Titem_, Tcapacity_>& src)
00051   {
00052     /* share block (header + items) with the source array */
00053     m_items = src.m_items;
00054     RefCnt()++; // now we share block with the source
00055   }
00056 
00058   ~CFixedSizeArrayT()
00059   {
00060     /* release one reference to the shared block */
00061     if ((--RefCnt()) > 0) return; // and return if there is still some owner
00062 
00063     Clear();
00064     /* free the memory block occupied by items */
00065     free(((int8*)m_items) - ThdrSize);
00066     m_items = NULL;
00067   }
00068 
00070   FORCEINLINE void Clear()
00071   {
00072     /* walk through all allocated items backward and destroy them */
00073     for (Titem *pItem = &m_items[Size() - 1]; pItem >= m_items; pItem--) {
00074       pItem->~Titem_();
00075     }
00076     /* number of items become zero */
00077     SizeRef() = 0;
00078   }
00079 
00080 protected:
00082   FORCEINLINE CHdr& Hdr() { return *(CHdr*)(((int8*)m_items) - ThdrSize); }
00084   FORCEINLINE const CHdr& Hdr() const { return *(CHdr*)(((int8*)m_items) - ThdrSize); }
00086   FORCEINLINE int& RefCnt() { return Hdr().m_ref_cnt; }
00088   FORCEINLINE int& SizeRef() { return Hdr().m_num_items; }
00089 public:
00091   FORCEINLINE int Size() const { return Hdr().m_num_items; }
00093   FORCEINLINE bool IsFull() const { return Size() >= Tcapacity; };
00095   FORCEINLINE bool IsEmpty() const { return Size() <= 0; };
00097   FORCEINLINE void CheckIdx(int idx) const { assert(idx >= 0); assert(idx < Size()); }
00099   FORCEINLINE Titem& AddNC() { assert(!IsFull()); return m_items[SizeRef()++]; }
00101   FORCEINLINE Titem& Add() { Titem& item = AddNC(); new(&item)Titem; return item; }
00103   FORCEINLINE Titem& operator [] (int idx) { CheckIdx(idx); return m_items[idx]; }
00105   FORCEINLINE const Titem& operator [] (int idx) const { CheckIdx(idx); return m_items[idx]; }
00106 };
00107 
00108 #endif /* FIXEDSIZEARRAY_HPP */

Generated on Tue Jan 5 21:02:54 2010 for OpenTTD by  doxygen 1.5.6