summaryrefslogtreecommitdiff
path: root/src/misc/array.hpp
diff options
context:
space:
mode:
authorKUDr <kudr@openttd.org>2007-01-13 13:33:36 +0000
committerKUDr <kudr@openttd.org>2007-01-13 13:33:36 +0000
commitf2e5e604fb671a1b86a942ea9bb480c03b5efa9d (patch)
treec12c9235da9fd1c9933108865ca991fa1f3092e4 /src/misc/array.hpp
parent38a9d092147cb48c48a786c10ec6a493e63f03c3 (diff)
downloadopenttd-f2e5e604fb671a1b86a942ea9bb480c03b5efa9d.tar.xz
(svn r8092) -Codechange: header files with miscellaneous template classes (smart pointers, blob, array, hashtable, etc.) moved from src/yapf to src/misc as they can now be used anywhere.
Diffstat (limited to 'src/misc/array.hpp')
-rw-r--r--src/misc/array.hpp71
1 files changed, 71 insertions, 0 deletions
diff --git a/src/misc/array.hpp b/src/misc/array.hpp
new file mode 100644
index 000000000..e8eff1c8c
--- /dev/null
+++ b/src/misc/array.hpp
@@ -0,0 +1,71 @@
+/* $Id$ */
+
+#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
+ {
+ CSubArray& sa = m_a[idx / Tblock_size];
+ Titem& item = sa [idx % Tblock_size];
+ return item;
+ }
+};
+
+#endif /* ARRAY_HPP */