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_DEPRECATED_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_DEPRECATED_EXPORT bool endsWith(std::string_view str,
39  std::string_view suffix);
40 
41 /// \brief Check if a string ends with a suffix char.
42 inline bool endsWith(std::string_view str, char suffix) {
43  return !str.empty() && str.back() == suffix;
44 }
45 
46 /// \brief Check if a string is a concatenation of two other strings
47 inline bool isConcatOf(std::string_view str, std::string_view sub1,
48  std::string_view sub2) {
49  return str.size() == sub1.size() + sub2.size() && str.starts_with(sub1) &&
50  str.ends_with(sub2);
51 }
52 
53 /// \brief Trim the whitespace by returning start end end of first and list non
54 /// whitespace character position.
55 ///
56 /// Will return a pair of equal value all characters are whitespace.
57 FCITXUTILS_EXPORT std::pair<std::string::size_type, std::string::size_type>
58 trimInplace(std::string_view str);
59 
60 /// \brief Trim the white space in string view
61 /// \see trimInplace
62 /// \since 5.0.16
63 FCITXUTILS_EXPORT std::string_view trimView(std::string_view);
64 
65 /// \brief Trim the white space in str.
66 /// \see trimInplace
67 FCITXUTILS_EXPORT std::string trim(std::string_view str);
68 
69 /// \brief Split the string by delim.
70 FCITXUTILS_EXPORT std::vector<std::string> split(std::string_view str,
71  std::string_view delim);
72 
73 enum class SplitBehavior { KeepEmpty, SkipEmpty };
74 
75 /// \brief Split the string by delim.
76 FCITXUTILS_EXPORT std::vector<std::string>
77 split(std::string_view str, std::string_view delim, SplitBehavior behavior);
78 
79 /// \brief Replace all substring appearance of before with after.
80 FCITXUTILS_EXPORT std::string replaceAll(std::string str,
81  const std::string &before,
82  const std::string &after);
83 
84 /// \brief Search string needle of size ol in string haystack.
85 /// \param from the number of bytes from end.
86 /// \return point to data or null.
87 FCITXUTILS_EXPORT const char *backwardSearch(const char *haystack, size_t l,
88  const char *needle, size_t ol,
89  size_t from);
90 
91 /// \brief The non-const version of backwardSearch
92 /// \see backwardSearch()
93 FCITXUTILS_EXPORT char *backwardSearch(char *haystack, size_t l,
94  const char *needle, size_t ol,
95  size_t from);
96 
97 /// \brief Fast backward substring search.
98 /// \return back from end.
99 ///
100 /// Example:
101 /// stringutils::backwardSearch("abcabc", "bc", 1) == 1
102 /// stringutils::backwardSearch("abcabc", "bc", 1) == 1
103 /// stringutils::backwardSearch("abcabc", "bc", 4) == 4
104 FCITXUTILS_EXPORT size_t backwardSearch(const std::string &haystack,
105  const std::string &needle, size_t from);
106 
107 /// \brief Join a range of string with delim.
108 template <typename Iter, typename T>
109 inline std::string join(Iter start, Iter end, T &&delim) {
110  std::string result;
111  if (start != end) {
112  result += (*start);
113  start++;
114  }
115  for (; start != end; start++) {
116  result += (delim);
117  result += (*start);
118  }
119  return result;
120 }
121 
122 /// \brief Join a set of string with delim.
123 template <typename C, typename T>
124 inline std::string join(C &&container, T &&delim) {
125  using std::begin;
126  using std::end;
127  return join(begin(container), end(container), delim);
128 }
129 
130 /// \brief Join the strings with delim.
131 template <typename C, typename T>
132 inline std::string join(std::initializer_list<C> &&container, T &&delim) {
133  using std::begin;
134  using std::end;
135  return join(begin(container), end(container), delim);
136 }
137 
138 template <typename... Args>
139 std::string concat(const Args &...args) {
140  using namespace ::fcitx::stringutils::details;
141  return concatPieces({static_cast<const UniversalPiece &>(
143  .toPair()...});
144 }
145 
146 template <typename FirstArg, typename... Args>
147 std::string joinPath(const FirstArg &firstArg, const Args &...args) {
148  using namespace ::fcitx::stringutils::details;
149  return concatPathPieces(
150  {static_cast<const UniversalPiece &>(
151  UniversalPieceHelper<FirstArg>::forward(firstArg))
152  .toPathPair(false),
153  static_cast<const UniversalPiece &>(
154  UniversalPieceHelper<Args>::forward(args))
155  .toPathPair()...});
156 }
157 
158 constexpr bool literalEqual(char const *a, char const *b) {
159  return *a == *b && (*a == '\0' || literalEqual(a + 1, b + 1));
160 }
161 
162 /// \brief Inplace unescape a string contains slash, new line, optionally quote.
163 FCITXUTILS_EXPORT bool unescape(std::string &str, bool unescapeQuote);
164 
165 /**
166  * \brief unescape a string, that is potentially quoted.
167  *
168  * \param str input string.
169  * \return unescaped string
170  * \see escapeForValue
171  * \since 5.0.16
172  */
173 FCITXUTILS_EXPORT std::optional<std::string>
174 unescapeForValue(std::string_view str);
175 
176 /**
177  * \brief escape a string, add quote if needed.
178  *
179  * \param str input string.
180  * \return escaped string
181  * \see unescapeForValue
182  * \since 5.0.16
183  */
184 FCITXUTILS_EXPORT std::string escapeForValue(std::string_view str);
185 
186 /**
187  * Return a substring of input str if str starts with given prefix.
188  *
189  * \param str input string
190  * \param prefix to check
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:42
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:132
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:47
bool startsWith(std::string_view str, char prefix)
Check if a string starts with a prefix char.
Definition: stringutils.h:33