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
14template<class CharT, class BaseT>
16{
17public:
18 using char_type = CharT;
19
20 using base_type = BaseT;
21 using base_traits = std::char_traits<base_type>;
22
23 static std::size_t length(char_type const* s) {
24 return base_traits::length(reinterpret_cast<base_type const*>(s));
25 }
26 static int compare(char_type const* s1, char_type const* s2, std::size_t count) {
27 return base_traits::compare(reinterpret_cast<base_type const*>(s1), reinterpret_cast<base_type const*>(s2), count);
28 }
29 static char_type* copy(char_type* dest, char_type const* src, std::size_t count) {
30 return reinterpret_cast<char_type*>(base_traits::copy(reinterpret_cast<base_type*>(dest), reinterpret_cast<base_type const*>(src), count));
31 }
32 static void assign( char_type& c1, char_type const& c2 ) noexcept {
33 c1 = c2;
34 }
35 static char_type const* find(char_type const* ptr, std::size_t count, char_type const& ch) {
36 return reinterpret_cast<char_type const*>(base_traits::find(reinterpret_cast<base_type const*>(ptr), count, reinterpret_cast<base_type const&>(ch)));
37 }
38 static bool eq(char_type a, char_type b) {
39 return base_traits::eq(static_cast<base_type>(a), static_cast<base_type>(b));
40 }
41};
42
43template<>
44class std::char_traits<uint8_t> : public traits_cloner<uint8_t, char>
45{};
46
53
54namespace fz {
55
67
68#ifdef FZ_WINDOWS
69typedef std::wstring native_string;
70typedef std::wstring_view native_string_view;
71#endif
72#if defined(FZ_UNIX) || defined(FZ_MAC)
73typedef std::string native_string;
74typedef std::string_view native_string_view;
75#endif
76
81native_string FZ_PUBLIC_SYMBOL to_native(std::string_view const& in);
82
87native_string FZ_PUBLIC_SYMBOL to_native(std::wstring_view const& in);
88
90template<typename T, typename std::enable_if_t<std::is_same_v<native_string, typename std::decay_t<T>>, int> = 0>
91inline native_string to_native(T const& in) {
92 return in;
93}
94
101int FZ_PUBLIC_SYMBOL stricmp(std::string_view const& a, std::string_view const& b);
102int FZ_PUBLIC_SYMBOL stricmp(std::wstring_view const& a, std::wstring_view const& b);
103
121template<typename Char>
122Char tolower_ascii(Char c) {
123 if (c >= 'A' && c <= 'Z') {
124 return c + ('a' - 'A');
125 }
126 return c;
127}
128
129template<>
130std::wstring::value_type FZ_PUBLIC_SYMBOL tolower_ascii(std::wstring::value_type c);
131
133template<typename Char>
134Char toupper_ascii(Char c) {
135 if (c >= 'a' && c <= 'z') {
136 return c + ('A' - 'a');
137 }
138 return c;
139}
140
141template<>
142std::wstring::value_type FZ_PUBLIC_SYMBOL toupper_ascii(std::wstring::value_type c);
143
146 // Note: For UTF-8 strings it works on individual octets!
147std::string FZ_PUBLIC_SYMBOL str_tolower_ascii(std::string_view const& s);
148std::wstring FZ_PUBLIC_SYMBOL str_tolower_ascii(std::wstring_view const& s);
149
150std::string FZ_PUBLIC_SYMBOL str_toupper_ascii(std::string_view const& s);
151std::wstring FZ_PUBLIC_SYMBOL str_toupper_ascii(std::wstring_view const& s);
152
155template<typename T, typename = void>
157
158template<typename T>
159struct string_value_type<T, std::void_t<typename T::value_type>> {
160 using type = typename T::value_type;
161};
162
163template<typename CharT>
164struct string_value_type<CharT*> {
165 using type = std::remove_cv_t<CharT>;
166};
167
168template<typename CharT, std::size_t N>
169struct string_value_type<CharT (&)[N]> {
170 using type = std::remove_cv_t<CharT>;
171};
172
173template<typename CharT, std::size_t N>
174struct string_value_type<CharT[N]> {
175 using type = std::remove_cv_t<CharT>;
176};
177
178// Helper alias for easier use.
179template<typename T>
180using string_value_type_t = typename string_value_type<T>::type;
181
187struct FZ_PUBLIC_SYMBOL less_insensitive_ascii final
188{
189 using is_transparent = std::true_type;
190
191 template<typename L, typename R,
192 std::enable_if_t<std::is_same_v<string_value_type_t<L>, string_value_type_t<R>>>* = nullptr>
193 bool operator()(L const& lhs, R const& rhs) const {
194 std::basic_string_view<string_value_type_t<L>> lv(lhs);
195 std::basic_string_view<string_value_type_t<R>> rv(rhs);
196
197 return std::lexicographical_compare(lv.begin(), lv.end(), rv.begin(), rv.end(),
198 [](auto const& a, auto const& b) {
199 return tolower_ascii(a) < tolower_ascii(b);
200 }
201 );
202 }
203};
204
209template<typename A, typename B,
210 std::enable_if_t<std::is_same_v<string_value_type_t<A>, string_value_type_t<B>>>* = nullptr>
211inline bool equal_insensitive_ascii(A const& a, B const& b)
212{
213 std::basic_string_view<string_value_type_t<A>> av(a);
214 std::basic_string_view<string_value_type_t<B>> bv(b);
215
216 return std::equal(av.cbegin(), av.cend(), bv.cbegin(), bv.cend(),
217 [](auto const& a, auto const& b) {
218 return tolower_ascii(a) == tolower_ascii(b);
219 }
220 );
221}
222
227std::wstring FZ_PUBLIC_SYMBOL to_wstring(std::string_view const& in);
228
233template <typename T>
234inline auto to_wstring(T && in) -> decltype(std::wstring(std::forward<T>(in)))
235{
236 return std::wstring(std::forward<T>(in));
237}
238
240template<typename Arg>
241inline typename std::enable_if<std::is_arithmetic_v<std::decay_t<Arg>>, std::wstring>::type to_wstring(Arg && arg)
242{
243 return std::to_wstring(std::forward<Arg>(arg));
244}
245
246
251std::wstring FZ_PUBLIC_SYMBOL to_wstring_from_utf8(std::string_view const& in);
252std::wstring FZ_PUBLIC_SYMBOL to_wstring_from_utf8(char const* s, size_t len);
253
254class buffer;
255std::wstring FZ_PUBLIC_SYMBOL to_wstring_from_utf8(fz::buffer const& in);
256
261std::string FZ_PUBLIC_SYMBOL to_string(std::wstring_view const& in);
262
267template <typename T>
268inline auto to_string(T && in) -> decltype(std::string(std::forward<T>(in)))
269{
270 return std::string(std::forward<T>(in));
271}
272
273
275template<typename Arg>
276inline typename std::enable_if<std::is_arithmetic_v<std::decay_t<Arg>>, std::string>::type to_string(Arg && arg)
277{
278 return std::to_string(std::forward<Arg>(arg));
279}
280
281
283template<typename Char>
284size_t strlen(Char const* str) {
285 return std::char_traits<Char>::length(str);
286}
287
288
295std::string FZ_PUBLIC_SYMBOL to_utf8(std::string_view const& in);
296
303std::string FZ_PUBLIC_SYMBOL to_utf8(std::wstring_view const& in);
304
306template<typename String, typename Arg>
307inline auto toString(Arg&& arg) -> typename std::enable_if<std::is_same_v<String, std::string>, decltype(to_string(std::forward<Arg>(arg)))>::type
308{
309 return to_string(std::forward<Arg>(arg));
310}
311
312template<typename String, typename Arg>
313inline auto toString(Arg&& arg) -> typename std::enable_if<std::is_same_v<String, std::wstring>, decltype(to_wstring(std::forward<Arg>(arg)))>::type
314{
315 return to_wstring(std::forward<Arg>(arg));
316}
317
318#if !defined(fzT) || defined(DOXYGEN)
319#ifdef FZ_WINDOWS
324#define fzT(x) L ## x
325#else
330#define fzT(x) x
331#endif
332#endif
333
335template<typename Char>
336constexpr Char const* choose_string(char const* c, wchar_t const* w);
337
338template<> constexpr inline char const* choose_string(char const* c, wchar_t const*) { return c; }
339template<> constexpr inline wchar_t const* choose_string(char const*, wchar_t const* w) { return w; }
340
341#if !defined(fzS) || defined(DOXYGEN)
353#define fzS(Char, s) fz::choose_string<Char>(s, L ## s)
354#endif
355
360std::string FZ_PUBLIC_SYMBOL replaced_substrings(std::string_view const& in, std::string_view const& find, std::string_view const& replacement);
361std::wstring FZ_PUBLIC_SYMBOL replaced_substrings(std::wstring_view const& in, std::wstring_view const& find, std::wstring_view const& replacement);
362
364std::string FZ_PUBLIC_SYMBOL replaced_substrings(std::string_view const& in, char find, char replacement);
365std::wstring FZ_PUBLIC_SYMBOL replaced_substrings(std::wstring_view const& in, wchar_t find, wchar_t replacement);
366
371bool FZ_PUBLIC_SYMBOL replace_substrings(std::string& in, std::string_view const& find, std::string_view const& replacement);
372bool FZ_PUBLIC_SYMBOL replace_substrings(std::wstring& in, std::wstring_view const& find, std::wstring_view const& replacement);
373
375bool FZ_PUBLIC_SYMBOL replace_substrings(std::string& in, char find, char replacement);
376bool FZ_PUBLIC_SYMBOL replace_substrings(std::wstring& in, wchar_t find, wchar_t replacement);
377
378namespace detail {
380template <typename T>
381struct operator_arrow_proxy
382{
383 T v_;
384
385 T* operator->() { return &v_; }
386};
387
388template <typename T>
389struct operator_arrow_proxy<const T>
390{
391 T v_;
392
393 T* operator->() const { return &v_; }
394};
395
396}
397
424template <typename String, typename Delims>
426{
427 using view_type = std::basic_string_view<std::decay_t<decltype(std::declval<String>()[0])>>;
428
429public:
436 constexpr strtokenizer(String && string, Delims &&delims, bool ignore_empty)
437 : string_(std::forward<String>(string))
438 , delims_(std::forward<Delims>(delims))
439 , ignore_empty_(ignore_empty)
440 {}
441
442 using value_type = const view_type;
443 using pointer = detail::operator_arrow_proxy<value_type>;
444 using reference = value_type&;
445 using size_type = std::size_t;
446 using difference_type = std::ptrdiff_t;
447
448 struct iterator
449 {
450 using iterator_category = std::forward_iterator_tag;
451 using difference_type = strtokenizer::difference_type;
452 using value_type = strtokenizer::value_type;
453 using pointer = strtokenizer::pointer;
454 using reference = strtokenizer::reference;
455
456 constexpr bool operator ==(iterator const& op) const
457 {
458 return s_.size() == op.s_.size();
459 }
460
461 constexpr bool operator !=(iterator const& op) const
462 {
463 return s_.size() != op.s_.size();
464 }
465
466 constexpr value_type operator*() const
467 {
468 return s_.substr(0, pos_);
469 }
470
471 constexpr pointer operator->() const
472 {
473 return { s_.substr(0, pos_) };
474 }
475
476 constexpr iterator &operator++()
477 {
478 for (;;) {
479 if (pos_ != s_.size()) {
480 ++pos_;
481 }
482
483 s_.remove_prefix(pos_);
484
485 pos_ = s_.find_first_of(t_->delims_);
486
487 if (pos_ == view_type::npos) {
488 pos_ = s_.size();
489 break;
490 }
491
492 if (pos_ != 0 || !t_->ignore_empty_) {
493 break;
494 }
495 }
496
497 return *this;
498 }
499
500 constexpr iterator operator++(int)
501 {
502 iterator copy(*this);
503 operator++();
504 return copy;
505 }
506
507 constexpr iterator() = default;
508
509 private:
510 friend strtokenizer;
511
512 constexpr iterator(const strtokenizer *t)
513 : t_(t)
514 , s_(view_type(t_->string_))
515 {
516 operator++();
517 }
518
519 const strtokenizer *t_{};
520 view_type s_{};
521 size_type pos_{view_type::npos};
522 };
523
524 using const_iterator = iterator;
525
526 constexpr iterator begin() const
527 {
528 return { this };
529 }
530
531 constexpr iterator end() const
532 {
533 return {};
534 }
535
536 constexpr const_iterator cbegin() const
537 {
538 return { this };
539 }
540
541 constexpr const_iterator cend() const
542 {
543 return {};
544 }
545
546public:
547 String string_;
548 Delims delims_;
549 bool ignore_empty_;
550};
551
558template <typename String, typename Delims>
559strtokenizer(String && string, Delims &&delims, bool ignore_empty) -> strtokenizer<String, Delims>;
560
564template <typename LhsString, typename LhsDelims, typename RhsString, typename RhsDelims>
566{
567 return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
568}
569
573template <typename LhsString, typename LhsDelims, typename RhsString, typename RhsDelims>
575{
576 return std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
577}
578
585std::vector<std::string> FZ_PUBLIC_SYMBOL strtok(std::string_view const& tokens, std::string_view const& delims, bool const ignore_empty = true);
586std::vector<std::wstring> FZ_PUBLIC_SYMBOL strtok(std::wstring_view const& tokens, std::wstring_view const& delims, bool const ignore_empty = true);
587inline auto strtok(std::string_view const& tokens, char const delim, bool const ignore_empty = true) {
588 return strtok(tokens, std::string_view(&delim, 1), ignore_empty);
589}
590inline auto strtok(std::wstring_view const& tokens, wchar_t const delim, bool const ignore_empty = true) {
591 return strtok(tokens, std::wstring_view(&delim, 1), ignore_empty);
592}
593
602std::vector<std::string_view> FZ_PUBLIC_SYMBOL strtok_view(std::string_view const& tokens, std::string_view const& delims, bool const ignore_empty = true);
603std::vector<std::wstring_view> FZ_PUBLIC_SYMBOL strtok_view(std::wstring_view const& tokens, std::wstring_view const& delims, bool const ignore_empty = true);
604inline auto strtok_view(std::string_view const& tokens, char const delim, bool const ignore_empty = true) {
605 return strtok_view(tokens, std::string_view(&delim, 1), ignore_empty);
606}
607inline auto strtok_view(std::wstring_view const& tokens, wchar_t const delim, bool const ignore_empty = true) {
608 return strtok_view(tokens, std::wstring_view(&delim, 1), ignore_empty);
609}
610
612template<typename T, typename String>
613bool to_integral_impl(String const& s, T & v)
614{
615 if constexpr (std::is_same_v<T, bool>) {
616 unsigned int w{};
617 if (!to_integral_impl(s, w)) {
618 return false;
619 }
620 v = w != 0;
621 return true;
622 }
623 else if constexpr (std::is_enum_v<T>) {
624 return to_integral_impl<std::underlying_type_t<T>>(s, reinterpret_cast<std::underlying_type_t<T>&>(v));
625 }
626 else {
627 bool negative{};
628
629 auto it = s.cbegin();
630 if (it != s.cend() && (*it == '-' || *it == '+')) {
631 if (*it == '-') {
632 if constexpr (std::is_signed_v<T>) {
633 negative = true;
634 }
635 else {
636 return false;
637 }
638 }
639 ++it;
640 }
641
642 if (it == s.cend()) {
643 return false;
644 }
645
646 v = T{};
647 if (negative) {
648 auto constexpr min = std::numeric_limits<T>::min();
649 auto constexpr min10 = min / 10;
650 for (; it != s.cend(); ++it) {
651 auto const& c = *it;
652 if (c < '0' || c > '9') {
653 return false;
654 }
655 if (v < min10) {
656 return false;
657 }
658 v *= 10;
659 auto digit = -static_cast<T>(c - '0');
660 if (min - v > digit) {
661 return false;
662 }
663 v += digit;
664 }
665 }
666 else {
667 auto constexpr max = std::numeric_limits<T>::max();
668 auto constexpr max10 = max / 10;
669 for (; it != s.cend(); ++it) {
670 auto const& c = *it;
671 if (c < '0' || c > '9') {
672 return false;
673 }
674 if (v > max10) {
675 return false;
676 }
677 v *= 10;
678 auto digit = static_cast<T>(c - '0');
679 if (max - v < digit) {
680 return false;
681 }
682 v += digit;
683 }
684 }
685 }
686 return true;
687}
688
690template<typename T>
691T to_integral(std::string_view const& s, T const errorval = T()) {
692 T out{};
693 if (!to_integral_impl<T>(s, out)) {
694 out = errorval;
695 }
696 return out;
697}
698
699template<typename T>
700T to_integral(std::wstring_view const& s, T const errorval = T()) {
701 T out{};
702 if (!to_integral_impl<T>(s, out)) {
703 out = errorval;
704 }
705 return out;
706}
707
708template<typename T, typename StringType>
709T to_integral(std::basic_string_view<StringType> const& s, T const errorval = T()) {
710 T out{};
711 if (!to_integral_impl<T>(s, out)) {
712 out = errorval;
713 }
714 return out;
715}
716
718template<typename T>
719std::optional<T> to_integral_o(std::string_view const& s) {
720 std::optional<T> ret;
721 T out{};
722 if (to_integral_impl<T>(s, out)) {
723 ret = out;
724 }
725 return ret;
726}
727
728template<typename T>
729std::optional<T> to_integral_o(std::wstring_view const& s) {
730 std::optional<T> ret;
731 T out{};
732 if (to_integral_impl<T>(s, out)) {
733 ret = out;
734 }
735 return ret;
736}
737
738template<typename T, typename StringType>
739std::optional<T> to_integral_o(std::basic_string_view<StringType> const& s) {
740 std::optional<T> ret;
741 T out{};
742 if (to_integral_impl<T>(s, out)) {
743 ret = out;
744 }
745 return ret;
746}
747
748
750template<typename String>
751bool str_is_ascii(String const& s) {
752 for (auto const& c : s) {
753 if (static_cast<std::make_unsigned_t<typename String::value_type>>(c) > 127) {
754 return false;
755 }
756 }
757
758 return true;
759}
760
762template<typename String, typename Chars>
763void trim_impl(String & s, Chars const& chars, bool fromLeft, bool fromRight) {
764 size_t const first = fromLeft ? s.find_first_not_of(chars) : 0;
765 if (first == String::npos) {
766 s = String();
767 return;
768 }
769
770 size_t const last = fromRight ? s.find_last_not_of(chars) : s.size();
771 if (last == String::npos) {
772 s = String();
773 return;
774 }
775
776 // Invariant: If first exists, then last >= first
777 s = s.substr(first, last - first + 1);
778}
779
781inline std::string trimmed(std::string_view s, std::string_view const& chars = " \r\n\t", bool fromLeft = true, bool fromRight = true)
782{
783 trim_impl(s, chars, fromLeft, fromRight);
784 return std::string(s);
785}
786
787inline std::wstring trimmed(std::wstring_view s, std::wstring_view const& chars = L" \r\n\t", bool fromLeft = true, bool fromRight = true)
788{
789 trim_impl(s, chars, fromLeft, fromRight);
790 return std::wstring(s);
791}
792
793inline std::string ltrimmed(std::string_view s, std::string_view const& chars = " \r\n\t")
794{
795 trim_impl(s, chars, true, false);
796 return std::string(s);
797}
798
799inline std::wstring ltrimmed(std::wstring_view s, std::wstring_view const& chars = L" \r\n\t")
800{
801 trim_impl(s, chars, true, false);
802 return std::wstring(s);
803}
804
805inline std::string rtrimmed(std::string_view s, std::string_view const& chars = " \r\n\t")
806{
807 trim_impl(s, chars, false, true);
808 return std::string(s);
809}
810
811inline std::wstring rtrimmed(std::wstring_view s, std::wstring_view const& chars = L" \r\n\t")
812{
813 trim_impl(s, chars, false, true);
814 return std::wstring(s);
815}
816
817
819template<typename String, typename std::enable_if_t<std::is_same_v<typename String::value_type, char>, int> = 0>
820inline void trim(String & s, std::string_view const& chars = " \r\n\t", bool fromLeft = true, bool fromRight = true)
821{
822 trim_impl(s, chars, fromLeft, fromRight);
823}
824
825template<typename String, typename std::enable_if_t<std::is_same_v<typename String::value_type, wchar_t>, int> = 0>
826inline void trim(String & s, std::wstring_view const& chars = L" \r\n\t", bool fromLeft = true, bool fromRight = true)
827{
828 trim_impl(s, chars, fromLeft, fromRight);
829}
830
831template<typename String, typename std::enable_if_t<std::is_same_v<typename String::value_type, char>, int> = 0>
832inline void ltrim(String& s, std::string_view const& chars = " \r\n\t")
833{
834 trim_impl(s, chars, true, false);
835}
836
837template<typename String, typename std::enable_if_t<std::is_same_v<typename String::value_type, wchar_t>, int> = 0>
838inline void ltrim(String& s, std::wstring_view const& chars = L" \r\n\t")
839{
840 trim_impl(s, chars, true, false);
841}
842
843template<typename String, typename std::enable_if_t<std::is_same_v<typename String::value_type, char>, int> = 0>
844inline void rtrim(String& s, std::string_view const& chars = " \r\n\t")
845{
846 trim_impl(s, chars, false, true);
847}
848
849template<typename String, typename std::enable_if_t<std::is_same_v<typename String::value_type, wchar_t>, int> = 0>
850inline void rtrim(String & s, std::wstring_view const& chars = L" \r\n\t")
851{
852 trim_impl(s, chars, false, true);
853}
854
859template<bool insensitive_ascii = false, typename String, typename Beginning>
860 std::enable_if_t<std::is_same_v<string_value_type_t<String>, string_value_type_t<Beginning>>,
861bool> starts_with(String const& s, Beginning const& beginning)
862{
863 std::basic_string_view<string_value_type_t<String>> sv(s);
864 std::basic_string_view<string_value_type_t<Beginning>> beginningv(beginning);
865
866 if (beginningv.size() > sv.size()) {
867 return false;
868 }
869
870 if constexpr (insensitive_ascii) {
871 return std::equal(beginningv.begin(), beginningv.end(), sv.begin(), [](auto const& a, auto const& b) {
872 return tolower_ascii(a) == tolower_ascii(b);
873 });
874 } else {
875 return std::equal(beginningv.begin(), beginningv.end(), sv.begin());
876 }
877}
878
883template<bool insensitive_ascii = false, typename String, typename Ending>
884 std::enable_if_t<std::is_same_v<string_value_type_t<String>, string_value_type_t<Ending>>,
885bool> ends_with(String const& s, Ending const& ending)
886{
887 std::basic_string_view<string_value_type_t<String>> sv(s);
888 std::basic_string_view<string_value_type_t<Ending>> endingv(ending);
889
890 if (endingv.size() > sv.size()) {
891 return false;
892 }
893
894 if constexpr (insensitive_ascii) {
895 return std::equal(endingv.rbegin(), endingv.rend(), sv.rbegin(), [](auto const& a, auto const& b) {
896 return tolower_ascii(a) == tolower_ascii(b);
897 });
898 }
899 else {
900 return std::equal(endingv.rbegin(), endingv.rend(), sv.rbegin());
901 }
902}
903
909std::string FZ_PUBLIC_SYMBOL normalize_hyphens(std::string_view const& in);
910std::wstring FZ_PUBLIC_SYMBOL normalize_hyphens(std::wstring_view const& in);
911
913bool FZ_PUBLIC_SYMBOL is_valid_utf8(std::string_view s);
914
935bool FZ_PUBLIC_SYMBOL is_valid_utf8(std::string_view s, size_t & state);
936
942void FZ_PUBLIC_SYMBOL unicode_codepoint_to_utf8_append(std::string& result, uint32_t codepoint);
943
964bool FZ_PUBLIC_SYMBOL utf16be_to_utf8_append(std::string & result, std::string_view data, uint32_t & state);
965
967bool FZ_PUBLIC_SYMBOL utf16le_to_utf8_append(std::string & result, std::string_view data, uint32_t & state);
968
969inline native_string to_native_from_utf8(std::string_view s) {
970#ifdef FZ_WINDOWS
971 return to_wstring_from_utf8(s);
972#else
974#endif
975}
976
977FZ_PUBLIC_SYMBOL void wipe_conversion_cache();
978
979}
980
981#endif
The buffer class is a simple buffer where data can be appended at the end and consumed at the front....
Definition buffer.hpp:28
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:426
constexpr strtokenizer(String &&string, Delims &&delims, bool ignore_empty)
strtokenizer class constructor.
Definition string.hpp:436
Definition string.hpp:16
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:284
Char toupper_ascii(Char c)
Converts ASCII lowercase characters to uppercase as if C-locale is used.
Definition string.hpp:134
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.
std::enable_if_t< std::is_same_v< string_value_type_t< String >, string_value_type_t< Beginning > >, bool > starts_with(String const &s, Beginning const &beginning)
Tests whether the first string starts with the second string.
Definition string.hpp:861
Char tolower_ascii(Char c)
Converts ASCII uppercase characters to lowercase as if C-locale is used.
Definition string.hpp:122
bool str_is_ascii(String const &s)
Returns true iff the string only has characters in the 7-bit ASCII range.
Definition string.hpp:751
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:307
constexpr Char const * choose_string(char const *c, wchar_t const *w)
Returns the function argument of the type matching the template argument.
bool equal_insensitive_ascii(A const &a, B const &b)
Locale-insensitive stricmp.
Definition string.hpp:211
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:820
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:781
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:69
std::enable_if_t< std::is_same_v< string_value_type_t< String >, string_value_type_t< Ending > >, bool > ends_with(String const &s, Ending const &ending)
Tests whether the first string ends with the second string.
Definition string.hpp:885
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.
std::vector< std::string > strtok(std::string_view const &tokens, std::string_view const &delims, bool const ignore_empty=true)
Tokenizes string.
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:719
bool operator==(symmetric_key const &lhs, symmetric_key const &rhs)
Side-channel safe comparison.
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 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:691
bool operator<(strtokenizer< LhsString, LhsDelims > const &lhs, strtokenizer< RhsString, RhsDelims > const &rhs)
strtokenizer class less-than comparator.
Definition string.hpp:565
Comparator to be used for std::map for case-insensitive keys.
Definition string.hpp:188
A type trait to identify the value_type of any string-like type.
Definition string.hpp:156
Definition string.hpp:449