libfilezilla
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 <string>
7 #include <vector>
8 
16 namespace fz {
17 
30 #ifdef FZ_WINDOWS
31 typedef std::wstring native_string;
32 #endif
33 #if defined(FZ_UNIX) || defined(FZ_MAC)
34 typedef std::string native_string;
35 #endif
36 
41 native_string FZ_PUBLIC_SYMBOL to_native(std::string const& in);
42 
47 native_string FZ_PUBLIC_SYMBOL to_native(std::wstring const& in);
48 
55 int FZ_PUBLIC_SYMBOL stricmp(std::string const& a, std::string const& b);
56 int FZ_PUBLIC_SYMBOL stricmp(std::wstring const& a, std::wstring const& b);
57 
75 template<typename Char>
76 Char tolower_ascii(Char c) {
77  if (c >= 'A' && c <= 'Z') {
78  return c + ('a' - 'A');
79  }
80  return c;
81 }
82 
83 template<>
84 std::wstring::value_type FZ_PUBLIC_SYMBOL tolower_ascii(std::wstring::value_type c);
85 
87 template<typename Char>
88 Char toupper_ascii(Char c) {
89  if (c >= 'a' && c <= 'z') {
90  return c + ('A' - 'a');
91  }
92  return c;
93 }
94 
95 template<>
96 std::wstring::value_type FZ_PUBLIC_SYMBOL toupper_ascii(std::wstring::value_type c);
97 
100  // Note: For UTF-8 strings it works on individual octets!
101 template<typename String>
102 String str_tolower_ascii(String const& s)
103 {
104  String ret = s;
105  for (auto& c : ret) {
106  c = tolower_ascii(c);
107  }
108  return ret;
109 }
110 
111 template<typename String>
112 String str_toupper_ascii(String const& s)
113 {
114  String ret = s;
115  for (auto& c : ret) {
116  c = toupper_ascii(c);
117  }
118  return ret;
119 }
120 
126 struct FZ_PUBLIC_SYMBOL less_insensitive_ascii final
127 {
128  template<typename T>
129  bool operator()(T const& lhs, T const& rhs) const {
130  return fz::str_tolower_ascii(lhs) < fz::str_tolower_ascii(rhs);
131  }
132 };
133 
140 std::wstring FZ_PUBLIC_SYMBOL to_wstring(std::string const& in);
141 
143 inline std::wstring FZ_PUBLIC_SYMBOL to_wstring(std::wstring const& in) { return in; }
144 
146 template<typename Arg>
147 inline typename std::enable_if<std::is_arithmetic<std::decay_t<Arg>>::value, std::wstring>::type to_wstring(Arg && arg)
148 {
149  return std::to_wstring(std::forward<Arg>(arg));
150 }
151 
152 
157 std::wstring FZ_PUBLIC_SYMBOL to_wstring_from_utf8(std::string const& in);
158 std::wstring FZ_PUBLIC_SYMBOL to_wstring_from_utf8(char const* s, size_t len);
159 
166 std::string FZ_PUBLIC_SYMBOL to_string(std::wstring const& in);
167 
169 inline std::string FZ_PUBLIC_SYMBOL to_string(std::string const& in) { return in; }
170 
172 template<typename Arg>
173 inline typename std::enable_if<std::is_arithmetic<std::decay_t<Arg>>::value, std::string>::type to_string(Arg && arg)
174 {
175  return std::to_string(std::forward<Arg>(arg));
176 }
177 
178 
180 template<typename Char>
181 size_t strlen(Char const* str) {
182  return std::char_traits<Char>::length(str);
183 }
184 
185 
192 std::string FZ_PUBLIC_SYMBOL to_utf8(std::string const& in);
193 
200 std::string FZ_PUBLIC_SYMBOL to_utf8(std::wstring const& in);
201 
203 template<typename String, typename Arg>
204 inline auto toString(Arg&& arg) -> typename std::enable_if<std::is_same<String, std::string>::value, decltype(to_string(std::forward<Arg>(arg)))>::type
205 {
206  return to_string(std::forward<Arg>(arg));
207 }
208 
209 template<typename String, typename Arg>
210 inline auto toString(Arg&& arg) -> typename std::enable_if<std::is_same<String, std::wstring>::value, decltype(to_wstring(std::forward<Arg>(arg)))>::type
211 {
212  return to_wstring(std::forward<Arg>(arg));
213 }
214 
215 #if !defined(fzT) || defined(DOXYGEN)
216 #ifdef FZ_WINDOWS
217 
221 #define fzT(x) L ## x
222 #else
223 
227 #define fzT(x) x
228 #endif
229 #endif
230 
232 template<typename Char>
233 Char const* choose_string(char const* c, wchar_t const* w);
234 
235 template<> inline char const* choose_string(char const* c, wchar_t const*) { return c; }
236 template<> inline wchar_t const* choose_string(char const*, wchar_t const* w) { return w; }
237 
238 #if !defined(fzS) || defined(DOXYGEN)
239 
250 #define fzS(Char, s) fz::choose_string<Char>(s, L ## s)
251 #endif
252 
254 std::string FZ_PUBLIC_SYMBOL replaced_substrings(std::string const& in, std::string const& find, std::string const& replacement);
255 std::wstring FZ_PUBLIC_SYMBOL replaced_substrings(std::wstring const& in, std::wstring const& find, std::wstring const& replacement);
256 
258 void FZ_PUBLIC_SYMBOL replace_substrings(std::string& in, std::string const& find, std::string const& replacement);
259 void FZ_PUBLIC_SYMBOL replace_substrings(std::wstring& in, std::wstring const& find, std::wstring const& replacement);
260 
262 template<typename String, typename Delim, typename Container = std::vector<String>>
263 Container strtok(String const& s, Delim const& delims)
264 {
265  Container ret;
266 
267  typename String::size_type start{}, pos{};
268  do {
269  pos = s.find_first_of(delims, start);
270 
271  // Not found, we're at ends;
272  if (pos == String::npos) {
273  if (start < s.size()) {
274  ret.emplace_back(s.substr(start));
275  }
276  }
277  else if (pos > start) {
278  // Non-empty substring
279  ret.emplace_back(s.substr(start, pos - start));
280  }
281  start = pos + 1;
282  } while (pos != String::npos);
283 
284  return ret;
285 }
286 
287 // Converts string to integral type T. If string is not convertible, T() is returned.
288 template<typename T, typename String>
289 T to_integral(String const& s, T const errorval = T())
290 {
291  T ret{};
292 
293  auto it = s.cbegin();
294  if (it != s.cend() && (*it == '-' || *it == '+')) {
295  ++it;
296  }
297 
298  if (it == s.cend()) {
299  return errorval;
300  }
301 
302  for (; it != s.cend(); ++it) {
303  auto const& c = *it;
304  if (c < '0' || c > '9') {
305  return errorval;
306  }
307  ret *= 10;
308  ret += c - '0';
309  }
310 
311  if (!s.empty() && s.front() == '-') {
312  return ret *= static_cast<T>(-1);
313  }
314  else {
315  return ret;
316  }
317 }
318 
320 template<typename String>
321 bool str_is_ascii(String const& s) {
322  for (auto const& c : s) {
323  if (static_cast<std::make_unsigned_t<typename String::value_type>>(c) > 127) {
324  return false;
325  }
326  }
327 
328  return true;
329 }
330 
332 template<typename String>
333 String trimmed(String const& s, String const& chars = fzS(typename String::value_type, " \r\n\t"), bool fromLeft = true, bool fromRight = true) {
334  size_t const first = fromLeft ? s.find_first_not_of(chars) : 0;
335  if (first == String::npos) {
336  return String();
337  }
338 
339  size_t const last = fromRight ? s.find_last_not_of(chars) : s.size();
340  if (last == String::npos) {
341  return String();
342  }
343  return s.substr(first, last - first + 1);
344 }
345 
346 template<typename String>
347 String ltrimmed(String const& s, String const& chars = fzS(typename String::value_type, " \r\n\t"), bool fromLeft = true, bool fromRight = true) {
348  return trimmed(s, chars, true, false);
349 }
350 
351 template<typename String>
352 String rtrimmed(String const& s, String const& chars = fzS(typename String::value_type, " \r\n\t"), bool fromLeft = true, bool fromRight = true) {
353  return trimmed(s, chars, false, true);
354 }
355 
357 template<typename String>
358 void trim(String & s, String const& chars = fzS(typename String::value_type, " \r\n\t")) {
359  s = trimmed(s, chars);
360 }
361 
362 template<typename String>
363 void ltrim(String & s, String const& chars = fzS(typename String::value_type, " \r\n\t")) {
364  s = trimmed(s, chars, true, false);
365 }
366 
367 template<typename String>
368 void rtrim(String & s, String const& chars = fzS(typename String::value_type, " \r\n\t")) {
369  s = trimmed(s, chars, false, true);
370 }
371 
372 }
373 
374 #endif
std::wstring to_wstring_from_utf8(std::string const &in)
Converts from std::string in UTF-8 into std::wstring.
Comparator to be used for std::map for case-insentitive keys.
Definition: string.hpp:126
Char toupper_ascii(Char c)
Converts ASCII lowercase characters to uppercase as if C-locale is used.
Definition: string.hpp:88
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:147
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:173
#define fzS(Char, s)
Macro to get const pointer to a string of the corresponding type.
Definition: string.hpp:250
int stricmp(std::string const &a, std::string const &b)
Locale-sensitive stricmp.
Char tolower_ascii(Char c)
Converts ASCII uppercase characters to lowercase as if C-locale is used.
Definition: string.hpp:76
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.
std::string to_utf8(std::string const &in)
Converts from std::string in native encoding into std::string in UTF-8.
void replace_substrings(std::string &in, std::string const &find, std::string const &replacement)
Modifies in, replacing all occurrences of find 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:181
bool str_is_ascii(String const &s)
Returns true iff the string only has characters in the 7-bit ASCII range.
Definition: string.hpp:321
Container strtok(String const &s, Delim const &delims)
Tokenizes string. Returns all non-empty substrings.
Definition: string.hpp:263
String trimmed(String const &s, String const &chars=fz::choose_string< typename String::value_type >(" \r\n\t", L" \r\n\t"), bool fromLeft=true, bool fromRight=true)
Return passed string with all leading and trailing whitespace removed.
Definition: string.hpp:333
std::wstring native_string
A string in the system&#39;s native character type and encoding. Note: This typedef changes depending on...
Definition: string.hpp:31
std::string to_string(std::wstring const &in)
Converts from std::wstring into std::string in system encoding.
The namespace used by libfilezilla.
Definition: apply.hpp:16
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:235
void trim(String &s, String const &chars=fz::choose_string< typename String::value_type >(" \r\n\t", L" \r\n\t"))
Remove all leading and trailing whitespace from string.
Definition: string.hpp:358
String str_tolower_ascii(String const &s)
tr_tolower_ascii does for strings what tolower_ascii does for individual characters ...
Definition: string.hpp:102
Sets some global macros and further includes string.hpp.
native_string to_native(std::string const &in)
Converts std::string to native_string.
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:204
std::wstring to_wstring(std::string const &in)
Converts from std::string in system encoding into std::wstring.