Skip to content

Commit ff8aa66

Browse files
committed
Merge pull request opencv#5201 from alalek:move_semantics
2 parents c385ac5 + e65de8d commit ff8aa66

File tree

5 files changed

+244
-0
lines changed

5 files changed

+244
-0
lines changed

modules/core/include/opencv2/core/cvdef.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,4 +230,23 @@
230230
# endif
231231
#endif
232232

233+
234+
/****************************************************************************************\
235+
* C++ Move semantics *
236+
\****************************************************************************************/
237+
238+
#ifndef CV_CXX_MOVE_SEMANTICS
239+
# if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) || defined(_MSC_VER) && _MSC_VER >= 1600
240+
# define CV_CXX_MOVE_SEMANTICS 1
241+
# elif defined(__clang)
242+
# if __has_feature(cxx_rvalue_references)
243+
# define CV_CXX_MOVE_SEMANTICS 1
244+
# endif
245+
# endif
246+
#else
247+
# if CV_CXX_MOVE_SEMANTICS == 0
248+
# undef CV_CXX_MOVE_SEMANTICS
249+
# endif
250+
#endif
251+
233252
#endif // __OPENCV_CORE_CVDEF_H__

modules/core/include/opencv2/core/cvstd.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,11 @@ struct Ptr
411411
template<typename Y>
412412
Ptr<Y> dynamicCast() const;
413413

414+
#ifdef CV_CXX_MOVE_SEMANTICS
415+
Ptr(Ptr&& o);
416+
Ptr& operator = (Ptr&& o);
417+
#endif
418+
414419
private:
415420
detail::PtrOwner* owner;
416421
T* stored;

modules/core/include/opencv2/core/mat.hpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1854,6 +1854,11 @@ class CV_EXPORTS Mat
18541854
/** @overload */
18551855
template<typename _Tp, typename Functor> void forEach(const Functor& operation) const;
18561856

1857+
#ifdef CV_CXX_MOVE_SEMANTICS
1858+
Mat(Mat&& m);
1859+
Mat& operator = (Mat&& m);
1860+
#endif
1861+
18571862
enum { MAGIC_VAL = 0x42FF0000, AUTO_STEP = 0, CONTINUOUS_FLAG = CV_MAT_CONT_FLAG, SUBMATRIX_FLAG = CV_SUBMAT_FLAG };
18581863
enum { MAGIC_MASK = 0xFFFF0000, TYPE_MASK = 0x00000FFF, DEPTH_MASK = 7 };
18591864

@@ -2084,6 +2089,16 @@ template<typename _Tp> class Mat_ : public Mat
20842089
template<int n> operator Vec<typename DataType<_Tp>::channel_type, n>() const;
20852090
//! conversion to Matx
20862091
template<int m, int n> operator Matx<typename DataType<_Tp>::channel_type, m, n>() const;
2092+
2093+
#ifdef CV_CXX_MOVE_SEMANTICS
2094+
Mat_(Mat_&& m);
2095+
Mat_& operator = (Mat_&& m);
2096+
2097+
Mat_(Mat&& m);
2098+
Mat_& operator = (Mat&& m);
2099+
2100+
Mat_(MatExpr&& e);
2101+
#endif
20872102
};
20882103

20892104
typedef Mat_<uchar> Mat1b;
@@ -2276,6 +2291,11 @@ class CV_EXPORTS UMat
22762291
//! returns N if the matrix is 1-channel (N x ptdim) or ptdim-channel (1 x N) or (N x 1); negative number otherwise
22772292
int checkVector(int elemChannels, int depth=-1, bool requireContinuous=true) const;
22782293

2294+
#ifdef CV_CXX_MOVE_SEMANTICS
2295+
UMat(UMat&& m);
2296+
UMat& operator = (UMat&& m);
2297+
#endif
2298+
22792299
void* handle(int accessFlags) const;
22802300
void ndoffset(size_t* ofs) const;
22812301

modules/core/include/opencv2/core/mat.inl.hpp

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,6 +1107,69 @@ void Mat::push_back(const MatExpr& expr)
11071107
push_back(static_cast<Mat>(expr));
11081108
}
11091109

