OpenTTD
fixedsizearray.hpp
Go to the documentation of this file.
1 /*
2  * This file is part of OpenTTD.
3  * 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.
4  * 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.
5  * 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/>.
6  */
7 
10 #ifndef FIXEDSIZEARRAY_HPP
11 #define FIXEDSIZEARRAY_HPP
12 
13 #include "../core/alloc_func.hpp"
14 
21 template <class T, uint C>
23 protected:
25  struct ArrayHeader
26  {
27  uint items;
29  };
30 
31  /* make constants visible from outside */
32  static const uint Tsize = sizeof(T);
33  static const uint HeaderSize = sizeof(ArrayHeader);
34 
39  T *data;
40 
42  inline ArrayHeader& Hdr()
43  {
44  return *(ArrayHeader*)(((byte*)data) - HeaderSize);
45  }
46 
48  inline const ArrayHeader& Hdr() const
49  {
50  return *(ArrayHeader*)(((byte*)data) - HeaderSize);
51  }
52 
54  inline uint& RefCnt()
55  {
56  return Hdr().reference_count;
57  }
58 
60  inline uint& SizeRef()
61  {
62  return Hdr().items;
63  }
64 
65 public:
68  {
69  /* Ensure the size won't overflow. */
70  assert_compile(C < (SIZE_MAX - HeaderSize) / Tsize);
71 
72  /* allocate block for header + items (don't construct items) */
73  data = (T*)((MallocT<byte>(HeaderSize + C * Tsize)) + HeaderSize);
74  SizeRef() = 0; // initial number of items
75  RefCnt() = 1; // initial reference counter
76  }
77 
80  {
81  /* share block (header + items) with the source array */
82  data = src.data;
83  RefCnt()++; // now we share block with the source
84  }
85 
88  {
89  /* release one reference to the shared block */
90  if ((--RefCnt()) > 0) return; // and return if there is still some owner
91 
92  Clear();
93  /* free the memory block occupied by items */
94  free(((byte*)data) - HeaderSize);
95  data = nullptr;
96  }
97 
99  inline void Clear()
100  {
101  /* Walk through all allocated items backward and destroy them
102  * Note: this->Length() can be zero. In that case data[this->Length() - 1] is evaluated unsigned
103  * on some compilers with some architectures. (e.g. gcc with x86) */
104  for (T *pItem = this->data + this->Length() - 1; pItem >= this->data; pItem--) {
105  pItem->~T();
106  }
107  /* number of items become zero */
108  SizeRef() = 0;
109  }
110 
112  inline uint Length() const
113  {
114  return Hdr().items;
115  }
116 
118  inline bool IsFull() const
119  {
120  return Length() >= C;
121  }
122 
124  inline bool IsEmpty() const
125  {
126  return Length() <= 0;
127  }
128 
130  inline T *Append()
131  {
132  assert(!IsFull());
133  return &data[SizeRef()++];
134  }
135 
137  inline T *AppendC()
138  {
139  T *item = Append();
140  new(item)T;
141  return item;
142  }
144  inline T& operator[](uint index)
145  {
146  assert(index < Length());
147  return data[index];
148  }
149 
151  inline const T& operator[](uint index) const
152  {
153  assert(index < Length());
154  return data[index];
155  }
156 };
157 
158 #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:129
uint & SizeRef()
return reference to number of used items
uint & RefCnt()
return reference to the block reference counter
header for fixed size array