Manticore  Version 2.0alpha
Physics of Molecular Clouds
util.h
Go to the documentation of this file.
1 #ifndef MUTILS_UTIL_H
2 #define MUTILS_UTIL_H
3 
23 #include "mutils/platform.h"
24 
25 #ifdef __cplusplus
26 # include <cctype>
27 # include <cstdint>
28 # include <cstdlib>
29 
30 # include <algorithm>
31 # include <map>
32 # include <vector>
33 
34 #include <mutils/Exception.h>
35 #else
36 # include <ctype.h>
37 # include <stdio.h>
38 # include <stdlib.h>
39 # include <string.h>
40 #endif
41 
42 #ifdef mu_os_mswin
43 # if !defined(strcasecmp)
44 # define strcasecmp stricmp
45 # define strncasecmp strnicmp
46 # endif
47 #else
48 # include <strings.h>
49 # include <unistd.h>
50 #endif
51 
52 #define MU_VERMAX 32 /* Max length of version string. */
53 #define MU_DATEMAX 24 /* Max length of cppdate string. */
54 
55 #ifdef __cplusplus
56 extern "C" {
57 #endif
58 
59 DLLSPEC extern void
60  mu_cppdate(char str[ /*MU_DATEMAX*/ ], const char *date, const char *time),
61  mu_error_action(int, const char *, const char *, int, int),
62  mu_split_tag(char pre[], int *maj, int *min, int *clas, int *bug,
63  int *y, int *m, int *d, const char *tag);
64 
65 DLLSPEC extern char
66  *mu_utoa9(char *str, unsigned i, int strip),
67  *mu_fgetline(char *, long int, FILE *);
68 
69 DLLSPEC extern const char
70  *mu_platform(void),
71  *mu_version(void),
72  *mu_verstr(char verstr[ /*MU_VERMAX*/ ], const char *pre,
73  int maj, int min, int clas, int bug);
74 
75 DLLSPEC extern int
76  mu_ppmtext(char *, char *, int, int, int),
77  mu_vernum(const char *name, const char *cvs);
78 
79 #define MU_iferr_abort(err, func) do { \
80  if (err) mu_error_action(-1, func, __FILE__, __LINE__, -1); } while (0)
81 
82 #define MU_iferr_warn(err, func) do { \
83  if (err) mu_error_action(-1, func, __FILE__, __LINE__, 0); } while (0)
84 
85 #define MU_iferr(err, func) do { \
86  if (err) mu_error_action(-1, func, __FILE__, __LINE__, 1); } while (0)
87 
88 #define MU_iferrn_abort(err, func) do { \
89  int errn=(err); \
90  if (errn) mu_error_action(errn, func, __FILE__, __LINE__, -1); } while (0)
91 
92 #define MU_iferrn_warn(err, func) do { \
93  int errn=(err); \
94  if (errn) mu_error_action(errn, func, __FILE__, __LINE__, 0); } while (0)
95 
96 #define MU_iferrn(err, func) do { \
97  int errn=(err); \
98  if (errn) mu_error_action(errn, func, __FILE__, __LINE__, 1); } while (0)
99 
100 #define mu_alloc(s) mu_alloc_r(NULL, s)
101 #define mu_realloc(p, s) mu_realloc_r(NULL, p, s)
102 #define mu_free(p) mu_free_r(NULL, p)
103 #define mu_freeall() mu_freeall_r(NULL)
104 
105 DLLSPEC extern int mu_free_r(void **, void *);
106 DLLSPEC extern void
107  mu_freeall_r(void *), *mu_alloc_r(void **, size_t),
108  *mu_realloc_r(void **, void *, size_t);
109 
110 
111 DLLSPEC extern int mu_clock_Hz(void);
112 DLLSPEC extern void mu_wait_time(double);
113 DLLSPEC extern double
114  mu_clock_time(void), mu_real_clock_time(void),
115  mu_cpu_time(void), mu_system_time(void), mu_user_time(void),
117 
118 
119 DLLSPEC extern char *mu_optarg;
120 DLLSPEC extern int
122  mu_getopt(int argc, char * const argv[], const char *opts);
123 
124 DLLSPEC extern double
125  mu_time_unary(double (*fn)(double), double x1, double x2, double tmin);
126 
127 DLLSPEC extern double
128  mu_time_binary(double (*fn)(double, double), double x1,
129  double x2, double y1, double y2, double tmin);
130 
131 DLLSPEC extern double
132  mu_time_trinary(double (*fn)(double, double, double), double x1,
133  double x2, double y1, double y2, double z1, double z2,
134  double tmin);
135 
136 
137  /* ============ C++ specific section below here ============ */
138 
139 #ifdef __cplusplus
140 } // extern "C"
141 
142 namespace mutils {
143 
145 extern std::string::size_type npos;
146 
148 extern const std::string nullStr;
149 
150 
152 extern const std::string siPrefixes;
153 
155 extern const std::map<char, const char *> siScaleMap;
156 
163 inline const char *siScale(char siPrefix)
164 {
165  auto p = siScaleMap.find(siPrefix);
166  return (p != siScaleMap.end() ? p->second : "NaN");
167 }
168 
180 inline bool siHasPrefix(const std::string &unit,
181  const std::vector<std::string> &baseUnits)
182 {
183  for (auto &base: baseUnits) { if (base == unit) { return false; } }
184  if (siPrefixes.find_first_of(unit.front()) != npos) {
185  for (auto &base: baseUnits) { if (base == &unit[1]) { return true; } }
186  }
187  return false;
188 }
189 
190 
192 extern int readLogicalLine(std::string &line, FILE *file,
193  unsigned *nLines = nullptr,
194  const char *eol = "\r\n");
195 
196 
204 template<typename C, typename I = typename C::const_iterator>
205 const typename C::value_type &getValue(I p)
206 {
207  return *p;
208 }
209 
217 template<typename C, typename I = typename C::const_iterator>
218 const typename C::key_type &getKey(I p)
219 {
220  return p->first;
221 }
222 
230 template<typename C, typename I = typename C::const_iterator>
231 const typename C::mapped_type &getMapped(I p)
232 {
233  return p->second;
234 }
235 
255 inline int strMatch(const std::string &s1, const std::string &s2,
256  std::string::size_type minChar = npos,
257  bool caseSense = false)
258 {
259  auto ncmp = (caseSense ? strncmp : strncasecmp);
260  auto n = std::min(s1.size(), s2.size()); // Minimum match.
261  if (n < minChar) { n = std::max(s1.size(), s2.size()); } // Complete match.
262  return ncmp(s1.c_str(), s2.c_str(), n);
263 }
264 
280 template<typename C, typename I = typename C::iterator,
281  const std::string &(*F)(I) = getValue<C, I>>
282 std::vector<I> findMatch(const std::string &s, C &pool,
283  std::string::size_type minChar = npos, bool caseSense = false)
284 {
285  std::vector<I> rtn;
286  for (I p = pool.begin(); p != pool.end(); ++p) {
287  if (strMatch(s, F(p), minChar, caseSense) == 0) { rtn.push_back(p); }
288  }
289  return rtn;
290 }
291 
313 template<typename C, typename I = typename C::iterator,
314  const std::string &(*F)(I) = getKey<C, I>>
315 I findUnique(const std::string &str, C &pool,
316  std::string::size_type minChar = npos, bool caseSense = false)
317 {
318  const char *fn = "util::findUnique";
319  auto matches = findMatch<C, I, F>(str, pool, minChar, caseSense);
320  std::string matchNames;
321  for (auto p: matches) {
322  matchNames += " ";
323  matchNames += F(p);
324  }
325  MU_EXCEPTION_IF(matches.size() > 1, fn,
326  "Multiple matches found for '%s':\n%s", str, matchNames);
327 
328  return (matches.empty() ? pool.end() : matches[0]);
329 }
330 
331 
349 template<typename R, typename S, typename T, typename... Args>
350 inline typename
351  std::enable_if<std::is_member_function_pointer<S>::value, R>::type
352 fn_call(S s, T &t, Args&&... args) { return (t.*s)(args...); }
353 
355 template<typename R, typename S, typename T, typename... Args>
356 inline typename
357  std::enable_if<!std::is_member_function_pointer<S>::value, R>::type
358 fn_call(S s, T &t, Args&&... args) { return s(t, args...); }
360 
361 
376 inline
377 std::string qualifyPath(const std::string &path, const std::string &file)
378 {
379  std::string rtn;
380  if (path != nullStr && file != nullStr) {
381  if (!path.empty() && !file.empty() && file[0] != '/'
382  && file != "-" && file != "!") {
383  rtn = path;
384  if (path.back() != '/') { rtn += '/'; }
385  }
386  rtn += file;
387  } else {
388  rtn = nullStr;
389  }
390  return rtn;
391 }
392 
404 inline
405 std::string getToken(const std::string &line, size_t *index = nullptr)
406 {
407  const std::string white{" \t\r\n"};
408  size_t i0 = line.find_first_not_of(white, (index ? *index : 0UL)),
409  i1 = line.find_first_of(white, i0);
410  if (index) { *index = i1; }
411  return (i0 != npos ? line.substr(i0, i1-i0) : "");
412 }
413 
414 } // namespace mutils
415 #endif /* __cplusplus */
416 
417 #endif /* MUTILS_UTIL_H */
DLLSPEC void mu_wait_time(double)
DLLSPEC int mu_free_r(void **, void *)
DLLSPEC int mu_optind
DLLSPEC char * mu_utoa9(char *str, unsigned i, int strip)
DLLSPEC double mu_cpu_time(void)
DLLSPEC double mu_system_time(void)
DLLSPEC double mu_clock_time(void)
DLLSPEC char * mu_optarg
DLLSPEC char * mu_fgetline(char *, long int, FILE *)
DLLSPEC const char * mu_verstr(char verstr[], const char *pre, int maj, int min, int clas, int bug)
DLLSPEC void * mu_realloc_r(void **, void *, size_t)
DLLSPEC double mu_time_unary(double(*fn)(double), double x1, double x2, double tmin)
DLLSPEC int mu_optopt
MathUtils platform identification macros.
DLLSPEC int mu_clock_Hz(void)
#define MU_EXCEPTION_IF(cond, src, msg,...)
Conditionally throws mutils::Exception.
Definition: Exception.h:101
DLLSPEC double mu_thread_cpu_time(void)
DLLSPEC const char * mu_version(void)
DLLSPEC int mu_opterr
const std::string nullStr(1, 0)
const std::string siPrefixes("YZEPTGMkhDdcmunpfazy")
DLLSPEC void mu_split_tag(char pre[], int *maj, int *min, int *clas, int *bug, int *y, int *m, int *d, const char *tag)
MathUtils package.
Definition: CommandLine.cc:10
std::string::size_type npos
Definition: statics.cc:24
DLLSPEC int mu_getopt(int argc, char *const argv[], const char *opts)
DLLSPEC void mu_cppdate(char str[], const char *date, const char *time)
DLLSPEC int mu_vernum(const char *name, const char *cvs)
DLLSPEC double mu_process_cpu_time(void)
DLLSPEC double mu_user_time(void)
DLLSPEC void mu_freeall_r(void *)
DLLSPEC double mu_real_clock_time(void)
DLLSPEC double mu_time_binary(double(*fn)(double, double), double x1, double x2, double y1, double y2, double tmin)
#define DLLSPEC
Definition: platform.h:206
DLLSPEC void mu_error_action(int, const char *, const char *, int, int)
const std::map< char, const char * > siScaleMap
Definition: statics.cc:45
DLLSPEC int mu_ppmtext(char *, char *, int, int, int)
Defines the Exception base class.
DLLSPEC double mu_time_trinary(double(*fn)(double, double, double), double x1, double x2, double y1, double y2, double z1, double z2, double tmin)
DLLSPEC const char * mu_platform(void)
DLLSPEC void * mu_alloc_r(void **, size_t)