OpenTTD
fixedsizearray.hpp
Go to the documentation of this file.
1 /* $Id: fixedsizearray.hpp 27363 2015-08-08 13:19:38Z alberth $ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * 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.
6  * 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.
7  * 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/>.
8  */
9 
12 #ifndef FIXEDSIZEARRAY_HPP
13 #define FIXEDSIZEARRAY_HPP
14 
15 #include "../core/alloc_func.hpp"
16 
23 template <class T, uint C>
25 protected:
27  struct ArrayHeader
28  {
29  uint items;
31  };
32 
33  /* make constants visible from outside */
34  static const uint Tsize = sizeof(T);
35  static const uint HeaderSize = sizeof(ArrayHeader);
36 
41  T *data;
42 
44  inline ArrayHeader& Hdr()
45  {
46  return *(ArrayHeader*)(((byte*)data) - HeaderSize);
47  }
48 
50  inline const ArrayHeader& Hdr() const
51  {
52  return *(ArrayHeader*)(((byte*)data) - HeaderSize);
53  }
54 
56  inline uint& RefCnt()
57  {
58  return Hdr().reference_count;
59  }
60 
62  inline uint& SizeRef()
63  {
64  return Hdr().items;
65  }
66 
67 public:
70  {
71  /* Ensure the size won't overflow. */
72  assert_compile(C < (SIZE_MAX - HeaderSize) / Tsize);
73 
74  /* allocate block for header + items (don't construct items) */
75  data = (T*)((MallocT<byte>(HeaderSize + C * Tsize)) + HeaderSize);
76  SizeRef() = 0; // initial number of items
77  RefCnt() = 1; // initial reference counter
78  }
79 
82  {
83  /* share block (header + items) with the source array */
84  data = src.data;
85  RefCnt()++; // now we share block with the source
86  }
87 
90  {
91  /* release one reference to the shared block */
92  if ((--RefCnt()) > 0) return; // and return if there is still some owner
93 
94  Clear();
95  /* free the memory block occupied by items */
96  free(((byte*)data) - HeaderSize);
97  data = NULL;
98  }
99 
101  inline void Clear()
102  {
103  /* Walk through all allocated items backward and destroy them
104  * Note: this->Length() can be zero. In that case data[this->Length() - 1] is evaluated unsigned
105  * on some compilers with some architectures. (e.g. gcc with x86) */
106  for (T *pItem = this->data + this->Length() - 1; pItem >= this->data; pItem--) {
107  pItem->~T();
108  }
109  /* number of items become zero */
110  SizeRef() = 0;
111  }
112 
114  inline uint Length() const
115  {
116  return Hdr().items;
117  }
118 
120  inline bool IsFull() const
121  {
122  return Length() >= C;
123  }
124 
126  inline bool IsEmpty() const
127  {
128  return Length() <= 0;
129  }
130 
132  inline T *Append()
133  {
134  assert(!IsFull());
135  return &data[SizeRef()++];
136  }
137 
139  inline T *AppendC()
140  {
141  T *item = Append();
142  new(item)T;
143  return item;
144  }
146  inline T& operator[](uint index)
147  {
148  assert(index < Length());
149  return data[index];
150  }
151 
153  inline const T& operator[](uint index) const
154  {
155  assert(index < Length());
156  return data[index];
157  }
158 };
159 
160 #endif /* FIXEDSIZEARRAY_HPP */
bool IsEmpty() const
return true if array is empty
T * Append()
add (allocate), but don&#39;t construct item
FixedSizeArray()
Default constructor.
bool IsFull() const
return true if array is full
FixedSizeArray(const FixedSizeArray< T, C > &src)
Copy constructor.
ArrayHeader & Hdr()
return reference to the array header (non-const)
T & operator[](uint index)
return item by index (non-const version)
uint items
number of items in the array
T * data
the only member of fixed size array is pointer to the block of C array of items.
static const uint Tsize
size of item
const ArrayHeader & Hdr() const
return reference to the array header (const)
~FixedSizeArray()
destroy remaining items and free the memory block
uint Length() const
return number of used items
uint reference_count
block reference counter (used by copy constructor and by destructor)
fixed size array Upon construction it preallocates fixed size block of memory for all items...
void Clear()
Clear (destroy) all items.
static const uint HeaderSize
size of header
T * AppendC()
add and construct item using default constructor
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
Definition: depend.cpp:114
uint & SizeRef()
return reference to number of used items
uint & RefCnt()
return reference to the block reference counter
header for fixed size array