20 #include <string_view>
26 template<
class char_t,
class traits_t =
string_traits::traits<
char_t>>
32 template<
class string_traits_t>
35 using size_type =
typename string_traits_t::size_type;
36 static constexpr size_type nSBOSize =
37 sizeof(
typename string_traits_t::value_type) * string_traits_t::small_string_size();
38 static constexpr
bool bShrinkToFitWhenSmall = string_traits_t::shrink_to_fit_when_small();
39 static constexpr
bool bPreserveContents =
true;
41 static constexpr size_type growth_strategy(size_type nOldCapacity) noexcept
43 return nOldCapacity + nOldCapacity / 2;
47 (nSBOSize & (nSBOSize - 1)) == 0,
48 "The buffer size should be such that the final size of the structure is aligned");
51 template<
class char_t>
52 using ostream = std::basic_ostream<char_t>;
54 template<
class char_t>
55 using istream = std::basic_istream<char_t>;
61 template<
class char_t,
class traits_t>
81 template<
class char_t,
class traits_t>
84 template<
class _
char_t,
class _traits_t>
85 friend qx::details::istream<_char_t>& ::operator>>(
86 qx::details::istream<_char_t>& is,
90 using traits_type = traits_t;
91 using value_type =
typename traits_type::value_type;
92 using pointer =
typename traits_type::pointer;
93 using const_pointer =
typename traits_type::const_pointer;
94 using reference =
typename traits_type::reference;
95 using const_reference =
typename traits_type::const_reference;
96 using difference_type =
typename traits_type::difference_type;
97 using size_type =
typename traits_type::size_type;
98 using string_view = basic_string_view<value_type>;
99 using sstream_type = std::basic_stringstream<value_type>;
100 using views = std::vector<string_view>;
101 template<
class... args_t>
102 using format_string_type =
typename traits_type::template format_string<args_t...>;
104 static constexpr size_type npos = std::numeric_limits<size_type>::max();
116 basic_string(size_type nSymbols, value_type chSymbol) noexcept;
123 basic_string(const_pointer pszSource, size_type nSymbols) noexcept;
149 template<
class fwd_it_t>
150 basic_string(fwd_it_t itFirst, fwd_it_t itLast) noexcept;
157 template<range_of_t_c<
char_t>
string_t>
165 void assign(size_type nSymbols, value_type chSymbol) noexcept;
172 void assign(const_pointer pszSource, size_type nSymbols) noexcept;
178 void assign(const_pointer pszSource) noexcept;
198 template<
class fwd_it_t>
199 void assign(fwd_it_t itFirst, fwd_it_t itLast) noexcept;
206 template<range_of_t_c<
char_t>
string_t>
207 void assign(
const string_t& str) noexcept;
216 template<
class... args_t>
217 requires format_acceptable_args_c<char_t, args_t...>
218 void format(
const format_string_type<std::type_identity_t<args_t>...> sFormat, args_t&&... args) noexcept;
228 template<
class... args_t>
229 requires format_acceptable_args_c<char_t, args_t...>
231 const format_string_type<std::type_identity_t<args_t>...> sFormat,
232 args_t&&... args) noexcept;
241 template<
class... args_t>
242 requires format_acceptable_args_c<char_t, args_t...>
243 void append_format(
const format_string_type<std::type_identity_t<args_t>...> sFormat, args_t&&... args) noexcept;
252 template<
class... args_t>
253 requires format_acceptable_args_c<char_t, args_t...>
254 void vformat(string_view svFormat, args_t&&... args);
264 template<
class... args_t>
265 requires format_acceptable_args_c<char_t, args_t...>
275 template<
class... args_t>
276 requires format_acceptable_args_c<char_t, args_t...>
290 size_type
reserve(size_type nCapacity) noexcept;
298 bool resize(size_type nSymbols) noexcept;
308 void free() noexcept;
316 string_view
substr(size_type nPos, size_type nSymbols = npos) const noexcept;
332 value_type
front() const noexcept;
338 value_type
back() const noexcept;
345 size_type
length() const noexcept;
351 const_pointer
c_str() const noexcept;
357 size_type
capacity() const noexcept;
363 static constexpr size_type
max_size() noexcept;
377 std::optional<to_t>
to(const_pointer pszFormat =
nullptr) const noexcept;
386 size_type
copy(pointer pDest, size_type nCount, size_type nPos = 0) const noexcept;
393 template<class from_t>
394 void from(const from_t& data);
402 template<class from_t>
409 void append(value_type chSymbol) noexcept;
416 void append(const_pointer pszStr, size_type nStrSize = npos) noexcept;
430 template<class fwd_it_t>
431 void append(fwd_it_t itBegin, fwd_it_t itEnd) noexcept;
438 template<range_of_t_c<char_t> string_t>
439 void append(const string_t& sStr) noexcept;
447 size_type
insert(size_type nPos, value_type chSymbol) noexcept;
456 size_type
insert(size_type nPos, const_pointer pszWhat, size_type nSymbols = npos) noexcept;
474 template<class fwd_it_t>
475 size_type
insert(size_type nPos, fwd_it_t itWhatBegin, fwd_it_t itWhatEnd) noexcept;
484 template<range_of_t_c<char_t> string_t>
485 size_type
insert(size_type nPos, string_t sWhat) noexcept;
502 size_type
insert(
const_iterator itPos, const_pointer pszWhat, size_type nSymbols = npos) noexcept;
520 template<class fwd_it_t>
530 template<range_of_t_c<char_t> string_t>
537 void push_back(value_type chSymbol) noexcept;
543 void push_front(value_type chSymbol) noexcept;
562 void erase(size_type nPos) noexcept;
569 void erase(size_type nPos, size_type nSymbols) noexcept;
594 size_type
trim_left(value_type chSymbol) noexcept;
601 size_type
trim_left(const_pointer pszStr) noexcept;
609 size_type
trim_left(const_pointer pszStr, size_type nStrSize) noexcept;
625 template<class fwd_it_t>
626 size_type
trim_left(fwd_it_t itBegin, fwd_it_t itEnd) noexcept;
634 template<range_of_t_c<char_t> string_t>
635 size_type
trim_left(const string_t& sStr) noexcept;
648 size_type
trim_right(value_type chSymbol) noexcept;
655 size_type
trim_right(const_pointer pszStr) noexcept;
663 size_type
trim_right(const_pointer pszStr, size_type nStrSize) noexcept;
679 template<class fwd_it_t>
680 size_type
trim_right(fwd_it_t itBegin, fwd_it_t itEnd) noexcept;
688 template<range_of_t_c<char_t> string_t>
689 size_type
trim_right(const string_t& sStr) noexcept;
695 size_type
trim() noexcept;
702 size_type
trim(value_type chSymbol) noexcept;
709 size_type
trim(const_pointer pszStr) noexcept;
717 size_type
trim(const_pointer pszStr, size_type nStrSize) noexcept;
733 template<class fwd_it_t>
734 size_type
trim(fwd_it_t itBegin, fwd_it_t itEnd) noexcept;
742 template<range_of_t_c<char_t> string_t>
743 size_type
trim(const string_t& sStr) noexcept;
752 size_type
remove(value_type chSymbol, size_type nBegin = 0, size_type nEnd = npos) noexcept;
763 const_pointer pszStr,
764 size_type nBegin = 0,
765 size_type nEnd = npos,
766 size_type nStrSize = npos) noexcept;
775 size_type
remove(const
basic_string& sStr, size_type nBegin = 0, size_type nEnd = npos) noexcept;
786 template<class fwd_it_t>
787 size_type
remove(fwd_it_t itBegin, fwd_it_t itEnd, size_type nBegin = 0, size_type nEnd = npos) noexcept;
797 template<range_of_t_c<char_t> string_t>
798 size_type
remove(const string_t& sStr, size_type nBegin = 0, size_type nEnd = npos) noexcept;
813 bool remove_prefix(const_pointer pszStr, size_type nStrSize = npos) noexcept;
829 template<class fwd_it_t>
830 bool remove_prefix(fwd_it_t itBegin, fwd_it_t itEnd) noexcept;
838 template<range_of_t_c<char_t> string_t>
854 bool remove_suffix(const_pointer pszStr, size_type nStrSize = npos) noexcept;
870 template<class fwd_it_t>
871 bool remove_suffix(fwd_it_t itBegin, fwd_it_t itEnd) noexcept;
879 template<range_of_t_c<char_t> string_t>
889 size_type
remove_all(value_type chSymbol, size_type nBegin = 0, size_type nEnd = npos) noexcept;
900 const_pointer pszStr,
901 size_type nBegin = 0,
902 size_type nEnd = npos,
903 size_type nStrSize = npos) noexcept;
923 template<class fwd_it_t>
924 size_type
remove_all(fwd_it_t itFirst, fwd_it_t itLast, size_type nBegin = 0, size_type nEnd = npos) noexcept;
934 template<range_of_t_c<char_t> string_t>
935 size_type
remove_all(const string_t& sStr, size_type nBegin = 0, size_type nEnd = npos) noexcept;
946 size_type
replace(size_type nBegin, size_type nSize, const_pointer pszReplace,
size_t nReplaceSize) noexcept;
957 template<class replace_string_t>
958 size_type
replace(size_type nBegin, size_type nSize, const replace_string_t& sReplace) noexcept;
970 template<class find_string_t, class replace_string_t>
972 const find_string_t& sFind,
973 const replace_string_t& sReplace,
974 size_type nBegin = 0,
975 size_type nEnd = npos) noexcept;
987 template<class find_string_t, class replace_string_t>
989 const find_string_t& sFind,
990 const replace_string_t& sReplace,
991 size_type nBegin = 0,
992 size_type nEnd = npos) noexcept;
1003 int compare(value_type chSymbol) const noexcept;
1014 int compare(const_pointer pszStr) const noexcept;
1026 int compare(const_pointer pStr, size_type nStrSize) const noexcept;
1050 template<class fwd_it_t>
1051 int compare(fwd_it_t itBegin, fwd_it_t itEnd) const noexcept;
1063 template<range_of_t_c<char_t> string_t>
1064 int compare(const string_t& sStr) const noexcept;
1073 size_type
find(value_type chSymbol, size_type nBegin = 0, size_type nEnd = npos) const noexcept;
1083 size_type
find(const_pointer pszWhat, size_type nBegin = 0, size_type nWhatSize = npos, size_type nEnd = npos)
1093 size_type
find(const
basic_string& sWhat, size_type nBegin = 0, size_type nEnd = npos) const noexcept;
1104 template<class fwd_it_t>
1105 size_type
find(fwd_it_t itWhatBegin, fwd_it_t itWhatEnd, size_type nBegin = 0, size_type nEnd = npos)
1116 template<range_of_t_c<char_t> string_t>
1117 size_type
find(string_t sWhat, size_type nBegin = 0, size_type nEnd = npos) const noexcept;
1127 size_type
rfind(value_type chSymbol, size_type nBegin = npos, size_type nEnd = 0) const noexcept;
1138 size_type
rfind(const_pointer pszWhat, size_type nBegin = npos, size_type nWhatSize = npos, size_type nEnd = 0)
1149 size_type
rfind(const
basic_string& sWhat, size_type nBegin = npos, size_type nEnd = 0) const noexcept;
1161 template<class fwd_it_t>
1162 size_type
rfind(fwd_it_t itWhatBegin, fwd_it_t itWhatEnd, size_type nBegin = npos, size_type nEnd = 0)
1174 template<range_of_t_c<char_t> string_t>
1175 size_type
rfind(string_t sWhat, size_type nBegin = npos, size_type nEnd = 0) const noexcept;
1183 size_type
find_first_of(value_type chSymbol, size_type nBegin = 0) const noexcept;
1192 size_type
find_first_of(const_pointer pszWhat, size_type nBegin, size_type nWhatSize) const noexcept;
1200 size_type
find_first_of(const_pointer pszWhat, size_type nBegin = 0) const noexcept;
1218 template<class fwd_it_t>
1219 size_type
find_first_of(fwd_it_t itWhatBegin, fwd_it_t itWhatEnd, size_type nBegin = 0) const noexcept;
1228 template<range_of_t_c<char_t> string_t>
1229 size_type
find_first_of(string_t sWhat, size_type nBegin = 0) const noexcept;
1237 size_type
find_last_of(value_type chSymbol, size_type nEnd = 0) const noexcept;
1246 size_type
find_last_of(const_pointer pszWhat, size_type nEnd, size_type nWhatSize) const noexcept;
1254 size_type
find_last_of(const_pointer pszWhat, size_type nEnd = 0) const noexcept;
1272 template<class fwd_it_t>
1273 size_type
find_last_of(fwd_it_t itWhatBegin, fwd_it_t itWhatEnd, size_type nEnd = 0) const noexcept;
1282 template<range_of_t_c<char_t> string_t>
1283 size_type
find_last_of(string_t sWhat, size_type nEnd = 0) const noexcept;
1291 size_type
find_first_not_of(value_type chSymbol, size_type nBegin = 0) const noexcept;
1300 size_type
find_first_not_of(const_pointer pszWhat, size_type nBegin, size_type nWhatSize) const noexcept;
1308 size_type
find_first_not_of(const_pointer pszWhat, size_type nBegin = 0) const noexcept;
1326 template<class fwd_it_t>
1327 size_type
find_first_not_of(fwd_it_t itWhatBegin, fwd_it_t itWhatEnd, size_type nBegin = 0) const noexcept;
1336 template<range_of_t_c<char_t> string_t>
1337 size_type
find_first_not_of(string_t sWhat, size_type nBegin = 0) const noexcept;
1345 size_type
find_last_not_of(value_type chSymbol, size_type nEnd = 0) const noexcept;
1354 size_type
find_last_not_of(const_pointer pszWhat, size_type nEnd, size_type nWhatSize) const noexcept;
1362 size_type
find_last_not_of(const_pointer pszWhat, size_type nEnd = 0) const noexcept;
1380 template<class fwd_it_t>
1381 size_type
find_last_not_of(fwd_it_t itWhatBegin, fwd_it_t itWhatEnd, size_type nEnd = 0) const noexcept;
1390 template<range_of_t_c<char_t> string_t>
1391 size_type
find_last_not_of(string_t sWhat, size_type nEnd = 0) const noexcept;
1398 views
split(const value_type chSeparator) const noexcept;
1406 views
split(const_pointer pszSeparator, size_type nSepLen = npos) const noexcept;
1422 template<class fwd_it_t>
1423 views
split(fwd_it_t itSepFirst, fwd_it_t itSepLast) const noexcept;
1431 template<range_of_t_c<char_t> string_t>
1432 views
split(const string_t& sSeparator) const noexcept;
1439 bool starts_with(value_type chSymbol) const noexcept;
1447 bool starts_with(const_pointer pszStr, size_type nStrSize = npos) const noexcept;
1463 template<class fwd_it_t>
1464 bool starts_with(fwd_it_t itBegin, fwd_it_t itEnd) const noexcept;
1472 template<range_of_t_c<char_t> string_t>
1473 bool starts_with(const string_t& sStr) const noexcept;
1480 bool ends_with(value_type chSymbol) const noexcept;
1488 bool ends_with(const_pointer pszStr, size_type nStrSize = npos) const noexcept;
1504 template<class fwd_it_t>
1505 bool ends_with(fwd_it_t itBegin, fwd_it_t itEnd) const noexcept;
1513 template<range_of_t_c<char_t> string_t>
1514 bool ends_with(const string_t& sStr) const noexcept;
1522 bool contains(value_type chSymbol) const noexcept;
1531 bool contains(const_pointer pszStr, size_type nStrSize = npos) const noexcept;
1549 template<class fwd_it_t>
1550 bool contains(fwd_it_t itBegin, fwd_it_t itEnd) const noexcept;
1559 template<range_of_t_c<char_t> string_t>
1560 bool contains(const string_t& sStr) const noexcept;
1562 basic_string& operator=(const_pointer pszSource) noexcept;
1565 template<range_of_t_c<char_t> string_t>
1566 basic_string& operator=(const string_t& sStr) noexcept;
1568 basic_string& operator+=(value_type chSymbol) noexcept;
1569 basic_string& operator+=(const_pointer pszSource) noexcept;
1571 template<range_of_t_c<char_t> string_t>
1572 basic_string& operator+=(const string_t& sStr) noexcept;
1574 bool operator==(value_type chSymbol) const noexcept;
1575 bool operator==(const_pointer pszSource) const noexcept;
1576 bool operator==(const
basic_string& sStr) const noexcept;
1577 template<range_of_t_c<char_t> string_t>
1578 bool operator==(const string_t& sStr) const noexcept;
1580 bool operator!=(value_type chSymbol) const noexcept;
1581 bool operator!=(const_pointer pszSource) const noexcept;
1582 bool operator!=(const
basic_string& sStr) const noexcept;
1583 template<range_of_t_c<char_t> string_t>
1584 bool operator!=(const string_t& sStr) const noexcept;
1586 bool operator<(value_type chSymbol) const noexcept;
1587 bool operator<(const_pointer pszSource) const noexcept;
1588 bool operator<(const
basic_string& sStr) const noexcept;
1589 template<range_of_t_c<char_t> string_t>
1590 bool operator<(const string_t& sStr) const noexcept;
1592 bool operator<=(value_type chSymbol) const noexcept;
1593 bool operator<=(const_pointer pszSource) const noexcept;
1594 bool operator<=(const
basic_string& sStr) const noexcept;
1595 template<range_of_t_c<char_t> string_t>
1596 bool operator<=(const string_t& sStr) const noexcept;
1598 bool operator>(value_type chSymbol) const noexcept;
1599 bool operator>(const_pointer pszSource) const noexcept;
1600 bool operator>(const
basic_string& sStr) const noexcept;
1601 template<range_of_t_c<char_t> string_t>
1602 bool operator>(const string_t& sStr) const noexcept;
1604 bool operator>=(value_type chSymbol) const noexcept;
1605 bool operator>=(const_pointer pszSource) const noexcept;
1606 bool operator>=(const
basic_string& sStr) const noexcept;
1607 template<range_of_t_c<char_t> string_t>
1608 bool operator>=(const string_t& sStr) const noexcept;
1610 reference operator[](size_type nSymbol) noexcept;
1611 const_reference operator[](size_type nSymbol) const noexcept;
1613 operator string_view() const noexcept;
1615 explicit operator
bool() const noexcept;
1624 template<class searcher_t>
1625 size_type _trim_left(const searcher_t& searcher) noexcept;
1633 template<class searcher_t>
1634 size_type _trim_right(const searcher_t& searcher) noexcept;
1642 template<class searcher_t>
1643 size_type _trim(const searcher_t& searcher) noexcept;
1653 template<class comparator_t>
1654 size_type _find(size_type nBegin, size_type nEnd, const comparator_t& comparator) const noexcept;
1664 template<class comparator_t>
1665 size_type _rfind(size_type nBegin, size_type nEnd, const comparator_t& comparator) const noexcept;
1677 template<class incrementer_t, class fwd_it_t>
1678 size_type _find_first_of(fwd_it_t itBegin, fwd_it_t itEnd, size_type nBegin, const incrementer_t& incrementer)
1691 template<class incrementer_t, class fwd_it_t>
1692 size_type _find_last_of(fwd_it_t itBegin, fwd_it_t itEnd, size_type nEnd, const incrementer_t& incrementer)
1705 template<class incrementer_t, class fwd_it_t>
1706 size_type _find_first_not_of(fwd_it_t itBegin, fwd_it_t itEnd, size_type nBegin, const incrementer_t& incrementer)
1719 template<class incrementer_t, class fwd_it_t>
1720 size_type _find_last_not_of(fwd_it_t itBegin, fwd_it_t itEnd, size_type nEnd, const incrementer_t& incrementer)
1729 template<class string_view_like_t>
1730 static size_type _get_string_view_like_size(const string_view_like_t& sValue) noexcept;
1738 template<class string_view_like_t>
1739 static const_pointer _get_string_view_like_data(const string_view_like_t& sValue) noexcept;
1742 sbo_bytes<details::string_sbo_traits<traits_t>> m_Data;
1751 #include <qx/containers/string/string.inl>
void push_back(value_type chSymbol) noexcept
Insert char in the end of the string.
void erase(iterator itFirst, iterator itLast) noexcept
Erase substring.
size_type find(value_type chSymbol, size_type nBegin=0, size_type nEnd=npos) const noexcept
Find substring.
bool remove_prefix(value_type chSymbol) noexcept
Remove string prefix if matches.
size_type remove_all(value_type chSymbol, size_type nBegin=0, size_type nEnd=npos) noexcept
Remove all occurrences of a substring in a string.
std::optional< to_t > to(const_pointer pszFormat=nullptr) const noexcept
Convert string to specified type.
int compare(value_type chSymbol) const noexcept
Performs a binary comparison of the characters.
size_type find_last_of(value_type chSymbol, size_type nEnd=0) const noexcept
Find last position of character.
void push_front(value_type chSymbol) noexcept
Insert char in the beginning of the string.
size_type capacity() const noexcept
Get allocated memory size (including null terminator)
value_type pop_back() noexcept
Erase last char and return it.
size_type copy(pointer pDest, size_type nCount, size_type nPos=0) const noexcept
Copies a substring [nPos, nPos + nCount) to character string pointed to by pDest.
views split(const value_type chSeparator) const noexcept
Split string by separator.
requires format_acceptable_args_c< char_t, args_t... > void append_format(const format_string_type< std::type_identity_t< args_t >... > sFormat, args_t &&... args) noexcept
Append the formatted string to the current one.
size_type rfind(value_type chSymbol, size_type nBegin=npos, size_type nEnd=0) const noexcept
Find substring (reverse direction)
size_type length() const noexcept
Get string length.
void free() noexcept
Clear string and free allocated memory.
void from(const from_t &data)
Construct string from custom type.
size_type trim_right() noexcept
Trim the string to the right (whitespace characters)
requires format_acceptable_args_c< char_t, args_t... > void vformat(string_view svFormat, args_t &&... args)
Clear the string and format it with the format string and the args.
void assign(size_type nSymbols, value_type chSymbol) noexcept
Assign by filling.
size_type replace_all(const find_string_t &sFind, const replace_string_t &sReplace, size_type nBegin=0, size_type nEnd=npos) noexcept
Replace all occurrences of sFind with sReplace.
bool ends_with(value_type chSymbol) const noexcept
Check if current string ends with char.
void swap(basic_string &sOther) noexcept
Swap this str and other.
value_type pop_front() noexcept
Erase first char and return it.
void append(value_type chSymbol) noexcept
Append char.
size_type trim() noexcept
Trim the string to the both sides (whitespace characters)
void to_upper() noexcept
Convert string to uppercase.
void shrink_to_fit() noexcept
Fit allocated size to string's actual size.
static basic_string static_from(const from_t &data)
Construct string from custom type and get it.
size_type find_last_not_of(value_type chSymbol, size_type nEnd=0) const noexcept
Finds the last character not equal to chSymbol.
size_type trim_left() noexcept
Trim the string to the left (whitespace characters)
size_type reserve(size_type nCapacity) noexcept
Reserve memory for the string.
requires format_acceptable_args_c< char_t, args_t... > void append_vformat(string_view svFormat, args_t &&... args)
Append the formatted string to the current one.
string_view substr(size_type nPos, size_type nSymbols=npos) const noexcept
Get substring.
void to_lower() noexcept
Convert string to lowercase.
size_type insert(size_type nPos, value_type chSymbol) noexcept
Insert substring.
bool remove_suffix(value_type chSymbol) noexcept
Remove string suffix if matches.
const_pointer c_str() const noexcept
Get pointer to string zero terminated.
requires static format_acceptable_args_c< char_t, args_t... > basic_string static_format(const format_string_type< std::type_identity_t< args_t >... > sFormat, args_t &&... args) noexcept
Create a string by formatting it with the format string and the args.
requires static format_acceptable_args_c< char_t, args_t... > basic_string static_vformat(string_view svFormat, args_t &&... args)
Create a string by formatting it with the format string and the args.
size_type remove(value_type chSymbol, size_type nBegin=0, size_type nEnd=npos) noexcept
Remove the first occurrence of a substring in a string.
static constexpr size_type max_size() noexcept
Get the theoretical maximum of string size.
bool starts_with(value_type chSymbol) const noexcept
Check if current string starts with char.
value_type front() const noexcept
Get first char of the string.
value_type back() const noexcept
Get last char of the string.
size_type replace(size_type nBegin, size_type nSize, const_pointer pszReplace, size_t nReplaceSize) noexcept
Replace a substring with a given string.
size_type find_first_of(value_type chSymbol, size_type nBegin=0) const noexcept
Find first position of character.
bool resize(size_type nSymbols) noexcept
Resize string.
size_type find_first_not_of(value_type chSymbol, size_type nBegin=0) const noexcept
Finds the first character not equal to chSymbol.
requires format_acceptable_args_c< char_t, args_t... > void format(const format_string_type< std::type_identity_t< args_t >... > sFormat, args_t &&... args) noexcept
Clear the string and format it with the format string and the args.
Const random access iterator type.
Non-const random access iterator type.
A type erased small buffer object that works with raw data.
requires(same_variadic_args_v< args_t... >) const expr auto coalesce(args_t &&... args)
Coalesce function, C# a ?? b analogue.
Check that tuple type contains T.