Nix (Dev) 3.5.10
dev - 3.5.10 - 1af9301
Loading...
Searching...
No Matches
stringUtils.hpp
Go to the documentation of this file.
1#ifndef IV_SRC_UTILS_STRINGUTILS_HPP_
2#define IV_SRC_UTILS_STRINGUTILS_HPP_
3
4#include "core/concepts.hpp"
5#include "core/exception.hpp"
6
7#include <algorithm>
8#include <array>
9#include <charconv>
10#include <cstdio>
11#include <cstring>
12#include <iomanip>
13#include <ranges>
14#include <string_view>
15#include <vector>
16
17namespace iv::utils
18{
19
26std::string stringJoin(const std::vector<std::string> &strings, char delim);
27
33uint32_t stringToIpv4(std::string_view ipStr);
34
40std::string ipv4ToString(uint32_t ipAddr);
41
45bool hostWildcardMatch(std::string_view issued_, std::string_view host_);
46
55template<typename CharT1, typename CharT2>
56inline int32_t compareSubstring(const CharT1 *str1, const CharT2 *str2, std::size_t length)
57 requires std::convertible_to<CharT1, char> && std::convertible_to<CharT2, char>
58{
59 if (str1 == nullptr || str2 == nullptr)
60 {
61 throw std::invalid_argument("Null pointer argument");
62 }
63
64 std::basic_string<CharT1> string1(str1);
65 std::basic_string<CharT2> string2(str2);
66
67 if (length > string1.size() || length > string2.size())
68 {
69 throw std::invalid_argument("Length exceeds string size");
70 }
71
72 return string1.compare(0, length, string2, 0, length);
73}
74
80template<typename StringType>
81inline void appendToString(std::string *strResult, StringType str)
82 requires std::convertible_to<StringType, const char *>
83{
84 if (strResult == nullptr)
85 {
86 throw std::invalid_argument("strResult pointer is nullptr");
87 }
88
89 if (str == nullptr)
90 {
91 throw std::invalid_argument("str pointer is nullptr");
92 }
93
94 strResult->append(str);
95}
96
103template<typename StringType, typename DelimiterType>
104std::vector<StringType> splitOn(const StringType &str, const DelimiterType &delim)
105 requires std::is_convertible_v<StringType, std::string> ||
106 (std::is_convertible_v<StringType, std::string_view> &&
107 (std::is_convertible_v<DelimiterType, std::string> ||
108 std::is_same_v<DelimiterType, typename StringType::value_type>) )
109{
110 if constexpr (std::is_same_v<DelimiterType, typename StringType::value_type>)
111 {
112 if (str.empty())
113 {
114 return {str};
115 }
116 }
117 else
118 {
119 if constexpr (std::is_class_v<DelimiterType>)
120 {
121 if (delim.empty())
122 {
123 throw std::invalid_argument("Delimiter cannot be empty");
124 }
125 }
126 else
127 {
128 if (delim == 0)
129 {
130 return {str};
131 }
132 }
133 }
134
135 std::vector<StringType> elems {};
136 size_t pos {0};
137 size_t found;
138
139 while ((found = str.find(delim, pos)) != StringType::npos)
140 {
141 elems.push_back(str.substr(pos, found - pos));
142
143 if constexpr (std::is_class_v<DelimiterType>)
144 {
145 pos = found + delim.size();
146 }
147 else
148 {
149 pos = found + 1;
150 }
151 }
152
153 elems.push_back(str.substr(pos));
154 return elems;
155}
156
157template<typename StringType>
158std::string truncate(const StringType &str, size_t length, bool show_ellipsis = true)
159 requires std::is_convertible_v<StringType, std::string> or std::is_convertible_v<StringType, std::string_view>
160{
161 if (str.size() <= length)
162 {
163 return str;
164 }
165
166 if (show_ellipsis)
167 {
168 return str.substr(0, length - 3) + "...";
169 }
170
171 return str.substr(0, length);
172}
173
174template<iv::concepts::StringRepresentable T1, iv::concepts::StringRepresentable T2>
175bool isEqualStringsCaseInsensitive(const T1 &str1, const T2 &str2)
176{
177 std::string_view sv1;
178 std::string_view sv2;
179
180 if constexpr (std::same_as<T1, char>)
181 {
182 sv1 = std::string_view(&str1, 1);
183 }
184 else if constexpr (std::same_as<T1, std::vector<char>>)
185 {
186 sv1 = std::string_view(str1.data(), str1.size());
187 }
188 else
189 {
190 sv1 = str1;
191 }
192
193 if constexpr (std::same_as<T2, char>)
194 {
195 sv2 = std::string_view(&str2, 1);
196 }
197 else if constexpr (std::same_as<T2, std::vector<char>>)
198 {
199 sv2 = std::string_view(str2.data(), str2.size());
200 }
201 else
202 {
203 sv2 = str2;
204 }
205
206 if (sv1.size() != sv2.size())
207 {
208 return false;
209 }
210
211 return std::equal(sv1.begin(), sv1.end(), sv2.begin(),
212 [](char a, char b) { return std::tolower(a) == std::tolower(b); });
213}
214
215template<iv::concepts::StringRepresentable T1, iv::concepts::StringRepresentable T2>
216bool isEqual(const T1 &str1, const T2 &str2)
217{
218 std::string_view sv1;
219 std::string_view sv2;
220
221 if constexpr (std::same_as<T1, char>)
222 {
223 sv1 = std::string_view(&str1, 1);
224 }
225 else if constexpr (std::same_as<T1, std::vector<char>>)
226 {
227 sv1 = std::string_view(str1.data(), str1.size());
228 }
229 else
230 {
231 sv1 = str1;
232 }
233
234 if constexpr (std::same_as<T2, char>)
235 {
236 sv2 = std::string_view(&str2, 1);
237 }
238 else if constexpr (std::same_as<T2, std::vector<char>>)
239 {
240 sv2 = std::string_view(str2.data(), str2.size());
241 }
242 else
243 {
244 sv2 = str2;
245 }
246
247 return sv1.compare(sv2) == 0;
248}
249
256inline void replaceSubString(std::string &source, const std::string &strToSearch, const std::string &strToReplace)
257{
258 size_t pos = 0;
259 while ((pos = source.find(strToSearch, pos)) != std::string::npos)
260 {
261 source.replace(pos, strToSearch.length(), strToReplace);
262 pos += strToReplace.length();
263 }
264}
265
272inline void replaceChar(std::string *str, char charSearching, char charToChange)
273{
274 std::replace(str->begin(), str->end(), charSearching, charToChange);
275}
276
277inline std::string createWithInitialization(char car, uint64_t numChars)
278{
279 return std::string(numChars, car);
280}
281
282std::optional<size_t> findCharacterInString(std::string_view str, char car);
283
284inline bool isAlphaNumericCharacter(char car)
285{
286 std::locale loc;
287 return std::isalnum(car, loc);
288}
289
290inline bool isAlphabeticCharacter(char car)
291{
292 std::locale loc;
293 return std::isalpha(car, loc);
294}
295
296inline bool isSpecialRealNumberCharacter(char car)
297{
298 static constexpr std::string_view validChars {".-"};
299 return validChars.contains(car);
300}
301
302inline bool isSpecialIntegerCharacter(char car)
303{
304 static constexpr std::string_view validChars {"-"};
305 return validChars.contains(car);
306}
307
308inline bool isDigitCharacter(char car)
309{
310 return std::isdigit(car);
311}
312
313inline bool isValidRealNumberCharacter(char car)
314{
316}
317
318inline bool isValidIntegerCharacter(char car)
319{
321}
322
323inline bool isHexadecimalCharacter(char car)
324{
325 const char *validChars = "0123456789abcdefABCDEF";
326 return std::strchr(validChars, car) != nullptr;
327}
328
329bool isHexadecimalString(const std::string &str);
330
331uint8_t calculateDecimalDigits(std::string_view str);
332
333uint8_t calculateDecimalDigits(double precision);
334
342template<typename T>
343std::string formatNumber(T number, std::optional<uint8_t> precision = std::nullopt)
345{
346 try
347 {
348 std::ostringstream out;
349
351 {
352 uint8_t decimalDigits {precision.value_or(calculateDecimalDigits(number))};
353 if (not precision.has_value() and decimalDigits == 0)
354 {
355 decimalDigits = 1;
356 }
357 out << std::fixed << std::setprecision(decimalDigits) << number;
358 }
359 else
360 {
361 if constexpr (std::is_same_v<T, int8_t> or std::is_same_v<T, uint8_t>)
362 {
363 out << static_cast<int32_t>(number);
364 }
365 else
366 {
367 out << number;
368 }
369 }
370
371 const auto strValue = out.str();
372 return strValue == "-0" ? "0" : strValue;
373 }
374 catch (const std::exception &e)
375 {
376 throw iv::exception::InvalidArgument("Error converting number to string: {}", e.what());
377 }
378}
379
380std::string demangle(const std::type_info &ti);
381
382std::string iso88591_to_utf8(std::string_view input);
383
384}// namespace iv::utils
385
386#endif//IV_SRC_UTILS_STRINGUTILS_HPP_
Definition concepts.hpp:192
Definition concepts.hpp:187
Definition utils.cpp:6
std::string iso88591_to_utf8(const std::string_view input)
Definition stringUtils.cpp:295
std::string demangle(const std::type_info &ti)
Definition stringUtils.cpp:283
void appendToString(std::string *strResult, StringType str)
Concatenate two string.
Definition stringUtils.hpp:81
bool isEqualStringsCaseInsensitive(const T1 &str1, const T2 &str2)
Definition stringUtils.hpp:175
bool isSpecialIntegerCharacter(char car)
Definition stringUtils.hpp:302
std::string createWithInitialization(char car, uint64_t numChars)
Definition stringUtils.hpp:277
std::string truncate(const StringType &str, size_t length, bool show_ellipsis=true)
Definition stringUtils.hpp:158
int32_t compareSubstring(const CharT1 *str1, const CharT2 *str2, std::size_t length)
Simple comparator of x chars where x is the length provided.
Definition stringUtils.hpp:56
bool isAlphaNumericCharacter(char car)
Definition stringUtils.hpp:284
std::vector< StringType > splitOn(const StringType &str, const DelimiterType &delim)
Definition stringUtils.hpp:104
std::optional< size_t > findCharacterInString(std::string_view str, char car)
Definition stringUtils.cpp:241
std::string stringJoin(const std::vector< std::string > &strings, char delim)
Definition stringUtils.cpp:17
bool isValidIntegerCharacter(char car)
Definition stringUtils.hpp:318
bool isValidRealNumberCharacter(char car)
Definition stringUtils.hpp:313
void replaceChar(std::string *str, char charSearching, char charToChange)
Look for a character into a string and when it is found, replace it for another character.
Definition stringUtils.hpp:272
bool isSpecialRealNumberCharacter(char car)
Definition stringUtils.hpp:296
uint32_t stringToIpv4(std::string_view str)
Definition stringUtils.cpp:37
bool isHexadecimalString(const std::string &str)
Definition stringUtils.cpp:313
std::string ipv4ToString(uint32_t ip)
Definition stringUtils.cpp:65
bool isDigitCharacter(char car)
Definition stringUtils.hpp:308
std::string formatNumber(T number, std::optional< uint8_t > precision=std::nullopt)
Check if a string is a number, only applies precision to floating point numbers.
Definition stringUtils.hpp:343
bool isEqual(const T1 &str1, const T2 &str2)
Definition stringUtils.hpp:216
uint8_t calculateDecimalDigits(std::string_view str)
Definition stringUtils.cpp:253
bool isHexadecimalCharacter(char car)
Definition stringUtils.hpp:323
bool hostWildcardMatch(std::string_view issued_, std::string_view host_)
Definition stringUtils.cpp:105
void replaceSubString(std::string &source, const std::string &strToSearch, const std::string &strToReplace)
Look for a substring into a string and when it is found, replace it for another substring.
Definition stringUtils.hpp:256
bool isAlphabeticCharacter(char car)
Definition stringUtils.hpp:290