Volume Cartographer 2.27.0
String.hpp
Go to the documentation of this file.
1#pragma once
2
5#include <algorithm>
6#include <iomanip>
7#include <locale>
8#include <sstream>
9#include <string>
10#include <string_view>
11#include <tuple>
12#include <type_traits>
13
14namespace volcart
15{
16
18static inline void to_upper(std::string& s)
19{
20 const auto& f = std::use_facet<std::ctype<char>>(std::locale());
21 f.toupper(s.data(), s.data() + s.size());
22}
23
25static inline std::string to_upper(std::string&& s)
26{
27 to_upper(s);
28 return s;
29}
30
32static inline std::string to_upper_copy(std::string s)
33{
34 to_upper(s);
35 return s;
36}
37
39static inline void to_lower(std::string& s)
40{
41 const auto& f = std::use_facet<std::ctype<char>>(std::locale());
42 f.tolower(s.data(), s.data() + s.size());
43}
44
46static inline std::string to_lower(std::string&& s)
47{
48 to_lower(s);
49 return s;
50}
51
53static inline std::string to_lower_copy(std::string s)
54{
55 to_lower(s);
56 return s;
57}
58
60static inline auto to_bool(const std::string& s) -> bool
61{
62 bool b{false};
63 if (s.size() == 1) {
64 std::stringstream(s) >> b;
65 } else if (s.size() > 1) {
66 std::stringstream(s) >> std::boolalpha >> b;
67 }
68 return b;
69}
70
76static inline void trim_left(std::string& s)
77{
78 const auto& loc = std::locale();
79 s.erase(s.begin(), std::find_if_not(s.begin(), s.end(), [&loc](auto ch) {
80 return std::isspace(ch, loc);
81 }));
82}
83
89static inline std::string trim_left(std::string&& s)
90{
91 trim_left(s);
92 return s;
93}
94
100static inline std::string trim_left_copy(std::string s)
101{
102 trim_left(s);
103 return s;
104}
105
111static inline void trim_right(std::string& s)
112{
113 const auto& loc = std::locale();
114 s.erase(
115 std::find_if_not(
116 s.rbegin(), s.rend(),
117 [&loc](auto ch) { return std::isspace(ch, loc); })
118 .base(),
119 s.end());
120}
121
127static inline std::string trim_right(std::string&& s)
128{
129 trim_right(s);
130 return s;
131}
132
138static inline std::string trim_right_copy(std::string s)
139{
140 trim_right(s);
141 return s;
142}
143
149static inline void trim(std::string& s)
150{
151 trim_left(s);
152 trim_right(s);
153}
154
160static inline std::string trim(std::string&& s)
161{
162 trim(s);
163 return s;
164}
165
171static inline std::string trim_copy(std::string s)
172{
173 trim(s);
174 return s;
175}
176
178template <typename... Ds>
179static inline std::vector<std::string> split(
180 const std::string& s, const Ds&... ds)
181{
182 // Build delimiters list
183 std::vector<char> delims;
184 if (sizeof...(ds)) {
185 delims = {ds...};
186 } else {
187 delims.emplace_back(' ');
188 }
189
190 // Get a list of all delimiter start positions
191 std::vector<std::string::size_type> delimPos;
192 for (const auto& delim : delims) {
193 auto b = s.find(delim, 0);
194 while (b != std::string::npos) {
195 delimPos.emplace_back(b);
196 b = s.find(delim, b + 1);
197 }
198 }
199
200 // Sort the delimiter start positions
201 std::sort(delimPos.begin(), delimPos.end());
202
203 // Split string
204 std::vector<std::string> tokens;
205 std::string::size_type begin{0};
206 for (std::size_t it = 0; it < delimPos.size(); it++) {
207 auto end = delimPos[it];
208 auto t = s.substr(begin, end - begin);
209 if (not t.empty()) {
210 tokens.emplace_back(t);
211 }
212 begin = end + 1;
213 }
214 auto t = s.substr(begin);
215 if (not t.empty()) {
216 tokens.emplace_back(t);
217 }
218
219 return tokens;
220}
221
223static inline auto partition(std::string_view s, std::string_view sep)
224 -> std::tuple<std::string, std::string, std::string>
225{
226 // Find the starting position
227 const auto startPos = s.find(sep);
228
229 // Didn't find the delimiter
230 if (startPos == std::string::npos) {
231 return {std::string(s), "", ""};
232 }
233
234 // Split into parts
235 auto pre = std::string(s.substr(0, startPos));
236 auto mid = std::string(s.substr(startPos, sep.size()));
237 auto post = std::string(s.substr(startPos + sep.size()));
238
239 // Return the parts
240 return {pre, mid, post};
241}
242
244template <
245 typename Integer,
246 std::enable_if_t<std::is_integral_v<Integer>, bool> = true>
247auto to_padded_string(Integer val, const int padding, const char fill = '0')
248 -> std::string
249{
250 std::stringstream stream;
251 stream << std::setw(padding) << std::setfill(fill) << val;
252 return stream.str();
253}
254
255} // namespace volcart
Volume Cartographer library
static void to_lower(std::string &s)
Convert string characters to lower case (in place)
Definition: String.hpp:39
static auto to_bool(const std::string &s) -> bool
Convert a string to a bool.
Definition: String.hpp:60
static void trim_left(std::string &s)
Left trim (in place)
Definition: String.hpp:76
static void to_upper(std::string &s)
Convert string characters to upper case (in place)
Definition: String.hpp:18
static std::string to_lower_copy(std::string s)
Convert string characters to lower case (copy)
Definition: String.hpp:53
static std::string to_upper_copy(std::string s)
Convert string characters to upper case (copy)
Definition: String.hpp:32
static void trim_right(std::string &s)
Right trim (in place)
Definition: String.hpp:111
static std::string trim_left_copy(std::string s)
Left trim (copy)
Definition: String.hpp:100
auto to_padded_string(Integer val, const int padding, const char fill='0') -> std::string
Convert an Integer to a padded string.
Definition: String.hpp:247
static std::string trim_right_copy(std::string s)
Right trim (copy)
Definition: String.hpp:138
static auto partition(std::string_view s, std::string_view sep) -> std::tuple< std::string, std::string, std::string >
Partition a string by a separator substring.
Definition: String.hpp:223
static std::string trim_copy(std::string s)
Right trim (copy)
Definition: String.hpp:171
static void trim(std::string &s)
Trim from both ends (in place)
Definition: String.hpp:149
static std::vector< std::string > split(const std::string &s, const Ds &... ds)
Split a string by a delimiter.
Definition: String.hpp:179