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(const std::string &input, T &output)
196{
197 std::size_t nValues = 0;
198 std::stringstream ss(input);
199 ss >> std::ws;
200 while (ss.good()) {
201 ++nValues;
202 if (nValues > 1) {
203 std::cout << " more than one element in string " << input << std::endl;
204 std::cout << " assigning first element " << std::endl;
205 return;
206 }
207
208 ss >> output;
209 ss >> std::ws;
210 }
211
212 if (nValues == 0) {
213 std::cout << " no useful information in string " << input << std::endl;
214 std::cout << " casting zero " << std::endl;
215
216 output = T{};
217 }
218}
219
232template <class T>
233void convertString(const std::string &input, std::vector<T> &output)
234{
235 output.clear();
236
237 std::stringstream ss(input);
238 ss >> std::ws;
239 while (ss.good()) {
240 T x;
241 ss >> x;
242 ss >> std::ws;
243 output.push_back(std::move(x));
244 }
245
246 if (output.empty()) {
247 std::cout << " no useful information in string " << input << std::endl;
248 std::cout << " returning empty vector " << std::endl;
249 };
250}
251
266template <class T, size_t n>
267void convertString(const std::string &input, std::array<T,n> &output)
268{
269 std::size_t nValues = 0;
270 std::stringstream ss(input);
271 ss >> std::ws;
272 while (ss.good()) {
273 ++nValues;
274 if (nValues > n) {
275 std::cout << " more than " << n << " elements in string " << input << std::endl;
276 std::cout << " assigning first " << n << " elements " << std::endl;
277 return;
278 }
279
280 ss >> output[nValues - 1];
281 ss >> std::ws;
282 }
283
284 if (nValues < n) {
285 std::cout << " not enough useful information in string " << input << std::endl;
286 std::cout << " casting zero into missing elements " << std::endl;
287
288 for(size_t i=nValues; i<n; i++) {
289 output[i] = T{};
290 }
291 }
292}
293
294}
295
296}
297
298}
299
300#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)
void convertString(const std::string &input, T &output)
std::string lfill(int nchars, const std::string &s, char c)
std::string & rtrim(std::string &s)
Namespace for string utility functions.
Namespace for generic utility functions.