swift
stringutils.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (C) 2015 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #ifndef SWIFT_MISC_STRINGUTILS_H
7 #define SWIFT_MISC_STRINGUTILS_H
8 
9 #include <algorithm>
10 #include <atomic>
11 
12 #include <QByteArray>
13 #include <QDateTime>
14 #include <QFlags>
15 #include <QList>
16 #include <QMap>
17 #include <QMapIterator>
18 #include <QSet>
19 #include <QString>
20 #include <QStringRef>
21 #include <QStringView>
22 #include <QtGlobal>
23 
24 #include "misc/range.h"
25 #include "misc/swiftmiscexport.h"
26 #include "misc/typetraits.h"
27 
28 template <class T1, class T2>
29 class QMap;
30 
31 namespace swift::misc
32 {
34  template <class F>
35  QString removeChars(const QString &s, F predicate)
36  {
37  QString result;
38  std::copy_if(s.begin(), s.end(), std::back_inserter(result), [=](auto c) { return !predicate(c); });
39  return result;
40  }
41 
43  inline QString removeIfInString(const QString &string, const QString &inString)
44  {
45  return removeChars(string.simplified(), [&](QChar c) { return inString.contains(c); });
46  }
47 
49  inline QString removeIfNotInString(const QString &string, const QString &inString)
50  {
51  return removeChars(string.simplified(), [&](QChar c) { return !inString.contains(c); });
52  }
53 
55  inline QString removeLineBreakAndTab(const QString &s)
56  {
57  return removeChars(s, [](QChar c) { return c == '\n' || c == '\t'; });
58  }
59 
61  SWIFT_MISC_EXPORT QString removeDateTimeSeparators(const QString &s);
62 
64  template <class F>
65  bool containsChar(const QString &s, F predicate)
66  {
67  return std::any_of(s.begin(), s.end(), predicate);
68  }
69 
71  inline bool containsLineBreakOrTab(const QString &s)
72  {
73  return containsChar(s, [](QChar c) { return c == '\n' || c == '\t'; });
74  }
75 
77  template <class F>
78  int indexOfChar(const QString &s, F predicate)
79  {
80  auto it = std::find_if(s.begin(), s.end(), predicate);
81  if (it == s.end()) { return -1; }
82  return static_cast<int>(std::distance(s.begin(), it));
83  }
84 
86  SWIFT_MISC_EXPORT int nthIndexOf(const QString &string, QChar ch, int nth = 1,
87  Qt::CaseSensitivity cs = Qt::CaseInsensitive);
88 
91  template <class F>
92  QList<QStringRef> splitStringRefs(const QString &s, F predicate)
93  {
94  QList<QStringRef> result;
95  auto notPredicate = [=](auto c) { return !predicate(c); };
96  auto begin = s.begin();
97  while (true)
98  {
99  begin = std::find_if(begin, s.end(), notPredicate);
100  if (begin == s.end()) { return result; }
101  auto end = std::find_if(begin, s.end(), predicate);
102  result.push_back(QStringRef(&s, std::distance(s.begin(), begin), std::distance(begin, end)));
103  begin = end;
104  }
105  }
106 
109  SWIFT_MISC_EXPORT QList<QStringRef> splitLinesRefs(const QString &s);
110 
112  template <class F>
113  void splitStringRefs(const QString &&, F) = delete;
114 
116  void splitLinesRefs(const QString &&) = delete;
117 
119  template <class F>
120  QStringList splitString(const QString &s, F predicate)
121  {
122  return makeRange(splitStringRefs(s, predicate)).transform([](QStringRef sr) { return sr.toString(); });
123  }
124 
126  SWIFT_MISC_EXPORT QStringList splitLines(const QString &s);
127 
129  SWIFT_MISC_EXPORT QByteArray utfToPercentEncoding(const QString &s, const QByteArray &allow = {},
130  char percent = '%');
131 
133  SWIFT_MISC_EXPORT QString utfFromPercentEncoding(const QByteArray &ba, char percent = '%');
134 
136  template <class K, class V>
137  QString qmapToString(const QMap<K, V> &map)
138  {
139  QString s;
140  static const QString kv("%1: %2 ");
141  QMapIterator<K, V> i(map);
142  while (i.hasNext())
143  {
144  i.next();
145  s.append(kv.arg(i.key()).arg(i.value()));
146  }
147  return s.trimmed();
148  }
149 
152 
154  inline bool is09(const QChar &c) { return c >= u'0' && c <= u'9'; }
155 
157  inline bool is09OrSeparator(const QChar &c) { return is09(c) || c == u',' || c == '.'; }
158 
160  inline const QString &safeAt(const QStringList &stringList, int index)
161  {
162  if (stringList.size() > index) { return stringList.at(index); }
163  static const QString empty;
164  return empty;
165  }
166 
168  inline bool isDigitsOnlyString(const QString &testString)
169  {
170  return !containsChar(testString, [](QChar c) { return !c.isDigit(); });
171  }
172 
174  inline bool is09OnlyString(const QString &testString)
175  {
176  return !containsChar(testString, [](QChar c) { return !is09(c); });
177  }
178 
180  inline bool is09OrSeparatorOnlyString(const QString &testString)
181  {
182  return !containsChar(testString, [](QChar c) { return !is09OrSeparator(c); });
183  }
184 
186  inline QString digitOnlyString(const QString &string)
187  {
188  return removeChars(string, [](QChar c) { return !c.isDigit(); });
189  }
190 
192  inline QString char09OnlyString(const QString &string)
193  {
194  return removeChars(string, [](QChar c) { return !is09(c); });
195  }
196 
198  inline QString char09OrSeparatorOnlyString(const QString &string)
199  {
200  return removeChars(string, [](QChar c) { return !is09OrSeparator(c); });
201  }
202 
204  inline QString asciiOnlyString(const QString &string)
205  {
206  return removeChars(string.simplified(), [](QChar c) { return c.unicode() > 127; });
207  }
208 
210  SWIFT_MISC_EXPORT QString inApostrophes(const QString &in, bool ignoreEmpty = false);
211 
213  SWIFT_MISC_EXPORT QString inQuotes(const QString &in, bool ignoreEmpty = false);
214 
216  SWIFT_MISC_EXPORT bool hasBalancedQuotes(const QString &in, char quote = '"');
217 
220 
222  SWIFT_MISC_EXPORT QString removeSurroundingQuotes(const QString &in);
223 
225  SWIFT_MISC_EXPORT const QString &boolToOnOff(bool v);
226 
228  SWIFT_MISC_EXPORT const QString &boolToYesNo(bool v);
229 
231  SWIFT_MISC_EXPORT const QString &boolToTrueFalse(bool v);
232 
234  SWIFT_MISC_EXPORT const QString &boolToEnabledDisabled(bool v);
235 
237  SWIFT_MISC_EXPORT const QString &boolToNullNotNull(bool isNull);
238 
240  SWIFT_MISC_EXPORT bool stringToBool(const QString &boolString);
241 
244  SWIFT_MISC_EXPORT int fuzzyShortStringComparision(const QString &str1, const QString &str2,
245  Qt::CaseSensitivity cs = Qt::CaseSensitive);
246 
248  SWIFT_MISC_EXPORT QString intToHex(int value, int digits = 2);
249 
252 
254  SWIFT_MISC_EXPORT QString dotToLocaleDecimalPoint(const QString &input);
255 
257  SWIFT_MISC_EXPORT QString stripDesignatorFromCompleterString(const QString &candidate);
258 
260  SWIFT_MISC_EXPORT QStringList textCodecNames(bool simpleNames, bool mibNames);
261 
263  SWIFT_MISC_EXPORT QString simplifyAccents(const QString &candidate);
264 
266  SWIFT_MISC_EXPORT QString simplifyByDecomposition(const QString &candidate);
267 
269  SWIFT_MISC_EXPORT bool caseInsensitiveStringCompare(const QString &c1, const QString &c2);
270 
272  SWIFT_MISC_EXPORT bool stringCompare(const QString &c1, const QString &c2, Qt::CaseSensitivity cs);
273 
275  SWIFT_MISC_EXPORT QString simplifyNameForSearch(const QString &name);
276 
278  SWIFT_MISC_EXPORT QString withQuestionMark(const QString &question);
279 
282  SWIFT_MISC_EXPORT QDateTime fromStringUtc(const QString &dateTimeString, const QString &format);
283 
286  SWIFT_MISC_EXPORT QDateTime fromStringUtc(const QString &dateTimeString, Qt::DateFormat format = Qt::TextDate);
287 
290  SWIFT_MISC_EXPORT QDateTime fromStringUtc(const QString &dateTimeString, const QLocale &locale,
291  QLocale::FormatType format);
292 
296  SWIFT_MISC_EXPORT QDateTime parseMultipleDateTimeFormats(const QString &dateTimeString);
297 
301  SWIFT_MISC_EXPORT QDateTime parseDateTimeStringOptimized(const QString &dateTimeString);
302 
304  SWIFT_MISC_EXPORT QString joinStringSet(const QSet<QString> &set, const QString &separator);
305 
307  SWIFT_MISC_EXPORT QString removeComments(const QString &in, bool removeSlash, bool removeDoubleSlash);
308 
310  SWIFT_MISC_EXPORT const QString &defaultIfEmpty(const QString &candidate, const QString &defaultIfEmpty);
311 
313  SWIFT_MISC_EXPORT bool containsAny(const QString &testString, const QStringList &any, Qt::CaseSensitivity cs);
314 
316  SWIFT_MISC_EXPORT double parseFraction(const QString &fraction,
317  double failDefault = std::numeric_limits<double>::quiet_NaN());
318 
320  SWIFT_MISC_EXPORT QString cleanNumber(const QString &number);
321 
325  template <typename T, typename = void>
326  struct TString;
327 
328  // Stringification traits specializations.
330  template <>
331  struct TString<QString>
332  {
333  static QString toQString(const QString &s) { return s; }
334  };
335  template <>
336  struct TString<QStringRef>
337  {
338  static QString toQString(const QStringRef &sr) { return sr.toString(); }
339  };
340  template <>
341  struct TString<QStringView>
342  {
343  static QString toQString(QStringView sv) { return sv.toString(); }
344  };
345  template <>
346  struct TString<QChar>
347  {
348  static QString toQString(QChar c) { return c; }
349  };
350  template <>
351  struct TString<char>
352  {
353  static QString toQString(char c) { return QChar(c); }
354  };
355  template <>
356  struct TString<bool>
357  {
358  static QString toQString(bool n) { return QString::number(n); }
359  };
360  template <>
361  struct TString<int>
362  {
363  static QString toQString(int n) { return QString::number(n); }
364  };
365  template <>
366  struct TString<uint>
367  {
368  static QString toQString(uint n) { return QString::number(n); }
369  };
370  template <>
371  struct TString<long>
372  {
373  static QString toQString(long n) { return QString::number(n); }
374  };
375  template <>
376  struct TString<ulong>
377  {
378  static QString toQString(ulong n) { return QString::number(n); }
379  };
380  template <>
381  struct TString<qlonglong>
382  {
383  static QString toQString(qlonglong n) { return QString::number(n); }
384  };
385  template <>
386  struct TString<qulonglong>
387  {
388  static QString toQString(qulonglong n) { return QString::number(n); }
389  };
390  template <>
391  struct TString<short>
392  {
393  static QString toQString(short n) { return QString::number(n); }
394  };
395  template <>
396  struct TString<ushort>
397  {
398  static QString toQString(ushort n) { return QString::number(n); }
399  };
400  template <>
401  struct TString<float>
402  {
403  static QString toQString(float n) { return QString::number(n); }
404  };
405  template <>
406  struct TString<double>
407  {
408  static QString toQString(double n) { return QString::number(n); }
409  };
410  template <typename T>
411  struct TString<T, std::enable_if_t<std::is_enum_v<T>>>
412  {
413  static QString toQString(T e) { return QString::number(e); }
414  };
415  template <typename T>
416  struct TString<T, std::enable_if_t<std::is_convertible_v<T, QString>>>
417  {
418  static QString toQString(const T &v) { return v; }
419  };
420  template <typename T>
421  struct TString<T, std::enable_if_t<THasToQString<T>::value>>
422  {
423  static QString toQString(const T &v) { return v.toQString(); }
424  };
425  template <typename T>
426  struct TString<QFlags<T>>
427  {
428  static QString toQString(QFlags<T> n) { return TString<typename QFlags<T>::Int>::toQString(n); }
429  };
430  template <typename T>
431  struct TString<std::atomic<T>>
432  {
433  static QString toQString(const std::atomic<T> &n) { return TString<T>::toQString(n); }
434  };
436 } // namespace swift::misc
437 
438 #endif // SWIFT_MISC_STRINGUTILS_H
Free functions in swift::misc.
SWIFT_MISC_EXPORT QString withQuestionMark(const QString &question)
Add a question mark at the end if not existing.
SWIFT_MISC_EXPORT QString simplifyNameForSearch(const QString &name)
Get a simplified upper case name for searching by removing all characters except A-Z.
const QString & safeAt(const QStringList &stringList, int index)
Safe "at" function, returns empty string if index does not exists.
Definition: stringutils.h:160
SWIFT_MISC_EXPORT QString cleanNumber(const QString &number)
Remove leading 0, trailing 0, " ", and "." from a number.
SWIFT_MISC_EXPORT QString inApostrophes(const QString &in, bool ignoreEmpty=false)
Return string in apostrophes.
T::const_iterator begin(const LockFreeReader< T > &reader)
Non-member begin() and end() for so LockFree containers can be used in ranged for loops.
Definition: lockfree.h:332
SWIFT_MISC_EXPORT QString intToHex(int value, int digits=2)
Int to hex value.
bool is09(const QChar &c)
Is 0-9 char, isDigit allows a bunch of more characters.
Definition: stringutils.h:154
SWIFT_MISC_EXPORT QByteArray utfToPercentEncoding(const QString &s, const QByteArray &allow={}, char percent='%')
Extended percent encoding supporting UTF-16.
SWIFT_MISC_EXPORT QString stripDesignatorFromCompleterString(const QString &candidate)
Strip a designator from a combined string.
SWIFT_MISC_EXPORT QDateTime parseMultipleDateTimeFormats(const QString &dateTimeString)
Parse multiple date time formats.
QString removeIfInString(const QString &string, const QString &inString)
Remove if in string.
Definition: stringutils.h:43
SWIFT_MISC_EXPORT QString utfFromPercentEncoding(const QByteArray &ba, char percent='%')
Reverse utfFromPercentEncoding.
SWIFT_MISC_EXPORT int fuzzyShortStringComparision(const QString &str1, const QString &str2, Qt::CaseSensitivity cs=Qt::CaseSensitive)
Fuzzy compare for short strings (like ICAO designators)
QString removeIfNotInString(const QString &string, const QString &inString)
Remove if NOT in string.
Definition: stringutils.h:49
QString removeChars(const QString &s, F predicate)
Return a string with characters removed that match the given predicate.
Definition: stringutils.h:35
bool is09OrSeparator(const QChar &c)
Is 0-9, or ","/";".
Definition: stringutils.h:157
bool is09OrSeparatorOnlyString(const QString &testString)
String with 0-9/separator only.
Definition: stringutils.h:180
SWIFT_MISC_EXPORT QString removeDateTimeSeparators(const QString &s)
Remove the typical separators such as "-", " ".
SWIFT_MISC_EXPORT QMap< QString, QString > parseIniValues(const QString &data)
Obtain ini file like values, e.g. foo=bar.
auto makeRange(I begin, I2 end) -> CRange< I >
Returns a CRange constructed from begin and end iterators of deduced types.
Definition: range.h:316
bool is09OnlyString(const QString &testString)
String with 0-9 only.
Definition: stringutils.h:174
SWIFT_MISC_EXPORT QString simplifyByDecomposition(const QString &candidate)
Remove accents / diacritic marks from a string by doing a Unicode decomposition and removing mark cha...
SWIFT_MISC_EXPORT int nthIndexOf(const QString &string, QChar ch, int nth=1, Qt::CaseSensitivity cs=Qt::CaseInsensitive)
nth index of ch
SWIFT_MISC_EXPORT bool caseInsensitiveStringCompare(const QString &c1, const QString &c2)
Case insensitive string compare.
SWIFT_MISC_EXPORT const QString & boolToOnOff(bool v)
Bool to on/off.
SWIFT_MISC_EXPORT QString removeSurroundingQuotes(const QString &in)
Remove surrounding quotes "foo" -> foo.
SWIFT_MISC_EXPORT double parseFraction(const QString &fraction, double failDefault=std::numeric_limits< double >::quiet_NaN())
Parse a fraction like 2/3.
SWIFT_MISC_EXPORT bool hasBalancedQuotes(const QString &in, char quote='"')
Has balanced quotes.
SWIFT_MISC_EXPORT QString dotToLocaleDecimalPoint(QString &input)
Replace dot '.' by locale decimal point.
SWIFT_MISC_EXPORT QString simplifyAccents(const QString &candidate)
Remove accents / diacritic marks from a string.
bool containsLineBreakOrTab(const QString &s)
Contains a line break or tab.
Definition: stringutils.h:71
SWIFT_MISC_EXPORT bool stringCompare(const QString &c1, const QString &c2, Qt::CaseSensitivity cs)
String compare.
int indexOfChar(const QString &s, F predicate)
Index of first character in the string matching the given predicate, or -1 if not found.
Definition: stringutils.h:78
SWIFT_MISC_EXPORT QString inQuotes(const QString &in, bool ignoreEmpty=false)
Return string in quotes.
QString asciiOnlyString(const QString &string)
String only with ASCII values.
Definition: stringutils.h:204
T::const_iterator end(const LockFreeReader< T > &reader)
Non-member begin() and end() for so LockFree containers can be used in ranged for loops.
Definition: lockfree.h:338
SWIFT_MISC_EXPORT QString removeSurroundingApostrophes(const QString &in)
Remove surrounding apostrophes 'foo' -> foo.
SWIFT_MISC_EXPORT QString joinStringSet(const QSet< QString > &set, const QString &separator)
Convert string to bool.
SWIFT_MISC_EXPORT const QString & boolToNullNotNull(bool isNull)
Bool isNull to null/no null.
QString digitOnlyString(const QString &string)
String only with digits.
Definition: stringutils.h:186
SWIFT_MISC_EXPORT QStringList splitLines(const QString &s)
Split a string into multiple lines. Blank lines are skipped.
SWIFT_MISC_EXPORT QStringList textCodecNames(bool simpleNames, bool mibNames)
Strip a designator from a combined string.
QString char09OnlyString(const QString &string)
String only with 0-9.
Definition: stringutils.h:192
SWIFT_MISC_EXPORT QString removeComments(const QString &in, bool removeSlash, bool removeDoubleSlash)
Remove comments such as /‍** **‍/ or //.
SWIFT_MISC_EXPORT const QString & boolToEnabledDisabled(bool v)
Bool to enabled/disabled.
QList< QStringRef > splitStringRefs(const QString &s, F predicate)
Split a string into multiple strings, using a predicate function to identify the split points.
Definition: stringutils.h:92
QStringList splitString(const QString &s, F predicate)
Split a string into multiple strings, using a predicate function to identify the split points.
Definition: stringutils.h:120
SWIFT_MISC_EXPORT bool stringToBool(const QString &boolString)
Convert string to bool.
SWIFT_MISC_EXPORT bool containsAny(const QString &testString, const QStringList &any, Qt::CaseSensitivity cs)
Contains any string of the list?
SWIFT_MISC_EXPORT const QString & boolToTrueFalse(bool v)
Bool to true/false.
QString char09OrSeparatorOnlyString(const QString &string)
String only with 0-9, or separator.
Definition: stringutils.h:198
bool isDigitsOnlyString(const QString &testString)
String with digits only.
Definition: stringutils.h:168
QString removeLineBreakAndTab(const QString &s)
Remove line breaks and tabs.
Definition: stringutils.h:55
SWIFT_MISC_EXPORT QDateTime fromStringUtc(const QString &dateTimeString, const QString &format)
Same as QDateTime::fromString but QDateTime will be set to UTC.
bool containsChar(const QString &s, F predicate)
True if any character in the string matches the given predicate.
Definition: stringutils.h:65
SWIFT_MISC_EXPORT const QString & defaultIfEmpty(const QString &candidate, const QString &defaultIfEmpty)
Default string if string is empty.
SWIFT_MISC_EXPORT const QString & boolToYesNo(bool v)
Bool to yes/no.
SWIFT_MISC_EXPORT QDateTime parseDateTimeStringOptimized(const QString &dateTimeString)
Parse yyyyMMddHHmmsszzz strings optimized.
QString qmapToString(const QMap< K, V > &map)
A map converted to string.
Definition: stringutils.h:137
SWIFT_MISC_EXPORT QList< QStringRef > splitLinesRefs(const QString &s)
Split a string into multiple lines. Blank lines are skipped.
Stringification traits class.
Definition: stringutils.h:326
#define SWIFT_MISC_EXPORT
Export a class or function from the library.