utility.hpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #ifndef REMOTEAR3_UTILITY_HPP
  2. #define REMOTEAR3_UTILITY_HPP
  3. #include <spdlog/spdlog.h>
  4. #include <chrono>
  5. // https://en.cppreference.com/w/cpp/utility/unreachable
  6. [[noreturn]] inline void unreachable() {
  7. // Uses compiler specific extensions if possible.
  8. // Even if no extension is used, undefined behavior is still raised by
  9. // an empty function body and the noreturn attribute.
  10. #ifdef __GNUC__ // GCC, Clang, ICC
  11. __builtin_unreachable();
  12. // #elifdef _MSC_VER // MSVC
  13. #else
  14. __assume(false);
  15. #endif
  16. }
  17. #define RET_ERROR \
  18. assert(false);\
  19. unreachable()
  20. #define RET_ERROR_B \
  21. assert(false); \
  22. return false
  23. inline bool check_function_call(bool function_ret, unsigned int line_number,
  24. const char *file_name, const char *function_call_str) {
  25. if (function_ret) [[likely]] return true;
  26. SPDLOG_ERROR("Function call {} failed at {}:{}.",
  27. function_call_str, file_name, line_number);
  28. RET_ERROR_B;
  29. }
  30. #define CALL_CHECK(function_call) \
  31. check_function_call( \
  32. function_call, __LINE__, __FILE__, #function_call)
  33. struct log_timer {
  34. void reset() {
  35. last_ts = clock_type::now();
  36. }
  37. void record(std::string_view name) {
  38. SPDLOG_TRACE("{} reached at {}ms", name,
  39. std::chrono::duration_cast<time_res>(clock_type::now() - last_ts).count());
  40. }
  41. private:
  42. using clock_type = std::chrono::high_resolution_clock;
  43. using time_res = std::chrono::milliseconds;
  44. clock_type::time_point last_ts;
  45. };
  46. extern log_timer global_timer;
  47. #define RESET_TIMER global_timer.reset()
  48. #define RECORD_TIME(name) global_timer.record(name)
  49. inline auto system_timestamp() {
  50. using namespace std::chrono;
  51. auto time_point = high_resolution_clock::now();
  52. return duration_cast<microseconds>(time_point.time_since_epoch()).count();
  53. }
  54. inline auto now_since_epoch_in_seconds() {
  55. using namespace std::chrono;
  56. return time_point_cast<seconds, system_clock>(system_clock::now());
  57. }
  58. template<typename T>
  59. struct smart_buffer {
  60. T *ptr = nullptr;
  61. size_t length = 0;
  62. ~smart_buffer() {
  63. delete ptr;
  64. }
  65. void create(size_t req_length) {
  66. if (req_length > capacity) [[unlikely]] {
  67. delete ptr;
  68. ptr = new T[req_length];
  69. capacity = req_length;
  70. }
  71. length = req_length;
  72. }
  73. private:
  74. size_t capacity = 0;
  75. };
  76. #endif //REMOTEAR3_UTILITY_HPP