CommonLibVR
BSString.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "RE/M/MemoryManager.h"
4 
5 namespace RE
6 {
7  template <class T, std::uint32_t N>
9  {
10  public:
11  using value_type = T;
12 
13  constexpr DynamicMemoryManagementPol() noexcept = default;
17 
20 
21  [[nodiscard]] value_type* allocate(std::uint32_t a_num)
22  {
23  if (a_num > N) {
24  return 0;
25  }
26 
27  auto size = a_num * sizeof(value_type);
28  auto mem = malloc<value_type>(size);
29  std::memset(mem, 0, size);
30  return mem;
31  }
32 
33  void deallocate(value_type* a_ptr) { free(a_ptr); }
34  };
35 
36  template <class T, std::uint32_t N>
38  {
39  public:
40  using value_type = T;
41 
42  constexpr FixedLengthMemoryManagementPol() noexcept = default;
43 
46 
48 
50  {
51  if (this != std::addressof(a_rhs)) {
52  copy_from(a_rhs);
53  }
54  return *this;
55  }
56 
58  {
59  if (this != std::addressof(a_rhs)) {
60  copy_from(a_rhs);
61  }
62  return *this;
63  }
64 
65  [[nodiscard]] value_type* allocate(std::uint32_t a_num)
66  {
67  return a_num > N ? 0 : _buffer;
68  }
69 
70  void deallocate(value_type*) { return; }
71 
72  private:
73  void copy_from(const FixedLengthMemoryManagementPol& a_rhs)
74  {
75  std::memcpy(_buffer, a_rhs._buffer, sizeof(value_type) * N);
76  }
77 
78  value_type _buffer[N]{ 0 }; // 00
79  };
80 
81  template <class CharT, std::uint32_t N, template <class, std::uint32_t> class Allocator>
82  class BSStringT : public Allocator<CharT, N>
83  {
84  private:
85  static constexpr auto MAX = static_cast<std::uint16_t>(N);
86 
87  public:
88  using value_type = CharT;
89  using traits_type = std::char_traits<value_type>;
90  using allocator_type = Allocator<value_type, N>;
91  using size_type = std::uint16_t;
93  using const_reference = const value_type&;
94  using pointer = value_type*;
95  using const_pointer = const value_type*;
96 
98  {
99  clear();
100  }
101 
102  BSStringT(const BSStringT& a_rhs) :
103  allocator_type(a_rhs)
104  {
105  set_cstr(a_rhs.c_str());
106  }
107 
108  BSStringT(BSStringT&& a_rhs) :
109  allocator_type(std::move(a_rhs)),
110  _data(a_rhs._data),
111  _size(a_rhs._size),
112  _capacity(a_rhs._capacity)
113  {
114  a_rhs._data = nullptr;
115  a_rhs._size = 0;
116  a_rhs._capacity = 0;
117  }
118 
119  BSStringT(const value_type* a_rhs)
120  {
121  set_cstr(a_rhs);
122  }
123 
124  BSStringT(const std::string_view& a_rhs)
125  {
126  set_cstr(a_rhs.data(), a_rhs.size());
127  }
128 
130  {
131  deallocate(_data);
132  _data = nullptr;
133  }
134 
136  {
137  if (this != std::addressof(a_rhs)) {
138  static_cast<allocator_type&>(*this) = a_rhs;
139  set_cstr(a_rhs.c_str());
140  }
141  return *this;
142  }
143 
145  {
146  if (this != std::addressof(a_rhs)) {
147  static_cast<allocator_type&>(*this) = std::move(a_rhs);
148 
149  _data = a_rhs._data;
150  a_rhs._data = nullptr;
151 
152  _size = a_rhs._size;
153  a_rhs._size = 0;
154 
155  _capacity = a_rhs._capacity;
156  a_rhs._capacity = 0;
157  }
158  return *this;
159  }
160 
162  {
163  set_cstr(a_rhs);
164  return *this;
165  }
166 
167  BSStringT& operator=(const std::basic_string_view<value_type>& a_rhs)
168  {
169  set_cstr(a_rhs.data(), a_rhs.size());
170  return *this;
171  }
172 
173  [[nodiscard]] constexpr reference operator[](size_type a_pos) noexcept
174  {
175  assert(a_pos <= size());
176  return data()[a_pos];
177  }
178 
179  [[nodiscard]] constexpr const_reference operator[](size_type a_pos) const noexcept
180  {
181  assert(a_pos <= size());
182  return data()[a_pos];
183  }
184 
185  [[nodiscard]] constexpr reference front() noexcept { return operator[](0); }
186  [[nodiscard]] constexpr const_reference front() const noexcept { return operator[](0); }
187 
188  [[nodiscard]] constexpr reference back() noexcept { return operator[](size() - 1); }
189  [[nodiscard]] constexpr const_reference back() const noexcept { return operator[](size() - 1); }
190 
191  [[nodiscard]] constexpr pointer data() noexcept { return _data ? _data : EMPTY; }
192  [[nodiscard]] constexpr const_pointer data() const noexcept { return _data ? _data : EMPTY; }
193 
194  [[nodiscard]] constexpr const_pointer c_str() const noexcept { return data(); }
195 
196  [[nodiscard]] operator std::basic_string_view<value_type>() const noexcept { return { data(), size() }; }
197 
198  [[nodiscard]] constexpr bool empty() const noexcept { return size() == 0; }
199 
200  [[nodiscard]] constexpr size_type size() const noexcept { return _size != MAX ? _size : static_cast<size_type>(traits_type::length(data())); }
201 
202  [[nodiscard]] constexpr size_type length() const noexcept { return size(); }
203 
204  void clear() { set_cstr(EMPTY); }
205 
206  [[nodiscard]] inline friend bool operator==(const BSStringT& a_lhs, const value_type* a_rhs) { return (a_lhs._data == a_rhs || stricmp(a_lhs._data, a_rhs) == 0); }
207  [[nodiscard]] inline friend bool operator!=(const BSStringT& a_lhs, const value_type* a_rhs) { return !(a_lhs == a_rhs); }
208  [[nodiscard]] inline friend bool operator==(const value_type* a_lhs, const BSStringT& a_rhs) { return a_rhs == a_lhs; }
209  [[nodiscard]] inline friend bool operator!=(const value_type* a_lhs, const BSStringT& a_rhs) { return !(a_lhs == a_rhs); }
210  [[nodiscard]] inline friend bool operator==(const BSStringT& a_lhs, const BSStringT& a_rhs) { return a_lhs == a_rhs.c_str(); }
211  [[nodiscard]] inline friend bool operator!=(const BSStringT& a_lhs, const BSStringT& a_rhs) { return !(a_lhs == a_rhs); }
212  [[nodiscard]] inline friend bool operator==(const BSStringT& a_lhs, const std::string_view& a_rhs) { return a_lhs._data == a_rhs.data() || strnicmp(a_lhs._data, a_rhs.data(), a_rhs.size()); }
213  [[nodiscard]] inline friend bool operator!=(const BSStringT& a_lhs, const std::string_view& a_rhs) { return !(a_lhs == a_rhs); }
214  [[nodiscard]] inline friend bool operator==(const std::string_view& a_lhs, const BSStringT& a_rhs) { return a_rhs == a_lhs; }
215  [[nodiscard]] inline friend bool operator!=(const std::string_view& a_lhs, const BSStringT& a_rhs) { return !(a_lhs == a_rhs); }
216 
218 
219  private:
220  [[nodiscard]] static int stricmp(const char* a_lhs, const char* a_rhs) { return _stricmp(a_lhs, a_rhs); }
221 
222  [[nodiscard]] static int stricmp(const wchar_t* a_lhs, const wchar_t* a_rhs) { return _wcsicmp(a_lhs, a_rhs); }
223 
224  [[nodiscard]] static int strnicmp(const char* a_lhs, const char* a_rhs, std::size_t len) { return _strnicmp(a_lhs, a_rhs, len); }
225 
226  [[nodiscard]] static int strnicmp(const wchar_t* a_lhs, const wchar_t* a_rhs, std::size_t len) { return _wcsnicmp(a_lhs, a_rhs, len); }
227 
228  [[nodiscard]] pointer allocate(std::uint32_t a_num) { return allocator_type::allocate(a_num); }
229 
230  void deallocate(pointer a_ptr) { allocator_type::deallocate(a_ptr); }
231 
232  bool set_cstr(const_pointer a_str, std::uint32_t a_len = 0)
233  {
234  auto len = static_cast<std::uint16_t>(a_len);
235  if (_data == a_str) {
236  return true;
237  }
238 
239  if (len == 0) {
240  len = static_cast<std::uint16_t>(traits_type::length(a_str));
241  }
242 
243  const size_type newSize = len > MAX ? MAX : len;
244  ++len;
245  const size_type newCap = len > MAX ? MAX : len;
246 
247  if (len <= _capacity) {
248  traits_type::copy(_data, a_str, len);
249  _size = newSize;
250  return true;
251  }
252 
253  const auto newData = allocate(len);
254  if (!newData) {
255  return false;
256  }
257 
258  traits_type::copy(newData, a_str, len);
259  if (_data) {
260  deallocate(_data);
261  }
262 
263  _data = newData;
264  _size = newSize;
265  _capacity = newCap;
266  return true;
267  }
268 
269  static constexpr value_type EMPTY[]{ 0 };
270 
271  // members
272  pointer _data{ nullptr }; // ?? (00)
273  size_type _size{ 0 }; // ?? (08)
274  size_type _capacity{ 0 }; // ?? (0A)
275  std::uint32_t _pad0C{ 0 }; // ?? (0C)
276  };
277 
279  static_assert(sizeof(BSString) == 0x10);
280 
281  template <std::uint32_t N>
282  class BSStaticStringT : public BSStringT<char, N, FixedLengthMemoryManagementPol>
283  {
284  public:
286  using Base::Base;
287  };
288 }
Definition: BSString.h:283
Definition: BSString.h:83
friend bool operator!=(const BSStringT &a_lhs, const value_type *a_rhs)
Definition: BSString.h:207
BSStringT & operator=(BSStringT &&a_rhs)
Definition: BSString.h:144
BSStringT & operator=(const std::basic_string_view< value_type > &a_rhs)
Definition: BSString.h:167
friend bool operator==(const BSStringT &a_lhs, const BSStringT &a_rhs)
Definition: BSString.h:210
value_type & reference
Definition: BSString.h:92
constexpr const_reference operator[](size_type a_pos) const noexcept
Definition: BSString.h:179
CharT value_type
Definition: BSString.h:88
constexpr const_pointer c_str() const noexcept
Definition: BSString.h:194
constexpr reference operator[](size_type a_pos) noexcept
Definition: BSString.h:173
std::char_traits< value_type > traits_type
Definition: BSString.h:89
const value_type & const_reference
Definition: BSString.h:93
friend bool operator!=(const std::string_view &a_lhs, const BSStringT &a_rhs)
Definition: BSString.h:215
BSStringT(const std::string_view &a_rhs)
Definition: BSString.h:124
value_type * pointer
Definition: BSString.h:94
friend bool operator!=(const BSStringT &a_lhs, const std::string_view &a_rhs)
Definition: BSString.h:213
friend bool operator!=(const value_type *a_lhs, const BSStringT &a_rhs)
Definition: BSString.h:209
constexpr size_type length() const noexcept
Definition: BSString.h:202
constexpr const_reference back() const noexcept
Definition: BSString.h:189
constexpr bool empty() const noexcept
Definition: BSString.h:198
BSStringT & operator=(const BSStringT &a_rhs)
Definition: BSString.h:135
friend bool operator!=(const BSStringT &a_lhs, const BSStringT &a_rhs)
Definition: BSString.h:211
friend bool operator==(const BSStringT &a_lhs, const value_type *a_rhs)
Definition: BSString.h:206
BSStringT()
Definition: BSString.h:97
BSStringT(const value_type *a_rhs)
Definition: BSString.h:119
constexpr size_type size() const noexcept
Definition: BSString.h:200
Allocator< value_type, N > allocator_type
Definition: BSString.h:90
constexpr reference front() noexcept
Definition: BSString.h:185
friend bool operator==(const std::string_view &a_lhs, const BSStringT &a_rhs)
Definition: BSString.h:214
constexpr reference back() noexcept
Definition: BSString.h:188
friend bool operator==(const BSStringT &a_lhs, const std::string_view &a_rhs)
Definition: BSString.h:212
BSStringT & operator=(const_pointer a_rhs)
Definition: BSString.h:161
~BSStringT()
Definition: BSString.h:129
void clear()
Definition: BSString.h:204
const value_type * const_pointer
Definition: BSString.h:95
friend bool operator==(const value_type *a_lhs, const BSStringT &a_rhs)
Definition: BSString.h:208
constexpr pointer data() noexcept
Definition: BSString.h:191
BSStringT(BSStringT &&a_rhs)
Definition: BSString.h:108
constexpr const_pointer data() const noexcept
Definition: BSString.h:192
std::uint16_t size_type
Definition: BSString.h:91
constexpr const_reference front() const noexcept
Definition: BSString.h:186
BSStringT(const BSStringT &a_rhs)
Definition: BSString.h:102
Definition: BSString.h:9
void deallocate(value_type *a_ptr)
Definition: BSString.h:33
constexpr DynamicMemoryManagementPol() noexcept=default
value_type * allocate(std::uint32_t a_num)
Definition: BSString.h:21
T value_type
Definition: BSString.h:11
Definition: BSString.h:38
T value_type
Definition: BSString.h:40
value_type * allocate(std::uint32_t a_num)
Definition: BSString.h:65
FixedLengthMemoryManagementPol(FixedLengthMemoryManagementPol &&a_rhs)
Definition: BSString.h:45
void deallocate(value_type *)
Definition: BSString.h:70
constexpr FixedLengthMemoryManagementPol() noexcept=default
FixedLengthMemoryManagementPol & operator=(FixedLengthMemoryManagementPol &&a_rhs)
Definition: BSString.h:57
FixedLengthMemoryManagementPol & operator=(const FixedLengthMemoryManagementPol &a_rhs)
Definition: BSString.h:49
Definition: AbsorbEffect.h:6
void free(void *a_ptr)
Definition: MemoryManager.h:187
Definition: EffectArchetypes.h:65