CommonLibSSE (powerof3)
hkArray.h
Go to the documentation of this file.
1 #pragma once
2 
4 
5 namespace RE
6 {
7  template <class T>
8  class hkArrayBase
9  {
10  public:
11  using value_type = T;
12  using size_type = std::int32_t;
14  using const_reference = const value_type&;
15  using iterator = T*;
16  using const_iterator = const T*;
17 
19  {
20  assert(a_pos >= 0 && a_pos < size());
21  return data()[a_pos];
22  }
23 
25  {
26  assert(a_pos >= 0 && a_pos < size());
27  return data()[a_pos];
28  }
29 
30  T* data()
31  {
32  return _data;
33  }
34 
35  [[nodiscard]] const T* data() const
36  {
37  return _data;
38  }
39 
41  {
42  return operator[](0);
43  }
44 
45  [[nodiscard]] const_reference front() const
46  {
47  return operator[](0);
48  }
49 
51  {
52  return operator[](size() - 1);
53  }
54 
55  [[nodiscard]] const_reference back() const
56  {
57  return operator[](size() - 1);
58  }
59 
61  {
62  return empty() ? iterator{} : std::addressof(data()[0]);
63  }
64 
65  [[nodiscard]] const_iterator begin() const
66  {
67  return empty() ? const_iterator{} : std::addressof(data()[0]);
68  }
69 
70  [[nodiscard]] const_iterator cbegin() const
71  {
72  return begin();
73  }
74 
76  {
77  return empty() ? iterator{} : std::addressof(data()[size()]);
78  }
79 
80  [[nodiscard]] const_iterator end() const
81  {
82  return empty() ? const_iterator{} : std::addressof(data()[size()]);
83  }
84 
85  [[nodiscard]] const_iterator cend() const
86  {
87  return end();
88  }
89 
90  [[nodiscard]] bool empty() const
91  {
92  return size() == 0;
93  }
94 
95  [[nodiscard]] size_type size() const noexcept
96  {
97  return _size;
98  }
99 
100  void reserve(size_type a_newCap)
101  {
102  assert(a_newCap <= kCapacityMask);
103  if (a_newCap <= capacity()) {
104  return;
105  }
106 
107  auto allocator = hkContainerHeapAllocator::GetSingleton();
108  size_type newSize = a_newCap * sizeof(T);
109  T* newMem = static_cast<T*>(allocator->BufAlloc(newSize));
110  if (_data) {
111  size_type oldSize = size() * sizeof(T);
112  std::memcpy(newMem, _data, oldSize);
113  if ((_capacityAndFlags & kDontDeallocFlag) == 0) {
114  allocator->BufFree(_data, oldSize);
115  }
116  }
117 
118  _data = newMem;
120  _capacityAndFlags |= a_newCap & kCapacityMask;
121  }
122 
123  [[nodiscard]] size_type capacity() const noexcept
124  {
126  }
127 
128  void push_back(const T& a_value)
129  {
130  if (size() == capacity()) {
131  reserve(static_cast<size_type>(std::ceil(size() * GROWTH_FACTOR)));
132  }
133  _data[_size++] = a_value;
134  }
135 
136  void resize(size_type a_count)
137  {
138  assert(a_count > 0 && a_count <= kCapacityMask);
139  if (a_count == size()) {
140  return;
141  }
142 
143  if (a_count < size()) { // if shrink
144  for (size_type i = a_count; i < size(); ++i) {
145  _data[i].~T();
146  }
147  }
148 
149  auto allocator = hkContainerHeapAllocator::GetSingleton();
150  size_type newSize = a_count * sizeof(T);
151  T* newMem = static_cast<T*>(allocator->BufAlloc(newSize));
152  if (_data) {
153  size_type oldSize = size() * sizeof(T);
154  std::memcpy(newMem, _data, std::min(oldSize, newSize));
155  if ((_capacityAndFlags & kDontDeallocFlag) == 0) {
156  allocator->BufFree(_data, oldSize);
157  }
158  }
159 
160  if (a_count > size()) { // if grow
161  for (size_type i = size(); i < a_count; ++i) {
162  new (&newMem[i]) T{};
163  }
164  }
165 
166  _data = newMem;
167  _size = a_count;
169  _capacityAndFlags |= a_count & kCapacityMask;
170  }
171 
172  enum : std::uint32_t
173  {
174  kCapacityMask = 0x3FFFFFFF,
175  kFlagMask = 0xC0000000,
176  kDontDeallocFlag = (std::uint32_t)1 << 31
177  };
178 
179  static constexpr float GROWTH_FACTOR = 1.5; // NOT PART OF NATIVE TYPE
180 
181  T* _data; // 00
182  std::int32_t _size; // 08
183  std::int32_t _capacityAndFlags; // 0C
184  };
185  static_assert(sizeof(hkArrayBase<void*>) == 0x10);
186 
187  template <class T, class Allocator = void>
188  class hkArray : public hkArrayBase<T>
189  {
190  public:
191  };
192  static_assert(sizeof(hkArray<void*>) == 0x10);
193 
194  template <class T, std::size_t N, class Allocator = void>
195  class hkInplaceArray : public hkArray<T, Allocator>
196  {
197  public:
198  T storage[N]; // 10
199  };
200 }
Definition: hkArray.h:9
iterator begin()
Definition: hkArray.h:60
void resize(size_type a_count)
Definition: hkArray.h:136
const_iterator cbegin() const
Definition: hkArray.h:70
std::int32_t _size
Definition: hkArray.h:182
const T * data() const
Definition: hkArray.h:35
const_reference back() const
Definition: hkArray.h:55
bool empty() const
Definition: hkArray.h:90
std::int32_t _capacityAndFlags
Definition: hkArray.h:183
value_type & reference
Definition: hkArray.h:13
T value_type
Definition: hkArray.h:11
T * data()
Definition: hkArray.h:30
const_reference operator[](size_type a_pos) const
Definition: hkArray.h:24
const T * const_iterator
Definition: hkArray.h:16
void reserve(size_type a_newCap)
Definition: hkArray.h:100
reference back()
Definition: hkArray.h:50
reference operator[](size_type a_pos)
Definition: hkArray.h:18
const_iterator begin() const
Definition: hkArray.h:65
const_iterator end() const
Definition: hkArray.h:80
size_type size() const noexcept
Definition: hkArray.h:95
T * _data
Definition: hkArray.h:181
void push_back(const T &a_value)
Definition: hkArray.h:128
const_reference front() const
Definition: hkArray.h:45
static constexpr float GROWTH_FACTOR
Definition: hkArray.h:179
@ kFlagMask
Definition: hkArray.h:175
@ kDontDeallocFlag
Definition: hkArray.h:176
@ kCapacityMask
Definition: hkArray.h:174
reference front()
Definition: hkArray.h:40
iterator end()
Definition: hkArray.h:75
std::int32_t size_type
Definition: hkArray.h:12
const value_type & const_reference
Definition: hkArray.h:14
const_iterator cend() const
Definition: hkArray.h:85
size_type capacity() const noexcept
Definition: hkArray.h:123
T * iterator
Definition: hkArray.h:15
Definition: hkArray.h:189
Definition: hkArray.h:196
T storage[N]
Definition: hkArray.h:198
Definition: AbsorbEffect.h:6
static Allocator * GetSingleton()
Definition: hkContainerAllocators.h:24