CommonLibSSE NG
Loading...
Searching...
No Matches
BSFixedString.h
Go to the documentation of this file.
1#pragma once
2
3#include "RE/B/BSStringPool.h"
4#include "RE/C/CRC.h"
5
6namespace RE
7{
8 namespace detail
9 {
10 template <class CharT>
12 {
13 public:
14 using size_type = std::uint32_t;
15 using value_type = CharT;
17 using const_pointer = const value_type*;
20
21 constexpr BSFixedString() noexcept = default;
22
23 inline BSFixedString(const BSFixedString& a_rhs) :
24 _data(a_rhs._data)
25 {
26 try_acquire();
27 }
28
29 inline BSFixedString(BSFixedString&& a_rhs) :
30 _data(a_rhs._data)
31 {
32 a_rhs._data = nullptr;
33 }
34
36 {
37 if (a_string) {
38 ctor(a_string);
39 }
40 }
41
42 template <
43 class T,
44 std::enable_if_t<
45 std::conjunction_v<
46 std::is_convertible<const T&, std::basic_string_view<value_type>>,
47 std::negation<
48 std::is_convertible<const T&, const_pointer>>>,
49 int> = 0>
50 inline BSFixedString(const T& a_string)
51 {
52 const auto view = static_cast<std::basic_string_view<value_type>>(a_string);
53 if (!view.empty()) {
54 ctor(view.data());
55 }
56 }
57
58 inline ~BSFixedString() { try_release(); }
59
61 {
62 if (this != std::addressof(a_rhs)) {
63 try_release();
64 _data = a_rhs._data;
65 try_acquire();
66 }
67 return *this;
68 }
69
71 {
72 if (this != std::addressof(a_rhs)) {
73 try_release();
74 _data = a_rhs._data;
75 a_rhs._data = nullptr;
76 }
77 return *this;
78 }
79
81 {
82 try_release();
83 if (a_string) {
84 ctor(a_string);
85 }
86 return *this;
87 }
88
89 template <
90 class T,
91 std::enable_if_t<
92 std::conjunction_v<
93 std::is_convertible<const T&, std::basic_string_view<value_type>>,
94 std::negation<
95 std::is_convertible<const T&, const_pointer>>>,
96 int> = 0>
97 inline BSFixedString& operator=(const T& a_string)
98 {
99 const auto view = static_cast<std::basic_string_view<value_type>>(a_string);
100 try_release();
101 if (!view.empty()) {
102 ctor(view.data());
103 }
104 return *this;
105 }
106
107 [[nodiscard]] inline const_reference operator[](size_type a_pos) const noexcept
108 {
109 assert(a_pos < size());
110 return _data[a_pos];
111 }
112
113 [[nodiscard]] inline const_reference front() const noexcept { return _data[0]; }
114 [[nodiscard]] inline const_reference back() const noexcept { return _data[size() - 1]; }
115
116 [[nodiscard]] inline const_pointer data() const noexcept
117 {
118 const auto proxy = get_proxy();
119 const auto cstr = proxy ? proxy->template data<value_type>() : nullptr;
120 return cstr ? cstr : EMPTY;
121 }
122
123 [[nodiscard]] inline const_pointer c_str() const noexcept { return data(); }
124
125 [[nodiscard]] constexpr operator std::basic_string_view<value_type>() const { return { c_str(), length() }; }
126
127 [[nodiscard]] constexpr bool empty() const noexcept { return size() == 0; }
128
129 [[nodiscard]] constexpr size_type size() const noexcept
130 {
131 const auto proxy = get_proxy();
132 return proxy ? proxy->size() : 0;
133 }
134
135 [[nodiscard]] constexpr size_type length() const noexcept { return size(); }
136
137 [[nodiscard]] inline friend bool operator==(const BSFixedString& a_lhs, const BSFixedString& a_rhs) noexcept
138 {
139 return a_lhs._data == a_rhs._data || (a_lhs.empty() && a_rhs.empty());
140 }
141
142 [[nodiscard]] inline friend bool operator!=(const BSFixedString& a_lhs, const BSFixedString& a_rhs) noexcept { return !(a_lhs == a_rhs); }
143
144 [[nodiscard]] inline friend bool operator==(const BSFixedString& a_lhs, std::basic_string_view<value_type> a_rhs)
145 {
146 if (a_lhs.empty() && a_rhs.empty()) {
147 return true;
148 } else if (const auto length = a_lhs.length(); length != a_rhs.length()) {
149 return false;
150 } else {
151 return strncmp(a_lhs.c_str(), a_rhs.data(), length) == 0;
152 }
153 }
154
155 [[nodiscard]] inline friend bool operator!=(const BSFixedString& a_lhs, std::basic_string_view<value_type> a_rhs) { return !(a_lhs == a_rhs); }
156 [[nodiscard]] inline friend bool operator==(std::basic_string_view<value_type> a_lhs, const BSFixedString& a_rhs) { return a_rhs == a_lhs; }
157 [[nodiscard]] inline friend bool operator!=(std::basic_string_view<value_type> a_lhs, const BSFixedString& a_rhs) { return !(a_lhs == a_rhs); }
158
159 [[nodiscard]] inline friend bool operator==(const BSFixedString& a_lhs, const_pointer a_rhs) { return a_lhs == std::basic_string_view<value_type>(a_rhs ? a_rhs : EMPTY); }
160 [[nodiscard]] inline friend bool operator!=(const BSFixedString& a_lhs, const_pointer a_rhs) { return !(a_lhs == a_rhs); }
161 [[nodiscard]] inline friend bool operator==(const_pointer a_lhs, const BSFixedString& a_rhs) { return a_rhs == a_lhs; }
162 [[nodiscard]] inline friend bool operator!=(const_pointer a_lhs, const BSFixedString& a_rhs) { return !(a_lhs == a_rhs); }
163
164 [[nodiscard]] inline bool contains(std::basic_string_view<value_type> a_rhs) const
165 {
166 if (a_rhs.length() > length()) {
167 return false;
168 }
169 for (size_type i = 0; i < length(); ++i) {
170 if (strncmp(&c_str()[i], a_rhs.data(), a_rhs.length()) == 0) {
171 return true;
172 }
173 }
174 return false;
175 }
176
177 private:
178 [[nodiscard]] static inline int strncmp(const char* a_lhs, const char* a_rhs, std::size_t a_length)
179 {
180 return _strnicmp(a_lhs, a_rhs, a_length);
181 }
182
183 [[nodiscard]] static inline int strncmp(const wchar_t* a_lhs, const wchar_t* a_rhs, std::size_t a_length)
184 {
185 return _wcsnicmp(a_lhs, a_rhs, a_length);
186 }
187
188 inline BSFixedString* ctor(const char* a_data) { return ctor8(a_data); }
189 inline BSFixedString* ctor(const wchar_t* a_data) { return ctor16(a_data); }
190
191 inline BSFixedString* ctor8(const char* a_data)
192 {
193 using func_t = decltype(&BSFixedString::ctor8);
194 REL::Relocation<func_t> func{ RELOCATION_ID(67819, 69161) };
195 return func(this, a_data);
196 }
197
198 inline BSFixedString* ctor16(const wchar_t* a_data)
199 {
200 using func_t = decltype(&BSFixedString::ctor16);
201 REL::Relocation<func_t> func{ RELOCATION_ID(67834, 69176) };
202 return func(this, a_data);
203 }
204
205 [[nodiscard]] inline BSStringPool::Entry* get_proxy() noexcept
206 {
207 return _data ?
208 reinterpret_cast<BSStringPool::Entry*>(const_cast<pointer>(_data)) - 1 :
209 nullptr;
210 }
211
212 [[nodiscard]] inline const BSStringPool::Entry* get_proxy() const noexcept
213 {
214 return _data ?
215 reinterpret_cast<const BSStringPool::Entry*>(_data) - 1 :
216 nullptr;
217 }
218
219 inline void try_acquire()
220 {
221 const auto proxy = get_proxy();
222 if (proxy) {
223 proxy->acquire();
224 }
225 }
226
227 inline void try_release() { BSStringPool::Entry::release(_data); }
228
229 static constexpr const value_type EMPTY[]{ 0 };
230
231 // members
232 const_pointer _data{ nullptr }; // 0
233 };
234
235 extern template class BSFixedString<char>;
236 extern template class BSFixedString<wchar_t>;
237 }
238
242
243 template <class CharT>
245 {
246 public:
247 [[nodiscard]] inline std::uint32_t operator()(const detail::BSFixedString<CharT>& a_key) const noexcept
248 {
249 return BSCRC32_<const void*>()(a_key.data());
250 }
251 };
252}
#define RELOCATION_ID(a_se, a_ae)
Definition PCH.h:794
static void release(const char *&a_entry)
Definition BSStringPool.h:23
Definition BSFixedString.h:12
constexpr size_type length() const noexcept
Definition BSFixedString.h:135
friend bool operator==(std::basic_string_view< value_type > a_lhs, const BSFixedString &a_rhs)
Definition BSFixedString.h:156
value_type & reference
Definition BSFixedString.h:18
constexpr BSFixedString() noexcept=default
CharT value_type
Definition BSFixedString.h:15
BSFixedString(BSFixedString &&a_rhs)
Definition BSFixedString.h:29
friend bool operator!=(const BSFixedString &a_lhs, std::basic_string_view< value_type > a_rhs)
Definition BSFixedString.h:155
const_reference front() const noexcept
Definition BSFixedString.h:113
friend bool operator!=(const BSFixedString &a_lhs, const BSFixedString &a_rhs) noexcept
Definition BSFixedString.h:142
BSFixedString(const_pointer a_string)
Definition BSFixedString.h:35
friend bool operator!=(std::basic_string_view< value_type > a_lhs, const BSFixedString &a_rhs)
Definition BSFixedString.h:157
value_type * pointer
Definition BSFixedString.h:16
BSFixedString(const T &a_string)
Definition BSFixedString.h:50
friend bool operator==(const BSFixedString &a_lhs, const BSFixedString &a_rhs) noexcept
Definition BSFixedString.h:137
friend bool operator==(const BSFixedString &a_lhs, const_pointer a_rhs)
Definition BSFixedString.h:159
BSFixedString & operator=(BSFixedString &&a_rhs)
Definition BSFixedString.h:70
friend bool operator==(const_pointer a_lhs, const BSFixedString &a_rhs)
Definition BSFixedString.h:161
bool contains(std::basic_string_view< value_type > a_rhs) const
Definition BSFixedString.h:164
friend bool operator!=(const_pointer a_lhs, const BSFixedString &a_rhs)
Definition BSFixedString.h:162
BSFixedString & operator=(const_pointer a_string)
Definition BSFixedString.h:80
const_reference back() const noexcept
Definition BSFixedString.h:114
const_pointer c_str() const noexcept
Definition BSFixedString.h:123
const value_type & const_reference
Definition BSFixedString.h:19
BSFixedString & operator=(const T &a_string)
Definition BSFixedString.h:97
~BSFixedString()
Definition BSFixedString.h:58
friend bool operator==(const BSFixedString &a_lhs, std::basic_string_view< value_type > a_rhs)
Definition BSFixedString.h:144
const_reference operator[](size_type a_pos) const noexcept
Definition BSFixedString.h:107
const_pointer data() const noexcept
Definition BSFixedString.h:116
const value_type * const_pointer
Definition BSFixedString.h:17
constexpr bool empty() const noexcept
Definition BSFixedString.h:127
BSFixedString & operator=(const BSFixedString &a_rhs)
Definition BSFixedString.h:60
friend bool operator!=(const BSFixedString &a_lhs, const_pointer a_rhs)
Definition BSFixedString.h:160
constexpr size_type size() const noexcept
Definition BSFixedString.h:129
std::uint32_t size_type
Definition BSFixedString.h:14
Definition Relocation.h:1638
Definition AbsorbEffect.h:6
detail::BSFixedString< char > BSFixedString
Definition BSFixedString.h:239
std::uint32_t operator()(const detail::BSFixedString< CharT > &a_key) const noexcept
Definition BSFixedString.h:247
Definition CRC.h:72