OpenTTD Source  1.11.2
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  static_assert(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 */
FixedSizeArray::FixedSizeArray
FixedSizeArray()
Default constructor.
Definition: fixedsizearray.hpp:67
FixedSizeArray::RefCnt
uint & RefCnt()
return reference to the block reference counter
Definition: fixedsizearray.hpp:54
FixedSizeArray::Clear
void Clear()
Clear (destroy) all items.
Definition: fixedsizearray.hpp:99
FixedSizeArray::HeaderSize
static const uint HeaderSize
size of header
Definition: fixedsizearray.hpp:33
FixedSizeArray::Tsize
static const uint Tsize
size of item
Definition: fixedsizearray.hpp:32
FixedSizeArray::data
T * data
the only member of fixed size array is pointer to the block of C array of items.
Definition: fixedsizearray.hpp:39
FixedSizeArray::FixedSizeArray
FixedSizeArray(const FixedSizeArray< T, C > &src)
Copy constructor.
Definition: fixedsizearray.hpp:79
FixedSizeArray::operator[]
T & operator[](uint index)
return item by index (non-const version)
Definition: fixedsizearray.hpp:144
FixedSizeArray::IsEmpty
bool IsEmpty() const
return true if array is empty
Definition: fixedsizearray.hpp:124
FixedSizeArray::Hdr
const ArrayHeader & Hdr() const
return reference to the array header (const)
Definition: fixedsizearray.hpp:48
FixedSizeArray::ArrayHeader
header for fixed size array
Definition: fixedsizearray.hpp:25
FixedSizeArray::SizeRef
uint & SizeRef()
return reference to number of used items
Definition: fixedsizearray.hpp:60
FixedSizeArray::ArrayHeader::items
uint items
number of items in the array
Definition: fixedsizearray.hpp:27
FixedSizeArray::Append
T * Append()
add (allocate), but don't construct item
Definition: fixedsizearray.hpp:130
FixedSizeArray::IsFull
bool IsFull() const
return true if array is full
Definition: fixedsizearray.hpp:118
FixedSizeArray
fixed size array Upon construction it preallocates fixed size block of memory for all items,...
Definition: fixedsizearray.hpp:22
FixedSizeArray::ArrayHeader::reference_count
uint reference_count
block reference counter (used by copy constructor and by destructor)
Definition: fixedsizearray.hpp:28
FixedSizeArray::~FixedSizeArray
~FixedSizeArray()
destroy remaining items and free the memory block
Definition: fixedsizearray.hpp:87
FixedSizeArray::Length
uint Length() const
return number of used items
Definition: fixedsizearray.hpp:112
FixedSizeArray::Hdr
ArrayHeader & Hdr()
return reference to the array header (non-const)
Definition: fixedsizearray.hpp:42
free
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
Definition: stdafx.h:456
FixedSizeArray::AppendC
T * AppendC()
add and construct item using default constructor
Definition: fixedsizearray.hpp:137