G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
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
31namespace gismo
32{
33
39namespace util
40{
41
42#if __cplusplus >= 201103L || _MSC_VER >= 1600
43template <class C, size_t N> // we catch up char arrays
44std::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
55template<typename C>
56std::string to_string(const C & value)
57{
58 std::ostringstream convert;
59 convert << value;
60 return convert.str();
61}
62
65inline 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
79inline 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
87using std::iota;
88using std::stod;
89using 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.
95template<class ForwardIterator, class T>
96void iota(ForwardIterator first, ForwardIterator last, T value)
97{
98 while(first != last) {
99 *first++ = value;
100 ++value;
101 }
102}
103
105inline 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
123inline 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
171inline 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
187inline 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
217inline void capitalize(std::string& str)
218{
219 str[0] = static_cast<char>(toupper(str[0]));
220}
221
224inline std::string returnCapitalized(const std::string& str)
225{
226 std::string newStr = str;
227 capitalize(newStr);
228 return newStr;
229}
230
233template<typename T>
234struct type
235{
236public:
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
263template<typename T>
264size_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
273using std::size;
274#else
275template <class T, size_t N>
276size_t size(const T (&)[N])
277{
278 return N;
279}
280template <class T>
281size_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 ) \
292inline bool operator!= (const T& a, const T& b) { return !(a==b); } \
293inline bool operator> (const T& a, const T& b) { return b<a; } \
294inline bool operator<= (const T& a, const T& b) { return !(b<a); } \
295inline 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 ) \
302inline bool operator== (const S& a, const T& b) = delete; \
303inline bool operator!= (const S& a, const T& b) = delete; \
304inline bool operator< (const S& a, const T& b) = delete; \
305inline bool operator> (const S& a, const T& b) = delete; \
306inline bool operator<= (const S& a, const T& b) = delete; \
307inline bool operator>= (const S& a, const T& b) = delete; \
308inline bool operator== (const T& a, const S& b) = delete; \
309inline bool operator!= (const T& a, const S& b) = delete; \
310inline bool operator< (const T& a, const S& b) = delete; \
311inline bool operator> (const T& a, const S& b) = delete; \
312inline bool operator<= (const T& a, const S& b) = delete; \
313inline bool operator>= (const T& a, const S& b) = delete;
314#else
315#define GISMO_DELETE_COMPARISON_OPERATORS( S, T ) \
316inline bool operator== (const S& a, const T& b); \
317inline bool operator!= (const S& a, const T& b); \
318inline bool operator< (const S& a, const T& b); \
319inline bool operator> (const S& a, const T& b); \
320inline bool operator<= (const S& a, const T& b); \
321inline bool operator>= (const S& a, const T& b); \
322inline bool operator== (const T& a, const S& b); \
323inline bool operator!= (const T& a, const S& b); \
324inline bool operator< (const T& a, const S& b); \
325inline bool operator> (const T& a, const S& b); \
326inline bool operator<= (const T& a, const S& b); \
327inline bool operator>= (const T& a, const S& b);
328
329#endif
330
331} // end namespace gismo
332
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
std::string returnCapitalized(const std::string &str)
Capitalize string.
Definition gsUtils.h:224
std::string to_string(const C &value)
Converts value to string, assuming "operator<<" defined on C.
Definition gsUtils.h:56
void capitalize(std::string &str)
Capitalize string in situ.
Definition gsUtils.h:217
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
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
This file contains the debugging and messaging system of G+Smo.
#define GISMO_ENSURE(cond, message)
Definition gsDebug.h:102
Handles shared library creation and other class attributes.
Provides utility function related to memory management.
OpenMP stub routines to be used when omp.h is not available.
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
double stod(const std::string &str)
equivalent to std::stod(str)
Definition gsUtils.h:123
The G+Smo namespace, containing all definitions for the library.
This namespace gathers several utility functions for miscellaneous tasks.
Print name of template type as a string.
Definition gsUtils.h:235