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 <QStringView>
21 #include <QtGlobal>
22 
23 #include "misc/range.h"
24 #include "misc/swiftmiscexport.h"
25 #include "misc/typetraits.h"
26 
27 template <class T1, class T2>
28 class QMap;
29 
30 namespace swift::misc
31 {
33  template <class F>
34  QString removeChars(const QString &s, F predicate)
35  {
36  QString result;
37  std::copy_if(s.begin(), s.end(), std::back_inserter(result), [=](auto c) { return !predicate(c); });
38  return result;
39  }
40 
42  inline QString removeIfInString(const QString &string, const QString &inString)
43  {
44  return removeChars(string.simplified(), [&](QChar c) { return inString.contains(c); });
45  }
46 
48  inline QString removeIfNotInString(const QString &string, const QString &inString)
49  {
50  return removeChars(string.simplified(), [&](QChar c) { return !inString.contains(c); });
51  }
52 
54  inline QString removeLineBreakAndTab(const QString &s)
55  {
56  return removeChars(s, [](QChar c) { return c == '\n' || c == '\t'; });
57  }
58 
60  SWIFT_MISC_EXPORT QString removeDateTimeSeparators(const QString &s);
61 
63  template <class F>
64  bool containsChar(const QString &s, F predicate)
65  {
66  return std::any_of(s.begin(), s.end(), predicate);
67  }
68 
70  inline bool containsLineBreakOrTab(const QString &s)
71  {
72  return containsChar(s, [](QChar c) { return c == '\n' || c == '\t'; });
73  }
74 
76  template <class F>
77  int indexOfChar(const QString &s, F predicate)
78  {
79  auto it = std::find_if(s.begin(), s.end(), predicate);
80  if (it == s.end()) { return -1; }
81  return static_cast<int>(std::distance(s.begin(), it));
82  }
83 
85  SWIFT_MISC_EXPORT qsizetype nthIndexOf(const QString &string, QChar ch, int nth = 1,
86  Qt::CaseSensitivity cs = Qt::CaseInsensitive);
87 
90  template <class F>
91  QList<QStringView> splitStringRefs(const QString &s, F predicate)
92  {
93  QList<QStringView> result;
94  auto notPredicate = [=](auto c) { return !predicate(c); };
95  const auto *begin = s.begin();
96  while (true)
97  {
98  begin = std::find_if(begin, s.end(), notPredicate);
99  if (begin == s.end()) { return result; }
100  auto end = std::find_if(begin, s.end(), predicate);
101  result.push_back(QStringView(s).slice(std::distance(s.begin(), begin), std::distance(begin, end)));
102  begin = end;
103  }
104  }
105 
108  SWIFT_MISC_EXPORT QList<QStringView> splitLinesRefs(const QString &s);
109 
111  template <class F>
112  void splitStringRefs(const QString &&, F) = delete;
113 
115  void splitLinesRefs(const QString &&) = delete;
116 
118  template <class F>
119  QStringList splitString(const QString &s, F predicate)
120  {
121  return makeRange(splitStringRefs(s, predicate)).transform([](QStringView sv) { return sv.toString(); });
122  }
123 
125  SWIFT_MISC_EXPORT QStringList splitLines(const QString &s);
126 
128  SWIFT_MISC_EXPORT QByteArray utfToPercentEncoding(const QString &s, const QByteArray &allow = {},
129  char percent = '%');
130 
132  SWIFT_MISC_EXPORT QString utfFromPercentEncoding(const QByteArray &ba, char percent = '%');
133 
135  template <class K, class V>
136  QString qmapToString(const QMap<K, V> &map)
137  {
138  QString s;
139  static const QString kv("%1: %2 ");
140  QMapIterator<K, V> i(map);
141  while (i.hasNext())
142  {
143  i.next();
144  s.append(kv.arg(i.key()).arg(i.value()));
145  }
146  return s.trimmed();
147  }
148 
151 
153  inline bool is09(const QChar &c) { return c >= u'0' && c <= u'9'; }
154 
156  inline bool is09OrSeparator(const QChar &c) { return is09(c) || c == u',' || c == '.'; }
157 
159  inline const QString &safeAt(const QStringList &stringList, int index)
160  {
161  if (stringList.size() > index) { return stringList.at(index); }
162  static const QString empty;
163  return empty;
164  }
165 
167  inline bool isDigitsOnlyString(const QString &testString)
168  {
169  return !containsChar(testString, [](QChar c) { return !c.isDigit(); });
170  }
171 
173  inline bool is09OnlyString(const QString &testString)
174  {
175  return !containsChar(testString, [](QChar c) { return !is09(c); });
176  }
177 
179  inline bool is09OrSeparatorOnlyString(const QString &testString)
180  {
181  return !containsChar(testString, [](QChar c) { return !is09OrSeparator(c); });
182  }
183 
185  inline QString digitOnlyString(const QString &string)
186  {
187  return removeChars(string, [](QChar c) { return !c.isDigit(); });
188  }
189 
191  inline QString char09OnlyString(const QString &string)
192  {
193  return removeChars(string, [](QChar c) { return !is09(c); });
194  }
195 
197  inline QString char09OrSeparatorOnlyString(const QString &string)
198  {
199  return removeChars(string, [](QChar c) { return !is09OrSeparator(c); });
200  }
201 
203  inline QString asciiOnlyString(const QString &string)
204  {
205  return removeChars(string.simplified(), [](QChar c) { return c.unicode() > 127; });
206  }
207 
209  SWIFT_MISC_EXPORT QString inApostrophes(const QString &in, bool ignoreEmpty = false);
210 
212  SWIFT_MISC_EXPORT QString inQuotes(const QString &in, bool ignoreEmpty = false);
213 
215  SWIFT_MISC_EXPORT bool hasBalancedQuotes(const QString &in, char quote = '"');
216 
219 
221  SWIFT_MISC_EXPORT QString removeSurroundingQuotes(const QString &in);
222 
224  SWIFT_MISC_EXPORT const QString &boolToOnOff(bool v);
225 
227  SWIFT_MISC_EXPORT const QString &boolToYesNo(bool v);
228 
230  SWIFT_MISC_EXPORT const QString &boolToTrueFalse(bool v);
231 
233  SWIFT_MISC_EXPORT const QString &boolToEnabledDisabled(bool v);
234 
236  SWIFT_MISC_EXPORT const QString &boolToNullNotNull(bool isNull);
237 
239  SWIFT_MISC_EXPORT bool stringToBool(const QString &boolString);
240 
243  SWIFT_MISC_EXPORT int fuzzyShortStringComparision(const QString &str1, const QString &str2,
244  Qt::CaseSensitivity cs = Qt::CaseSensitive);
245 
247  SWIFT_MISC_EXPORT QString intToHex(int value, int digits = 2);
248 
251 
253  SWIFT_MISC_EXPORT QString dotToLocaleDecimalPoint(const QString &input);
254 
256  SWIFT_MISC_EXPORT QString stripDesignatorFromCompleterString(const QString &candidate);
257 
259  SWIFT_MISC_EXPORT QString simplifyAccents(const QString &candidate);
260 
262  SWIFT_MISC_EXPORT QString simplifyByDecomposition(const QString &candidate);
263 
265  SWIFT_MISC_EXPORT bool caseInsensitiveStringCompare(const QString &c1, const QString &c2);
266 
268  SWIFT_MISC_EXPORT bool stringCompare(const QString &c1, const QString &c2, Qt::CaseSensitivity cs);
269 
271  SWIFT_MISC_EXPORT QString simplifyNameForSearch(const QString &name);
272 
274  SWIFT_MISC_EXPORT QString withQuestionMark(const QString &question);
275 
278  SWIFT_MISC_EXPORT QDateTime fromStringUtc(const QString &dateTimeString, const QString &format);
279 
282  SWIFT_MISC_EXPORT QDateTime fromStringUtc(const QString &dateTimeString, Qt::DateFormat format = Qt::TextDate);
283 
286  SWIFT_MISC_EXPORT QDateTime fromStringUtc(const QString &dateTimeString, const QLocale &locale,
287  QLocale::FormatType format);
288 
292  SWIFT_MISC_EXPORT QDateTime parseMultipleDateTimeFormats(const QString &dateTimeString);
293 
297  SWIFT_MISC_EXPORT QDateTime parseDateTimeStringOptimized(const QString &dateTimeString);
298 
300  SWIFT_MISC_EXPORT QString joinStringSet(const QSet<QString> &set, const QString &separator);
301 
303  SWIFT_MISC_EXPORT QString removeComments(const QString &in, bool removeSlash, bool removeDoubleSlash);
304 
306  SWIFT_MISC_EXPORT bool containsAny(const QString &testString, const QStringList &any, Qt::CaseSensitivity cs);
307 
309  SWIFT_MISC_EXPORT double parseFraction(const QString &fraction,
310  double failDefault = std::numeric_limits<double>::quiet_NaN());
311 
313  SWIFT_MISC_EXPORT QString cleanNumber(const QString &number);
314 
318  template <typename T, typename = void>
319  struct TString;
320 
321  // Stringification traits specializations.
323  template <>
324  struct TString<QString>
325  {
326  static QString toQString(const QString &s) { return s; }
327  };
328  template <>
329  struct TString<QStringView>
330  {
331  static QString toQString(QStringView sv) { return sv.toString(); }
332  };
333  template <>
334  struct TString<QChar>
335  {
336  static QString toQString(QChar c) { return c; }
337  };
338  template <>
339  struct TString<char>
340  {
341  static QString toQString(char c) { return QChar(c); }
342  };
343  template <>
344  struct TString<bool>
345  {
346  static QString toQString(bool n) { return QString::number(n); }
347  };
348  template <>
349  struct TString<int>
350  {
351  static QString toQString(int n) { return QString::number(n); }
352  };
353  template <>
354  struct TString<uint>
355  {
356  static QString toQString(uint n) { return QString::number(n); }
357  };
358  template <>
359  struct TString<long>
360  {
361  static QString toQString(long n) { return QString::number(n); }
362  };
363  template <>
364  struct TString<ulong>
365  {
366  static QString toQString(ulong n) { return QString::number(n); }
367  };
368  template <>
369  struct TString<qlonglong>
370  {
371  static QString toQString(qlonglong n) { return QString::number(n); }
372  };
373  template <>
374  struct TString<qulonglong>
375  {
376  static QString toQString(qulonglong n) { return QString::number(n); }
377  };
378  template <>
379  struct TString<short>
380  {
381  static QString toQString(short n) { return QString::number(n); }
382  };
383  template <>
384  struct TString<ushort>
385  {
386  static QString toQString(ushort n) { return QString::number(n); }
387  };
388  template <>
389  struct TString<float>
390  {
391  static QString toQString(float n) { return QString::number(n); }
392  };
393  template <>
394  struct TString<double>
395  {
396  static QString toQString(double n) { return QString::number(n); }
397  };
398  template <typename T>
399  struct TString<T, std::enable_if_t<std::is_enum_v<T>>>
400  {
401  static QString toQString(T e) { return QString::number(e); }
402  };
403  template <typename T>
404  struct TString<T, std::enable_if_t<std::is_convertible_v<T, QString>>>
405  {
406  static QString toQString(const T &v) { return v; }
407  };
408  template <typename T>
409  struct TString<T, std::enable_if_t<THasToQString<T>::value>>
410  {
411  static QString toQString(const T &v) { return v.toQString(); }
412  };
413  template <typename T>
414  struct TString<QFlags<T>>
415  {
416  static QString toQString(QFlags<T> n) { return TString<typename QFlags<T>::Int>::toQString(n); }
417  };
418  template <typename T>
419  struct TString<std::atomic<T>>
420  {
421  static QString toQString(const std::atomic<T> &n) { return TString<T>::toQString(n); }
422  };
424 } // namespace swift::misc
425 
426 #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:159
SWIFT_MISC_EXPORT qsizetype nthIndexOf(const QString &string, QChar ch, int nth=1, Qt::CaseSensitivity cs=Qt::CaseInsensitive)
nth index of ch
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:153
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:42
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:48
QString removeChars(const QString &s, F predicate)
Return a string with characters removed that match the given predicate.
Definition: stringutils.h:34
bool is09OrSeparator(const QChar &c)
Is 0-9, or ","/";".
Definition: stringutils.h:156
SWIFT_MISC_EXPORT QList< QStringView > splitLinesRefs(const QString &s)
Split a string into multiple lines. Blank lines are skipped.
bool is09OrSeparatorOnlyString(const QString &testString)
String with 0-9/separator only.
Definition: stringutils.h:179
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:173
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 bool caseInsensitiveStringCompare(const QString &c1, const QString &c2)
Case insensitive string compare.
QList< QStringView > splitStringRefs(const QString &s, F predicate)
Split a string into multiple strings, using a predicate function to identify the split points.
Definition: stringutils.h:91
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:70
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:77
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:203
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:185
SWIFT_MISC_EXPORT QStringList splitLines(const QString &s)
Split a string into multiple lines. Blank lines are skipped.
QString char09OnlyString(const QString &string)
String only with 0-9.
Definition: stringutils.h:191
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.
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:119
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:197
bool isDigitsOnlyString(const QString &testString)
String with digits only.
Definition: stringutils.h:167
QString removeLineBreakAndTab(const QString &s)
Remove line breaks and tabs.
Definition: stringutils.h:54
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:64
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:136
Stringification traits class.
Definition: stringutils.h:319
#define SWIFT_MISC_EXPORT
Export a class or function from the library.