1110+
#ifdef CV_CXX_MOVE_SEMANTICS
1111+
1112+
inline
1113+
Mat::Mat(Mat&& m)
1114+
: flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), data(m.data),
1115+
datastart(m.datastart), dataend(m.dataend), datalimit(m.datalimit), allocator(m.allocator),
1116+
u(m.u), size(&rows)
1117+
{
1118+
if (m.dims <= 2) // move new step/size info
1119+
{
1120+
step[0] = m.step[0];
1121+
step[1] = m.step[1];
1122+
}
1123+
else
1124+
{
1125+
CV_DbgAssert(m.step.p != m.step.buf);
1126+
step.p = m.step.p;
1127+
size.p = m.size.p;
1128+
m.step.p = m.step.buf;
1129+
m.size.p = &m.rows;
1130+
}
1131+
m.flags = MAGIC_VAL; m.dims = m.rows = m.cols = 0;
1132+
m.data = NULL; m.datastart = NULL; m.dataend = NULL; m.datalimit = NULL;
1133+
m.allocator = NULL;
1134+
m.u = NULL;
1135+
}
1136+
1137+
inline
1138+
Mat& Mat::operator = (Mat&& m)
1139+
{
1140+
release();
1141+
flags = m.flags; dims = m.dims; rows = m.rows; cols = m.cols; data = m.data;
1142+
datastart = m.datastart; dataend = m.dataend; datalimit = m.datalimit; allocator = m.allocator;
1143+
u = m.u;
1144+
if (step.p != step.buf) // release self step/size
1145+
{
1146+
fastFree(step.p);
1147+
step.p = step.buf;
1148+
size.p = &rows;
1149+
}
1150+
if (m.dims <= 2) // move new step/size info
1151+
{
1152+
step[0] = m.step[0];
1153+
step[1] = m.step[1];
1154+
}
1155+
else
1156+
{
1157+
CV_DbgAssert(m.step.p != m.step.buf);
1158+
step.p = m.step.p;
1159+
size.p = m.size.p;
1160+
m.step.p = m.step.buf;
1161+
m.size.p = &m.rows;
1162+
}
1163+
m.flags = MAGIC_VAL; m.dims = m.rows = m.cols = 0;
1164+
m.data = NULL; m.datastart = NULL; m.dataend = NULL; m.datalimit = NULL;
1165+
m.allocator = NULL;
1166+
m.u = NULL;
1167+
return *this;
1168+
}
1169+
1170+
#endif
1171+
1172+
11101173
///////////////////////////// MatSize ////////////////////////////
11111174

11121175
inline
@@ -1655,6 +1718,57 @@ void Mat_<_Tp>::forEach(const Functor& operation) const {
16551718
Mat::forEach<_Tp, Functor>(operation);
16561719
}
16571720

1721+
#ifdef CV_CXX_MOVE_SEMANTICS
1722+
1723+
template<typename _Tp> inline
1724+
Mat_<_Tp>::Mat_(Mat_&& m)
1725+
: Mat(m)
1726+
{
1727+
}
1728+
1729+
template<typename _Tp> inline
1730+
Mat_<_Tp>& Mat_<_Tp>::operator = (Mat_&& m)
1731+
{
1732+
Mat::operator = (m);
1733+
return *this;
1734+
}
1735+
1736+
template<typename _Tp> inline
1737+
Mat_<_Tp>::Mat_(Mat&& m)
1738+
: Mat()
1739+
{
1740+
flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type;
1741+
*this = m;
1742+
}
1743+
1744+
template<typename _Tp> inline
1745+
Mat_<_Tp>& Mat_<_Tp>::operator = (Mat&& m)
1746+
{
1747+
if( DataType<_Tp>::type == m.type() )
1748+
{
1749+
Mat::operator = ((Mat&&)m);
1750+
return *this;
1751+
}
1752+
if( DataType<_Tp>::depth == m.depth() )
1753+
{
1754+
Mat::operator = ((Mat&&)m.reshape(DataType<_Tp>::channels, m.dims, 0));
1755+
return *this;
1756+
}
1757+
CV_DbgAssert(DataType<_Tp>::channels == m.channels());
1758+
m.convertTo(*this, type());
1759+
return *this;
1760+
}
1761+
1762+
template<typename _Tp> inline
1763+
Mat_<_Tp>::Mat_(MatExpr&& e)
1764+
: Mat()
1765+
{
1766+
flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type;
1767+
*this = Mat(e);
1768+
}
1769+
1770+
#endif
1771+
16581772
///////////////////////////// SparseMat /////////////////////////////
16591773

