SPH
StringUtils.cpp
Go to the documentation of this file.
2 
4 
5 template <>
6 Optional<std::string> fromString(const std::string& s) {
7  return s;
8 }
9 
10 template <>
11 Optional<int> fromString(const std::string& s) {
12  try {
13  std::size_t idx;
14  const int result = std::stoi(s, &idx);
15  if (idx == s.size()) {
16  return result;
17  } else {
18  return NOTHING;
19  }
20  } catch (const std::exception&) {
21  return NOTHING;
22  }
23 }
24 
25 template <>
26 Optional<Size> fromString(const std::string& s) {
27  try {
28  std::size_t idx;
29  const Size result = std::stoul(s, &idx);
30  if (idx == s.size()) {
31  return result;
32  } else {
33  return NOTHING;
34  }
35  } catch (const std::exception&) {
36  return NOTHING;
37  }
38 }
39 
40 template <>
41 Optional<float> fromString(const std::string& s) {
42  try {
43  std::size_t idx;
44  const float result = std::stof(s, &idx);
45  if (idx == s.size()) {
46  return result;
47  } else {
48  return NOTHING;
49  }
50  } catch (const std::exception&) {
51  return NOTHING;
52  }
53 }
54 
55 template <>
56 Optional<double> fromString(const std::string& s) {
57  try {
58  std::size_t idx;
59  const double result = std::stod(s, &idx);
60  if (idx == s.size()) {
61  return result;
62  } else {
63  return NOTHING;
64  }
65  } catch (const std::exception&) {
66  return NOTHING;
67  }
68 }
69 
70 bool startsWith(const std::string& s, const std::string& start) {
71  return s.size() >= start.size() && s.substr(0, start.size()) == start;
72 }
73 
74 std::string trim(const std::string& s) {
75  Size i1 = 0;
76  for (; i1 < s.size(); ++i1) {
77  if (s[i1] != ' ') {
78  break;
79  }
80  }
81  Size i2 = s.size();
82  for (; i2 > 0; --i2) {
83  if (s[i2 - 1] != ' ') {
84  break;
85  }
86  }
87  std::string trimmed;
88  for (Size i = i1; i < i2; ++i) {
89  trimmed.push_back(s[i]);
90  }
91  return trimmed;
92 }
93 
94 std::string lowercase(const std::string& s) {
95  std::string l = s;
96  for (char& c : l) {
97  if (c >= 'A' && c <= 'Z') {
98  c = c - 'A' + 'a';
99  }
100  }
101  return l;
102 }
103 
104 std::string replaceFirst(const std::string& source, const std::string& old, const std::string& s) {
105  const std::size_t n = source.find(old);
106  if (n == std::string::npos) {
107  return source;
108  }
109  std::string replaced = source;
110  replaced.replace(n, old.size(), s);
111  return replaced;
112 }
113 
114 std::string replaceAll(const std::string& source, const std::string& old, const std::string& s) {
115  std::string current = source;
116  std::size_t pos = 0;
117  while (true) {
118  const std::size_t n = current.find(old, pos);
119  if (n == std::string::npos) {
120  return current;
121  }
122  current.replace(n, old.size(), s);
123  pos = n + s.size();
124  }
125 }
126 
127 std::string setLineBreak(const std::string& s, const Size lineWidth) {
128  const std::string emptyChars = " \t\r";
129  const std::string canBreakChars = ".,;\n" + emptyChars;
130  std::string result = s;
131  std::size_t lastLineBreak = 0;
132  std::size_t lastSpaceNum = 0;
133  bool commaFound = false;
134 
135  for (std::size_t n = 0; n < result.size();) {
136  // find the next possible break
137  std::size_t pos = result.find_first_of(canBreakChars, n);
138  if (pos == std::string::npos) {
139  pos = result.size();
140  }
141  if (result[pos] == '\n') {
142  // there already is a line break, reset the counter and continue
143  n = pos + 1;
144  lastLineBreak = n;
145  commaFound = false;
146  lastSpaceNum = 0;
147  continue;
148  }
149  if (pos - lastLineBreak <= lineWidth) {
150  // no need to break
151  n = pos + 1;
152  continue;
153  } else {
154  // remove all empty chars before the break
155  --n;
156  while (n < result.size() && emptyChars.find(result[n]) != std::string::npos) {
157  result.erase(n, 1);
158  --n;
159  }
160  ++n;
161  // insert a line break here
162  result.insert(n++, "\n");
163 
164  if (commaFound && lastSpaceNum > 0) {
165  result.insert(n, std::string(lastSpaceNum, ' '));
166  n += lastSpaceNum;
167  }
168  // indent if there is a pattern ' - %s: ' on the previous line
169  const std::size_t comma = result.find("- ", lastLineBreak);
170  if (comma < n) {
171  const std::size_t colon = result.find(": ", comma);
172  if (colon < n) {
173  std::size_t spaceNum = colon + 2 - lastLineBreak;
174  result.insert(n, std::string(spaceNum, ' '));
175  n += spaceNum;
176  lastSpaceNum = spaceNum;
177  commaFound = true;
178  }
179  }
180 
181  lastLineBreak = n;
182 
183  // remove all following empty chars
184  while (n < result.size() && emptyChars.find(result[n]) != std::string::npos) {
185  result.erase(n, 1);
186  }
187  }
188  }
189  return result;
190 }
191 
192 Array<std::string> split(const std::string& s, const char delimiter) {
193  Array<std::string> parts;
194  std::size_t n1 = -1; // yes, -1, unsigned int overflow is well defined
195  std::size_t n2;
196  while ((n2 = s.find(delimiter, n1 + 1)) != std::string::npos) {
197  parts.push(s.substr(n1 + 1, n2 - n1 - 1));
198  n1 = n2;
199  }
200  // add the last part
201  parts.push(s.substr(n1 + 1));
202  return parts;
203 }
204 
205 Pair<std::string> splitByFirst(const std::string& s, const char delimiter) {
206  const std::size_t n = s.find(delimiter);
207  if (n == std::string::npos) {
208  return {};
209  } else {
210  Pair<std::string> parts;
211  parts[0] = s.substr(0, n);
212  parts[1] = s.substr(n + 1);
213  return parts;
214  }
215 }
216 
217 static Array<std::string> capitalizationBlacklist{ "and", "or", "of", "for", "to", "et", "al" };
218 
219 static bool shouldCapitalize(const std::string& s) {
220  for (const std::string& b : capitalizationBlacklist) {
221  if (s.size() < b.size()) {
222  continue;
223  }
224  if (s.substr(0, b.size()) == b && (s.size() == b.size() || s[b.size()] == ' ')) {
225  return false;
226  }
227  }
228  return true;
229 }
230 
231 std::string capitalize(const std::string& input) {
232  std::string result = input;
233  for (Size i = 0; i < result.size(); ++i) {
234  if (i == 0 || (result[i - 1] == ' ' && shouldCapitalize(result.substr(i)))) {
235  result[i] = toupper(result[i]);
236  }
237  }
238  return result;
239 }
240 
242  for (const std::string& name : initial) {
243  names.insert(name);
244  }
245 }
246 
247 std::string UniqueNameManager::getName(const std::string& name) {
248  std::string tested = name;
249 
250  for (Size postfix = 1; postfix < 999; ++postfix) {
251  if (names.find(tested) == names.end()) {
252  names.insert(tested);
253  return tested;
254  } else {
256  tested = name + " (" + std::to_string(postfix) + ")";
257  }
258  }
259  return name;
260 }
261 
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
uint32_t Size
Integral type used to index arrays (by default).
Definition: Globals.h:16
#define NAMESPACE_SPH_END
Definition: Object.h:12
const NothingType NOTHING
Definition: Optional.h:16
std::string replaceFirst(const std::string &source, const std::string &old, const std::string &s)
Replaces first occurence of string with a new string.
std::string setLineBreak(const std::string &s, const Size lineWidth)
Inserts to string so that no line is longer than given limit.
std::string trim(const std::string &s)
Removes all leading and trailing spaces from a string.
Definition: StringUtils.cpp:74
NAMESPACE_SPH_BEGIN Optional< std::string > fromString(const std::string &s)
Converts a string to given type.
Definition: StringUtils.cpp:6
std::string replaceAll(const std::string &source, const std::string &old, const std::string &s)
Replaces all occurences of string with a new string.
Array< std::string > split(const std::string &s, const char delimiter)
Splits a string into an array of string using given delimiter.
Pair< std::string > splitByFirst(const std::string &s, const char delimiter)
Splits a string into two parts, using first occurence of given delimiter.
std::string capitalize(const std::string &input)
Capitalizes first letters of all words in the string, except for words like 'and',...
bool startsWith(const std::string &s, const std::string &start)
Checks if the given string starts with given substring.
Definition: StringUtils.cpp:70
std::string lowercase(const std::string &s)
Converts all uppercase characters to their lowercase variants. Other characters are unchanged.
Definition: StringUtils.cpp:94
Object providing safe access to continuous memory of data.
Definition: ArrayView.h:17
INLINE void push(U &&u)
Adds new element to the end of the array, resizing the array if necessary.
Definition: Array.h:306
Array with fixed number of allocated elements.
Definition: StaticArray.h:19
UniqueNameManager()=default
std::string getName(const std::string &name)