1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-31 08:13:04 +04:00

core: add "check" macros

This commit is contained in:
Alexander Alekhin
2018-02-23 09:24:44 +00:00
parent 86488ac1bc
commit 567ae61e78
5 changed files with 822 additions and 3 deletions
+160
View File
@@ -0,0 +1,160 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "precomp.hpp"
#include "opencv2/core/check.hpp"
namespace cv {
const char* depthToString(int depth)
{
const char* s = detail::depthToString_(depth);
return s ? s : "<invalid depth>";
}
const cv::String typeToString(int type)
{
cv::String s = detail::typeToString_(type);
if (s.empty())
{
static cv::String invalidType("<invalid type>");
return invalidType;
}
return s;
}
namespace detail {
static const char* getTestOpPhraseStr(unsigned testOp)
{
static const char* _names[] = { "{custom check}", "equal to", "not equal to", "less than or equal to", "less than", "greater than or equal to", "greater than" };
CV_DbgAssert(testOp < CV__LAST_TEST_OP);
return testOp < CV__LAST_TEST_OP ? _names[testOp] : "???";
}
static const char* getTestOpMath(unsigned testOp)
{
static const char* _names[] = { "???", "==", "!=", "<=", "<", ">=", ">" };
CV_DbgAssert(testOp < CV__LAST_TEST_OP);
return testOp < CV__LAST_TEST_OP ? _names[testOp] : "???";
}
const char* depthToString_(int depth)
{
static const char* depthNames[] = { "CV_8U", "CV_8S", "CV_16U", "CV_16S", "CV_32S", "CV_32F", "CV_64F", "CV_USRTYPE1" };
return depth <= CV_USRTYPE1 ? depthNames[depth] : NULL;
}
const cv::String typeToString_(int type)
{
int depth = CV_MAT_DEPTH(type);
int cn = CV_MAT_CN(type);
if (depth >= 0 && depth <= CV_USRTYPE1)
return cv::format("%sC%d", depthToString_(depth), cn);
return cv::String();
}
template<typename T> static CV_NORETURN
void check_failed_auto_(const T& v1, const T& v2, const CheckContext& ctx)
{
std::stringstream ss;
ss << ctx.message << " (expected: '" << ctx.p1_str << " " << getTestOpMath(ctx.testOp) << " " << ctx.p2_str << "'), where" << std::endl
<< " '" << ctx.p1_str << "' is " << v1 << std::endl;
if (ctx.testOp != TEST_CUSTOM && ctx.testOp < CV__LAST_TEST_OP)
{
ss << "must be " << getTestOpPhraseStr(ctx.testOp) << std::endl;
}
ss << " '" << ctx.p2_str << "' is " << v2;
cv::errorNoReturn(cv::Error::StsError, ss.str(), ctx.func, ctx.file, ctx.line);
}
void check_failed_MatDepth(const int v1, const int v2, const CheckContext& ctx)
{
std::stringstream ss;
ss << ctx.message << " (expected: '" << ctx.p1_str << " " << getTestOpMath(ctx.testOp) << " " << ctx.p2_str << "'), where" << std::endl
<< " '" << ctx.p1_str << "' is " << v1 << " (" << depthToString(v1) << ")" << std::endl;
if (ctx.testOp != TEST_CUSTOM && ctx.testOp < CV__LAST_TEST_OP)
{
ss << "must be " << getTestOpPhraseStr(ctx.testOp) << std::endl;
}
ss << " '" << ctx.p2_str << "' is " << v2 << " (" << depthToString(v2) << ")";
cv::errorNoReturn(cv::Error::StsError, ss.str(), ctx.func, ctx.file, ctx.line);
}
void check_failed_MatType(const int v1, const int v2, const CheckContext& ctx)
{
std::stringstream ss;
ss << ctx.message << " (expected: '" << ctx.p1_str << " " << getTestOpMath(ctx.testOp) << " " << ctx.p2_str << "'), where" << std::endl
<< " '" << ctx.p1_str << "' is " << v1 << " (" << typeToString(v1) << ")" << std::endl;
if (ctx.testOp != TEST_CUSTOM && ctx.testOp < CV__LAST_TEST_OP)
{
ss << "must be " << getTestOpPhraseStr(ctx.testOp) << std::endl;
}
ss << " '" << ctx.p2_str << "' is " << v2 << " (" << typeToString(v2) << ")";
cv::errorNoReturn(cv::Error::StsError, ss.str(), ctx.func, ctx.file, ctx.line);
}
void check_failed_MatChannels(const int v1, const int v2, const CheckContext& ctx)
{
check_failed_auto_<int>(v1, v2, ctx);
}
void check_failed_auto(const int v1, const int v2, const CheckContext& ctx)
{
check_failed_auto_<int>(v1, v2, ctx);
}
void check_failed_auto(const float v1, const float v2, const CheckContext& ctx)
{
check_failed_auto_<float>(v1, v2, ctx);
}
void check_failed_auto(const double v1, const double v2, const CheckContext& ctx)
{
check_failed_auto_<double>(v1, v2, ctx);
}
template<typename T> static CV_NORETURN
void check_failed_auto_(const T& v, const CheckContext& ctx)
{
std::stringstream ss;
ss << ctx.message << ":" << std::endl
<< " '" << ctx.p2_str << "'" << std::endl
<< "where" << std::endl
<< " '" << ctx.p1_str << "' is " << v;
cv::errorNoReturn(cv::Error::StsError, ss.str(), ctx.func, ctx.file, ctx.line);
}
void check_failed_MatDepth(const int v, const CheckContext& ctx)
{
std::stringstream ss;
ss << ctx.message << ":" << std::endl
<< " '" << ctx.p2_str << "'" << std::endl
<< "where" << std::endl
<< " '" << ctx.p1_str << "' is " << v << " (" << depthToString(v) << ")";
cv::errorNoReturn(cv::Error::StsError, ss.str(), ctx.func, ctx.file, ctx.line);
}
void check_failed_MatType(const int v, const CheckContext& ctx)
{
std::stringstream ss;
ss << ctx.message << ":" << std::endl
<< " '" << ctx.p2_str << "'" << std::endl
<< "where" << std::endl
<< " '" << ctx.p1_str << "' is " << v << " (" << typeToString(v) << ")";
cv::errorNoReturn(cv::Error::StsError, ss.str(), ctx.func, ctx.file, ctx.line);
}
void check_failed_MatChannels(const int v, const CheckContext& ctx)
{
check_failed_auto_<int>(v, ctx);
}
void check_failed_auto(const int v, const CheckContext& ctx)
{
check_failed_auto_<int>(v, ctx);
}
void check_failed_auto(const float v, const CheckContext& ctx)
{
check_failed_auto_<float>(v, ctx);
}
void check_failed_auto(const double v, const CheckContext& ctx)
{
check_failed_auto_<double>(v, ctx);
}
}} // namespace
+27 -3
View File
@@ -249,10 +249,34 @@ const char* Exception::what() const throw() { return msg.c_str(); }
void Exception::formatMessage()
{
if( func.size() > 0 )
msg = format("OpenCV(%s) %s:%d: error: (%d) %s: %s in function %s\n", CV_VERSION, file.c_str(), line, code, cvErrorStr(code), err.c_str(), func.c_str());
size_t pos = err.find('\n');
bool multiline = pos != cv::String::npos;
if (multiline)
{
std::stringstream ss;
size_t prev_pos = 0;
while (pos != cv::String::npos)
{
ss << "> " << err.substr(prev_pos, pos - prev_pos) << std::endl;
prev_pos = pos + 1;
pos = err.find('\n', prev_pos);
}
ss << "> " << err.substr(prev_pos);
if (err[err.size() - 1] != '\n')
ss << std::endl;
err = ss.str();
}
if (func.size() > 0)
{
if (multiline)
msg = format("OpenCV(%s) %s:%d: error: (%d:%s) in function '%s'\n%s", CV_VERSION, file.c_str(), line, code, cvErrorStr(code), func.c_str(), err.c_str());
else
msg = format("OpenCV(%s) %s:%d: error: (%d:%s) %s in function '%s'\n", CV_VERSION, file.c_str(), line, code, cvErrorStr(code), err.c_str(), func.c_str());
}
else
msg = format("OpenCV(%s) %s:%d: error: (%d) %s: %s\n", CV_VERSION, file.c_str(), line, code, cvErrorStr(code), err.c_str());
{
msg = format("OpenCV(%s) %s:%d: error: (%d:%s) %s%s", CV_VERSION, file.c_str(), line, code, cvErrorStr(code), err.c_str(), multiline ? "" : "\n");
}
}
static const char* g_hwFeatureNames[CV_HARDWARE_MAX_FEATURE] = { NULL };