提交 72f789bf 编写于 作者: A Alexander Alekhin

core: fix type traits

上级 f6265500
......@@ -107,7 +107,7 @@ RECURSIVE = YES
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS = *.inl.hpp *.impl.hpp *_detail.hpp */cudev/**/detail/*.hpp *.m
EXCLUDE_SYMBOLS = cv::DataType<*> int void
EXCLUDE_SYMBOLS = cv::DataType<*> cv::traits::* int void CV__*
EXAMPLE_PATH = @CMAKE_DOXYGEN_EXAMPLE_PATH@
EXAMPLE_PATTERNS = *
EXAMPLE_RECURSIVE = YES
......
......@@ -233,7 +233,7 @@ template<typename _Tp, int n> static inline
std::ostream& operator << (std::ostream& out, const Vec<_Tp, n>& vec)
{
out << "[";
if(Vec<_Tp, n>::depth < CV_32F)
if (cv::traits::Depth<_Tp>::value <= CV_32S)
{
for (int i = 0; i < n - 1; ++i) {
out << (int)vec[i] << ", ";
......
......@@ -1531,6 +1531,11 @@ public:
*/
template<typename _Tp> void push_back(const Mat_<_Tp>& elem);
/** @overload
@param elem Added element(s).
*/
template<typename _Tp> void push_back(const std::vector<_Tp>& elem);
/** @overload
@param m Added line(s).
*/
......
......@@ -100,11 +100,14 @@ In case if C++11 features are avaliable, std::initializer_list can be also used
template<typename _Tp, int m, int n> class Matx
{
public:
enum { depth = DataType<_Tp>::depth,
enum {
rows = m,
cols = n,
channels = rows*cols,
#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
depth = traits::Type<_Tp>::value,
type = CV_MAKETYPE(depth, channels),
#endif
shortdim = (m < n ? m : n)
};
......@@ -259,13 +262,23 @@ public:
typedef value_type vec_type;
enum { generic_type = 0,
depth = DataType<channel_type>::depth,
channels = m * n,
fmt = DataType<channel_type>::fmt + ((channels - 1) << 8),
type = CV_MAKETYPE(depth, channels)
fmt = traits::SafeFmt<channel_type>::fmt + ((channels - 1) << 8)
#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
,depth = DataType<channel_type>::depth
,type = CV_MAKETYPE(depth, channels)
#endif
};
};
namespace traits {
template<typename _Tp, int m, int n>
struct Depth< Matx<_Tp, m, n> > { enum { value = Depth<_Tp>::value }; };
template<typename _Tp, int m, int n>
struct Type< Matx<_Tp, m, n> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, n*m) }; };
} // namespace
/** @brief Comma-separated Matrix Initializer
*/
template<typename _Tp, int m, int n> class MatxCommaInitializer
......@@ -323,9 +336,13 @@ template<typename _Tp, int cn> class Vec : public Matx<_Tp, cn, 1>
{
public:
typedef _Tp value_type;
enum { depth = Matx<_Tp, cn, 1>::depth,
enum {
channels = cn,
type = CV_MAKETYPE(depth, channels)
#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
depth = Matx<_Tp, cn, 1>::depth,
type = CV_MAKETYPE(depth, channels),
#endif
_dummy_enum_finalizer = 0
};
//! default constructor
......@@ -422,13 +439,24 @@ public:
typedef value_type vec_type;
enum { generic_type = 0,
depth = DataType<channel_type>::depth,
channels = cn,
fmt = DataType<channel_type>::fmt + ((channels - 1) << 8),
type = CV_MAKETYPE(depth, channels)
#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
depth = DataType<channel_type>::depth,
type = CV_MAKETYPE(depth, channels),
#endif
_dummy_enum_finalizer = 0
};
};
namespace traits {
template<typename _Tp, int cn>
struct Depth< Vec<_Tp, cn> > { enum { value = Depth<_Tp>::value }; };
template<typename _Tp, int cn>
struct Type< Vec<_Tp, cn> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, cn) }; };
} // namespace
/** @brief Comma-separated Vec Initializer
*/
template<typename _Tp, int m> class VecCommaInitializer : public MatxCommaInitializer<_Tp, m, 1>
......
......@@ -815,7 +815,7 @@ namespace internal
VecWriterProxy( FileStorage* _fs ) : fs(_fs) {}
void operator()(const std::vector<_Tp>& vec) const
{
int _fmt = DataType<_Tp>::fmt;
int _fmt = traits::SafeFmt<_Tp>::fmt;
char fmt[] = { (char)((_fmt >> 8) + '1'), (char)_fmt, '\0' };
fs->writeRaw(fmt, !vec.empty() ? (uchar*)&vec[0] : 0, vec.size() * sizeof(_Tp));
}
......@@ -846,7 +846,7 @@ namespace internal
{
size_t remaining = it->remaining;
size_t cn = DataType<_Tp>::channels;
int _fmt = DataType<_Tp>::fmt;
int _fmt = traits::SafeFmt<_Tp>::fmt;
char fmt[] = { (char)((_fmt >> 8)+'1'), (char)_fmt, '\0' };
size_t remaining1 = remaining / cn;
count = count < remaining1 ? count : remaining1;
......@@ -999,7 +999,7 @@ void write( FileStorage& fs, const std::vector<DMatch>& vec )
template<typename _Tp> static inline
void write( FileStorage& fs, const std::vector<_Tp>& vec )
{
cv::internal::VecWriterProxy<_Tp, DataType<_Tp>::fmt != 0> w(&fs);
cv::internal::VecWriterProxy<_Tp, traits::SafeFmt<_Tp>::fmt != 0> w(&fs);
w(vec);
}
......@@ -1076,7 +1076,7 @@ void write(FileStorage& fs, const String& name, const DMatch& r )
template<typename _Tp> static inline
void write( FileStorage& fs, const String& name, const std::vector<_Tp>& vec )
{
cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+(DataType<_Tp>::fmt != 0 ? FileNode::FLOW : 0));
cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+(traits::SafeFmt<_Tp>::fmt != 0 ? FileNode::FLOW : 0));
write(fs, vec);
}
......@@ -1086,7 +1086,7 @@ void write( FileStorage& fs, const String& name, const std::vector< std::vector<
cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ);
for(size_t i = 0; i < vec.size(); i++)
{
cv::internal::WriteStructContext ws_(fs, name, FileNode::SEQ+(DataType<_Tp>::fmt != 0 ? FileNode::FLOW : 0));
cv::internal::WriteStructContext ws_(fs, name, FileNode::SEQ+(traits::SafeFmt<_Tp>::fmt != 0 ? FileNode::FLOW : 0));
write(fs, vec[i]);
}
}
......@@ -1139,7 +1139,7 @@ void read(const FileNode& node, short& value, short default_value)
template<typename _Tp> static inline
void read( FileNodeIterator& it, std::vector<_Tp>& vec, size_t maxCount = (size_t)INT_MAX )
{
cv::internal::VecReaderProxy<_Tp, DataType<_Tp>::fmt != 0> r(&it);
cv::internal::VecReaderProxy<_Tp, traits::SafeFmt<_Tp>::fmt != 0> r(&it);
r(vec, maxCount);
}
......@@ -1228,7 +1228,7 @@ FileNodeIterator& operator >> (FileNodeIterator& it, _Tp& value)
template<typename _Tp> static inline
FileNodeIterator& operator >> (FileNodeIterator& it, std::vector<_Tp>& vec)
{
cv::internal::VecReaderProxy<_Tp, DataType<_Tp>::fmt != 0> r(&it);
cv::internal::VecReaderProxy<_Tp, traits::SafeFmt<_Tp>::fmt != 0> r(&it);
r(vec, (size_t)INT_MAX);
return it;
}
......
......@@ -49,11 +49,15 @@
namespace cv
{
//#define OPENCV_TRAITS_ENABLE_DEPRECATED
//! @addtogroup core_basic
//! @{
/** @brief Template "trait" class for OpenCV primitive data types.
@note Deprecated. This is replaced by "single purpose" traits: traits::Type and traits::Depth
A primitive OpenCV data type is one of unsigned char, bool, signed char, unsigned short, signed
short, int, float, double, or a tuple of values of one of these types, where all the values in the
tuple have the same type. Any primitive type from the list can be defined by an identifier in the
......@@ -102,10 +106,13 @@ So, such traits are used to tell OpenCV which data type you are working with, ev
not native to OpenCV. For example, the matrix B initialization above is compiled because OpenCV
defines the proper specialized template class DataType\<complex\<_Tp\> \> . This mechanism is also
useful (and used in OpenCV this way) for generic algorithms implementations.
@note Default values were dropped to stop confusing developers about using of unsupported types (see #7599)
*/
template<typename _Tp> class DataType
{
public:
#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
typedef _Tp value_type;
typedef value_type work_type;
typedef value_type channel_type;
......@@ -116,6 +123,7 @@ public:
fmt = 0,
type = CV_MAKETYPE(depth, channels)
};
#endif
};
template<> class DataType<bool>
......@@ -270,11 +278,14 @@ public:
};
#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
template<int _depth> class TypeDepth
{
#ifdef OPENCV_TRAITS_ENABLE_LEGACY_DEFAULTS
enum { depth = CV_USRTYPE1 };
typedef void value_type;
#endif
};
template<> class TypeDepth<CV_8U>
......@@ -319,8 +330,68 @@ template<> class TypeDepth<CV_64F>
typedef double value_type;
};
#endif
//! @}
namespace traits {
namespace internal {
#define CV_CREATE_MEMBER_CHECK(X) \
template<typename T> class CheckMember_##X { \
struct Fallback { int X; }; \
struct Derived : T, Fallback { }; \
template<typename U, U> struct Check; \
typedef char CV_NO[1]; \
typedef char CV_YES[2]; \
template<typename U> static CV_NO & func(Check<int Fallback::*, &U::X> *); \
template<typename U> static CV_YES & func(...); \
public: \
typedef CheckMember_##X type; \
enum { value = sizeof(func<Derived>(0)) == sizeof(CV_YES) }; \
};
CV_CREATE_MEMBER_CHECK(fmt)
CV_CREATE_MEMBER_CHECK(type)
} // namespace internal
template<typename T>
struct Depth
{ enum { value = DataType<T>::depth }; };
template<typename T>
struct Type
{ enum { value = DataType<T>::type }; };
/** Similar to traits::Type<T> but has value = -1 in case of unknown type (instead of compiler error) */
template<typename T, bool available = internal::CheckMember_type< DataType<T> >::value >
struct SafeType {};
template<typename T>
struct SafeType<T, false>
{ enum { value = -1 }; };
template<typename T>
struct SafeType<T, true>
{ enum { value = Type<T>::value }; };
template<typename T, bool available = internal::CheckMember_fmt< DataType<T> >::value >
struct SafeFmt {};
template<typename T>
struct SafeFmt<T, false>
{ enum { fmt = 0 }; };
template<typename T>
struct SafeFmt<T, true>
{ enum { fmt = DataType<T>::fmt }; };
} // namespace
} // cv
#endif // OPENCV_CORE_TRAITS_HPP
......@@ -105,7 +105,7 @@ CV_OperationsTest::~CV_OperationsTest() {}
template<typename _Tp> void CV_OperationsTest::TestType(Size sz, _Tp value)
{
cv::Mat_<_Tp> m(sz);
CV_Assert(m.cols == sz.width && m.rows == sz.height && m.depth() == DataType<_Tp>::depth &&
CV_Assert(m.cols == sz.width && m.rows == sz.height && m.depth() == cv::traits::Depth<_Tp>::value &&
m.channels() == DataType<_Tp>::channels &&
m.elemSize() == sizeof(_Tp) && m.step == m.elemSize()*m.cols);
for( int y = 0; y < sz.height; y++ )
......
......@@ -1076,7 +1076,7 @@ template<typename _Tp> struct pyopencvVecConverter
int i, j, n = (int)PySequence_Fast_GET_SIZE(seq);
value.resize(n);
int type = DataType<_Tp>::type;
int type = traits::Type<_Tp>::value;
int depth = CV_MAT_DEPTH(type), channels = CV_MAT_CN(type);
PyObject** items = PySequence_Fast_ITEMS(seq);
......@@ -1159,7 +1159,9 @@ template<typename _Tp> struct pyopencvVecConverter
{
if(value.empty())
return PyTuple_New(0);
Mat src((int)value.size(), DataType<_Tp>::channels, DataType<_Tp>::depth, (uchar*)&value[0]);
int type = traits::Type<_Tp>::value;
int depth = CV_MAT_DEPTH(type), channels = CV_MAT_CN(type);
Mat src((int)value.size(), channels, depth, (uchar*)&value[0]);
return pyopencv_from(src);
}
};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册