Fcitx
stringutils.h
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2015-2017 CSSlayer <wengxt@gmail.com>
3  *
4  * SPDX-License-Identifier: LGPL-2.1-or-later
5  *
6  */
7 #ifndef _FCITX_UTILS_STRINGUTILS_H_
8 #define _FCITX_UTILS_STRINGUTILS_H_
9 
10 /// \addtogroup FcitxUtils
11 /// \{
12 /// \file
13 /// \brief String handle utilities.
14 
15 #include <cstddef>
16 #include <initializer_list>
17 #include <iterator>
18 #include <optional>
19 #include <string>
20 #include <string_view>
21 #include <utility>
22 #include <vector>
23 #include <fcitx-utils/fcitxutils_export.h>
24 #include <fcitx-utils/stringutils_details.h> // IWYU pragma: export
25 
26 namespace fcitx::stringutils {
27 
28 /// \brief Check if a string starts with a prefix.
29 FCITXUTILS_EXPORT bool startsWith(std::string_view str,
30  std::string_view prefix);
31 
32 /// \brief Check if a string starts with a prefix char.
33 inline bool startsWith(std::string_view str, char prefix) {
34  return !str.empty() && str.front() == prefix;
35 }
36 
37 /// \brief Check if a string ends with a suffix.
38 FCITXUTILS_EXPORT bool endsWith(std::string_view str, std::string_view suffix);
39 
40 /// \brief Check if a string ends with a suffix char.
41 inline bool endsWith(std::string_view str, char suffix) {
42  return !str.empty() && str.back() == suffix;
43 }
44 
45 /// \brief Check if a string is a concatenation of two other strings
46 inline bool isConcatOf(std::string_view str, std::string_view sub1,
47  std::string_view sub2) {
48  return str.size() == sub1.size() + sub2.size() && startsWith(str, sub1) &&
49  endsWith(str, sub2);
50 }
51 
52 /// \brief Trim the whitespace by returning start end end of first and list non
53 /// whitespace character position.
54 ///
55 /// Will return a pair of equal value all characters are whitespace.
56 FCITXUTILS_EXPORT std::pair<std::string::size_type, std::string::size_type>
57 trimInplace(std::string_view str);
58 
59 /// \brief Trim the white space in string view
60 /// \see trimInplace
61 /// \since 5.0.16
62 FCITXUTILS_EXPORT std::string_view trimView(std::string_view);
63 
64 /// \brief Trim the white space in str.
65 /// \see trimInplace
66 FCITXUTILS_EXPORT std::string trim(std::string_view str);
67 
68 /// \brief Split the string by delim.
69 FCITXUTILS_EXPORT std::vector<std::string> split(std::string_view str,
70  std::string_view delim);
71 
72 enum class SplitBehavior { KeepEmpty, SkipEmpty };
73 
74 /// \brief Split the string by delim.
75 FCITXUTILS_EXPORT std::vector<std::string>
76 split(std::string_view str, std::string_view delim, SplitBehavior behavior);
77 
78 /// \brief Replace all substring appearance of before with after.
79 FCITXUTILS_EXPORT std::string replaceAll(std::string str,
80  const std::string &before,
81  const std::string &after);
82 
83 /// \brief Search string needle of size ol in string haystack.
84 /// \param from the number of bytes from end.
85 /// \return point to data or null.
86 FCITXUTILS_EXPORT const char *backwardSearch(const char *haystack, size_t l,
87  const char *needle, size_t ol,
88  size_t from);
89 
90 /// \brief The non-const version of backwardSearch
91 /// \see backwardSearch()
92 FCITXUTILS_EXPORT char *backwardSearch(char *haystack, size_t l,
93  const char *needle, size_t ol,
94  size_t from);
95 
96 /// \brief Fast backward substring search.
97 /// \return back from end.
98 ///
99 /// Example:
100 /// stringutils::backwardSearch("abcabc", "bc", 1) == 1
101 /// stringutils::backwardSearch("abcabc", "bc", 1) == 1
102 /// stringutils::backwardSearch("abcabc", "bc", 4) == 4
103 FCITXUTILS_EXPORT size_t backwardSearch(const std::string &haystack,
104  const std::string &needle, size_t from);
105 
106 /// \brief Join a range of string with delim.
107 template <typename Iter, typename T>
108 inline std::string join(Iter start, Iter end, T &&delim) {
109  std::string result;
110  if (start != end) {
111  result += (*start);
112  start++;
113  }
114  for (; start != end; start++) {
115  result += (delim);
116  result += (*start);
117  }
118  return result;
119 }
120 
121 /// \brief Join a set of string with delim.
122 template <typename C, typename T>
123 inline std::string join(C &&container, T &&delim) {
124  using std::begin;
125  using std::end;
126  return join(begin(container), end(container), delim);
127 }
128 
129 /// \brief Join the strings with delim.
130 template <typename C, typename T>
131 inline std::string join(std::initializer_list<C> &&container, T &&delim) {
132  using std::begin;
133  using std::end;
134  return join(begin(container), end(container), delim);
135 }
136 
137 template <typename... Args>
138 std::string concat(const Args &...args) {
139  using namespace ::fcitx::stringutils::details;
140  return concatPieces({static_cast<const UniversalPiece &>(
142  .toPair()...});
143 }
144 
145 template <typename FirstArg, typename... Args>
146 std::string joinPath(const FirstArg &firstArg, const Args &...args) {
147  using namespace ::fcitx::stringutils::details;
148  return concatPathPieces(
149  {static_cast<const UniversalPiece &>(
150  UniversalPieceHelper<FirstArg>::forward(firstArg))
151  .toPathPair(false),
152  static_cast<const UniversalPiece &>(
153  UniversalPieceHelper<Args>::forward(args))
154  .toPathPair()...});
155 }
156 
157 constexpr bool literalEqual(char const *a, char const *b) {
158  return *a == *b && (*a == '\0' || literalEqual(a + 1, b + 1));
159 }
160 
161 /// \brief Inplace unescape a string contains slash, new line, optionally quote.
162 FCITXUTILS_EXPORT bool unescape(std::string &str, bool unescapeQuote);
163 
164 /**
165  * \brief unescape a string, that is potentially quoted.
166  *
167  * \param str input string.
168  * \return unescaped string
169  * \see escapeForValue
170  * \since 5.0.16
171  */
172 FCITXUTILS_EXPORT std::optional<std::string>
173 unescapeForValue(std::string_view str);
174 
175 /**
176  * \brief escape a string, add quote if needed.
177  *
178  * \param str input string.
179  * \return escaped string
180  * \see unescapeForValue
181  * \since 5.0.16
182  */
183 FCITXUTILS_EXPORT std::string escapeForValue(std::string_view str);
184 
185 /**
186  * Return a substring of input str if str starts with given prefix.
187  *
188  * \param str input string
189  * \param prefix to check
190  * \see startsWith
191  * \since 5.1.12
192  */
193 FCITXUTILS_EXPORT bool consumePrefix(std::string_view &str,
194  std::string_view prefix);
195 
196 } // namespace fcitx::stringutils
197 
198 #endif // _FCITX_UTILS_STRINGUTILS_H_
std::optional< std::string > unescapeForValue(std::string_view str)
unescape a string, that is potentially quoted.
bool unescape(std::string &str, bool unescapeQuote)
Inplace unescape a string contains slash, new line, optionally quote.
bool consumePrefix(std::string_view &str, std::string_view prefix)
Return a substring of input str if str starts with given prefix.
std::pair< std::string::size_type, std::string::size_type > trimInplace(std::string_view str)
Trim the whitespace by returning start end end of first and list non whitespace character position...
bool endsWith(std::string_view str, char suffix)
Check if a string ends with a suffix char.
Definition: stringutils.h:41
std::vector< std::string > split(std::string_view str, std::string_view delim, SplitBehavior behavior)
Split the string by delim.
std::string_view trimView(std::string_view str)
Trim the white space in string view.
std::string join(std::initializer_list< C > &&container, T &&delim)
Join the strings with delim.
Definition: stringutils.h:131
const char * backwardSearch(const char *haystack, size_t l, const char *needle, size_t ol, size_t from)
Search string needle of size ol in string haystack.
std::string replaceAll(std::string str, const std::string &before, const std::string &after)
Replace all substring appearance of before with after.
std::string escapeForValue(std::string_view str)
escape a string, add quote if needed.
std::string trim(std::string_view str)
Trim the white space in str.
bool isConcatOf(std::string_view str, std::string_view sub1, std::string_view sub2)
Check if a string is a concatenation of two other strings.
Definition: stringutils.h:46
bool startsWith(std::string_view str, char prefix)
Check if a string starts with a prefix char.
Definition: stringutils.h:33