yoda is hosted by Hepforge, IPPP Durham
YODA - Yet more Objects for Data Analysis 2.0.0
StringUtils.h
Go to the documentation of this file.
1// -*- C++ -*-
2//
3// This file is part of YODA -- Yet more Objects for Data Analysis
4// Copyright (C) 2008-2023 The YODA collaboration (see AUTHORS for details)
5//
6#ifndef YODA_STRINGUTILS_H
7#define YODA_STRINGUTILS_H
8
9#include <vector>
10#include <sstream>
11#include <algorithm>
12#include <stdexcept>
13
14namespace YODA {
15 namespace Utils {
16
17
19 struct bad_lexical_cast : public std::runtime_error {
20 bad_lexical_cast(const std::string& what) : std::runtime_error(what) {}
21 };
22
24 template<typename T, typename U>
25 T lexical_cast(const U& in) {
26 try {
27 std::stringstream ss;
28 ss << in;
29 T out;
30 ss >> out;
31 return out;
32 } catch (const std::exception& e) {
33 throw bad_lexical_cast(e.what());
34 }
35 }
36
37
39 template <typename T>
40 inline std::string toStr(const T& x) {
41 // std::ostringstream ss; ss << x;
42 // return ss.str();
43 return lexical_cast<std::string>(x);
44 }
45
46
48 inline std::string toLower(const std::string& s) {
49 std::string out = s;
50 std::transform(out.begin(), out.end(), out.begin(), (int(*)(int)) tolower);
51 return out;
52 }
53
54
56 inline std::string toUpper(const std::string& s) {
57 std::string out = s;
58 std::transform(out.begin(), out.end(), out.begin(), (int(*)(int)) toupper);
59 return out;
60 }
61
62
64 inline std::string encodeForXML(const std::string& in) {
65 std::string out = in;
66 typedef std::pair<std::string, std::string> CharsToEntities;
67 std::vector<CharsToEntities> cs2es;
68 cs2es.push_back(std::make_pair("&", "&amp;"));
69 cs2es.push_back(std::make_pair("<", "&lt;"));
70 cs2es.push_back(std::make_pair(">", "&gt;"));
71 for (std::vector<CharsToEntities>::const_iterator c2e = cs2es.begin(); c2e != cs2es.end(); ++c2e) {
72 std::string::size_type pos = -1;
73 while ( ( pos = out.find(c2e->first, pos + 1) ) != std::string::npos ) {
74 out.replace(pos, 1, c2e->second);
75 }
76 }
77 return out;
78 }
79
80
82 inline bool contains(const std::string& s, const std::string& sub) {
83 return s.find(sub) != std::string::npos;
84 }
85
87 inline bool startswith(const std::string& s, const std::string& sub) {
88 return s.find(sub) == 0;
89 }
90
92 inline bool endswith(const std::string& s, const std::string& sub) {
93 const size_t pos = s.find(sub);
94 return pos != std::string::npos && pos == (s.size()-sub.size());
95 }
96
97
99 inline std::string& iltrim(std::string& s) {
100 s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char c){ return !std::isspace(c); }));
101
102 return s;
103 }
104
106 inline std::string& irtrim(std::string& s) {
107 s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char c){ return !std::isspace(c); }).base(), s.end());
108 return s;
109 }
110
112 inline std::string& itrim(std::string& s) {
113 return iltrim(irtrim(s));
114 }
115
116
118 inline std::string ltrim(const std::string& s) { //< @note Could just pass by value, but const& sends a symbolic message
119 std::string s2 = s;
120 return iltrim(s2);
121 }
122
124 inline std::string rtrim(const std::string& s) { //< @note Could just pass by value, but const& sends a symbolic message
125 std::string s2 = s;
126 return irtrim(s2);
127 }
128
130 inline std::string trim(const std::string& s) { //< @note Could just pass by value, but const& sends a symbolic message
131 std::string s2 = s;
132 return itrim(s2);
133 }
134
136 inline std::vector<std::string> split(const std::string& s, const std::string& sep) {
137 std::vector<std::string> dirs;
138 std::string tmp = s;
139 while (true) {
140 const size_t delim_pos = tmp.find(sep);
141 if (delim_pos == std::string::npos) break;
142 const std::string dir = tmp.substr(0, delim_pos);
143 if (dir.length()) dirs.push_back(dir); // Don't insert "empties"
144 tmp.replace(0, delim_pos+1, "");
145 }
146 if (tmp.length()) dirs.push_back(tmp); // Don't forget the trailing component!
147 return dirs;
148 }
149
153 inline std::vector<std::string> pathsplit(const std::string& path) {
154 return split(path, ":");
155 }
156
157 }
158
159
160 // Annoyingly, this doesn't work without significant SFINAE etc., due to clashes with existing string & stream operators
161 // /// string + any appending operator for convenience in the YODA namespace
162 // template <typename T>
163 // std::string& operator + (std::string& s, const T& x) {
164 // s += Utils::toStr(x);
165 // return s;
166 // }
167 // template <typename T>
168 // std::string operator + (const T& x, std::string& s) {
169 // return Utils::toStr(x) + s;
170 // }
171 // template <typename T>
172 // std::string operator + (const char* s, const T& x) {
173 // return s + Utils::toStr(x);
174 // }
175 // template <typename T>
176 // std::string operator + (const T& x, const char* s) {
177 // return Utils::toStr(x) + x;
178 // }
179
180
181}
182
183#endif
Anonymous namespace to limit visibility.