OpenMS
Loading...
Searching...
No Matches
StringUtils.h
Go to the documentation of this file.
1// Copyright (c) 2002-present, OpenMS Inc. -- EKU Tuebingen, ETH Zurich, and FU Berlin
2// SPDX-License-Identifier: BSD-3-Clause
3//
4// --------------------------------------------------------------------------
5// $Maintainer: Timo Sachsenberg, Chris Bielow $
6// $Authors: Marc Sturm, Stephan Aiche, Chris Bielow $
7// --------------------------------------------------------------------------
8
9#pragma once
10
11// NOTE: Do NOT include String.h here — String.h includes us. Use std::string directly.
12
15#include <OpenMS/OpenMSConfig.h>
16
17#include <charconv>
18
19#include <algorithm>
20#include <cmath>
21#include <cstdio>
22#include <cstring>
23#include <limits>
24#include <ranges>
25#include <sstream>
26#include <string>
27#include <string_view>
28#include <vector>
29
30namespace OpenMS
31{
32 class DataValue; // forward — DataValue.h includes String.h, so we cannot include it here
33 class ParamValue; // forward — same reason
34
35 // -------------------------------------------------------------------------
36 // QuotingMethod — formerly String::QuotingMethod
37 // -------------------------------------------------------------------------
39 enum class QuotingMethod { NONE, ESCAPE, DOUBLE };
40
41
42 // =========================================================================
43 // StringUtilsHelper — parsing helpers (definitions in StringUtils.cpp)
44 // =========================================================================
45 class OPENMS_DLLAPI StringUtilsHelper
46 {
47 public:
49 static Int32 toInt32(const std::string& s);
51 static Int64 toInt64(const std::string& s);
53 static float toFloat(const std::string& s);
55 static double toDouble(const std::string& s);
56
59 static bool extractDouble(const char*& begin, const char* end, double& target);
60
63 static bool extractInt(const char*& begin, const char* end, int& target);
64 };
65
66
67 // =========================================================================
68 // StringUtils — unified string utility namespace
69 // =========================================================================
70 namespace StringUtils
71 {
72
73 // -----------------------------------------------------------------------
74 // Append numeric value to a string (non-inline; defined in StringUtils.cpp)
75 // -----------------------------------------------------------------------
76
77 OPENMS_DLLAPI void appendToStr(int i, std::string& target);
78 OPENMS_DLLAPI void appendToStr(unsigned int i, std::string& target);
79 OPENMS_DLLAPI void appendToStr(short int i, std::string& target);
80 OPENMS_DLLAPI void appendToStr(short unsigned int i, std::string& target);
81 OPENMS_DLLAPI void appendToStr(long int i, std::string& target);
82 OPENMS_DLLAPI void appendToStr(long unsigned int i, std::string& target);
83 OPENMS_DLLAPI void appendToStr(long long unsigned int i, std::string& target);
84 OPENMS_DLLAPI void appendToStr(long long signed int i, std::string& target);
85
86 OPENMS_DLLAPI void appendToStr(float f, std::string& target);
87 OPENMS_DLLAPI void appendToStrLowP(float f, std::string& target);
88 OPENMS_DLLAPI void appendToStr(double d, std::string& target);
89 OPENMS_DLLAPI void appendToStrLowP(double d, std::string& target);
90 OPENMS_DLLAPI void appendToStr(long double ld, std::string& target);
91 OPENMS_DLLAPI void appendToStrLowP(long double ld, std::string& target);
92
94 OPENMS_DLLAPI void appendToStr(const DataValue& d, bool full_precision, std::string& target);
95
96
97 // -----------------------------------------------------------------------
98 // toStr() — convert a value to a new std::string
99 // -----------------------------------------------------------------------
100
101 inline std::string toStr(int i)
102 { std::string s; appendToStr(i, s); return s; }
103 inline std::string toStr(unsigned int i)
104 { std::string s; appendToStr(i, s); return s; }
105 inline std::string toStr(short int i)
106 { std::string s; appendToStr(i, s); return s; }
107 inline std::string toStr(short unsigned int i)
108 { std::string s; appendToStr(i, s); return s; }
109 inline std::string toStr(long int i)
110 { std::string s; appendToStr(i, s); return s; }
111 inline std::string toStr(long unsigned int i)
112 { std::string s; appendToStr(i, s); return s; }
113 inline std::string toStr(long long unsigned int i)
114 { std::string s; appendToStr(i, s); return s; }
115 inline std::string toStr(long long signed int i)
116 { std::string s; appendToStr(i, s); return s; }
117
119 OPENMS_DLLAPI std::string toStr(float f, bool full_precision = true);
121 OPENMS_DLLAPI std::string toStr(double d, bool full_precision = true);
123 OPENMS_DLLAPI std::string toStr(long double ld, bool full_precision = true);
124
125 inline std::string toStr(char c)
126 { return std::string(1, c); }
127
128 inline std::string toStr(const std::string& s)
129 { return s; }
130
131 inline std::string toStr(const char* s)
132 { return std::string(s); }
133
155 OPENMS_DLLAPI std::string toStr(const DataValue& d, bool full_precision = true);
156
158 OPENMS_DLLAPI std::string toStr(const ParamValue& p, bool full_precision = true);
159
161 inline std::string toStr(std::string_view sv) { return std::string(sv); }
162
163
164 // -----------------------------------------------------------------------
165 // Parse string → numeric
166 // -----------------------------------------------------------------------
167
168 inline Int32 toInt32(const std::string& s) { return StringUtilsHelper::toInt32(s); }
169 inline Int64 toInt64(const std::string& s) { return StringUtilsHelper::toInt64(s); }
170 inline float toFloat(const std::string& s) { return StringUtilsHelper::toFloat(s); }
171 inline double toDouble(const std::string& s) { return StringUtilsHelper::toDouble(s); }
172
173 inline bool extractDouble(const char*& begin, const char* end, double& target)
174 { return StringUtilsHelper::extractDouble(begin, end, target); }
175
176 inline bool extractInt(const char*& begin, const char* end, int& target)
177 { return StringUtilsHelper::extractInt(begin, end, target); }
178
180 inline bool extractDouble(std::string::const_iterator& begin, const std::string::const_iterator& end, double& target)
181 {
182 const char* const p_start = &(*begin);
183 const char* p = p_start;
184 const char* e = &(*end);
185 bool ok = StringUtilsHelper::extractDouble(p, e, target);
186 begin += (p - p_start); // advance iterator by number of consumed chars (MSVC iterators cannot be built from a raw pointer)
187 return ok;
188 }
189
190 inline bool extractDouble(std::string::iterator& begin, const std::string::iterator& end, double& target)
191 {
192 const char* const p_start = &(*begin);
193 const char* p = p_start;
194 const char* e = &(*end);
195 bool ok = StringUtilsHelper::extractDouble(p, e, target);
196 begin += (p - p_start);
197 return ok;
198 }
199
200 inline bool extractInt(std::string::const_iterator& begin, const std::string::const_iterator& end, int& target)
201 {
202 const char* const p_start = &(*begin);
203 const char* p = p_start;
204 const char* e = &(*end);
205 bool ok = StringUtilsHelper::extractInt(p, e, target);
206 begin += (p - p_start);
207 return ok;
208 }
209
210 inline bool extractInt(std::string::iterator& begin, const std::string::iterator& end, int& target)
211 {
212 const char* const p_start = &(*begin);
213 const char* p = p_start;
214 const char* e = &(*end);
215 bool ok = StringUtilsHelper::extractInt(p, e, target);
216 begin += (p - p_start);
217 return ok;
218 }
219
220
221 // -----------------------------------------------------------------------
222 // Whitespace scanning (SIMD-accelerated; non-inline)
223 // -----------------------------------------------------------------------
224
226 OPENMS_DLLAPI const char* skipWhitespace(const char* p, const char* p_end);
227
229 inline int skipWhitespace(const std::string_view& data)
230 {
231 auto pos = skipWhitespace(data.data(), data.data() + data.size());
232 return static_cast<int>(pos - data.data());
233 }
234
236 OPENMS_DLLAPI const char* skipNonWhitespace(const char* p, const char* p_end);
237
239 inline int skipNonWhitespace(const std::string_view& data)
240 {
241 auto pos = skipNonWhitespace(data.data(), data.data() + data.size());
242 return static_cast<int>(pos - data.data());
243 }
244
245
246 // -----------------------------------------------------------------------
247 // Static factory methods
248 // -----------------------------------------------------------------------
249
251 [[maybe_unused]] OPENMS_DLLAPI std::string number(double d, UInt n);
252
254 [[maybe_unused]] OPENMS_DLLAPI std::string numberLength(double d, UInt n);
255
257 OPENMS_DLLAPI std::string random(UInt length);
258
259
260 // -----------------------------------------------------------------------
261 // Predicates
262 // -----------------------------------------------------------------------
263
264 inline bool hasPrefix(const std::string& s, const std::string& prefix)
265 {
266 if (prefix.size() > s.size()) return false;
267 if (prefix.empty()) return true;
268 return s.compare(0, prefix.size(), prefix) == 0;
269 }
270 inline bool hasPrefix(const std::string& s, char c)
271 { return !s.empty() && s.front() == c; }
272
273 inline bool hasSuffix(const std::string& s, const std::string& sfx)
274 {
275 if (sfx.size() > s.size()) return false;
276 if (sfx.empty()) return true;
277 return s.compare(s.size() - sfx.size(), sfx.size(), sfx) == 0;
278 }
279 inline bool hasSuffix(const std::string& s, char c)
280 { return !s.empty() && s.back() == c; }
281
282 inline bool hasSubstring(const std::string& s, const std::string& sub)
283 {
284 return s.find(sub) != std::string::npos;
285 }
286 inline bool hasSubstring(const std::string& s, char c)
287 { return s.find(c) != std::string::npos; }
288
289 inline bool has(const std::string& s, Byte byte)
290 {
291 return s.find(static_cast<char>(byte)) != std::string::npos;
292 }
293 inline bool has(const std::string& s, char c)
294 { return s.find(c) != std::string::npos; }
295
296
297 // -----------------------------------------------------------------------
298 // Accessors (return new string)
299 // -----------------------------------------------------------------------
300
301 inline std::string prefix(const std::string& s, size_t length)
302 {
303 if (length > s.size())
304 throw Exception::IndexOverflow(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, length, s.size());
305 return s.substr(0, length);
306 }
307
308 inline std::string suffix(const std::string& s, size_t length)
309 {
310 if (length > s.size())
311 throw Exception::IndexOverflow(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, length, s.size());
312 return s.substr(s.size() - length, length);
313 }
314
315 inline std::string prefix(const std::string& s, Int length)
316 {
317 if (length < 0)
318 throw Exception::IndexUnderflow(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, length, 0);
319 return prefix(s, static_cast<size_t>(length));
320 }
321
322 inline std::string suffix(const std::string& s, Int length)
323 {
324 if (length < 0)
325 throw Exception::IndexUnderflow(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, length, 0);
326 return suffix(s, static_cast<size_t>(length));
327 }
328
334 inline std::string prefix(const std::string& s, char delim)
335 {
336 return s.substr(0, s.find(delim)); // find() returns npos if absent -> substr(0, npos) -> whole string
337 }
338
344 inline std::string suffix(const std::string& s, char delim)
345 {
346 size_t pos = s.rfind(delim);
347 return pos == std::string::npos ? s : s.substr(pos + 1);
348 }
349
351 inline std::string substr(const std::string& s, size_t pos = 0, size_t n = std::string::npos)
352 {
353 size_t begin = std::min(pos, s.size());
354 return s.substr(begin, n);
355 }
357 inline std::string substr(std::string_view s, size_t pos = 0, size_t n = std::string::npos)
358 {
359 size_t begin = std::min(pos, s.size());
360 return std::string(s.substr(begin, n));
361 }
362
364 inline bool hasPrefix(std::string_view s, const std::string& prefix)
365 { return s.size() >= prefix.size() && s.substr(0, prefix.size()) == prefix; }
366 inline bool hasSuffix(std::string_view s, const std::string& sfx)
367 { return s.size() >= sfx.size() && s.substr(s.size() - sfx.size()) == sfx; }
368 inline bool hasSubstring(std::string_view s, const std::string& sub)
369 { return s.find(sub) != std::string_view::npos; }
370
372 inline std::string chop(const std::string& s, Size n)
373 {
374 size_t end = (n < s.size()) ? s.size() - n : 0;
375 return std::string(s.begin(), s.begin() + end);
376 }
377
378
379 // -----------------------------------------------------------------------
380 // In-place mutators (all return std::string& for chaining via free fns)
381 // -----------------------------------------------------------------------
382
383 inline std::string& trim(std::string& s)
384 {
385 auto begin = s.begin();
386 while (begin != s.end() && (*begin == ' ' || *begin == '\t' || *begin == '\n' || *begin == '\r'))
387 ++begin;
388 if (begin == s.end()) { s.clear(); return s; }
389 auto end = s.end() - 1;
390 while (end != begin && (*end == ' ' || *end == '\n' || *end == '\t' || *end == '\r'))
391 --end;
392 ++end;
393 if (begin != s.begin() || end != s.end())
394 s.assign(begin, end);
395 return s;
396 }
397
399 inline std::string trimmed(std::string s) { return std::move(trim(s)); }
400
401 inline std::string& toUpper(std::string& s)
402 {
403 std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c){ return std::toupper(c); });
404 return s;
405 }
406
407 inline std::string& toLower(std::string& s)
408 {
409 std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c){ return std::tolower(c); });
410 return s;
411 }
413 inline std::string toUppered(std::string s) { return std::move(toUpper(s)); }
415 inline std::string toLowered(std::string s) { return std::move(toLower(s)); }
416
417 inline std::string& firstToUpper(std::string& s)
418 {
419 if (!s.empty()) s[0] = static_cast<char>(std::toupper(static_cast<unsigned char>(s[0])));
420 return s;
421 }
422
423 inline std::string& reverse(std::string& s)
424 {
425 std::reverse(s.begin(), s.end());
426 return s;
427 }
428
429 inline std::string& simplify(std::string& s)
430 {
431 std::string result;
432 result.reserve(s.size());
433 bool last_ws = false;
434 for (char c : s)
435 {
436 if (c == ' ' || c == '\n' || c == '\t' || c == '\r')
437 {
438 if (!last_ws) result += ' ';
439 last_ws = true;
440 }
441 else
442 {
443 result += c;
444 last_ws = false;
445 }
446 }
447 s.swap(result);
448 return s;
449 }
450
451 inline std::string& fillLeft(std::string& s, char c, UInt size)
452 {
453 if (s.size() < size)
454 s.insert(s.begin(), size - s.size(), c);
455 return s;
456 }
457
458 inline std::string& fillRight(std::string& s, char c, UInt size)
459 {
460 if (s.size() < size)
461 s.append(size - s.size(), c);
462 return s;
463 }
464
465 inline std::string& substitute(std::string& s, char from, char to)
466 {
467 std::replace(s.begin(), s.end(), from, to);
468 return s;
469 }
470
472 inline std::string& substitute(std::string& s, const std::string& from, const std::string& to)
473 {
474 if (from.empty()) return s;
475 std::string result;
476 result.reserve(s.size());
477 size_t start = 0;
478 size_t pos;
479 while ((pos = s.find(from, start)) != std::string::npos)
480 {
481 result.append(s, start, pos - start);
482 result += to;
483 start = pos + from.size();
484 }
485 result.append(s, start, std::string::npos);
486 s.swap(result);
487 return s;
488 }
490 inline std::string substituted(std::string s, char from, char to) { return std::move(substitute(s, from, to)); }
491 inline std::string substituted(std::string s, const std::string& from, const std::string& to) { return std::move(substitute(s, from, to)); }
492
493 inline std::string& remove(std::string& s, char what)
494 {
495 s.erase(std::remove(s.begin(), s.end(), what), s.end());
496 return s;
497 }
498
499 // rvalue-ref overloads so chained/temporary strings can be padded in place
500 inline std::string fillLeft(std::string&& s, char c, UInt size) { fillLeft(s, c, size); return std::move(s); }
501 inline std::string fillRight(std::string&& s, char c, UInt size) { fillRight(s, c, size); return std::move(s); }
502
503 inline std::string& ensureLastChar(std::string& s, char end)
504 {
505 if (s.empty() || s.back() != end) s.push_back(end);
506 return s;
507 }
509 inline std::string ensureLastChar(std::string&& s, char end) { ensureLastChar(s, end); return std::move(s); }
510
511 inline std::string& removeWhitespaces(std::string& s)
512 {
513 // skip unmodified prefix
514 int start = skipNonWhitespace(std::string_view(s.data(), s.size()));
515 auto it = s.cbegin() + start;
516 auto dest = s.begin() + start;
517 auto it_end = s.cend();
518 bool has_spaces = false;
519 while (it != it_end)
520 {
521 const char c = *it;
522 if (c == ' ' || c == '\t' || c == '\n' || c == '\r')
523 {
524 ++it;
525 has_spaces = true;
526 continue;
527 }
528 if (has_spaces) *dest = *it;
529 ++dest;
530 ++it;
531 }
532 if (has_spaces) s.resize(static_cast<size_t>(dest - s.begin()));
533 return s;
534 }
535
536 inline bool isQuoted(const std::string& s, char q)
537 {
538 return s.size() >= 2 && s.front() == q && s.back() == q;
539 }
540
541 inline std::string& quote(std::string& s, char q = '"', QuotingMethod method = QuotingMethod::ESCAPE)
542 {
543 if (method == QuotingMethod::ESCAPE)
544 {
545 substitute(s, std::string("\\"), std::string("\\\\"));
546 substitute(s, std::string(1, q), std::string("\\") + q);
547 }
548 else if (method == QuotingMethod::DOUBLE)
549 {
550 substitute(s, std::string(1, q), std::string(2, q));
551 }
552 s.insert(s.begin(), q);
553 s.push_back(q);
554 return s;
555 }
556
557 inline std::string& unquote(std::string& s, char q = '"', QuotingMethod method = QuotingMethod::ESCAPE)
558 {
559 if (!isQuoted(s, q))
560 throw Exception::ConversionError(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
561 "'" + s + "' does not have the expected format of a quoted string");
562 s.erase(s.begin());
563 s.pop_back();
564 if (method == QuotingMethod::ESCAPE)
565 {
566 substitute(s, std::string("\\") + q, std::string(1, q));
567 substitute(s, std::string("\\\\"), std::string("\\"));
568 }
569 else if (method == QuotingMethod::DOUBLE)
570 {
571 substitute(s, std::string(2, q), std::string(1, q));
572 }
573 return s;
574 }
575
576
577 // -----------------------------------------------------------------------
578 // Split / Join
579 // -----------------------------------------------------------------------
580
584 inline bool split(const std::string& s, char splitter,
585 std::vector<std::string>& substrings,
586 bool quote_protect = false)
587 {
588 substrings.clear();
589 if (s.empty()) return false;
590
591 size_t nsplits = static_cast<size_t>(std::count(s.begin(), s.end(), splitter));
592
593 if (!quote_protect && nsplits == 0)
594 {
595 substrings.push_back(s);
596 return false;
597 }
598
599 substrings.reserve(nsplits + 1);
600
601 if (quote_protect)
602 {
603 int quote_count = 0;
604 auto begin = s.cbegin();
605 auto end = s.cbegin();
606 for (; end != s.cend(); ++end)
607 {
608 if (*end == '"') ++quote_count;
609 if ((quote_count % 2 == 0) && (*end == splitter))
610 {
611 std::string block(begin, end);
612 trim(block);
613 bool has_start = block.size() >= 1 && block.front() == '"';
614 bool has_end = block.size() >= 1 && block.back() == '"';
615 if (block.size() >= 2 && (has_start ^ has_end))
616 throw Exception::ConversionError(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
617 "Could not dequote string '" + block + "' due to wrongly placed '\"'.");
618 if (block.size() >= 2 && has_start && has_end)
619 block = block.substr(1, block.size() - 2);
620 substrings.push_back(std::move(block));
621 begin = end + 1;
622 }
623 }
624 if (substrings.empty()) { substrings.push_back(s); return false; }
625 std::string block(begin, end);
626 trim(block);
627 bool has_start = block.size() >= 1 && block.front() == '"';
628 bool has_end = block.size() >= 1 && block.back() == '"';
629 if (block.size() >= 2 && (has_start ^ has_end))
630 throw Exception::ConversionError(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
631 "Could not dequote string '" + block + "' due to wrongly placed '\"'.");
632 if (block.size() >= 2 && has_start && has_end)
633 block = block.substr(1, block.size() - 2);
634 substrings.push_back(std::move(block));
635 }
636 else
637 {
638 auto begin = s.cbegin();
639 for (auto it = s.cbegin(); it != s.cend(); ++it)
640 {
641 if (*it == splitter)
642 {
643 substrings.emplace_back(begin, it);
644 begin = it + 1;
645 }
646 }
647 substrings.emplace_back(begin, s.cend());
648 }
649 return true;
650 }
651
654 inline bool split(const std::string& s, const std::string& splitter,
655 std::vector<std::string>& substrings)
656 {
657 substrings.clear();
658 if (s.empty()) return false;
659 if (splitter.empty())
660 {
661 substrings.resize(s.size());
662 for (size_t i = 0; i < s.size(); ++i) substrings[i] = std::string(1, s[i]);
663 return true;
664 }
665 size_t len = splitter.size();
666 size_t start = 0;
667 size_t pos = s.find(splitter);
668 while (pos != std::string::npos)
669 {
670 substrings.push_back(s.substr(start, pos - start));
671 start = pos + len;
672 pos = s.find(splitter, start);
673 }
674 substrings.push_back(s.substr(start));
675 return substrings.size() > 1;
676 }
677
680 inline bool split_quoted(const std::string& s, const std::string& splitter,
681 std::vector<std::string>& substrings,
682 char q = '"', QuotingMethod method = QuotingMethod::ESCAPE)
683 {
684 substrings.clear();
685 if (s.empty() || splitter.empty()) return false;
686
687 bool in_quote = false;
688 char targets[2] = {q, splitter[0]};
689 std::string rest = splitter.substr(1);
690 size_t start = 0;
691
692 for (size_t i = 0; i < s.size(); ++i)
693 {
694 if (in_quote)
695 {
696 bool embedded = false;
697 if (method == QuotingMethod::ESCAPE)
698 {
699 for (; i < s.size(); ++i)
700 {
701 if (s[i] == '\\') embedded = !embedded;
702 else if (s[i] == q && !embedded) break;
703 else embedded = false;
704 }
705 }
706 else
707 {
708 for (; i < s.size(); ++i)
709 {
710 if (s[i] == q)
711 {
712 if (method == QuotingMethod::NONE) break;
713 if (i + 1 < s.size() && s[i + 1] == q) embedded = !embedded;
714 else if (!embedded) break;
715 else embedded = false;
716 }
717 }
718 }
719 in_quote = false;
720 }
721 else
722 {
723 i = s.find_first_of(targets, i, 2);
724 if (i == std::string::npos) break;
725 if (s[i] == q) { in_quote = true; }
726 else if (s.compare(i + 1, rest.size(), rest) == 0)
727 {
728 substrings.push_back(s.substr(start, i - start));
729 start = i + splitter.size();
730 i = start - 1;
731 }
732 }
733 }
734 if (in_quote)
735 throw Exception::ConversionError(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
736 "unbalanced quotation marks in string '" + s + "'");
737 substrings.push_back(s.substr(start));
738 return substrings.size() > 1;
739 }
740
742 template <class StringIterator>
743 inline void concatenate(std::string& target,
744 StringIterator first, StringIterator last,
745 const std::string& glue = "")
746 {
747 if (first == last) { target.clear(); return; }
748 target = *first;
749 for (auto it = ++first; it != last; ++it)
750 {
751 target += glue;
752 target += *it;
753 }
754 }
755
757 template <class StringIterator>
758 inline std::string concatenate(StringIterator first, StringIterator last,
759 const std::string& glue = "")
760 {
761 std::string result;
762 concatenate(result, first, last, glue);
763 return result;
764 }
765
777 template <std::ranges::range Container>
778 inline std::string concatenate(const Container& container, const std::string& glue = "")
779 {
780 return concatenate(container.begin(), container.end(), glue);
781 }
782
783 } // namespace StringUtils
784
785
786 // =========================================================================
787 // Legacy StringConversions namespace — thin forwarding layer
788 // Prefer StringUtils:: for new code.
789 // =========================================================================
790 namespace StringConversions
791 {
792 inline void append(int i, std::string& target)
793 { StringUtils::appendToStr(i, target); }
794 inline void append(unsigned int i, std::string& target)
795 { StringUtils::appendToStr(i, target); }
796 inline void append(short int i, std::string& target)
797 { StringUtils::appendToStr(i, target); }
798 inline void append(short unsigned int i, std::string& target)
799 { StringUtils::appendToStr(i, target); }
800 inline void append(long int i, std::string& target)
801 { StringUtils::appendToStr(i, target); }
802 inline void append(long unsigned int i, std::string& target)
803 { StringUtils::appendToStr(i, target); }
804 inline void append(long long unsigned int i, std::string& target)
805 { StringUtils::appendToStr(i, target); }
806 inline void append(long long signed int i, std::string& target)
807 { StringUtils::appendToStr(i, target); }
808 inline void append(float f, std::string& target)
809 { StringUtils::appendToStr(f, target); }
810 inline void append(double d, std::string& target)
811 { StringUtils::appendToStr(d, target); }
812 inline void append(long double ld, std::string& target)
813 { StringUtils::appendToStr(ld, target); }
814 inline void appendLowP(float f, std::string& target)
815 { StringUtils::appendToStrLowP(f, target); }
816 inline void appendLowP(double d, std::string& target)
817 { StringUtils::appendToStrLowP(d, target); }
818 inline void appendLowP(long double ld, std::string& target)
819 { StringUtils::appendToStrLowP(ld, target); }
820 inline void append(const DataValue& d, bool full_precision, std::string& target)
821 { StringUtils::appendToStr(d, full_precision, target); }
822
823 template <typename T>
824 inline std::string toString(const T& i)
825 { return StringUtils::toStr(i); }
826 inline std::string toString(float f, bool fp = true)
827 { return StringUtils::toStr(f, fp); }
828 inline std::string toString(double d, bool fp = true)
829 { return StringUtils::toStr(d, fp); }
830 inline std::string toString(long double ld, bool fp = true)
831 { return StringUtils::toStr(ld, fp); }
832 inline std::string toString(const DataValue& d, bool fp = true)
833 { return StringUtils::toStr(d, fp); }
834 inline std::string toString()
835 { return {}; }
836
837 inline std::string toStringLowP(float f) { return StringUtils::toStr(f, false); }
838 inline std::string toStringLowP(double d) { return StringUtils::toStr(d, false); }
839 inline std::string toStringLowP(long double ld) { return StringUtils::toStr(ld, false); }
840
841 } // namespace StringConversions
842
843} // namespace OpenMS
844
845
846// =============================================================================
847// Global operator+ / operator+= for std::string + numeric types
848//
849// Placing these in the global namespace ensures they are found by unqualified
850// lookup regardless of which OpenMS namespace the caller is in.
851// =============================================================================
852
853inline std::string& operator+=(std::string& s, int i)
854{ OpenMS::StringUtils::appendToStr(i, s); return s; }
855inline std::string& operator+=(std::string& s, unsigned int i)
856{ OpenMS::StringUtils::appendToStr(i, s); return s; }
857inline std::string& operator+=(std::string& s, short int i)
858{ OpenMS::StringUtils::appendToStr(i, s); return s; }
859inline std::string& operator+=(std::string& s, short unsigned int i)
860{ OpenMS::StringUtils::appendToStr(i, s); return s; }
861inline std::string& operator+=(std::string& s, long int i)
862{ OpenMS::StringUtils::appendToStr(i, s); return s; }
863inline std::string& operator+=(std::string& s, long unsigned int i)
864{ OpenMS::StringUtils::appendToStr(i, s); return s; }
865inline std::string& operator+=(std::string& s, long long unsigned int i)
866{ OpenMS::StringUtils::appendToStr(i, s); return s; }
867inline std::string& operator+=(std::string& s, long long signed int i)
868{ OpenMS::StringUtils::appendToStr(i, s); return s; }
869inline std::string& operator+=(std::string& s, float f)
870{ OpenMS::StringUtils::appendToStr(f, s); return s; }
871inline std::string& operator+=(std::string& s, double d)
872{ OpenMS::StringUtils::appendToStr(d, s); return s; }
873inline std::string& operator+=(std::string& s, long double ld)
874{ OpenMS::StringUtils::appendToStr(ld, s); return s; }
875
876// operator+ reuses operator+= on a value-copy, enabling move-from-rvalue
877inline std::string operator+(std::string s, int i)
878{ return std::move(s += i); }
879inline std::string operator+(std::string s, unsigned int i)
880{ return std::move(s += i); }
881inline std::string operator+(std::string s, short int i)
882{ return std::move(s += i); }
883inline std::string operator+(std::string s, short unsigned int i)
884{ return std::move(s += i); }
885inline std::string operator+(std::string s, long int i)
886{ return std::move(s += i); }
887inline std::string operator+(std::string s, long unsigned int i)
888{ return std::move(s += i); }
889inline std::string operator+(std::string s, long long unsigned int i)
890{ return std::move(s += i); }
891inline std::string operator+(std::string s, long long signed int i)
892{ return std::move(s += i); }
893inline std::string operator+(std::string s, float f)
894{ return std::move(s += f); }
895inline std::string operator+(std::string s, double d)
896{ return std::move(s += d); }
897inline std::string operator+(std::string s, long double ld)
898{ return std::move(s += ld); }
std::string & operator+=(std::string &s, int i)
Definition StringUtils.h:853
std::string operator+(std::string s, int i)
Definition StringUtils.h:877
Class to hold strings, numeric values, lists of strings and lists of numeric values.
Definition DataValue.h:33
Invalid conversion exception.
Definition Exception.h:331
Int overflow exception.
Definition Exception.h:211
Int underflow exception.
Definition Exception.h:175
Class to hold strings, numeric values, vectors of strings and vectors of numeric values using the stl...
Definition ParamValue.h:31
Definition StringUtils.h:46
static double toDouble(const std::string &s)
Parse double from string (leading/trailing whitespace allowed)
static Int64 toInt64(const std::string &s)
Parse int64 from string (leading/trailing whitespace allowed)
static bool extractDouble(const char *&begin, const char *end, double &target)
static Int32 toInt32(const std::string &s)
Parse int32 from string (leading/trailing whitespace allowed)
static float toFloat(const std::string &s)
Parse float from string (leading/trailing whitespace allowed)
static bool extractInt(const char *&begin, const char *end, int &target)
int32_t Int32
Signed integer type (32bit)
Definition Types.h:26
int64_t Int64
Signed integer type (64bit)
Definition Types.h:40
uint8_t Byte
Byte type.
Definition Types.h:81
int Int
Signed integer type.
Definition Types.h:72
unsigned int UInt
Unsigned integer type.
Definition Types.h:64
size_t Size
Size type e.g. used as variable which can hold result of size()
Definition Types.h:97
void append(int i, std::string &target)
Definition StringUtils.h:792
void appendLowP(float f, std::string &target)
Definition StringUtils.h:814
std::string toStringLowP(float f)
Definition StringUtils.h:837
std::string toString()
Definition StringUtils.h:834
float toFloat(const std::string &s)
Definition StringUtils.h:170
void appendToStr(int i, std::string &target)
std::string & fillRight(std::string &s, char c, UInt size)
Definition StringUtils.h:458
Int64 toInt64(const std::string &s)
Definition StringUtils.h:169
std::string substituted(std::string s, char from, char to)
substitute on a copy (for chained/rvalue expressions)
Definition StringUtils.h:490
bool hasPrefix(const std::string &s, const std::string &prefix)
Definition StringUtils.h:264
std::string & toUpper(std::string &s)
Definition StringUtils.h:401
std::string chop(const std::string &s, Size n)
Remove n characters from the end; returns empty string if n >= size.
Definition StringUtils.h:372
std::string & trim(std::string &s)
Definition StringUtils.h:383
std::string & unquote(std::string &s, char q='"', QuotingMethod method = QuotingMethod::ESCAPE)
Definition StringUtils.h:557
bool hasSuffix(const std::string &s, const std::string &sfx)
Definition StringUtils.h:273
bool extractDouble(const char *&begin, const char *end, double &target)
Definition StringUtils.h:173
std::string & fillLeft(std::string &s, char c, UInt size)
Definition StringUtils.h:451
std::string & firstToUpper(std::string &s)
Definition StringUtils.h:417
void appendToStrLowP(float f, std::string &target)
std::string suffix(const std::string &s, size_t length)
Definition StringUtils.h:308
std::string substr(const std::string &s, size_t pos=0, size_t n=std::string::npos)
Wrapper around std::string::substr; clamps pos to [0, size].
Definition StringUtils.h:351
bool extractInt(const char *&begin, const char *end, int &target)
Definition StringUtils.h:176
std::string random(UInt length)
Returns a random string of length characters from [0-9a-zA-Z].
bool isQuoted(const std::string &s, char q)
Definition StringUtils.h:536
std::string toLowered(std::string s)
Returns a lower-cased copy of s (for use in chained/rvalue expressions)
Definition StringUtils.h:415
std::string & removeWhitespaces(std::string &s)
Definition StringUtils.h:511
std::string numberLength(double d, UInt n)
Returns a string for d with at most n characters total (scientific notation if needed)
std::string number(double d, UInt n)
Returns a string with exactly n decimal places for d.
std::string prefix(const std::string &s, size_t length)
Definition StringUtils.h:301
const char * skipNonWhitespace(const char *p, const char *p_end)
Returns pointer to first whitespace character in [p, p_end), or p_end.
bool hasSubstring(const std::string &s, const std::string &sub)
Definition StringUtils.h:282
const char * skipWhitespace(const char *p, const char *p_end)
Returns pointer to first non-whitespace character in [p, p_end), or p_end.
std::string trimmed(std::string s)
Returns a trimmed copy of s (for use in chained/rvalue expressions)
Definition StringUtils.h:399
std::string toStr(int i)
Definition StringUtils.h:101
bool split(const std::string &s, char splitter, std::vector< std::string > &substrings, bool quote_protect=false)
Definition StringUtils.h:584
std::string & ensureLastChar(std::string &s, char end)
Definition StringUtils.h:503
void concatenate(std::string &target, StringIterator first, StringIterator last, const std::string &glue="")
Join elements [first, last) with glue between them, storing result in target.
Definition StringUtils.h:743
std::string & simplify(std::string &s)
Definition StringUtils.h:429
std::string & reverse(std::string &s)
Definition StringUtils.h:423
bool has(const std::string &s, Byte byte)
Definition StringUtils.h:289
double toDouble(const std::string &s)
Definition StringUtils.h:171
std::string & toLower(std::string &s)
Definition StringUtils.h:407
std::string & remove(std::string &s, char what)
Definition StringUtils.h:493
std::string toUppered(std::string s)
Returns an upper-cased copy of s (for use in chained/rvalue expressions)
Definition StringUtils.h:413
Int32 toInt32(const std::string &s)
Definition StringUtils.h:168
bool split_quoted(const std::string &s, const std::string &splitter, std::vector< std::string > &substrings, char q='"', QuotingMethod method = QuotingMethod::ESCAPE)
Definition StringUtils.h:680
std::string & quote(std::string &s, char q='"', QuotingMethod method = QuotingMethod::ESCAPE)
Definition StringUtils.h:541
std::string & substitute(std::string &s, char from, char to)
Definition StringUtils.h:465
Main OpenMS namespace.
Definition openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/ISpectrumAccess.h:19
QuotingMethod
How to handle embedded quotes when quoting strings.
Definition StringUtils.h:39