expect.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #pragma once
  2. #include <iostream>
  3. #include <sstream>
  4. #if defined(__clang__) || defined(__GNUC__)
  5. #define JVALIDATE_LIKELY(x) __builtin_expect(!!(x), 1)
  6. #define JVALIDATE_UNLIKELY(x) __builtin_expect(!!(x), 0)
  7. #else
  8. #define JVALIDATE_LIKELY(x) (x)
  9. #define JVALIDATE_UNLIKELY(x) (x)
  10. #endif
  11. #if defined(JVALIDATE_USE_EXCEPTIONS)
  12. /**
  13. * @brief Throw an exception after construcing the error message.
  14. *
  15. * @param extype A subtype of std::exception that can be constructed using a
  16. * std::string.
  17. *
  18. * @param message The error "message" to be emit - in the form of an iostream
  19. * output chain (e.g. `"unsupported index " << i << ", valid items " << items`).
  20. */
  21. #define JVALIDATE_THROW(extype, message) \
  22. do { \
  23. std::stringstream ss; \
  24. ss << message; \
  25. throw extype(ss.str()); \
  26. } while (false)
  27. #else
  28. /**
  29. * @brief Print an error message and then terminate execution
  30. *
  31. * @param extype[ignored]
  32. *
  33. * @param message The error "message" to be emit - in the form of an iostream
  34. * output chain (e.g. `"unsupported index " << i << ", valid items " << items`).
  35. */
  36. #define JVALIDATE_THROW(extype, message) \
  37. do { \
  38. std::cerr << message << std::endl; \
  39. std::terminate(); \
  40. } while (false)
  41. #endif
  42. /**
  43. * @brief Assert a certain pre/post-condition is true, else emit an error of a
  44. * specified type and message.
  45. *
  46. * @param condition A boolean or boolean-like expression that should be TRUE.
  47. * If the condition is FALSE, then the other params are used to produce errors.
  48. *
  49. * @param extype A subtype of std::exception that can be constructed using a
  50. * std::string. If exceptions are enabled, and condition is FALSE - then this
  51. * is the type that will be thrown.
  52. *
  53. * @param message The error "message" to be emit - in the form of an iostream
  54. * output chain (e.g. `"unsupported index " << i << ", valid items " << items`).
  55. */
  56. #define EXPECT_T(condition, extype, message) \
  57. if (JVALIDATE_UNLIKELY(!(condition))) { \
  58. JVALIDATE_THROW(extype, message); \
  59. }
  60. /**
  61. * @brief Assert a certain pre/post-condition is true, else emit an error of a
  62. * specified message.
  63. *
  64. * @param condition A boolean or boolean-like expression that should be TRUE.
  65. * If the condition is FALSE, then the other params are used to produce errors.
  66. *
  67. * @param message The error "message" to be emit - in the form of an iostream
  68. * output chain (e.g. `"unsupported index " << i << ", valid items " << items`).
  69. */
  70. #define EXPECT_M(condition, message) EXPECT_T(condition, std::runtime_error, message)
  71. /**
  72. * @brief Assert a certain pre/post-condition is true, else emit a generic error.
  73. *
  74. * @param condition A boolean or boolean-like expression that should be TRUE.
  75. * If the condition is FALSE, then the other params are used to produce errors.
  76. */
  77. #define EXPECT(condition) EXPECT_M(condition, #condition " at " __FILE__ ":" << __LINE__)
  78. /**
  79. * @brief Assert a certain pre/post-condition is true, else return the default
  80. * expression (or void).
  81. *
  82. * @param condition A boolean or boolean-like expression that should be TRUE.
  83. * If the condition is FALSE, then the other params are used to produce errors.
  84. *
  85. * @param ... Zero or One arguments representing the return value if the
  86. * condition is FALSE. Zero arguments is equivalent to `return void();`, which
  87. * doesn't need to be explicitly stated.
  88. */
  89. #define RETURN_UNLESS(condition, ...) \
  90. if (JVALIDATE_UNLIKELY(!(condition))) { \
  91. return __VA_ARGS__; \
  92. }