libfilezilla
Loading...
Searching...
No Matches
string.hpp
Go to the documentation of this file.
1#ifndef LIBFILEZILLA_STRING_HEADER
2#define LIBFILEZILLA_STRING_HEADER
3
4#include "libfilezilla.hpp"
5
6#include <algorithm>
7#include <cstdint>
8#include <limits>
9#include <optional>
10#include <string>
11#include <string_view>
12#include <vector>
13
21namespace fz {
22
35#ifdef FZ_WINDOWS
36typedef std::wstring native_string;
37typedef std::wstring_view native_string_view;
38#endif
39#if defined(FZ_UNIX) || defined(FZ_MAC)
40typedef std::string native_string;
41typedef std::string_view native_string_view;
42#endif
43
48native_string FZ_PUBLIC_SYMBOL to_native(std::string_view const& in);
49
54native_string FZ_PUBLIC_SYMBOL to_native(std::wstring_view const& in);
55
57template<typename T, typename std::enable_if_t<std::is_same_v<native_string, typename std::decay_t<T>>, int> = 0>
58inline native_string to_native(T const& in) {
59 return in;
60}
61
68int FZ_PUBLIC_SYMBOL stricmp(std::string_view const& a, std::string_view const& b);
69int FZ_PUBLIC_SYMBOL stricmp(std::wstring_view const& a, std::wstring_view const& b);
70
88template<typename Char>
90 if (c >= 'A' && c <= 'Z') {
91 return c + ('a' - 'A');
92 }
93 return c;
94}
95
96template<>
97std::wstring::value_type FZ_PUBLIC_SYMBOL tolower_ascii(std::wstring::value_type c);
98
100template<typename Char>
102 if (c >= 'a' && c <= 'z') {
103 return c + ('A' - 'a');
104 }
105 return c;
106}
107
108template<>
109std::wstring::value_type FZ_PUBLIC_SYMBOL toupper_ascii(std::wstring::value_type c);
110
113 // Note: For UTF-8 strings it works on individual octets!
114std::string FZ_PUBLIC_SYMBOL str_tolower_ascii(std::string_view const& s);
115std::wstring FZ_PUBLIC_SYMBOL str_tolower_ascii(std::wstring_view const& s);
116
117std::string FZ_PUBLIC_SYMBOL str_toupper_ascii(std::string_view const& s);
118std::wstring FZ_PUBLIC_SYMBOL str_toupper_ascii(std::wstring_view const& s);
119
126{
127 template<typename T>
128 bool operator()(T const& lhs, T const& rhs) const {
129 return std::lexicographical_compare(lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend(),
130 [](typename T::value_type const& a, typename T::value_type const& b) {
131 return tolower_ascii(a) < tolower_ascii(b);
132 }
133 );
134 }
135};
136
141inline bool equal_insensitive_ascii(std::string_view a, std::string_view b)
142{
143 return std::equal(a.cbegin(), a.cend(), b.cbegin(), b.cend(),
144 [](auto const& a, auto const& b) {
145 return tolower_ascii(a) == tolower_ascii(b);
146 }
147 );
148}
149inline bool equal_insensitive_ascii(std::wstring_view a, std::wstring_view b)
150{
151 return std::equal(a.cbegin(), a.cend(), b.cbegin(), b.cend(),
152 [](auto const& a, auto const& b) {
153 return tolower_ascii(a) == tolower_ascii(b);
154 }
155 );
156}
157
162std::wstring FZ_PUBLIC_SYMBOL to_wstring(std::string_view const& in);
163
168template <typename T>
169inline auto to_wstring(T && in) -> decltype(std::wstring(std::forward<T>(in)))
170{
171 return std::wstring(std::forward<T>(in));
172}
173
175template<typename Arg>
176inline typename std::enable_if<std::is_arithmetic_v<std::decay_t<Arg>>, std::wstring>::type to_wstring(Arg && arg)
177{
178 return std::to_wstring(std::forward<Arg>(arg));
179}
180
181
186std::wstring FZ_PUBLIC_SYMBOL to_wstring_from_utf8(std::string_view const& in);
187std::wstring FZ_PUBLIC_SYMBOL to_wstring_from_utf8(char const* s, size_t len);
188
189class buffer;
191
196std::string FZ_PUBLIC_SYMBOL to_string(std::wstring_view const& in);
197
202template <typename T>
203inline auto to_string(T && in) -> decltype(std::string(std::forward<T>(in)))
204{
205 return std::string(std::forward<T>(in));
206}
207
208
210template<typename Arg>
211inline typename std::enable_if<std::is_arithmetic_v<std::decay_t<Arg>>, std::string>::type to_string(Arg && arg)
212{
213 return std::to_string(std::forward<Arg>(arg));
214}
215
216
218template<typename Char>
219size_t strlen(Char const* str) {
220 return std::char_traits<Char>::length(str);
221}
222
223
230std::string FZ_PUBLIC_SYMBOL to_utf8(std::string_view const& in);
231
238std::string FZ_PUBLIC_SYMBOL to_utf8(std::wstring_view const& in);
239
241template<typename String, typename Arg>
242inline auto toString(Arg&& arg) -> typename std::enable_if<std::is_same_v<String, std::string>, decltype(to_string(std::forward<Arg>(arg)))>::type
243{
244 return to_string(std::forward<Arg>(arg));
245}
246
247template<typename String, typename Arg>
248inline auto toString(Arg&& arg) -> typename std::enable_if<std::is_same_v<String, std::wstring>, decltype(to_wstring(std::forward<Arg>(arg)))>::type
249{
250 return to_wstring(std::forward<Arg>(arg));
251}
252
253#if !defined(fzT) || defined(DOXYGEN)
254#ifdef FZ_WINDOWS
259#define fzT(x) L ## x
260#else
265#define fzT(x) x
266#endif
267#endif
268
270template<typename Char>
271constexpr Char const* choose_string(char const* c, wchar_t const* w);
272
273template<> constexpr inline char const* choose_string(char const* c, wchar_t const*) { return c; }
274template<> constexpr inline wchar_t const* choose_string(char const*, wchar_t const* w) { return w; }
275
276#if !defined(fzS) || defined(DOXYGEN)
288#define fzS(Char, s) fz::choose_string<Char>(s, L ## s)
289#endif
290
295std::string FZ_PUBLIC_SYMBOL replaced_substrings(std::string_view const& in, std::string_view const& find, std::string_view const& replacement);
296std::wstring FZ_PUBLIC_SYMBOL replaced_substrings(std::wstring_view const& in, std::wstring_view const& find, std::wstring_view const& replacement);
297
299std::string FZ_PUBLIC_SYMBOL replaced_substrings(std::string_view const& in, char find, char replacement);
300std::wstring FZ_PUBLIC_SYMBOL replaced_substrings(std::wstring_view const& in, wchar_t find, wchar_t replacement);
301
306bool FZ_PUBLIC_SYMBOL replace_substrings(std::string& in, std::string_view const& find, std::string_view const& replacement);
307bool FZ_PUBLIC_SYMBOL replace_substrings(std::wstring& in, std::wstring_view const& find, std::wstring_view const& replacement);
308
311bool FZ_PUBLIC_SYMBOL replace_substrings(std::wstring& in, wchar_t find, wchar_t replacement);
312
339template <typename String, typename Delims>
341{
342 using view_type = std::basic_string_view<std::decay_t<decltype(std::declval<String>()[0])>>;
343
344public:
351 constexpr strtokenizer(String && string, Delims &&delims, bool ignore_empty)
352 : string_(std::forward<String>(string))
353 , delims_(std::forward<Delims>(delims))
354 , ignore_empty_(ignore_empty)
355 {}
356
357 using value_type = const view_type;
358 using pointer = value_type*;
359 using reference = value_type&;
360 using size_type = std::size_t;
361 using difference_type = std::ptrdiff_t;
362
363 struct sentinel{};
364
365 struct iterator
366 {
367 using iterator_category = std::input_iterator_tag;
368 using difference_type = strtokenizer::difference_type;
369 using value_type = strtokenizer::value_type;
370 using pointer = strtokenizer::pointer;
371 using reference = strtokenizer::reference;
372
373 constexpr bool operator !=(sentinel) const
374 {
375 return !s_.empty();
376 }
377
378 constexpr bool operator ==(sentinel) const
379 {
380 return s_.empty();
381 }
382
383 constexpr bool operator ==(iterator const& op) const
384 {
385 return s_.size() == op.s_.size();
386 }
387
388 constexpr bool operator !=(iterator const& op) const
389 {
390 return s_.size() != op.s_.size();
391 }
392
393 constexpr value_type operator*() const
394 {
395 return s_.substr(0, pos_);
396 }
397
398 constexpr iterator &operator++()
399 {
400 for (;;) {
401 if (pos_ != s_.size()) {
402 ++pos_;
403 }
404
405 s_.remove_prefix(pos_);
406
407 pos_ = s_.find_first_of(t_->delims_);
408
409 if (pos_ == view_type::npos) {
410 pos_ = s_.size();
411 break;
412 }
413
414 if (pos_ != 0 || !t_->ignore_empty_) {
415 break;
416 }
417 }
418
419 return *this;
420 }
421
422 private:
423 friend strtokenizer;
424
425 constexpr iterator(const strtokenizer *t)
426 : t_(t)
427 , s_(view_type(t_->string_))
428 , pos_(view_type::npos)
429 {
430 operator++();
431 }
432
433 const strtokenizer *t_;
434 view_type s_;
435 size_type pos_;
436 };
437
438 using const_value_type = value_type;
439 using const_pointer = pointer;
440 using const_reference = reference;
441 using const_iterator = iterator;
442
443 constexpr iterator begin() const
444 {
445 return { this };
446 }
447
448 constexpr sentinel end() const
449 {
450 return {};
451 }
452
453 constexpr const_iterator cbegin() const
454 {
455 return { this };
456 }
457
458 constexpr sentinel cend() const
459 {
460 return {};
461 }
462
463public:
464 String string_;
465 Delims delims_;
466 bool ignore_empty_;
467};
468
475template <typename String, typename Delims>
477
484std::vector<std::string> FZ_PUBLIC_SYMBOL strtok(std::string_view const& tokens, std::string_view const& delims, bool const ignore_empty = true);
485std::vector<std::wstring> FZ_PUBLIC_SYMBOL strtok(std::wstring_view const& tokens, std::wstring_view const& delims, bool const ignore_empty = true);
486inline auto FZ_PUBLIC_SYMBOL strtok(std::string_view const& tokens, char const delim, bool const ignore_empty = true) {
487 return strtok(tokens, std::string_view(&delim, 1), ignore_empty);
488}
489inline auto FZ_PUBLIC_SYMBOL strtok(std::wstring_view const& tokens, wchar_t const delim, bool const ignore_empty = true) {
490 return strtok(tokens, std::wstring_view(&delim, 1), ignore_empty);
491}
492
501std::vector<std::string_view> FZ_PUBLIC_SYMBOL strtok_view(std::string_view const& tokens, std::string_view const& delims, bool const ignore_empty = true);
502std::vector<std::wstring_view> FZ_PUBLIC_SYMBOL strtok_view(std::wstring_view const& tokens, std::wstring_view const& delims, bool const ignore_empty = true);
503inline auto FZ_PUBLIC_SYMBOL strtok_view(std::string_view const& tokens, char const delim, bool const ignore_empty = true) {
504 return strtok_view(tokens, std::string_view(&delim, 1), ignore_empty);
505}
506inline auto FZ_PUBLIC_SYMBOL strtok_view(std::wstring_view const& tokens, wchar_t const delim, bool const ignore_empty = true) {
507 return strtok_view(tokens, std::wstring_view(&delim, 1), ignore_empty);
508}
509
511template<typename T, typename String>
512bool to_integral_impl(String const& s, T & v)
513{
514 if constexpr (std::is_same_v<T, bool>) {
515 unsigned int w{};
516 if (!to_integral_impl(s, w)) {
517 return false;
518 }
519 v = w != 0;
520 return true;
521 }
522 else if constexpr (std::is_enum_v<T>) {
523 return to_integral_impl<std::underlying_type_t<T>>(s, reinterpret_cast<std::underlying_type_t<T>&>(v));
524 }
525 else {
526 bool negative{};
527
528 auto it = s.cbegin();
529 if (it != s.cend() && (*it == '-' || *it == '+')) {
530 if (*it == '-') {
531 if constexpr (std::is_signed_v<T>) {
532 negative = true;
533 }
534 else {
535 return false;
536 }
537 }
538 ++it;
539 }
540
541 if (it == s.cend()) {
542 return false;
543 }
544
545 v = T{};
546 if (negative) {
547 auto constexpr min = std::numeric_limits<T>::min();
548 auto constexpr min10 = min / 10;
549 for (; it != s.cend(); ++it) {
550 auto const& c = *it;
551 if (c < '0' || c > '9') {
552 return false;
553 }
554 if (v < min10) {
555 return false;
556 }
557 v *= 10;
558 auto digit = -static_cast<T>(c - '0');
559 if (min - v > digit) {
560 return false;
561 }
562 v += digit;
563 }
564 }
565 else {
566 auto constexpr max = std::numeric_limits<T>::max();
567 auto constexpr max10 = max / 10;
568 for (; it != s.cend(); ++it) {
569 auto const& c = *it;
570 if (c < '0' || c > '9') {
571 return false;
572 }
573 if (v > max10) {
574 return false;
575 }
576 v *= 10;
577 auto digit = static_cast<T>(c - '0');
578 if (max - v < digit) {
579 return false;
580 }
581 v += digit;
582 }
583 }
584 }
585 return true;
586}
587
589template<typename T>
590T to_integral(std::string_view const& s, T const errorval = T()) {
591 T out{};
592 if (!to_integral_impl<T>(s, out)) {
593 out = errorval;
594 }
595 return out;
596}
597
598template<typename T>
599T to_integral(std::wstring_view const& s, T const errorval = T()) {
600 T out{};
601 if (!to_integral_impl<T>(s, out)) {
602 out = errorval;
603 }
604 return out;
605}
606
607template<typename T, typename StringType>
608T to_integral(std::basic_string_view<StringType> const& s, T const errorval = T()) {
609 T out{};
610 if (!to_integral_impl<T>(s, out)) {
611 out = errorval;
612 }
613 return out;
614}
615
617template<typename T>
618std::optional<T> to_integral_o(std::string_view const& s) {
619 std::optional<T> ret;
620 T out{};
621 if (to_integral_impl<T>(s, out)) {
622 ret = out;
623 }
624 return ret;
625}
626
627template<typename T>
628std::optional<T> to_integral_o(std::wstring_view const& s) {
629 std::optional<T> ret;
630 T out{};
631 if (to_integral_impl<T>(s, out)) {
632 ret = out;
633 }
634 return ret;
635}
636
637template<typename T, typename StringType>
638std::optional<T> to_integral_o(std::basic_string_view<StringType> const& s) {
639 std::optional<T> ret;
640 T out{};
641 if (to_integral_impl<T>(s, out)) {
642 ret = out;
643 }
644 return ret;
645}
646
647
649template<typename String>
650bool str_is_ascii(String const& s) {
651 for (auto const& c : s) {
652 if (static_cast<std::make_unsigned_t<typename String::value_type>>(c) > 127) {
653 return false;
654 }
655 }
656
657 return true;
658}
659
661template<typename String, typename Chars>
662void trim_impl(String & s, Chars const& chars, bool fromLeft, bool fromRight) {
663 size_t const first = fromLeft ? s.find_first_not_of(chars) : 0;
664 if (first == String::npos) {
665 s = String();
666 return;
667 }
668
669 size_t const last = fromRight ? s.find_last_not_of(chars) : s.size();
670 if (last == String::npos) {
671 s = String();
672 return;
673 }
674
675 // Invariant: If first exists, then last >= first
676 s = s.substr(first, last - first + 1);
677}
678
680inline std::string FZ_PUBLIC_SYMBOL trimmed(std::string_view s, std::string_view const& chars = " \r\n\t", bool fromLeft = true, bool fromRight = true)
681{
682 trim_impl(s, chars, fromLeft, fromRight);
683 return std::string(s);
684}
685
686inline std::wstring FZ_PUBLIC_SYMBOL trimmed(std::wstring_view s, std::wstring_view const& chars = L" \r\n\t", bool fromLeft = true, bool fromRight = true)
687{
688 trim_impl(s, chars, fromLeft, fromRight);
689 return std::wstring(s);
690}
691
692inline std::string FZ_PUBLIC_SYMBOL ltrimmed(std::string_view s, std::string_view const& chars = " \r\n\t")
693{
694 trim_impl(s, chars, true, false);
695 return std::string(s);
696}
697
698inline std::wstring FZ_PUBLIC_SYMBOL ltrimmed(std::wstring_view s, std::wstring_view const& chars = L" \r\n\t")
699{
700 trim_impl(s, chars, true, false);
701 return std::wstring(s);
702}
703
704inline std::string FZ_PUBLIC_SYMBOL rtrimmed(std::string_view s, std::string_view const& chars = " \r\n\t")
705{
706 trim_impl(s, chars, false, true);
707 return std::string(s);
708}
709
710inline std::wstring FZ_PUBLIC_SYMBOL rtrimmed(std::wstring_view s, std::wstring_view const& chars = L" \r\n\t")
711{
712 trim_impl(s, chars, false, true);
713 return std::wstring(s);
714}
715
716
718template<typename String, typename std::enable_if_t<std::is_same_v<typename String::value_type, char>, int> = 0>
719inline void trim(String & s, std::string_view const& chars = " \r\n\t", bool fromLeft = true, bool fromRight = true)
720{
721 trim_impl(s, chars, fromLeft, fromRight);
722}
723
724template<typename String, typename std::enable_if_t<std::is_same_v<typename String::value_type, wchar_t>, int> = 0>
725inline void trim(String & s, std::wstring_view const& chars = L" \r\n\t", bool fromLeft = true, bool fromRight = true)
726{
727 trim_impl(s, chars, fromLeft, fromRight);
728}
729
730template<typename String, typename std::enable_if_t<std::is_same_v<typename String::value_type, char>, int> = 0>
731inline void ltrim(String& s, std::string_view const& chars = " \r\n\t")
732{
733 trim_impl(s, chars, true, false);
734}
735
736template<typename String, typename std::enable_if_t<std::is_same_v<typename String::value_type, wchar_t>, int> = 0>
737inline void ltrim(String& s, std::wstring_view const& chars = L" \r\n\t")
738{
739 trim_impl(s, chars, true, false);
740}
741
742template<typename String, typename std::enable_if_t<std::is_same_v<typename String::value_type, char>, int> = 0>
743inline void rtrim(String& s, std::string_view const& chars = " \r\n\t")
744{
745 trim_impl(s, chars, false, true);
746}
747
748template<typename String, typename std::enable_if_t<std::is_same_v<typename String::value_type, wchar_t>, int> = 0>
749inline void rtrim(String & s, std::wstring_view const& chars = L" \r\n\t")
750{
751 trim_impl(s, chars, false, true);
752}
753
758template<bool insensitive_ascii = false, typename String>
759bool starts_with(String const& s, String const& beginning)
760{
761 if (beginning.size() > s.size()) {
762 return false;
763 }
764 if constexpr (insensitive_ascii) {
765 return std::equal(beginning.begin(), beginning.end(), s.begin(), [](typename String::value_type const& a, typename String::value_type const& b) {
766 return tolower_ascii(a) == tolower_ascii(b);
767 });
768 }
769 else {
770 return std::equal(beginning.begin(), beginning.end(), s.begin());
771 }
772}
773
778template<bool insensitive_ascii = false, typename String>
779bool ends_with(String const& s, String const& ending)
780{
781 if (ending.size() > s.size()) {
782 return false;
783 }
784
785 if constexpr (insensitive_ascii) {
786 return std::equal(ending.rbegin(), ending.rend(), s.rbegin(), [](typename String::value_type const& a, typename String::value_type const& b) {
787 return tolower_ascii(a) == tolower_ascii(b);
788 });
789 }
790 else {
791 return std::equal(ending.rbegin(), ending.rend(), s.rbegin());
792 }
793}
794
800std::string FZ_PUBLIC_SYMBOL normalize_hyphens(std::string_view const& in);
801std::wstring FZ_PUBLIC_SYMBOL normalize_hyphens(std::wstring_view const& in);
802
804bool FZ_PUBLIC_SYMBOL is_valid_utf8(std::string_view s);
805
826bool FZ_PUBLIC_SYMBOL is_valid_utf8(std::string_view s, size_t & state);
827
834
855bool FZ_PUBLIC_SYMBOL utf16be_to_utf8_append(std::string & result, std::string_view data, uint32_t & state);
856
858bool FZ_PUBLIC_SYMBOL utf16le_to_utf8_append(std::string & result, std::string_view data, uint32_t & state);
859
860inline native_string to_native_from_utf8(std::string_view s) {
861#ifdef FZ_WINDOWS
862 return to_wstring_from_utf8(s);
863#else
865#endif
866}
867
868}
869
870#endif
The buffer class is a simple buffer where data can be appended at the end and consumed at the front....
Definition buffer.hpp:27
Small class to return filesystem errors.
Definition fsresult.hpp:26
Container-like class that can be used to iterate over tokens in a string.
Definition string.hpp:341
constexpr strtokenizer(String &&string, Delims &&delims, bool ignore_empty)
strtokenizer class constructor.
Definition string.hpp:351
Sets some global macros and further includes string.hpp.
The namespace used by libfilezilla.
Definition apply.hpp:17
size_t strlen(Char const *str)
Returns length of 0-terminated character sequence. Works with both narrow and wide-characters.
Definition string.hpp:219
Char toupper_ascii(Char c)
Converts ASCII lowercase characters to uppercase as if C-locale is used.
Definition string.hpp:101
bool utf16le_to_utf8_append(std::string &result, std::string_view data, uint32_t &state)
Just as utf16be_to_utf8_append but for little-endian UTF-16.
std::vector< std::string_view > strtok_view(std::string_view const &tokens, std::string_view const &delims, bool const ignore_empty=true)
Tokenizes string.
Char tolower_ascii(Char c)
Converts ASCII uppercase characters to lowercase as if C-locale is used.
Definition string.hpp:89
bool str_is_ascii(String const &s)
Returns true iff the string only has characters in the 7-bit ASCII range.
Definition string.hpp:650
strtokenizer(String &&string, Delims &&delims, bool ignore_empty) -> strtokenizer< String, Delims >
strtokenizer class construction-guide.
auto toString(Arg &&arg) -> typename std::enable_if< std::is_same_v< String, std::string >, decltype(to_string(std::forward< Arg >(arg)))>::type
Calls either fz::to_string or fz::to_wstring depending on the passed template argument.
Definition string.hpp:242
constexpr Char const * choose_string(char const *c, wchar_t const *w)
Returns the function argument of the type matching the template argument.
void trim(String &s, std::string_view const &chars=" \r\n\t", bool fromLeft=true, bool fromRight=true)
Remove all leading and trailing whitespace from string.
Definition string.hpp:719
bool is_valid_utf8(std::string_view s)
Verifies that the input data is valid UTF-8.
std::string trimmed(std::string_view s, std::string_view const &chars=" \r\n\t", bool fromLeft=true, bool fromRight=true)
Return passed string with all leading and trailing whitespace removed.
Definition string.hpp:680
std::wstring to_wstring_from_utf8(std::string_view const &in)
Converts from std::string in UTF-8 into std::wstring.
std::string normalize_hyphens(std::string_view const &in)
std::wstring native_string
A string in the system's native character type and encoding. Note: This typedef changes depending on...
Definition string.hpp:36
bool utf16be_to_utf8_append(std::string &result, std::string_view data, uint32_t &state)
Converts from UTF-16-BE and appends it to the passed string.
std::string to_utf8(std::string_view const &in)
Converts from std::string in native encoding into std::string in UTF-8.
bool ends_with(String const &s, String const &ending)
Tests whether the first string ends with the second string.
Definition string.hpp:779
bool equal_insensitive_ascii(std::string_view a, std::string_view b)
Locale-insensitive stricmp.
Definition string.hpp:141
std::vector< std::string > strtok(std::string_view const &tokens, std::string_view const &delims, bool const ignore_empty=true)
Tokenizes string.
bool dispatch(event_base const &ev, F &&f)
Dispatch for simple_event<> based events to simple functors.
Definition event_handler.hpp:199
std::string to_string(std::wstring_view const &in)
Converts from std::wstring into std::string in system encoding.
std::wstring to_wstring(std::string_view const &in)
Converts from std::string in system encoding into std::wstring.
std::optional< T > to_integral_o(std::string_view const &s)
Converts string to integral type T. If string is not convertible, nullopt.
Definition string.hpp:618
std::string replaced_substrings(std::string_view const &in, std::string_view const &find, std::string_view const &replacement)
Returns in with all occurrences of find in the input string replaced with replacement.
bool starts_with(String const &s, String const &beginning)
Tests whether the first string starts with the second string.
Definition string.hpp:759
bool replace_substrings(std::string &in, std::string_view const &find, std::string_view const &replacement)
Modifies in, replacing all occurrences of find with replacement.
int stricmp(std::string_view const &a, std::string_view const &b)
Locale-sensitive stricmp.
std::string str_tolower_ascii(std::string_view const &s)
tr_tolower_ascii does for strings what tolower_ascii does for individual characters
void unicode_codepoint_to_utf8_append(std::string &result, uint32_t codepoint)
Encodes a valid Unicode codepoint as UTF-8 and appends it to the passed string.
native_string to_native(std::string_view const &in)
Converts std::string to native_string.
T to_integral(std::string_view const &s, T const errorval=T())
Converts string to integral type T. If string is not convertible, errorval is returned.
Definition string.hpp:590
Comparator to be used for std::map for case-insensitive keys.
Definition string.hpp:126
Definition string.hpp:366
Definition string.hpp:363