16601774
inline
@@ -3419,6 +3533,69 @@ size_t UMat::total() const
34193533
return p;
34203534
}
34213535

3536+
#ifdef CV_CXX_MOVE_SEMANTICS
3537+
3538+
inline
3539+
UMat::UMat(UMat&& m)
3540+
: flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), allocator(m.allocator),
3541+
usageFlags(m.usageFlags), u(m.u), offset(m.offset), size(&rows)
3542+
{
3543+
if (m.dims <= 2) // move new step/size info
3544+
{
3545+
step[0] = m.step[0];
3546+
step[1] = m.step[1];
3547+
}
3548+
else
3549+
{
3550+
CV_DbgAssert(m.step.p != m.step.buf);
3551+
step.p = m.step.p;
3552+
size.p = m.size.p;
3553+
m.step.p = m.step.buf;
3554+
m.size.p = &m.rows;
3555+
}
3556+
m.flags = MAGIC_VAL; m.dims = m.rows = m.cols = 0;
3557+
m.allocator = NULL;
3558+
m.u = NULL;
3559+
m.offset = 0;
3560+
}
3561+
3562+
inline
3563+
UMat& UMat::operator = (UMat&& m)
3564+
{
3565+
release();
3566+
flags = m.flags; dims = m.dims; rows = m.rows; cols = m.cols;
3567+
allocator = m.allocator; usageFlags = m.usageFlags;
3568+
u = m.u;
3569+
offset = m.offset;
3570+
if (step.p != step.buf) // release self step/size
3571+
{
3572+
fastFree(step.p);
3573+
step.p = step.buf;
3574+
size.p = &rows;
3575+
}
3576+
if (m.dims <= 2) // move new step/size info
3577+
{
3578+
step[0] = m.step[0];
3579+
step[1] = m.step[1];
3580+
}
3581+
else
3582+
{
3583+
CV_DbgAssert(m.step.p != m.step.buf);
3584+
step.p = m.step.p;
3585+
size.p = m.size.p;
3586+
m.step.p = m.step.buf;
3587+
m.size.p = &m.rows;
3588+
}
3589+
m.flags = MAGIC_VAL; m.dims = m.rows = m.cols = 0;
3590+
m.allocator = NULL;
3591+
m.u = NULL;
3592+
m.offset = 0;
3593+
return *this;
3594+
}
3595+
3596+
#endif
3597+
3598+
34223599
inline bool UMatData::hostCopyObsolete() const { return (flags & HOST_COPY_OBSOLETE) != 0; }
34233600
inline bool UMatData::deviceCopyObsolete() const { return (flags & DEVICE_COPY_OBSOLETE) != 0; }
34243601
inline bool UMatData::deviceMemMapped() const { return (flags & DEVICE_MEM_MAPPED) != 0; }

modules/core/include/opencv2/core/ptr.inl.hpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,29 @@ Ptr<Y> Ptr<T>::dynamicCast() const
252252
return Ptr<Y>(*this, dynamic_cast<Y*>(stored));
253253
}
254254

255+
#ifdef CV_CXX_MOVE_SEMANTICS
256+
257+
template<typename T>
258+
Ptr<T>::Ptr(Ptr&& o) : owner(o.owner), stored(o.stored)
259+
{
260+
o.owner = NULL;
261+
o.stored = NULL;
262+
}
263+
264+
template<typename T>
265+
Ptr<T>& Ptr<T>::operator = (Ptr<T>&& o)
266+
{
267+
release();
268+
owner = o.owner;
269+
stored = o.stored;
270+
o.owner = NULL;
271+
o.stored = NULL;
272+
return *this;
273+
}
274+
275+
#endif
276+
277+
255278
template<typename T>
256279
void swap(Ptr<T>& ptr1, Ptr<T>& ptr2){
257280
ptr1.swap(ptr2);

0 commit comments

Comments
 (0)