check.hpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // This file is part of OpenCV project.
  2. // It is subject to the license terms in the LICENSE file found in the top-level directory
  3. // of this distribution and at http://opencv.org/license.html.
  4. #ifndef OPENCV_CORE_CHECK_HPP
  5. #define OPENCV_CORE_CHECK_HPP
  6. #include <opencv2/core/base.hpp>
  7. namespace cv {
  8. /** Returns string of cv::Mat depth value: CV_8U -> "CV_8U" or "<invalid depth>" */
  9. CV_EXPORTS const char* depthToString(int depth);
  10. /** Returns string of cv::Mat depth value: CV_8UC3 -> "CV_8UC3" or "<invalid type>" */
  11. CV_EXPORTS String typeToString(int type);
  12. //! @cond IGNORED
  13. namespace detail {
  14. /** Returns string of cv::Mat depth value: CV_8U -> "CV_8U" or NULL */
  15. CV_EXPORTS const char* depthToString_(int depth);
  16. /** Returns string of cv::Mat depth value: CV_8UC3 -> "CV_8UC3" or cv::String() */
  17. CV_EXPORTS cv::String typeToString_(int type);
  18. enum TestOp {
  19. TEST_CUSTOM = 0,
  20. TEST_EQ = 1,
  21. TEST_NE = 2,
  22. TEST_LE = 3,
  23. TEST_LT = 4,
  24. TEST_GE = 5,
  25. TEST_GT = 6,
  26. CV__LAST_TEST_OP
  27. };
  28. struct CheckContext {
  29. const char* func;
  30. const char* file;
  31. int line;
  32. enum TestOp testOp;
  33. const char* message;
  34. const char* p1_str;
  35. const char* p2_str;
  36. };
  37. #ifndef CV__CHECK_FILENAME
  38. # define CV__CHECK_FILENAME __FILE__
  39. #endif
  40. #ifndef CV__CHECK_FUNCTION
  41. # if defined _MSC_VER
  42. # define CV__CHECK_FUNCTION __FUNCSIG__
  43. # elif defined __GNUC__
  44. # define CV__CHECK_FUNCTION __PRETTY_FUNCTION__
  45. # else
  46. # define CV__CHECK_FUNCTION "<unknown>"
  47. # endif
  48. #endif
  49. #define CV__CHECK_LOCATION_VARNAME(id) CVAUX_CONCAT(CVAUX_CONCAT(__cv_check_, id), __LINE__)
  50. #define CV__DEFINE_CHECK_CONTEXT(id, message, testOp, p1_str, p2_str) \
  51. static const cv::detail::CheckContext CV__CHECK_LOCATION_VARNAME(id) = \
  52. { CV__CHECK_FUNCTION, CV__CHECK_FILENAME, __LINE__, testOp, "" message, "" p1_str, "" p2_str }
  53. CV_EXPORTS void CV_NORETURN check_failed_auto(const bool v1, const bool v2, const CheckContext& ctx);
  54. CV_EXPORTS void CV_NORETURN check_failed_auto(const int v1, const int v2, const CheckContext& ctx);
  55. CV_EXPORTS void CV_NORETURN check_failed_auto(const size_t v1, const size_t v2, const CheckContext& ctx);
  56. CV_EXPORTS void CV_NORETURN check_failed_auto(const float v1, const float v2, const CheckContext& ctx);
  57. CV_EXPORTS void CV_NORETURN check_failed_auto(const double v1, const double v2, const CheckContext& ctx);
  58. CV_EXPORTS void CV_NORETURN check_failed_auto(const Size_<int> v1, const Size_<int> v2, const CheckContext& ctx);
  59. CV_EXPORTS void CV_NORETURN check_failed_MatDepth(const int v1, const int v2, const CheckContext& ctx);
  60. CV_EXPORTS void CV_NORETURN check_failed_MatType(const int v1, const int v2, const CheckContext& ctx);
  61. CV_EXPORTS void CV_NORETURN check_failed_MatChannels(const int v1, const int v2, const CheckContext& ctx);
  62. CV_EXPORTS void CV_NORETURN check_failed_true(const bool v, const CheckContext& ctx);
  63. CV_EXPORTS void CV_NORETURN check_failed_false(const bool v, const CheckContext& ctx);
  64. CV_EXPORTS void CV_NORETURN check_failed_auto(const int v, const CheckContext& ctx);
  65. CV_EXPORTS void CV_NORETURN check_failed_auto(const size_t v, const CheckContext& ctx);
  66. CV_EXPORTS void CV_NORETURN check_failed_auto(const float v, const CheckContext& ctx);
  67. CV_EXPORTS void CV_NORETURN check_failed_auto(const double v, const CheckContext& ctx);
  68. CV_EXPORTS void CV_NORETURN check_failed_auto(const Size_<int> v, const CheckContext& ctx);
  69. CV_EXPORTS void CV_NORETURN check_failed_auto(const std::string& v1, const CheckContext& ctx);
  70. CV_EXPORTS void CV_NORETURN check_failed_MatDepth(const int v, const CheckContext& ctx);
  71. CV_EXPORTS void CV_NORETURN check_failed_MatType(const int v, const CheckContext& ctx);
  72. CV_EXPORTS void CV_NORETURN check_failed_MatChannels(const int v, const CheckContext& ctx);
  73. #define CV__TEST_EQ(v1, v2) ((v1) == (v2))
  74. #define CV__TEST_NE(v1, v2) ((v1) != (v2))
  75. #define CV__TEST_LE(v1, v2) ((v1) <= (v2))
  76. #define CV__TEST_LT(v1, v2) ((v1) < (v2))
  77. #define CV__TEST_GE(v1, v2) ((v1) >= (v2))
  78. #define CV__TEST_GT(v1, v2) ((v1) > (v2))
  79. #define CV__CHECK(id, op, type, v1, v2, v1_str, v2_str, msg_str) do { \
  80. if(CV__TEST_##op((v1), (v2))) ; else { \
  81. CV__DEFINE_CHECK_CONTEXT(id, msg_str, cv::detail::TEST_ ## op, v1_str, v2_str); \
  82. cv::detail::check_failed_ ## type((v1), (v2), CV__CHECK_LOCATION_VARNAME(id)); \
  83. } \
  84. } while (0)
  85. #define CV__CHECK_CUSTOM_TEST(id, type, v, test_expr, v_str, test_expr_str, msg_str) do { \
  86. if(!!(test_expr)) ; else { \
  87. CV__DEFINE_CHECK_CONTEXT(id, msg_str, cv::detail::TEST_CUSTOM, v_str, test_expr_str); \
  88. cv::detail::check_failed_ ## type((v), CV__CHECK_LOCATION_VARNAME(id)); \
  89. } \
  90. } while (0)
  91. } // namespace
  92. //! @endcond
  93. /// Supported values of these types: int, float, double
  94. #define CV_CheckEQ(v1, v2, msg) CV__CHECK(_, EQ, auto, v1, v2, #v1, #v2, msg)
  95. #define CV_CheckNE(v1, v2, msg) CV__CHECK(_, NE, auto, v1, v2, #v1, #v2, msg)
  96. #define CV_CheckLE(v1, v2, msg) CV__CHECK(_, LE, auto, v1, v2, #v1, #v2, msg)
  97. #define CV_CheckLT(v1, v2, msg) CV__CHECK(_, LT, auto, v1, v2, #v1, #v2, msg)
  98. #define CV_CheckGE(v1, v2, msg) CV__CHECK(_, GE, auto, v1, v2, #v1, #v2, msg)
  99. #define CV_CheckGT(v1, v2, msg) CV__CHECK(_, GT, auto, v1, v2, #v1, #v2, msg)
  100. /// Check with additional "decoding" of type values in error message
  101. #define CV_CheckTypeEQ(t1, t2, msg) CV__CHECK(_, EQ, MatType, t1, t2, #t1, #t2, msg)
  102. /// Check with additional "decoding" of depth values in error message
  103. #define CV_CheckDepthEQ(d1, d2, msg) CV__CHECK(_, EQ, MatDepth, d1, d2, #d1, #d2, msg)
  104. #define CV_CheckChannelsEQ(c1, c2, msg) CV__CHECK(_, EQ, MatChannels, c1, c2, #c1, #c2, msg)
  105. /// Example: type == CV_8UC1 || type == CV_8UC3
  106. #define CV_CheckType(t, test_expr, msg) CV__CHECK_CUSTOM_TEST(_, MatType, t, (test_expr), #t, #test_expr, msg)
  107. /// Example: depth == CV_32F || depth == CV_64F
  108. #define CV_CheckDepth(t, test_expr, msg) CV__CHECK_CUSTOM_TEST(_, MatDepth, t, (test_expr), #t, #test_expr, msg)
  109. /// Example: v == A || v == B
  110. #define CV_Check(v, test_expr, msg) CV__CHECK_CUSTOM_TEST(_, auto, v, (test_expr), #v, #test_expr, msg)
  111. /// Example: v == true
  112. #define CV_CheckTrue(v, msg) CV__CHECK_CUSTOM_TEST(_, true, v, v, #v, "", msg)
  113. /// Example: v == false
  114. #define CV_CheckFalse(v, msg) CV__CHECK_CUSTOM_TEST(_, false, v, (!(v)), #v, "", msg)
  115. /// Some complex conditions: CV_Check(src2, src2.empty() || (src2.type() == src1.type() && src2.size() == src1.size()), "src2 should have same size/type as src1")
  116. // TODO define pretty-printers
  117. #ifndef NDEBUG
  118. #define CV_DbgCheck(v, test_expr, msg) CV__CHECK_CUSTOM_TEST(_, auto, v, (test_expr), #v, #test_expr, msg)
  119. #define CV_DbgCheckEQ(v1, v2, msg) CV__CHECK(_, EQ, auto, v1, v2, #v1, #v2, msg)
  120. #define CV_DbgCheckNE(v1, v2, msg) CV__CHECK(_, NE, auto, v1, v2, #v1, #v2, msg)
  121. #define CV_DbgCheckLE(v1, v2, msg) CV__CHECK(_, LE, auto, v1, v2, #v1, #v2, msg)
  122. #define CV_DbgCheckLT(v1, v2, msg) CV__CHECK(_, LT, auto, v1, v2, #v1, #v2, msg)
  123. #define CV_DbgCheckGE(v1, v2, msg) CV__CHECK(_, GE, auto, v1, v2, #v1, #v2, msg)
  124. #define CV_DbgCheckGT(v1, v2, msg) CV__CHECK(_, GT, auto, v1, v2, #v1, #v2, msg)
  125. #else
  126. #define CV_DbgCheck(v, test_expr, msg) do { } while (0)
  127. #define CV_DbgCheckEQ(v1, v2, msg) do { } while (0)
  128. #define CV_DbgCheckNE(v1, v2, msg) do { } while (0)
  129. #define CV_DbgCheckLE(v1, v2, msg) do { } while (0)
  130. #define CV_DbgCheckLT(v1, v2, msg) do { } while (0)
  131. #define CV_DbgCheckGE(v1, v2, msg) do { } while (0)
  132. #define CV_DbgCheckGT(v1, v2, msg) do { } while (0)
  133. #endif
  134. } // namespace
  135. #endif // OPENCV_CORE_CHECK_HPP