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