ezEngine  Milestone 7
HybridArray_inl.h
1 
2 template <typename T, ezUInt32 Size>
4 {
5  this->m_pElements = GetStaticArray();
6  this->m_uiCapacity = Size;
7  this->m_pAllocator = pAllocator;
8 }
9 
10 template <typename T, ezUInt32 Size>
12 {
13  this->m_pElements = GetStaticArray();
14  this->m_uiCapacity = Size;
15  this->m_pAllocator = pAllocator;
16 
17  ezArrayBase<T, ezHybridArrayBase<T, Size>>::operator=((ezArrayPtr<const T>)other); // redirect this to the ezArrayPtr version
18 }
19 
20 template <typename T, ezUInt32 Size>
22 {
23  this->m_pElements = GetStaticArray();
24  this->m_uiCapacity = Size;
25  this->m_pAllocator = pAllocator;
26 
27  *this = std::move(other);
28 }
29 
30 template <typename T, ezUInt32 Size>
32 {
33  this->m_pElements = GetStaticArray();
34  this->m_uiCapacity = Size;
35  this->m_pAllocator = pAllocator;
36 
38 }
39 
40 template <typename T, ezUInt32 Size>
42 {
43  this->Clear();
44 
45  if (this->m_pElements != GetStaticArray())
46  EZ_DELETE_RAW_BUFFER(this->m_pAllocator, this->m_pElements);
47 
48  this->m_pElements = nullptr;
49 }
50 
51 template <typename T, ezUInt32 Size>
53 {
54  return reinterpret_cast<T*>(m_StaticData);
55 }
56 
57 template <typename T, ezUInt32 Size>
59 {
60  ezArrayBase<T, ezHybridArrayBase<T, Size>>::operator=((ezArrayPtr<const T>)rhs); // redirect this to the ezArrayPtr version
61 }
62 
63 template <typename T, ezUInt32 Size>
65 {
66  if (rhs.m_pElements == rhs.GetStaticArray() || (m_pAllocator != rhs.m_pAllocator))
67  {
68  ezArrayBase<T, ezHybridArrayBase<T, Size>>::operator=((ezArrayPtr<const T>)rhs); // redirect this to the ezArrayPtr version
69  rhs.Clear();
70  }
71  else
72  {
73  // Move semantics !
74  // We cannot do this when the allocators of this and rhs are different,
75  // because the memory will be freed by this and not by rhs anymore.
76 
77  this->Clear();
78 
79  if (this->m_pElements != GetStaticArray())
80  EZ_DELETE_RAW_BUFFER(this->m_pAllocator, this->m_pElements);
81 
82  this->m_pElements = rhs.m_pElements;
83  this->m_uiCapacity = rhs.m_uiCapacity;
84  this->m_uiCount = rhs.m_uiCount;
85 
86  rhs.m_uiCount = 0;
87  rhs.m_pElements = rhs.GetStaticArray();
88  rhs.m_uiCapacity = Size;
89  }
90 }
91 
92 template <typename T, ezUInt32 Size>
93 void ezHybridArrayBase<T, Size>::SetCapacity(ezUInt32 uiCapacity)
94 {
95  T* pNewData = nullptr;
96 
97  // if the static buffer is sufficient, use that
98  if (uiCapacity <= Size)
99  {
100  this->m_uiCapacity = Size;
101 
102  // if we already use that static buffer, no reallocation is needed
103  if (this->m_pElements == GetStaticArray())
104  return;
105 
106  pNewData = GetStaticArray();
107  }
108  else
109  {
110  // otherwise allocate a new buffer
111  this->m_uiCapacity = uiCapacity;
112  pNewData = EZ_NEW_RAW_BUFFER(m_pAllocator, T, this->m_uiCapacity);
113  }
114 
115  ezMemoryUtils::RelocateConstruct(pNewData, this->m_pElements, this->m_uiCount);
116 
117  // if the previous buffer is not the static array, deallocate it
118  if (this->m_pElements != GetStaticArray())
119  EZ_DELETE_RAW_BUFFER(this->m_pAllocator, this->m_pElements);
120 
121  this->m_pElements = pNewData;
122 }
123 
124 template <typename T, ezUInt32 Size>
125 void ezHybridArrayBase<T, Size>::Reserve(ezUInt32 uiCapacity)
126 {
127  // m_uiCapacity will always be at least Size
128  if (this->m_uiCapacity >= uiCapacity)
129  return;
130 
131  ezUInt32 uiNewCapacity = ezMath::Max(this->m_uiCapacity + (this->m_uiCapacity / 2), uiCapacity);
132  uiNewCapacity = (uiNewCapacity + (CAPACITY_ALIGNMENT - 1)) & ~(CAPACITY_ALIGNMENT - 1);
133 
134  SetCapacity(uiNewCapacity);
135 }
136 
137 template <typename T, ezUInt32 Size>
139 {
140  if (this->IsEmpty())
141  {
142  // completely deallocate all data, if the array is empty.
143  if (this->m_pElements != GetStaticArray())
144  EZ_DELETE_RAW_BUFFER(this->m_pAllocator, this->m_pElements);
145 
146  this->m_uiCapacity = Size;
147  this->m_pElements = GetStaticArray();
148  }
149  else
150  {
151  const ezUInt32 uiNewCapacity = (this->m_uiCount + (CAPACITY_ALIGNMENT - 1)) & ~(CAPACITY_ALIGNMENT - 1);
152  if (this->m_uiCapacity != uiNewCapacity)
153  SetCapacity(uiNewCapacity);
154  }
155 }
156 
157 template <typename T, ezUInt32 Size>
159 {
160  if (this->m_uiCapacity <= Size)
161  return 0;
162 
163  return (ezUInt64) sizeof(T) * (ezUInt64) this->m_uiCapacity;
164 }
165 
166 template <typename T, ezUInt32 Size, typename A>
167 ezHybridArray<T, Size, A>::ezHybridArray() : ezHybridArrayBase<T, Size>(A::GetAllocator())
168 {
169 }
170 
171 template <typename T, ezUInt32 Size, typename A>
173 {
174 }
175 
176 template <typename T, ezUInt32 Size, typename A>
177 ezHybridArray<T, Size, A>::ezHybridArray(const ezHybridArray<T, Size, A>& other) : ezHybridArrayBase<T, Size>(other, A::GetAllocator())
178 {
179 }
180 
181 template <typename T, ezUInt32 Size, typename A>
182 ezHybridArray<T, Size, A>::ezHybridArray(const ezHybridArrayBase<T, Size>& other) : ezHybridArrayBase<T, Size>(other, A::GetAllocator())
183 {
184 }
185 
186 template <typename T, ezUInt32 Size, typename A>
187 ezHybridArray<T, Size, A>::ezHybridArray(ezHybridArray<T, Size, A>&& other) : ezHybridArrayBase<T, Size>(std::move(other), A::GetAllocator())
188 {
189 }
190 
191 template <typename T, ezUInt32 Size, typename A>
192 ezHybridArray<T, Size, A>::ezHybridArray(ezHybridArrayBase<T, Size>&& other) : ezHybridArrayBase<T, Size>(std::move(other), A::GetAllocator())
193 {
194 }
195 
196 template <typename T, ezUInt32 Size, typename A>
197 ezHybridArray<T, Size, A>::ezHybridArray(const ezArrayPtr<const T>& other) : ezHybridArrayBase<T, Size>(other, A::GetAllocator())
198 {
199 }
200 
201 template <typename T, ezUInt32 Size, typename A>
203 {
205 }
206 
207 template <typename T, ezUInt32 Size, typename A>
209 {
211 }
212 
213 template <typename T, ezUInt32 Size, typename A>
215 {
217 }
218 
219 template <typename T, ezUInt32 Size, typename A>
221 {
223 }
224 
225 template <typename T, ezUInt32 Size, typename A>
227 {
229 }
230