Cbeam
Loading...
Searching...
No Matches
string.hpp
Go to the documentation of this file.
1/*
2Copyright (c) 2025 acrion innovations GmbH
3Authors: Stefan Zipproth, s.zipproth@acrion.ch
4
5This file is part of Cbeam, see https://github.com/acrion/cbeam and https://cbeam.org
6
7Cbeam is offered under a commercial and under the AGPL license.
8For commercial licensing, contact us at https://acrion.ch/sales. For AGPL licensing, see below.
9
10AGPL licensing:
11
12Cbeam is free software: you can redistribute it and/or modify
13it under the terms of the GNU Affero General Public License as published by
14the Free Software Foundation, either version 3 of the License, or
15(at your option) any later version.
16
17Cbeam is distributed in the hope that it will be useful,
18but WITHOUT ANY WARRANTY; without even the implied warranty of
19MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20GNU Affero General Public License for more details.
21
22You should have received a copy of the GNU Affero General Public License
23along with Cbeam. If not, see <https://www.gnu.org/licenses/>.
24*/
25
26#pragma once
27
29
30#include <time.h> // for localtime, strftime, time_t
31
32#include <cctype> // std::tolower
33
34#include <algorithm> // for std::transform
35#include <chrono> // for std::chrono::duration_cast, std::chrono::milliseconds, std::chrono::seconds, std::chrono::time_point
36#include <codecvt> // for std::codecvt_utf8_utf16, note https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0618r0.html
37#include <cstdint> // for std::uintptr_t
38#include <iomanip> // for std::operator<<, std::setfill, std::setw
39#include <locale> // for std::wstring_convert, std::locale
40
41#include <sstream> // for std::basic_ostream, std::operator<<, std::stringstream, std::basic_ios::imbue, std::hex, std::showbase, std::istringstream, std::ostream
42#include <stdexcept> // for std::range_error
43#include <string> // for std::basic_string, std::char_traits, std::string, std::wstring, std::allocator
44#include <type_traits> // for std::declval, std::enable_if, std::false_type, std::true_type, std::void_t
45
46namespace cbeam::convert
47{
54 inline std::string indent(int indentation)
55 {
56 return std::string(indentation, '\t');
57 }
58
68 inline std::string to_lower(std::string s)
69 {
70 std::transform(s.begin(),
71 s.end(),
72 s.begin(),
73 [](unsigned char c)
74 { return (char)std::tolower(c); });
75 return s;
76 }
77
97 inline std::string escape_string(const std::string& input, const char escape_character, const std::string& characters_to_escape)
98 {
99 std::ostringstream escaped;
100 for (char ch : input)
101 {
102 if (characters_to_escape.find(ch) != std::string::npos)
103 {
104 escaped << escape_character;
105 }
106 escaped << ch;
107 }
108 return escaped.str();
109 }
110
132 inline std::string unescape_string(const std::string& input, char escape_character, const std::string& characters_to_unescape)
133 {
134 std::string result;
135 result.reserve(input.size());
136
137 auto it = input.begin();
138 while (it != input.end())
139 {
140 char c = *it;
141 if (c == escape_character && it + 1 != input.end() && characters_to_unescape.find(*(it + 1)) != std::string::npos)
142 {
143 result.push_back(*(++it));
144 }
145 else
146 {
147 result.push_back(c);
148 }
149 ++it;
150 }
151
152 return result;
153 }
154
170 template <typename T>
171 T from_string(const std::string& str)
172 {
173 T result;
174 std::istringstream istr(str);
175 istr.imbue(std::locale("C"));
176 istr >> result;
177 return result;
178 }
179
195 template <>
196 inline std::wstring from_string<std::wstring>(const std::string& str)
197 {
198 try
199 {
200 CBEAM_SUPPRESS_WARNINGS_PUSH() // note https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2872r2.pdf
201 std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
203 return converter.from_bytes(str);
204 }
205 catch (const std::range_error&)
206 {
207 // Fallback to element-wise conversion in case of invalid UTF-8 input.
208 // CBEAM_LOG_DEBUG is not used because it relies on these conversion methods.
209 std::wstring converted;
210 for (char c : str)
211 {
212 converted.push_back(static_cast<unsigned char>(c));
213 }
214 return converted;
215 }
216 }
217
258 template <typename T, typename = void>
259 struct has_insertion_operator : std::false_type
260 {
261 };
262
263 template <typename T>
264 struct has_insertion_operator<T, std::void_t<decltype(std::declval<std::ostream&>() << std::declval<T>())>> : std::true_type
265 {
266 };
267
275 template <typename T>
276 inline typename std::enable_if<has_insertion_operator<T>::value, std::string>::type to_string(const T& value)
277 {
278 std::stringstream stream;
279 stream.imbue(std::locale("C"));
280 stream << value;
281 return stream.str();
282 }
283
291 template <typename T>
292 inline std::string to_string(T* const& val)
293 {
294 std::stringstream stream;
295 stream << std::hex << std::showbase << reinterpret_cast<std::uintptr_t>(val);
296 return stream.str();
297 }
298
314 inline std::string to_string(const std::wstring& str)
315 {
316 try
317 {
318 CBEAM_SUPPRESS_WARNINGS_PUSH() // note https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2872r2.pdf
319 std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
320 CBEAM_SUPPRESS_WARNINGS_POP()
321 return converter.to_bytes(str);
322 }
323 catch (const std::range_error&)
324 {
325 // Fallback to element-wise conversion in case of invalid UTF-16 input.
326 // CBEAM_LOG_DEBUG is not used because it relies on these conversion methods.
327 std::string converted;
328 for (wchar_t c : str)
329 {
330 if ((c >> 8) != 0)
331 {
332 converted.push_back(static_cast<char>(c >> 8));
333 }
334 if ((c & 0xff) != 0)
335 {
336 converted.push_back(static_cast<char>(c & 0xff));
337 }
338 }
339 return converted;
340 }
341 }
342
360 template <typename T>
361 inline std::string to_string(std::chrono::time_point<T> time)
362 {
363 char sRep[100];
364 {
365 time_t curr_time = T::to_time_t(time);
366// struct tm buffer;
367// localtime_s(&buffer, &curr_time);
368#pragma warning(suppress : 4996) // The implementation of localtime_s in Microsoft CRT is incompatible with the C standard since it has reversed parameter order and returns errno_t.
369 struct tm* buffer = localtime(&curr_time);
370 strftime(sRep, sizeof(sRep), "%Y-%m-%d %H:%M:%S", buffer);
371 }
372
373 typename T::duration t = time.time_since_epoch();
374 auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(t - std::chrono::duration_cast<std::chrono::seconds>(t));
375
376 std::stringstream result;
377 result << sRep << "." << std::setfill('0') << std::setw(3) << ms.count(); // append milliseconds 000..999
378 return result.str();
379 }
380
390 template <typename T>
391 std::wstring to_wstring(T value)
392 {
393 return from_string<std::wstring>(to_string(value));
394 }
395}
Header file containing macros for compiler compatibility and warning suppression.
#define CBEAM_SUPPRESS_WARNINGS_PUSH()
Definition compiler_compatibility.hpp:64
#define CBEAM_SUPPRESS_WARNINGS_POP()
Definition compiler_compatibility.hpp:86
Contains conversion utilities to transform data between different formats and types....
Definition buffer.hpp:35
std::string unescape_string(const std::string &input, char escape_character, const std::string &characters_to_unescape)
Definition string.hpp:132
std::string to_lower(std::string s)
Converts characters A-Z in the given string to lower case and returns the modified string.
Definition string.hpp:68
std::string escape_string(const std::string &input, const char escape_character, const std::string &characters_to_escape)
Definition string.hpp:97
std::string indent(int indentation)
Returns a string consisting of indentation tab characters.
Definition string.hpp:54
T from_string(const std::string &str)
Converts a given std::string to a specified type.
Definition string.hpp:171
std::wstring from_string< std::wstring >(const std::string &str)
Converts the given std::string to std::wstring using UTF-8 to UTF-16 encoding.
Definition string.hpp:196
The has_insertion_operator trait provides static meta-information about whether a type T has overload...
Definition string.hpp:260