G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsUtils.h
Go to the documentation of this file.
1 
14 #pragma once
15 
16 #include <sstream>
17 #include <numeric>
18 
19 #include <gsCore/gsExport.h>
20 #include <gsCore/gsDebug.h>
21 #include <gsCore/gsMemory.h>
22 #include <gsParallel/gsOpenMP.h>
23 
24 #ifdef __GNUC__
25 #include <cxxabi.h>
26 #include <cstdlib>
27 #endif
28 
29 #define STRINGIFY(x) #x
30 
31 namespace gismo
32 {
33 
39 namespace util
40 {
41 
42 #if __cplusplus >= 201103L || _MSC_VER >= 1600
43 template <class C, size_t N> // we catch up char arrays
44 std::string to_string(C (& value)[N])
45 {
46  static_assert(!std::is_same<C[N], char[N]>::value, "Character arrays are not allowed");
47  std::ostringstream convert;
48  convert << value;
49  return convert.str();
50 }
51 #endif
52 
55 template<typename C>
56 std::string to_string(const C & value)
57 {
58  std::ostringstream convert;
59  convert << value;
60  return convert.str();
61 }
62 
65 inline bool starts_with( const std::string & haystack, const std::string & needle )
66 {
67  std::string::const_iterator it1 = haystack.begin();
68  std::string::const_iterator it2 = needle.begin();
69  while ( it2!=needle.end() )
70  {
71  if ( it1 == haystack.end() || *it1 != *it2) return false;
72  it1++; it2++;
73  }
74  return true;
75 }
76 
79 inline bool ends_with( const std::string & haystack, const std::string & needle )
80 {
81  if (needle.size() > haystack.size()) return false;
82  //std::transform(haystack.begin(), value.end(), tmp.begin(), ::tolower);
83  return std::equal(needle.rbegin(), needle.rend(), haystack.rbegin());
84 }
85 
86 #if __cplusplus > 199711L || _MSC_VER >= 1600
87 using std::iota;
88 using std::stod;
89 using std::stoi;
90 
91 #else
92 
93 // Fills the range [first, last) with sequentially increasing values,
94 // starting with value and rep//etitively evaluating ++value.
95 template<class ForwardIterator, class T>
96 void iota(ForwardIterator first, ForwardIterator last, T value)
97 {
98  while(first != last) {
99  *first++ = value;
100  ++value;
101  }
102 }
103 
105 inline int stoi(const std::string& str)
106 {
107  std::istringstream ss(str);
108  int i;
109  if (!(ss >> std::skipws >> i)) // leading whitespaces are ignored by std::stoi
110  //Extracting an int failed
111  throw std::invalid_argument("stoi"); // if CXX11 code throws, CXX98 should do too, or?
112 
113  // std::stoi ignores all after a valid number
114  //char c;
115  //if (ss >> c)
116  // //There was something after the number
117  // return 0;
118 
119  return i;
120 }
121 
123 inline double stod(const std::string& str)
124 {
125  std::istringstream ss(str);
126  double i;
127  if (!(ss >> i))
128  //Extracting double failed
129  throw std::invalid_argument("stod");
130 
131  size_t pos;
132 
133  // hex is valid for std::stod - not a good implementation yet
134  // ssi and ssd correct, better move to double need be done => convert to decimal string and let it parse at usual way.
135  if(i == 0 && (((pos = str.find("0x")) != std::string::npos) || ((pos = str.find("0X")) != std::string::npos)))
136  {
137  bool negative = false;
138  if (pos > 0)
139  if (str[pos - 1] == '-')
140  negative = true;
141 
142  size_t comma = str.find(".", pos+2);
143 
144  size_t integer, decimal;
145  std::istringstream ssi(str.substr(pos+2, comma - pos - 2));
146  std::istringstream ssd(str.substr(++comma)); // we need always comma+1
147 
148  if (!(ssi >> std::hex >> integer))
149  throw std::invalid_argument("stod");
150 
151  if (!(ssd >> std::hex >> decimal))
152  throw std::invalid_argument("stod");
153 
154  size_t lenght = str.find_first_not_of("0123456789abcdefABCDEF", comma);
155  if (lenght == std::string::npos)
156  lenght = str.length() - comma;
157  else
158  lenght -= comma;
159 
160  i = (integer + (decimal/pow(16, lenght))) * (negative ? -1. : 1.);
161  }
162 
163  return i;
164 }
165 
166 #endif
167 
171 inline void string_replace(std::string& str,
172  const std::string& oldStr,
173  const std::string& newStr)
174 {
175  size_t pos = 0;
176  while((pos = str.find(oldStr, pos)) != std::string::npos)
177  {
178  str.replace(pos, oldStr.length(), newStr);
179  pos += newStr.length();
180  }
181 }
182 
187 inline std::string tokenize(const std::string& str,
188  const std::string& delim,
189  const size_t token)
190 {
191  size_t token_end = std::string::npos;
192  size_t token_begin = 0;
193  size_t token_count = 0;
194  bool catched = false;
195 
196  do
197  {
198  GISMO_ENSURE(!catched,
199  "Requested token exceeds the number of tokens");
200 
201  token_begin = token_end + 1;
202  token_end = str.find_first_of(delim, token_begin);
203 
204  if(token_end == std::string::npos) // catch in next iteration
205  catched = true;
206 
207  if (token_end != token_begin) // ignore empty sequences
208  ++token_count;
209  }
210  while (token_count <= token);
211 
212  return str.substr(token_begin, token_end - token_begin);
213 }
214 
217 inline void capitalize(std::string& str)
218 {
219  str[0] = static_cast<char>(toupper(str[0]));
220 }
221 
224 inline std::string returnCapitalized(const std::string& str)
225 {
226  std::string newStr = str;
227  capitalize(newStr);
228  return newStr;
229 }
230 
233 template<typename T>
234 struct type
235 {
236 public:
237  static std::string name()
238  {
239 #ifdef __GNUC__
240  int status = 0;
241 #if __cplusplus > 199711L
242  memory::unique_ptr<char,decltype(std::free)*>
243  dm(__cxxabiv1::__cxa_demangle( typeid(T).name(), NULL, NULL, &status ), std::free);
244  return (status==0) ? dm.get() : typeid(T).name();
245 #else
246  char * dm = __cxxabiv1::__cxa_demangle( typeid(T).name(), NULL, NULL, &status );
247  if (status!=0)
248  {
249  std::free(dm);
250  return typeid(T).name();
251  }
252  std::string res(dm);
253  std::free(dm);
254  return res;
255 #endif
256 #else // not __GNUC__
257  return typeid(T).name();
258 #endif // __GNUC__
259  }
260 };
261 
263 template<typename T>
264 size_t hash_range(T const * start, const T * const end)
265 {
266  size_t seed = end - start;
267  for(; start!=end; ++start)
268  seed ^= *start + 0x9e3779b9 + (seed << 6) + (seed >> 2);
269  return seed;
270 }
271 
272 #if __cplusplus >= 201703L || _MSVC_LANG >= 201703L
273 using std::size;
274 #else
275 template <class T, size_t N>
276 size_t size(const T (&)[N])
277 {
278  return N;
279 }
280 template <class T>
281 size_t size(const T& t)
282 {
283  return t.size();
284 }
285 #endif
286 
287 } // end namespace util
288 
289 // This macro assumes the operators == and < to be present and
290 // defines other four operators !=, >, <= and >=
291 #define GISMO_DELEGATING_COMPARISON_OPERATORS( T ) \
292 inline bool operator!= (const T& a, const T& b) { return !(a==b); } \
293 inline bool operator> (const T& a, const T& b) { return b<a; } \
294 inline bool operator<= (const T& a, const T& b) { return !(b<a); } \
295 inline bool operator>= (const T& a, const T& b) { return !(a<b); }
296 
297 // This macro deletes the operators ==, !=, <, >, <= and >=
298 // for operations that involve the types S and T (in either
299 // order)
300 #if __cplusplus >= 201103L || _MSC_VER >= 1600
301 #define GISMO_DELETE_COMPARISON_OPERATORS( S, T ) \
302 inline bool operator== (const S& a, const T& b) = delete; \
303 inline bool operator!= (const S& a, const T& b) = delete; \
304 inline bool operator< (const S& a, const T& b) = delete; \
305 inline bool operator> (const S& a, const T& b) = delete; \
306 inline bool operator<= (const S& a, const T& b) = delete; \
307 inline bool operator>= (const S& a, const T& b) = delete; \
308 inline bool operator== (const T& a, const S& b) = delete; \
309 inline bool operator!= (const T& a, const S& b) = delete; \
310 inline bool operator< (const T& a, const S& b) = delete; \
311 inline bool operator> (const T& a, const S& b) = delete; \
312 inline bool operator<= (const T& a, const S& b) = delete; \
313 inline bool operator>= (const T& a, const S& b) = delete;
314 #else
315 #define GISMO_DELETE_COMPARISON_OPERATORS( S, T ) \
316 inline bool operator== (const S& a, const T& b); \
317 inline bool operator!= (const S& a, const T& b); \
318 inline bool operator< (const S& a, const T& b); \
319 inline bool operator> (const S& a, const T& b); \
320 inline bool operator<= (const S& a, const T& b); \
321 inline bool operator>= (const S& a, const T& b); \
322 inline bool operator== (const T& a, const S& b); \
323 inline bool operator!= (const T& a, const S& b); \
324 inline bool operator< (const T& a, const S& b); \
325 inline bool operator> (const T& a, const S& b); \
326 inline bool operator<= (const T& a, const S& b); \
327 inline bool operator>= (const T& a, const S& b);
328 
329 #endif
330 
331 } // end namespace gismo
332 
Print name of template type as a string.
Definition: gsUtils.h:234
double stod(const std::string &str)
equivalent to std::stod(str)
Definition: gsUtils.h:123
std::string to_string(const C &value)
Converts value to string, assuming &quot;operator&lt;&lt;&quot; defined on C.
Definition: gsUtils.h:56
void string_replace(std::string &str, const std::string &oldStr, const std::string &newStr)
Replaces appearance of oldStr with newStr inside the string str.
Definition: gsUtils.h:171
#define GISMO_ENSURE(cond, message)
Definition: gsDebug.h:102
Provides utility function related to memory management.
OpenMP stub routines to be used when omp.h is not available.
This file contains the debugging and messaging system of G+Smo.
Handles shared library creation and other class attributes.
void capitalize(std::string &str)
Capitalize string in situ.
Definition: gsUtils.h:217
int stoi(const std::string &str)
equivalent to std::stoi(str), and therefore std::stoi(str, 0, 10)
Definition: gsUtils.h:105
size_t hash_range(T const *start, const T *const end)
Create hash key for a rangle of (integral) numbers.
Definition: gsUtils.h:264
std::string returnCapitalized(const std::string &str)
Capitalize string.
Definition: gsUtils.h:224
bool starts_with(const std::string &haystack, const std::string &needle)
Checks if a string haystack begins with the string needle.
Definition: gsUtils.h:65
bool ends_with(const std::string &haystack, const std::string &needle)
Checks if a string haystack ends with the string needle.
Definition: gsUtils.h:79