52template <std::
size_t _Size,
bool fill8 = (_Size <= std::numeric_limits<u
int8_t>::max()),
53 bool fill16 = (_Size <= std::numeric_limits<u
int16_t>::max())>
55 using type = std::
size_t;
61template <std::
size_t _Size>
69template <std::
size_t _Size>
71 using type = uint16_t;
85template <std::
size_t _Size = 30>
86class string :
public std::array<char, _Size + 1> {
87 static_assert(_Size > 0,
"String size must be greater than 0");
89 using base_t = std::array<char, _Size + 1>;
90 using size_type =
typename internal::best_size<_Size + 1>::type;
94 using value_type = char;
95 using reference =
char&;
96 using const_reference =
const char&;
97 using pointer =
char*;
98 using const_pointer =
const char*;
99 using iterator =
typename base_t::iterator;
100 using const_iterator =
typename base_t::const_iterator;
101 using reverse_iterator =
typename base_t::reverse_iterator;
102 using const_reverse_iterator =
typename base_t::const_reverse_iterator;
103 using difference_type =
typename base_t::difference_type;
105 static constexpr std::size_t npos = std::numeric_limits<std::size_t>::max();
125 template <std::
size_t N>
126 constexpr string(
const char (&str)[N])
noexcept {
136 template <
typename T>
166 string(std::size_t count,
char ch)
noexcept {
167 _size =
static_cast<size_type
>(std::min(count,
static_cast<std::size_t
>(_Size)));
168 std::fill_n(base_t::data(), _size, ch);
169 base_t::data()[_size] =
'\0';
175 string(
const string& other)
noexcept =
default;
180 string(
string&& other)
noexcept =
default;
185 string&
operator=(
const string& other)
noexcept =
default;
201 _size =
static_cast<size_type
>(std::min(
size,
static_cast<std::size_t
>(_Size)));
203 std::memcpy(base_t::data(), rhs, _size);
204 base_t::data()[_size] =
'\0';
216 template <std::
size_t N>
219 return assign(str, N - 1);
229 template <
typename T>
232 return assign(rhs.data(), rhs.size());
243 return assign(rhs, std::strlen(rhs));
254 assign(std::size_t count,
char ch)
noexcept {
255 _size =
static_cast<size_type
>(std::min(count,
static_cast<std::size_t
>(_Size)));
256 std::fill_n(base_t::data(), _size, ch);
257 base_t::data()[_size] =
'\0';
268 template <std::
size_t N>
271 return assign(str, N - 1);
281 template <
typename T>
314 operator std::string() const noexcept {
315 return {base_t::data(), _size};
323 operator std::string_view() const noexcept {
324 return {base_t::data(), _size};
335 reference
at(std::size_t pos) {
337 throw std::out_of_range(
"qb::string::at: index out of range");
339 return base_t::data()[pos];
349 const_reference
at(std::size_t pos)
const {
351 throw std::out_of_range(
"qb::string::at: index out of range");
353 return base_t::data()[pos];
363 return base_t::data()[pos];
373 return base_t::data()[pos];
382 return base_t::data()[0];
390 const_reference
front() const noexcept {
391 return base_t::data()[0];
400 return base_t::data()[_size - 1];
408 const_reference
back() const noexcept {
409 return base_t::data()[_size - 1];
418 return base_t::data();
426 const_pointer
data() const noexcept {
427 return base_t::data();
435 [[nodiscard]] const_pointer
c_str() const noexcept {
436 return base_t::data();
446 return base_t::begin() + _size;
454 const_iterator
end() const noexcept {
455 return base_t::begin() + _size;
463 const_iterator
cend() const noexcept {
464 return base_t::cbegin() + _size;
473 return std::reverse_iterator(
end());
481 const_reverse_iterator
rbegin() const noexcept {
482 return std::reverse_iterator(
end());
490 const_reverse_iterator
crbegin() const noexcept {
491 return std::reverse_iterator(
cend());
500 [[nodiscard]]
constexpr bool empty() const noexcept {
509 [[nodiscard]]
constexpr std::size_t
size() const noexcept {
518 [[nodiscard]]
constexpr std::size_t
length() const noexcept {
527 [[nodiscard]]
constexpr std::size_t
max_size() const noexcept {
536 [[nodiscard]]
constexpr std::size_t
capacity() const noexcept {
547 *base_t::begin() =
'\0';
557 void resize(std::size_t count,
char ch =
'\0') noexcept {
558 count = std::min(count,
static_cast<std::size_t
>(_Size));
561 std::fill(base_t::data() + _size, base_t::data() + count, ch);
564 _size =
static_cast<size_type
>(count);
565 base_t::data()[_size] =
'\0';
573 void swap(
string& other)
noexcept {
574 base_t temp_data = *
this;
575 size_type temp_size = _size;
581 other._size = temp_size;
592 string substr(std::size_t pos = 0, std::size_t len = npos)
const {
594 throw std::out_of_range(
"qb::string::substr: position out of range");
597 std::size_t actual_len = std::min(len, _size - pos);
599 result.
assign(base_t::data() + pos, actual_len);
609 int compare(
const string& str)
const noexcept {
610 return std::strcmp(base_t::data(), str.c_str());
620 return std::strcmp(base_t::data(), str);
631 int compare(std::size_t pos, std::size_t len,
const string& str)
const {
632 return substr(pos, len).compare(str);
643 std::size_t
find(
const string& str, std::size_t pos = 0) const noexcept {
654 std::size_t
find(
const char* str, std::size_t pos = 0) const noexcept {
655 if (pos >= _size)
return npos;
657 const char* result = std::strstr(base_t::data() + pos, str);
658 return result ?
static_cast<std::size_t
>(result - base_t::data()) : npos;
668 std::size_t
find(
char ch, std::size_t pos = 0) const noexcept {
669 if (pos >= _size)
return npos;
671 const char* result = std::strchr(base_t::data() + pos, ch);
672 return (result && result < base_t::data() + _size) ?
673 static_cast<std::size_t
>(result - base_t::data()) : npos;
683 std::size_t
rfind(
const char* str, std::size_t pos = npos)
const noexcept {
684 std::size_t str_len = std::strlen(str);
685 if (str_len > _size)
return npos;
687 std::size_t start = std::min(pos, _size - str_len);
689 for (std::size_t i = start + 1; i > 0; --i) {
690 if (std::strncmp(base_t::data() + i - 1, str, str_len) == 0) {
704 std::size_t
rfind(
char ch, std::size_t pos = npos)
const noexcept {
705 if (_size == 0)
return npos;
707 std::size_t start = std::min(pos,
static_cast<std::size_t
>(_size - 1));
709 for (std::size_t i = start + 1; i > 0; --i) {
710 if (base_t::data()[i - 1] == ch) {
724 string&
append(
const string& str)
noexcept {
725 return append(str.c_str(), str.size());
734 string&
append(
const char* str)
noexcept {
735 return append(str, std::strlen(str));
745 string&
append(
const char* str, std::size_t len)
noexcept {
746 std::size_t new_size = std::min(_size + len,
static_cast<std::size_t
>(_Size));
747 std::size_t actual_len = new_size - _size;
749 std::memcpy(base_t::data() + _size, str, actual_len);
750 _size =
static_cast<size_type
>(new_size);
751 base_t::data()[_size] =
'\0';
773 string&
append(std::size_t count,
char ch)
noexcept {
774 std::size_t new_size = std::min(_size + count,
static_cast<std::size_t
>(_Size));
775 std::size_t actual_count = new_size - _size;
777 std::fill_n(base_t::data() + _size, actual_count, ch);
778 _size =
static_cast<size_type
>(new_size);
779 base_t::data()[_size] =
'\0';
791 base_t::data()[_size] = ch;
793 base_t::data()[_size] =
'\0';
803 base_t::data()[_size] =
'\0';
846 std::size_t prefix_len = std::strlen(prefix);
847 return _size >= prefix_len && std::strncmp(base_t::data(), prefix, prefix_len) == 0;
867 return _size > 0 && base_t::data()[0] == ch;
877 std::size_t suffix_len = std::strlen(suffix);
878 return _size >= suffix_len &&
879 std::strncmp(base_t::data() + _size - suffix_len, suffix, suffix_len) == 0;
899 return _size > 0 && base_t::data()[_size - 1] == ch;
909 return find(str) != npos;
919 return find(str) != npos;
929 return find(ch) != npos;
940 template <
typename T>
942 return rhs == base_t::data();
952 return std::strcmp(base_t::data(), rhs) == 0;
962 return _size == rhs._size && std::strcmp(base_t::data(), rhs.c_str()) == 0;
972 return !(*
this == rhs);
982 return !(*
this == rhs);
1077template <std::
size_t _Size1, std::
size_t _Size2>
1079 string<std::max(_Size1, _Size2)> result(lhs);
1092template <std::
size_t _Size>
1107template <std::
size_t _Size>
1122template <std::
size_t _Size>
1137template <std::
size_t _Size>
1151template <std::
size_t _Size>
1164template <std::
size_t _Size>
1179template <std::
size_t _Size>
1189template <std::
size_t _Size>
1190bool operator==(
const char* lhs,
const string<_Size>& rhs)
noexcept {
1194template <std::
size_t _Size>
1195bool operator!=(
const char* lhs,
const string<_Size>& rhs)
noexcept {
Platform, compiler, and C++ feature detection macros for the QB Framework.
Fixed-size string with optimized storage.
Definition string.h:86
void pop_back() noexcept
Remove last character.
Definition string.h:800
const_reverse_iterator crbegin() const noexcept
Get const reverse iterator to the beginning of the string.
Definition string.h:490
reference back() noexcept
Access last character.
Definition string.h:399
bool operator!=(const char *rhs) const noexcept
Inequality comparison with C-style string.
Definition string.h:981
reference at(std::size_t pos)
Access character at index with bounds checking.
Definition string.h:335
string(const string &other) noexcept=default
Copy constructor.
reverse_iterator rbegin() noexcept
Get reverse iterator to the beginning of the string.
Definition string.h:472
bool ends_with(const string &suffix) const noexcept
Check if string ends with given suffix.
Definition string.h:888
bool contains(const char *str) const noexcept
Check if string contains given substring.
Definition string.h:908
string(T const &rhs) noexcept
Constructor from string-like object.
Definition string.h:137
string & operator=(char const *rhs) noexcept
Assignment operator for C-style strings.
Definition string.h:294
string(const char *str) noexcept
Constructor from C-style string.
Definition string.h:156
constexpr std::size_t capacity() const noexcept
Get the capacity.
Definition string.h:536
string & append(const char *str, std::size_t len) noexcept
Append C-style string with length.
Definition string.h:745
bool operator>(const char *rhs) const noexcept
Greater than comparison with C-style string.
Definition string.h:1021
string & append(std::size_t count, char ch) noexcept
Append multiple characters.
Definition string.h:773
reference front() noexcept
Access first character.
Definition string.h:381
const_reference at(std::size_t pos) const
Access character at index with bounds checking (const version)
Definition string.h:349
const_reference operator[](std::size_t pos) const noexcept
Access character at index (no bounds checking, const version)
Definition string.h:372
string & operator+=(const char *str) noexcept
Append operator for C-style string.
Definition string.h:823
string & assign(T const &rhs) noexcept
Assign from string-like object.
Definition string.h:231
std::size_t find(const string &str, std::size_t pos=0) const noexcept
Find substring.
Definition string.h:643
constexpr string() noexcept
Default constructor.
Definition string.h:116
void push_back(char ch) noexcept
Add character to end.
Definition string.h:789
bool starts_with(char ch) const noexcept
Check if string starts with given character.
Definition string.h:866
std::size_t rfind(char ch, std::size_t pos=npos) const noexcept
Find last occurrence of character.
Definition string.h:704
bool operator>(const string &rhs) const noexcept
Greater than comparison.
Definition string.h:1011
bool operator<=(const char *rhs) const noexcept
Less than or equal comparison with C-style string.
Definition string.h:1041
string & operator=(string &&other) noexcept=default
Move assignment operator.
bool contains(char ch) const noexcept
Check if string contains given character.
Definition string.h:928
const_reference front() const noexcept
Access first character (const version)
Definition string.h:390
bool operator<(const string &rhs) const noexcept
Less than comparison.
Definition string.h:991
bool operator!=(const string &rhs) const noexcept
Inequality comparison.
Definition string.h:971
string & assign(std::size_t count, char ch) noexcept
Assign with fill.
Definition string.h:254
void resize(std::size_t count, char ch='\0') noexcept
Resize the string.
Definition string.h:557
const_pointer data() const noexcept
Get pointer to underlying data (const version)
Definition string.h:426
bool operator<=(const string &rhs) const noexcept
Less than or equal comparison.
Definition string.h:1031
constexpr string & operator=(const char(&str)[N]) noexcept
Assignment operator for C-style string literals.
Definition string.h:270
const_reference back() const noexcept
Access last character (const version)
Definition string.h:408
string(string &&other) noexcept=default
Move constructor.
const_iterator end() const noexcept
Get const iterator to the end of the string.
Definition string.h:454
string & operator+=(char ch) noexcept
Append operator for character.
Definition string.h:833
bool ends_with(char ch) const noexcept
Check if string ends with given character.
Definition string.h:898
string & append(const string &str) noexcept
Append string.
Definition string.h:724
bool operator==(const string &rhs) const noexcept
Equality comparison with another qb::string.
Definition string.h:961
string & operator+=(const string &str) noexcept
Append operator.
Definition string.h:813
constexpr std::size_t length() const noexcept
Get the string length (alias for size())
Definition string.h:518
string & append(char ch) noexcept
Append character.
Definition string.h:762
bool contains(const string &str) const noexcept
Check if string contains given substring.
Definition string.h:918
iterator end() noexcept
Get iterator to the end of the string.
Definition string.h:445
string(std::size_t count, char ch) noexcept
Fill constructor.
Definition string.h:166
std::size_t rfind(const char *str, std::size_t pos=npos) const noexcept
Find last occurrence of substring.
Definition string.h:683
constexpr string & assign(const char(&str)[N]) noexcept
Assign from C-style string literal.
Definition string.h:218
string & operator=(T const &rhs) noexcept
Assignment operator for string-like objects.
Definition string.h:283
string & assign(char const *rhs) noexcept
Assign from C-style string.
Definition string.h:242
std::size_t find(const char *str, std::size_t pos=0) const noexcept
Find C-style string.
Definition string.h:654
bool ends_with(const char *suffix) const noexcept
Check if string ends with given suffix.
Definition string.h:876
bool starts_with(const string &prefix) const noexcept
Check if string starts with given prefix.
Definition string.h:856
int compare(const char *str) const noexcept
Compare with C-style string.
Definition string.h:619
const_reverse_iterator rbegin() const noexcept
Get const reverse iterator to the beginning of the string.
Definition string.h:481
pointer data() noexcept
Get pointer to underlying data.
Definition string.h:417
bool operator==(T const &rhs) const noexcept
Equality comparison with string-like object.
Definition string.h:941
std::size_t find(char ch, std::size_t pos=0) const noexcept
Find character.
Definition string.h:668
bool operator<(const char *rhs) const noexcept
Less than comparison with C-style string.
Definition string.h:1001
int compare(std::size_t pos, std::size_t len, const string &str) const
Compare substring with another string.
Definition string.h:631
const_iterator cend() const noexcept
Get const iterator to the end of the string.
Definition string.h:463
constexpr bool empty() const noexcept
Check if the string is empty.
Definition string.h:500
bool operator>=(const string &rhs) const noexcept
Greater than or equal comparison.
Definition string.h:1051
bool operator>=(const char *rhs) const noexcept
Greater than or equal comparison with C-style string.
Definition string.h:1061
bool starts_with(const char *prefix) const noexcept
Check if string starts with given prefix.
Definition string.h:845
const_pointer c_str() const noexcept
Get C-style string representation.
Definition string.h:435
constexpr string(const char(&str)[N]) noexcept
Constructor from C-style string literal.
Definition string.h:126
string & operator=(const string &other) noexcept=default
Copy assignment operator.
void clear() noexcept
Clear the string.
Definition string.h:546
int compare(const string &str) const noexcept
Compare with another string.
Definition string.h:609
string & assign(char const *rhs, std::size_t size) noexcept
Assign from C-style string and size.
Definition string.h:200
constexpr std::size_t max_size() const noexcept
Get the maximum possible size.
Definition string.h:527
void swap(string &other) noexcept
Swap contents with another string.
Definition string.h:573
bool operator==(char const *rhs) const noexcept
Equality comparison with C-style string.
Definition string.h:951
string & append(const char *str) noexcept
Append C-style string.
Definition string.h:734
constexpr std::size_t size() const noexcept
Get the string length.
Definition string.h:509
string substr(std::size_t pos=0, std::size_t len=npos) const
Extract substring.
Definition string.h:592
string(const char *str, std::size_t size) noexcept
Constructor from C-style string and size.
Definition string.h:147
string & operator=(char ch) noexcept
Assignment operator for single character.
Definition string.h:305
reference operator[](std::size_t pos) noexcept
Access character at index (no bounds checking)
Definition string.h:362
std::ostream & operator<<(std::ostream &os, qb::Actor const &actor)
Stream output operator for Actor objects.
json::string_t string
JSON string type from nlohmann::json.
Definition json.h:67
std::istream & operator>>(std::istream &is, qb::string< _Size > &str) noexcept
Input stream operator for qb::string.
Definition string.h:1181
string< std::max(_Size1, _Size2)> operator+(const string< _Size1 > &lhs, const string< _Size2 > &rhs) noexcept
Concatenation operator.
Definition string.h:1078
void swap(string< _Size > &lhs, string< _Size > &rhs) noexcept
Swap function for strings.
Definition string.h:1152
Determines the optimal integer type for size storage based on max capacity.
Definition string.h:54