1 #ifndef LIBFILEZILLA_STRING_HEADER
2 #define LIBFILEZILLA_STRING_HEADER
34 typedef std::wstring_view native_string_view;
36 #if defined(FZ_UNIX) || defined(FZ_MAC)
38 typedef std::string_view native_string_view;
45 native_string FZ_PUBLIC_SYMBOL
to_native(std::string_view
const& in);
51 native_string FZ_PUBLIC_SYMBOL
to_native(std::wstring_view
const& in);
54 template<
typename T,
typename std::enable_if_t<std::is_same_v<native_
string,
typename std::decay_t<T>>,
int> = 0>
65 int FZ_PUBLIC_SYMBOL
stricmp(std::string_view
const& a, std::string_view
const& b);
66 int FZ_PUBLIC_SYMBOL
stricmp(std::wstring_view
const& a, std::wstring_view
const& b);
85 template<
typename Char>
87 if (c >=
'A' && c <=
'Z') {
88 return c + (
'a' -
'A');
94 std::wstring::value_type FZ_PUBLIC_SYMBOL
tolower_ascii(std::wstring::value_type c);
97 template<
typename Char>
99 if (c >=
'a' && c <=
'z') {
100 return c + (
'A' -
'a');
106 std::wstring::value_type FZ_PUBLIC_SYMBOL
toupper_ascii(std::wstring::value_type c);
114 std::string FZ_PUBLIC_SYMBOL str_toupper_ascii(std::string_view
const& s);
115 std::wstring FZ_PUBLIC_SYMBOL str_toupper_ascii(std::wstring_view
const& s);
125 bool operator()(T
const& lhs, T
const& rhs)
const {
126 return std::lexicographical_compare(lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend(),
127 [](
typename T::value_type
const& a,
typename T::value_type
const& b) {
140 return std::equal(a.cbegin(), a.cend(), b.cbegin(), b.cend(),
141 [](
auto const& a,
auto const& b) {
148 return std::equal(a.cbegin(), a.cend(), b.cbegin(), b.cend(),
149 [](
auto const& a,
auto const& b) {
159 std::wstring FZ_PUBLIC_SYMBOL
to_wstring(std::string_view
const& in);
160 inline std::wstring FZ_PUBLIC_SYMBOL
to_wstring(std::wstring_view
const& in) {
return std::wstring(in); }
166 template<
typename T,
typename std::enable_if_t<std::is_same_v<std::w
string,
typename std::decay_t<T>>,
int> = 0>
172 template<
typename Arg>
173 inline typename std::enable_if<std::is_arithmetic<std::decay_t<Arg>>::value, std::wstring>::type
to_wstring(Arg && arg)
190 std::string FZ_PUBLIC_SYMBOL
to_string(std::wstring_view
const& in);
191 inline std::string FZ_PUBLIC_SYMBOL
to_string(std::string_view
const& in) {
return std::string(in); }
197 template<
typename T,
typename std::enable_if_t<std::is_same_v<std::
string,
typename std::decay_t<T>>,
int> = 0>
204 template<
typename Arg>
205 inline typename std::enable_if<std::is_arithmetic<std::decay_t<Arg>>::value, std::string>::type
to_string(Arg && arg)
212 template<
typename Char>
214 return std::char_traits<Char>::length(str);
224 std::string FZ_PUBLIC_SYMBOL
to_utf8(std::string_view
const& in);
232 std::string FZ_PUBLIC_SYMBOL
to_utf8(std::wstring_view
const& in);
235 template<
typename String,
typename Arg>
236 inline auto toString(Arg&& arg) ->
typename std::enable_if<std::is_same<String, std::string>::value, decltype(
to_string(std::forward<Arg>(arg)))>::type
238 return to_string(std::forward<Arg>(arg));
241 template<
typename String,
typename Arg>
242 inline auto toString(Arg&& arg) ->
typename std::enable_if<std::is_same<String, std::wstring>::value, decltype(
to_wstring(std::forward<Arg>(arg)))>::type
247 #if !defined(fzT) || defined(DOXYGEN)
253 #define fzT(x) L ## x
264 template<
typename Char>
267 template<>
inline char const*
choose_string(
char const* c,
wchar_t const*) {
return c; }
268 template<>
inline wchar_t const*
choose_string(
char const*,
wchar_t const* w) {
return w; }
270 #if !defined(fzS) || defined(DOXYGEN)
282 #define fzS(Char, s) fz::choose_string<Char>(s, L ## s)
286 std::string FZ_PUBLIC_SYMBOL
replaced_substrings(std::string
const& in, std::string
const& find, std::string
const& replacement);
287 std::wstring FZ_PUBLIC_SYMBOL
replaced_substrings(std::wstring
const& in, std::wstring
const& find, std::wstring
const& replacement);
290 bool FZ_PUBLIC_SYMBOL
replace_substrings(std::string& in, std::string
const& find, std::string
const& replacement);
291 bool FZ_PUBLIC_SYMBOL
replace_substrings(std::wstring& in, std::wstring
const& find, std::wstring
const& replacement);
299 std::vector<std::string> FZ_PUBLIC_SYMBOL
strtok(std::string_view
const& tokens, std::string_view
const& delims,
bool const ignore_empty =
true);
300 std::vector<std::wstring> FZ_PUBLIC_SYMBOL
strtok(std::wstring_view
const& tokens, std::wstring_view
const& delims,
bool const ignore_empty =
true);
301 inline auto FZ_PUBLIC_SYMBOL
strtok(std::string_view
const& tokens,
char const delim,
bool const ignore_empty =
true) {
302 return strtok(tokens, std::string_view(&delim, 1), ignore_empty);
304 inline auto FZ_PUBLIC_SYMBOL
strtok(std::wstring_view
const& tokens,
wchar_t const delim,
bool const ignore_empty =
true) {
305 return strtok(tokens, std::wstring_view(&delim, 1), ignore_empty);
316 std::vector<std::string_view> FZ_PUBLIC_SYMBOL
strtok_view(std::string_view
const& tokens, std::string_view
const& delims,
bool const ignore_empty =
true);
317 std::vector<std::wstring_view> FZ_PUBLIC_SYMBOL
strtok_view(std::wstring_view
const& tokens, std::wstring_view
const& delims,
bool const ignore_empty =
true);
318 inline auto FZ_PUBLIC_SYMBOL
strtok_view(std::string_view
const& tokens,
char const delim,
bool const ignore_empty =
true) {
319 return strtok_view(tokens, std::string_view(&delim, 1), ignore_empty);
321 inline auto FZ_PUBLIC_SYMBOL
strtok_view(std::wstring_view
const& tokens,
wchar_t const delim,
bool const ignore_empty =
true) {
322 return strtok_view(tokens, std::wstring_view(&delim, 1), ignore_empty);
326 template<
typename T,
typename String>
327 T to_integral_impl(String
const& s, T
const errorval = T())
329 if constexpr (std::is_enum_v<T>) {
330 return static_cast<T
>(to_integral_impl<std::underlying_type_t<T>>(s,
static_cast<std::underlying_type_t<T>
>(errorval)));
334 auto it = s.cbegin();
335 if (it != s.cend() && (*it ==
'-' || *it ==
'+')) {
339 if (it == s.cend()) {
343 for (; it != s.cend(); ++it) {
345 if (c < '0' || c >
'9') {
352 if (!s.empty() && s.front() ==
'-') {
353 ret *=
static_cast<T
>(-1);
361 T
to_integral(std::string_view
const& s, T
const errorval = T()) {
362 return to_integral_impl<T>(s, errorval);
366 T
to_integral(std::wstring_view
const& s, T
const errorval = T()) {
367 return to_integral_impl<T>(s, errorval);
370 template<
typename T,
typename StringType>
371 T
to_integral(std::basic_string_view<StringType>
const& s, T
const errorval = T()) {
372 return to_integral_impl<T>(s, errorval);
377 template<
typename String>
379 for (
auto const& c : s) {
380 if (
static_cast<std::make_unsigned_t<typename String::value_type>
>(c) > 127) {
389 template<
typename String,
typename Chars>
390 void trim_impl(String & s, Chars
const& chars,
bool fromLeft,
bool fromRight) {
391 size_t const first = fromLeft ? s.find_first_not_of(chars) : 0;
392 if (first == String::npos) {
397 size_t const last = fromRight ? s.find_last_not_of(chars) : s.size();
398 if (last == String::npos) {
404 s = s.substr(first, last - first + 1);
408 inline std::string FZ_PUBLIC_SYMBOL
trimmed(std::string_view s, std::string_view
const& chars =
" \r\n\t",
bool fromLeft =
true,
bool fromRight =
true)
410 trim_impl(s, chars, fromLeft, fromRight);
411 return std::string(s);
414 inline 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)
416 trim_impl(s, chars, fromLeft, fromRight);
417 return std::wstring(s);
420 inline std::string FZ_PUBLIC_SYMBOL ltrimmed(std::string_view s, std::string_view
const& chars =
" \r\n\t")
422 trim_impl(s, chars,
true,
false);
423 return std::string(s);
426 inline std::wstring FZ_PUBLIC_SYMBOL ltrimmed(std::wstring_view s, std::wstring_view
const& chars = L
" \r\n\t")
428 trim_impl(s, chars,
true,
false);
429 return std::wstring(s);
432 inline std::string FZ_PUBLIC_SYMBOL rtrimmed(std::string_view s, std::string_view
const& chars =
" \r\n\t")
434 trim_impl(s, chars,
false,
true);
435 return std::string(s);
438 inline std::wstring FZ_PUBLIC_SYMBOL rtrimmed(std::wstring_view s, std::wstring_view
const& chars = L
" \r\n\t")
440 trim_impl(s, chars,
false,
true);
441 return std::wstring(s);
446 template<
typename String,
typename std::enable_if_t<std::is_same_v<
typename String::value_type,
char>,
int> = 0>
447 inline void trim(String & s, std::string_view
const& chars =
" \r\n\t",
bool fromLeft =
true,
bool fromRight =
true)
449 trim_impl(s, chars, fromLeft, fromRight);
452 template<
typename String,
typename std::enable_if_t<std::is_same_v<
typename String::value_type,
wchar_t>,
int> = 0>
453 inline void trim(String & s, std::wstring_view
const& chars = L
" \r\n\t",
bool fromLeft =
true,
bool fromRight =
true)
455 trim_impl(s, chars, fromLeft, fromRight);
458 template<
typename String,
typename std::enable_if_t<std::is_same_v<
typename String::value_type,
char>,
int> = 0>
459 inline void ltrim(String& s, std::string_view
const& chars =
" \r\n\t")
461 trim_impl(s, chars,
true,
false);
464 template<
typename String,
typename std::enable_if_t<std::is_same_v<
typename String::value_type,
wchar_t>,
int> = 0>
465 inline void ltrim(String& s, std::wstring_view
const& chars = L
" \r\n\t")
467 trim_impl(s, chars,
true,
false);
470 template<
typename String,
typename std::enable_if_t<std::is_same_v<
typename String::value_type,
char>,
int> = 0>
471 inline void rtrim(String& s, std::string_view
const& chars =
" \r\n\t")
473 trim_impl(s, chars,
false,
true);
476 template<
typename String,
typename std::enable_if_t<std::is_same_v<
typename String::value_type,
wchar_t>,
int> = 0>
477 inline void rtrim(String & s, std::wstring_view
const& chars = L
" \r\n\t")
479 trim_impl(s, chars,
false,
true);
486 template<
bool insensitive_ascii = false,
typename String>
489 if (beginning.size() > s.size()) {
492 if constexpr (insensitive_ascii) {
493 return std::equal(beginning.begin(), beginning.end(), s.begin(), [](
typename String::value_type
const& a,
typename String::value_type
const& b) {
498 return std::equal(beginning.begin(), beginning.end(), s.begin());
506 template<
bool insensitive_ascii = false,
typename String>
509 if (ending.size() > s.size()) {
513 if constexpr (insensitive_ascii) {
514 return std::equal(ending.rbegin(), ending.rend(), s.rbegin(), [](
typename String::value_type
const& a,
typename String::value_type
const& b) {
519 return std::equal(ending.rbegin(), ending.rend(), s.rbegin());
std::wstring to_wstring_from_utf8(std::string const &in)
Converts from std::string in UTF-8 into std::wstring.
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:361
Comparator to be used for std::map for case-insensitive keys.
Definition: string.hpp:122
bool starts_with(String const &s, String const &beginning)
Tests whether the first string starts with the second string.
Definition: string.hpp:487
std::wstring to_wstring(std::string_view const &in)
Converts from std::string in system encoding into std::wstring.
Char toupper_ascii(Char c)
Converts ASCII lowercase characters to uppercase as if C-locale is used.
Definition: string.hpp:98
native_string to_native(std::string_view const &in)
Converts std::string to native_string.
std::string to_utf8(std::string_view const &in)
Converts from std::string in native encoding into std::string in UTF-8.
std::enable_if< std::is_arithmetic< std::decay_t< Arg > >::value, std::wstring >::type to_wstring(Arg &&arg)
Converts from arithmetic type to std::wstring.
Definition: string.hpp:173
std::enable_if< std::is_arithmetic< std::decay_t< Arg > >::value, std::string >::type to_string(Arg &&arg)
Converts from arithmetic type to std::string.
Definition: string.hpp:205
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::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:408
bool equal_insensitive_ascii(std::string_view a, std::string_view b)
Locale-insensitive stricmp.
Definition: string.hpp:138
Char tolower_ascii(Char c)
Converts ASCII uppercase characters to lowercase as if C-locale is used.
Definition: string.hpp:86
std::string replaced_substrings(std::string const &in, std::string const &find, std::string const &replacement)
Returns in with all occurrences of find in the input string replaced with replacement.
size_t strlen(Char const *str)
Returns length of 0-terminated character sequence. Works with both narrow and wide-characters.
Definition: string.hpp:213
bool str_is_ascii(String const &s)
Returns true iff the string only has characters in the 7-bit ASCII range.
Definition: string.hpp:378
std::string str_tolower_ascii(std::string_view const &s)
tr_tolower_ascii does for strings what tolower_ascii does for individual characters ...
bool ends_with(String const &s, String const &ending)
Tests whether the first string ends with the second string.
Definition: string.hpp:507
std::wstring native_string
A string in the system's native character type and encoding. Note: This typedef changes depending on...
Definition: string.hpp:33
bool replace_substrings(std::string &in, std::string const &find, std::string const &replacement)
Modifies in, replacing all occurrences of find with replacement.
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:447
The namespace used by libfilezilla.
Definition: apply.hpp:17
Char const * choose_string(char const *c, wchar_t const *w)
Returns the function argument of the type matching the template argument.
Definition: string.hpp:267
std::vector< std::string > strtok(std::string_view const &tokens, std::string_view const &delims, bool const ignore_empty=true)
Tokenizes string.
Sets some global macros and further includes string.hpp.
int stricmp(std::string_view const &a, std::string_view const &b)
Locale-sensitive stricmp.
auto toString(Arg &&arg) -> typename std::enable_if< std::is_same< String, std::string >::value, 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:236
std::string to_string(std::wstring_view const &in)
Converts from std::wstring into std::string in system encoding.