Misc.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. // Copyright 2017, University of Freiburg,
  2. // Chair of Algorithms and Data Structures.
  3. // Authors: Patrick Brosi <brosi@informatik.uni-freiburg.de>
  4. #ifndef UTIL_MISC_H_
  5. #define UTIL_MISC_H_
  6. #include <cmath>
  7. #include <cstring>
  8. #include <chrono>
  9. #include <sstream>
  10. #include <iostream>
  11. #include <unistd.h>
  12. #include <sys/types.h>
  13. #include <pwd.h>
  14. #define UNUSED(expr) do { (void)(expr); } while (0)
  15. #define TIME() std::chrono::high_resolution_clock::now()
  16. #define TOOK(t1, t2) (std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count() / 1000.0)
  17. #define T_START(n) auto _tstart_##n = std::chrono::high_resolution_clock::now()
  18. #define T_STOP(n) (std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - _tstart_##n).count() / 1000.0)
  19. #define _TEST3(s, o, e) if (!(s o e)) { std::cerr << "\n" << __FILE__ << ":" << __LINE__ << ": Test failed!\n Expected " << #s << " " << #o " " << (e) << ", got " << (s) << std::endl; exit(1);}
  20. #define _TEST2(s, e) _TEST3(s, ==, o)
  21. #define _TEST1(s) _TEST3(static_cast<bool>(s), ==, true)
  22. #define _GET_TEST_MACRO(_1,_2,_3,NAME,...) NAME
  23. #define TEST(...) _GET_TEST_MACRO(__VA_ARGS__, _TEST3, _TEST2, _TEST1)(__VA_ARGS__)
  24. #define TODO(msg) std::cerr << "\n" __FILE__ << ":" << __LINE__ << ": TODO: " << #msg << std::endl;
  25. namespace util {
  26. // cached first 10 powers of 10
  27. static int pow10[10] = {
  28. 1, 10, 100, 1000, 10000,
  29. 100000, 1000000, 10000000, 100000000, 1000000000};
  30. // _____________________________________________________________________________
  31. inline uint64_t factorial(uint64_t n) {
  32. if (n < 2) return 1;
  33. return n * factorial(n - 1);
  34. }
  35. // _____________________________________________________________________________
  36. inline uint64_t atoul(const char* p) {
  37. uint64_t ret = 0;
  38. while (*p) {
  39. ret = ret * 10 + (*p++ - '0');
  40. }
  41. return ret;
  42. }
  43. // _____________________________________________________________________________
  44. inline bool isFloatingPoint(const std::string& str) {
  45. std::stringstream ss(str);
  46. double f;
  47. ss >> std::noskipws >> f;
  48. return ss.eof() && ! ss.fail();
  49. }
  50. // _____________________________________________________________________________
  51. inline double atof(const char* p, uint8_t mn) {
  52. // this atof implementation works only on "normal" float strings like
  53. // 56.445 or -345.00, but should be faster than std::atof
  54. double ret = 0.0;
  55. bool neg = false;
  56. if (*p == '-') {
  57. neg = true;
  58. p++;
  59. }
  60. while (*p >= '0' && *p <= '9') {
  61. ret = ret * 10.0 + (*p - '0');
  62. p++;
  63. }
  64. if (*p == '.') {
  65. p++;
  66. double f = 0;
  67. uint8_t n = 0;
  68. for (; n < mn && *p >= '0' && *p <= '9'; n++, p++) {
  69. f = f * 10.0 + (*p - '0');
  70. }
  71. if (n < 10)
  72. ret += f / pow10[n];
  73. else
  74. ret += f / std::pow(10, n);
  75. }
  76. if (neg) return -ret;
  77. return ret;
  78. }
  79. // _____________________________________________________________________________
  80. inline double atof(const char* p) { return atof(p, 38); }
  81. // _____________________________________________________________________________
  82. inline std::string getHomeDir() {
  83. // parse implicit paths
  84. const char* homedir = 0;
  85. char* buf = 0;
  86. if ((homedir = getenv("HOME")) == 0) {
  87. homedir = "";
  88. struct passwd pwd;
  89. struct passwd* result;
  90. size_t bufsize;
  91. bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
  92. if (bufsize == static_cast<size_t>(-1)) bufsize = 0x4000;
  93. buf = static_cast<char*>(malloc(bufsize));
  94. if (buf != 0) {
  95. getpwuid_r(getuid(), &pwd, buf, bufsize, &result);
  96. if (result != NULL) homedir = result->pw_dir;
  97. }
  98. }
  99. std::string ret(homedir);
  100. if (buf) free(buf);
  101. return ret;
  102. }
  103. // _____________________________________________________________________________
  104. inline std::string getTmpDir() {
  105. // first, check if an env variable is set
  106. const char* tmpdir = getenv("TMPDIR");
  107. if (tmpdir && std::strlen(tmpdir)) return std::string(tmpdir);
  108. // second, check if /tmp is writable
  109. if (access("/tmp/", W_OK) == 0) return "/tmp";
  110. // third, check if the cwd is writable
  111. if (access(".", W_OK) == 0) return ".";
  112. // lastly, return the users home directory as a fallback
  113. return getHomeDir();
  114. }
  115. // _____________________________________________________________________________
  116. class approx {
  117. public:
  118. explicit approx(double magnitude)
  119. : _epsilon{std::numeric_limits<float>::epsilon() * 100},
  120. _magnitude{magnitude} {}
  121. friend bool operator==(double lhs, approx const& rhs) {
  122. return std::abs(lhs - rhs._magnitude) < rhs._epsilon;
  123. }
  124. friend bool operator==(approx const& lhs, double rhs) {
  125. return operator==(rhs, lhs);
  126. }
  127. friend bool operator!=(double lhs, approx const& rhs) {
  128. return !operator==(lhs, rhs);
  129. }
  130. friend bool operator!=(approx const& lhs, double rhs) {
  131. return !operator==(rhs, lhs);
  132. }
  133. friend bool operator<=(double lhs, approx const& rhs) {
  134. return lhs < rhs._magnitude || lhs == rhs;
  135. }
  136. friend bool operator<=(approx const& lhs, double rhs) {
  137. return lhs._magnitude < rhs || lhs == rhs;
  138. }
  139. friend bool operator>=(double lhs, approx const& rhs) {
  140. return lhs > rhs._magnitude || lhs == rhs;
  141. }
  142. friend bool operator>=(approx const& lhs, double rhs) {
  143. return lhs._magnitude > rhs || lhs == rhs;
  144. }
  145. friend std::ostream& operator<< (std::ostream &out, const approx &a) {
  146. out << "~" << a._magnitude;
  147. return out;
  148. }
  149. private:
  150. double _epsilon;
  151. double _magnitude;
  152. };
  153. } // namespace util
  154. #endif // UTIL_MISC_H_