KUDr@5633: /* $Id$ */ KUDr@5633: belugas@6481: /** @file array.hpp */ belugas@6481: KUDr@5633: #ifndef ARRAY_HPP KUDr@5633: #define ARRAY_HPP KUDr@5633: KUDr@5633: #include "fixedsizearray.hpp" KUDr@5633: KUDr@5633: /** Flexible array with size limit. Implemented as fixed size KUDr@5633: * array of fixed size arrays */ KUDr@5633: template KUDr@5633: class CArrayT { KUDr@5633: public: KUDr@5633: typedef Titem_ Titem; ///< Titem is now visible from outside KUDr@5633: typedef CFixedSizeArrayT CSubArray; ///< inner array KUDr@5633: typedef CFixedSizeArrayT CSuperArray; ///< outer array KUDr@5633: KUDr@5633: protected: KUDr@5633: CSuperArray m_a; ///< array of arrays of items KUDr@5633: KUDr@5633: public: KUDr@5633: static const int Tblock_size = Tblock_size_; ///< block size is now visible from outside KUDr@5633: static const int Tnum_blocks = Tnum_blocks_; ///< number of blocks is now visible from outside KUDr@5633: static const int Tcapacity = Tblock_size * Tnum_blocks; ///< total max number of items KUDr@5633: KUDr@5633: /** implicit constructor */ KUDr@5633: FORCEINLINE CArrayT() { } KUDr@5633: /** Clear (destroy) all items */ KUDr@5633: FORCEINLINE void Clear() {m_a.Clear();} KUDr@5633: /** Return actual number of items */ KUDr@5633: FORCEINLINE int Size() const KUDr@5633: { KUDr@5633: int super_size = m_a.Size(); KUDr@5633: if (super_size == 0) return 0; KUDr@5633: int sub_size = m_a[super_size - 1].Size(); KUDr@5633: return (super_size - 1) * Tblock_size + sub_size; KUDr@5633: } KUDr@5633: /** return true if array is empty */ KUDr@5633: FORCEINLINE bool IsEmpty() { return m_a.IsEmpty(); } KUDr@5633: /** return true if array is full */ KUDr@5633: FORCEINLINE bool IsFull() { return m_a.IsFull() && m_a[Tnum_blocks - 1].IsFull(); } KUDr@5633: /** return first sub-array with free space for new item */ KUDr@5633: FORCEINLINE CSubArray& FirstFreeSubArray() KUDr@5633: { KUDr@5633: int super_size = m_a.Size(); KUDr@5633: if (super_size > 0) { KUDr@5633: CSubArray& sa = m_a[super_size - 1]; KUDr@5633: if (!sa.IsFull()) return sa; KUDr@5633: } KUDr@5633: return m_a.Add(); KUDr@5633: } KUDr@5633: /** allocate but not construct new item */ KUDr@5633: FORCEINLINE Titem_& AddNC() { return FirstFreeSubArray().AddNC(); } KUDr@5633: /** allocate and construct new item */ KUDr@5633: FORCEINLINE Titem_& Add() { return FirstFreeSubArray().Add(); } KUDr@5633: /** indexed access (non-const) */ KUDr@5633: FORCEINLINE Titem& operator [] (int idx) KUDr@5633: { KUDr@5633: CSubArray& sa = m_a[idx / Tblock_size]; KUDr@5633: Titem& item = sa [idx % Tblock_size]; KUDr@5633: return item; KUDr@5633: } KUDr@5633: /** indexed access (const) */ KUDr@5633: FORCEINLINE const Titem& operator [] (int idx) const KUDr@5633: { KUDr@7117: const CSubArray& sa = m_a[idx / Tblock_size]; KUDr@7117: const Titem& item = sa [idx % Tblock_size]; KUDr@5633: return item; KUDr@5633: } KUDr@7119: KUDr@7119: template void Dump(D &dmp) const KUDr@7119: { KUDr@7119: dmp.WriteLine("capacity = %d", Tcapacity); KUDr@7119: int num_items = Size(); KUDr@7119: dmp.WriteLine("num_items = %d", num_items); KUDr@7119: CStrA name; KUDr@7119: for (int i = 0; i < num_items; i++) { KUDr@7119: const Titem& item = (*this)[i]; KUDr@7119: name.Format("item[%d]", i); KUDr@7119: dmp.WriteStructT(name.Data(), &item); KUDr@7119: } KUDr@7119: } KUDr@5633: }; KUDr@5633: KUDr@5633: #endif /* ARRAY_HPP */