Loading...
Searching...
No Matches
stringUtils.tpp
1/*---------------------------------------------------------------------------*\
2 *
3 * bitpit
4 *
5 * Copyright (C) 2015-2021 OPTIMAD engineering Srl
6 *
7 * -------------------------------------------------------------------------
8 * License
9 * This file is part of bitpit.
10 *
11 * bitpit is free software: you can redistribute it and/or modify it
12 * under the terms of the GNU Lesser General Public License v3 (LGPL)
13 * as published by the Free Software Foundation.
14 *
15 * bitpit is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18 * License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with bitpit. If not, see <http://www.gnu.org/licenses/>.
22 *
23\*---------------------------------------------------------------------------*/
24
25#ifndef __BITPIT_STRING_UTILS_TPP__
26#define __BITPIT_STRING_UTILS_TPP__
27
28namespace bitpit {
29
30namespace utils {
31
32namespace string {
33
46inline std::string & ltrim(std::string &s)
47{
48 // The argument of the lambda function passed to the erase method is an
49 // unsigned char, that's because, like all other functions from <cctype>,
50 // the behavior of std::isspace is undefined if the argument's value is
51 // neither representable as unsigned char nor equal to EOF. To use these
52 // functions safely, they should not be directly used with standard
53 // algorithms when the iterator's value type is char or signed char.
54 // Instead, the value should be converted to unsigned char first (see
55 // https://en.cppreference.com/w/cpp/string/byte/isspace#Notes).
56 s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char c){ return !std::isspace(c); }));
57
58 return s;
59}
60
72inline std::string &rtrim(std::string &s)
73{
74 // The argument of the lambda function passed to the erase method is an
75 // unsigned char, that's because, like all other functions from <cctype>,
76 // the behavior of std::isspace is undefined if the argument's value is
77 // neither representable as unsigned char nor equal to EOF. To use these
78 // functions safely, they should not be directly used with standard
79 // algorithms when the iterator's value type is char or signed char.
80 // Instead, the value should be converted to unsigned char first (see
81 // https://en.cppreference.com/w/cpp/string/byte/isspace#Notes).
82 s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char c){ return !std::isspace(c); }).base(), s.end());
83
84 return s;
85}
86
98inline std::string &trim(std::string &s)
99{
100 return ltrim(rtrim(s));
101}
102
115inline std::string lfill(int nchars, const std::string &s, char c)
116{
117 std::stringstream ss;
118 ss << std::string(nchars - s.length(), c) << s;
119
120 return ss.str();
121}
122
135inline std::string rfill(int nchars, const std::string &s, char c)
136{
137 std::stringstream ss;
138 ss << s << std::string(nchars - s.length(), c);
139
140 return ss.str();
141}
142
158inline std::string zeroPadNumber(int nchars, int num)
159{
160 std::ostringstream ss;
161 ss << std::setw(nchars) << std::setfill('0') << num;
162
163 return ss.str();
164}
165
175inline bool keywordInString(const std::string &line, const std::string &key)
176{
177 return (line.find(key) != std::string::npos);
178}
179
194template <class T>
195void convertString(std::string input, T &output)
196{
197 trim(input);
198 std::stringstream ss(input);
199
200 T x;
201 std::vector<T> tmp;
202 while (ss.good()) {
203 ss >> x;
204 tmp.push_back(x);
205 }
206
207 if (tmp.size() == 0) {
208 std::cout << " no useful information in string " << input << std::endl;
209 std::cout << " casting zero " << std::endl;
210
211 x = static_cast<T> (0);
212 } else if (tmp.size() == 1) {
213 x = tmp[0];
214 } else if(tmp.size() > 1) {
215 std::cout << " more than one element in string " << input << std::endl;
216 std::cout << " assigning first element " << std::endl;
217
218 x = tmp[0];
219 }
220
221 output = x;
222}
223
236template <class T>
237void convertString(std::string input, std::vector<T> &output)
238{
239 output.clear();
240
241 trim(input);
242 std::stringstream ss(input);
243
244 T x;
245 std::vector<T> tmp;
246 while (ss.good()) {
247 ss >> x;
248 tmp.push_back(x);
249 }
250
251 if (tmp.size() == 0) {
252 std::cout << " no useful information in string " << input << std::endl;
253 std::cout << " returning void vector " << std::endl;
254 };
255
256 output = tmp;
257}
258
273template <class T, size_t n>
274void convertString(std::string input, std::array<T,n> &output)
275{
276 T x;
277 std::vector<T> tmp;
278
279 tmp.clear();
280
281 trim(input);
282 std::stringstream ss(input);
283
284 while (ss.good()) {
285 ss >> x;
286 tmp.push_back(x);
287 }
288
289 if (tmp.size() < n) {
290 std::cout << " not enough useful information in string " << input << std::endl;
291 std::cout << " casting zero into missing elements " << std::endl;
292
293 x = static_cast<T>(0);
294 output.fill(x);
295
296 for(size_t i=0; i<tmp.size(); i++) {
297 output[i] = tmp[i];
298 }
299 } else if (tmp.size() == n) {
300 for(size_t i = 0; i < n; i++) {
301 output[i] = tmp[i];
302 }
303 } else if (tmp.size() > n) {
304 std::cout << " more than " << n << " elements in string " << input << std::endl;
305 std::cout << " assigning first element " << n << " elements " << std::endl;
306
307 for(size_t i = 0; i < n; i++) {
308 output[i] = tmp[i];
309 }
310 }
311}
312
313}
314
315}
316
317}
318
319#endif
std::string & trim(std::string &s)
std::string rfill(int nchars, const std::string &s, char c)
std::string zeroPadNumber(int nchars, int num)
std::string & ltrim(std::string &s)
bool keywordInString(const std::string &line, const std::string &key)
std::string lfill(int nchars, const std::string &s, char c)
void convertString(std::string input, T &output)
std::string & rtrim(std::string &s)
--- layout: doxygen_footer ---