Files @ r7596:afd285ff90bb
Branch filter:

Location: cpp/openttd-patchpack/source/src/misc/array.hpp

miham
(svn r11123) -Update: WebTranslator2 update to 2007-09-17 12:45:29
afrikaans - 47 fixed, 52 changed by TrueTenacity (99)
brazilian_portuguese - 23 changed by fukumori (23)
bulgarian - 14 fixed by thetitan (14)
catalan - 3 changed by arnaullv (3)
croatian - 6 fixed, 12 changed by knovak (15), tperic (3)
danish - 20 fixed by ThomasA (20)
finnish - 20 fixed by habazi (20)
german - 10 fixed by Timwi (10)
hungarian - 1 fixed by miham (1)
italian - 1 fixed by lorenzodv (1)
japanese - 6 fixed by ickoonite (6)
norwegian_nynorsk - 6 fixed by pollux (6)
piglatin - 20 fixed by adammw (20)
russian - 20 fixed by Smoky555 (20)
slovak - 1 fixed by lengyel (1)
slovenian - 7 fixed by Necrolyte (7)
spanish - 1 changed by Cabu (1)
traditional_chinese - 21 fixed by xbddc (21)
/* $Id$ */

/** @file array.hpp */

#ifndef  ARRAY_HPP
#define  ARRAY_HPP

#include "fixedsizearray.hpp"

/** Flexible array with size limit. Implemented as fixed size
 *  array of fixed size arrays */
template <class Titem_, int Tblock_size_ = 1024, int Tnum_blocks_ = Tblock_size_>
class CArrayT {
public:
	typedef Titem_ Titem; ///< Titem is now visible from outside
	typedef CFixedSizeArrayT<Titem_, Tblock_size_> CSubArray; ///< inner array
	typedef CFixedSizeArrayT<CSubArray, Tnum_blocks_> CSuperArray; ///< outer array

protected:
	CSuperArray     m_a; ///< array of arrays of items

public:
	static const int Tblock_size = Tblock_size_; ///< block size is now visible from outside
	static const int Tnum_blocks = Tnum_blocks_; ///< number of blocks is now visible from outside
	static const int Tcapacity   = Tblock_size * Tnum_blocks; ///< total max number of items

	/** implicit constructor */
	FORCEINLINE CArrayT() { }
	/** Clear (destroy) all items */
	FORCEINLINE void Clear() {m_a.Clear();}
	/** Return actual number of items */
	FORCEINLINE int Size() const
	{
		int super_size = m_a.Size();
		if (super_size == 0) return 0;
		int sub_size = m_a[super_size - 1].Size();
		return (super_size - 1) * Tblock_size + sub_size;
	}
	/** return true if array is empty */
	FORCEINLINE bool IsEmpty() { return m_a.IsEmpty(); }
	/** return true if array is full */
	FORCEINLINE bool IsFull() { return m_a.IsFull() && m_a[Tnum_blocks - 1].IsFull(); }
	/** return first sub-array with free space for new item */
	FORCEINLINE CSubArray& FirstFreeSubArray()
	{
		int super_size = m_a.Size();
		if (super_size > 0) {
			CSubArray& sa = m_a[super_size - 1];
			if (!sa.IsFull()) return sa;
		}
		return m_a.Add();
	}
	/** allocate but not construct new item */
	FORCEINLINE Titem_& AddNC() { return FirstFreeSubArray().AddNC(); }
	/** allocate and construct new item */
	FORCEINLINE Titem_& Add()   { return FirstFreeSubArray().Add(); }
	/** indexed access (non-const) */
	FORCEINLINE Titem& operator [] (int idx)
	{
		CSubArray& sa = m_a[idx / Tblock_size];
		Titem& item   = sa [idx % Tblock_size];
		return item;
	}
	/** indexed access (const) */
	FORCEINLINE const Titem& operator [] (int idx) const
	{
		const CSubArray& sa = m_a[idx / Tblock_size];
		const Titem& item   = sa [idx % Tblock_size];
		return item;
	}

	template <typename D> void Dump(D &dmp) const
	{
		dmp.WriteLine("capacity = %d", Tcapacity);
		int num_items = Size();
		dmp.WriteLine("num_items = %d", num_items);
		CStrA name;
		for (int i = 0; i < num_items; i++) {
			const Titem& item = (*this)[i];
			name.Format("item[%d]", i);
			dmp.WriteStructT(name.Data(), &item);
		}
	}
};

#endif /* ARRAY_HPP */