mirror of
https://github.com/opencv/opencv.git
synced 2026-07-30 15:53:03 +04:00
Merge branch 'master' into gpu-cuda-rename
Conflicts: modules/core/include/opencv2/core/cuda.hpp modules/cudacodec/src/thread.cpp modules/cudacodec/src/thread.hpp modules/superres/perf/perf_superres.cpp modules/superres/src/btv_l1_cuda.cpp modules/superres/src/optical_flow.cpp modules/videostab/src/global_motion.cpp modules/videostab/src/inpainting.cpp samples/cpp/stitching_detailed.cpp samples/cpp/videostab.cpp samples/gpu/stereo_multi.cpp
This commit is contained in:
@@ -638,6 +638,48 @@ The keypoint constructors
|
||||
:param _class_id: object id
|
||||
|
||||
|
||||
KeyPoint::convert
|
||||
--------------------
|
||||
|
||||
This method converts vector of keypoints to vector of points or the reverse, where each keypoint is assigned the same size and the same orientation.
|
||||
|
||||
.. ocv:function:: void KeyPoint::convert(const std::vector<KeyPoint>& keypoints, std::vector<Point2f>& points2f, const std::vector<int>& keypointIndexes=std::vector<int>())
|
||||
|
||||
.. ocv:function:: void KeyPoint::convert(const std::vector<Point2f>& points2f, std::vector<KeyPoint>& keypoints, float size=1, float response=1, int octave=0, int class_id=-1)
|
||||
|
||||
.. ocv:pyfunction:: cv2.KeyPoint_convert(keypoints[, keypointIndexes]) -> points2f
|
||||
|
||||
.. ocv:pyfunction:: cv2.KeyPoint_convert(points2f[, size[, response[, octave[, class_id]]]]) -> keypoints
|
||||
|
||||
:param keypoints: Keypoints obtained from any feature detection algorithm like SIFT/SURF/ORB
|
||||
|
||||
:param points2f: Array of (x,y) coordinates of each keypoint
|
||||
|
||||
:param keypointIndexes: Array of indexes of keypoints to be converted to points. (Acts like a mask to convert only specified keypoints)
|
||||
|
||||
:param _size: keypoint diameter
|
||||
|
||||
:param _response: keypoint detector response on the keypoint (that is, strength of the keypoint)
|
||||
|
||||
:param _octave: pyramid octave in which the keypoint has been detected
|
||||
|
||||
:param _class_id: object id
|
||||
|
||||
|
||||
KeyPoint::overlap
|
||||
--------------------
|
||||
|
||||
This method computes overlap for pair of keypoints. Overlap is the ratio between area of keypoint regions' intersection and area of keypoint regions' union (considering keypoint region as circle). If they don't overlap, we get zero. If they coincide at same location with same size, we get 1.
|
||||
|
||||
.. ocv:function:: float KeyPoint::overlap(const KeyPoint& kp1, const KeyPoint& kp2)
|
||||
|
||||
.. ocv:pyfunction:: cv2.KeyPoint_overlap(kp1, kp2) -> retval
|
||||
|
||||
:param kp1: First keypoint
|
||||
|
||||
:param kp2: Second keypoint
|
||||
|
||||
|
||||
DMatch
|
||||
------
|
||||
.. ocv:class:: DMatch
|
||||
@@ -668,187 +710,328 @@ train descriptor index, train image index, and distance between descriptors. ::
|
||||
};
|
||||
|
||||
|
||||
|
||||
.. _Ptr:
|
||||
|
||||
Ptr
|
||||
---
|
||||
.. ocv:class:: Ptr
|
||||
|
||||
Template class for smart reference-counting pointers ::
|
||||
Template class for smart pointers with shared ownership. ::
|
||||
|
||||
template<typename _Tp> class Ptr
|
||||
template<typename T>
|
||||
struct Ptr
|
||||
{
|
||||
public:
|
||||
// default constructor
|
||||
typedef T element_type;
|
||||
|
||||
Ptr();
|
||||
// constructor that wraps the object pointer
|
||||
Ptr(_Tp* _obj);
|
||||
// destructor: calls release()
|
||||
|
||||
template<typename Y>
|
||||
explicit Ptr(Y* p);
|
||||
template<typename Y, typename D>
|
||||
Ptr(Y* p, D d);
|
||||
|
||||
Ptr(const Ptr& o);
|
||||
template<typename Y>
|
||||
Ptr(const Ptr<Y>& o);
|
||||
template<typename Y>
|
||||
Ptr(const Ptr<Y>& o, T* p);
|
||||
|
||||
~Ptr();
|
||||
// copy constructor; increments ptr's reference counter
|
||||
Ptr(const Ptr& ptr);
|
||||
// assignment operator; decrements own reference counter
|
||||
// (with release()) and increments ptr's reference counter
|
||||
Ptr& operator = (const Ptr& ptr);
|
||||
// increments reference counter
|
||||
void addref();
|
||||
// decrements reference counter; when it becomes 0,
|
||||
// delete_obj() is called
|
||||
|
||||
Ptr& operator = (const Ptr& o);
|
||||
template<typename Y>
|
||||
Ptr& operator = (const Ptr<Y>& o);
|
||||
|
||||
void release();
|
||||
// user-specified custom object deletion operation.
|
||||
// by default, "delete obj;" is called
|
||||
void delete_obj();
|
||||
// returns true if obj == 0;
|
||||
|
||||
template<typename Y>
|
||||
void reset(Y* p);
|
||||
template<typename Y, typename D>
|
||||
void reset(Y* p, D d);
|
||||
|
||||
void swap(Ptr& o);
|
||||
|
||||
T* get() const;
|
||||
|
||||
T& operator * () const;
|
||||
T* operator -> () const;
|
||||
operator T* () const;
|
||||
|
||||
bool empty() const;
|
||||
|
||||
// provide access to the object fields and methods
|
||||
_Tp* operator -> ();
|
||||
const _Tp* operator -> () const;
|
||||
|
||||
// return the underlying object pointer;
|
||||
// thanks to the methods, the Ptr<_Tp> can be
|
||||
// used instead of _Tp*
|
||||
operator _Tp* ();
|
||||
operator const _Tp*() const;
|
||||
protected:
|
||||
// the encapsulated object pointer
|
||||
_Tp* obj;
|
||||
// the associated reference counter
|
||||
int* refcount;
|
||||
template<typename Y>
|
||||
Ptr<Y> staticCast() const;
|
||||
template<typename Y>
|
||||
Ptr<Y> constCast() const;
|
||||
template<typename Y>
|
||||
Ptr<Y> dynamicCast() const;
|
||||
};
|
||||
|
||||
|
||||
The ``Ptr<_Tp>`` class is a template class that wraps pointers of the corresponding type. It is
|
||||
similar to ``shared_ptr`` that is part of the Boost library
|
||||
(http://www.boost.org/doc/libs/1_40_0/libs/smart_ptr/shared_ptr.htm) and also part of the
|
||||
`C++0x <http://en.wikipedia.org/wiki/C++0x>`_ standard.
|
||||
A ``Ptr<T>`` pretends to be a pointer to an object of type T.
|
||||
Unlike an ordinary pointer, however, the object will be automatically
|
||||
cleaned up once all ``Ptr`` instances pointing to it are destroyed.
|
||||
|
||||
This class provides the following options:
|
||||
``Ptr`` is similar to ``boost::shared_ptr`` that is part of the Boost library
|
||||
(http://www.boost.org/doc/libs/release/libs/smart_ptr/shared_ptr.htm)
|
||||
and ``std::shared_ptr`` from the `C++11 <http://en.wikipedia.org/wiki/C++11>`_ standard.
|
||||
|
||||
This class provides the following advantages:
|
||||
|
||||
*
|
||||
Default constructor, copy constructor, and assignment operator for an arbitrary C++ class
|
||||
or a C structure. For some objects, like files, windows, mutexes, sockets, and others, a copy
|
||||
or C structure. For some objects, like files, windows, mutexes, sockets, and others, a copy
|
||||
constructor or an assignment operator are difficult to define. For some other objects, like
|
||||
complex classifiers in OpenCV, copy constructors are absent and not easy to implement. Finally,
|
||||
some of complex OpenCV and your own data structures may be written in C.
|
||||
However, copy constructors and default constructors can simplify programming a lot.Besides,
|
||||
they are often required (for example, by STL containers). By wrapping a pointer to such a
|
||||
complex object ``TObj`` to ``Ptr<TObj>``, you automatically get all of the necessary
|
||||
However, copy constructors and default constructors can simplify programming a lot. Besides,
|
||||
they are often required (for example, by STL containers). By using a ``Ptr`` to such an
|
||||
object instead of the object itself, you automatically get all of the necessary
|
||||
constructors and the assignment operator.
|
||||
|
||||
*
|
||||
*O(1)* complexity of the above-mentioned operations. While some structures, like ``std::vector``,
|
||||
provide a copy constructor and an assignment operator, the operations may take a considerable
|
||||
amount of time if the data structures are large. But if the structures are put into ``Ptr<>``,
|
||||
amount of time if the data structures are large. But if the structures are put into a ``Ptr``,
|
||||
the overhead is small and independent of the data size.
|
||||
|
||||
*
|
||||
Automatic destruction, even for C structures. See the example below with ``FILE*``.
|
||||
Automatic and customizable cleanup, even for C structures. See the example below with ``FILE*``.
|
||||
|
||||
*
|
||||
Heterogeneous collections of objects. The standard STL and most other C++ and OpenCV containers
|
||||
can store only objects of the same type and the same size. The classical solution to store objects
|
||||
of different types in the same container is to store pointers to the base class ``base_class_t*``
|
||||
instead but then you loose the automatic memory management. Again, by using ``Ptr<base_class_t>()``
|
||||
instead of the raw pointers, you can solve the problem.
|
||||
of different types in the same container is to store pointers to the base class (``Base*``)
|
||||
instead but then you lose the automatic memory management. Again, by using ``Ptr<Base>``
|
||||
instead of raw pointers, you can solve the problem.
|
||||
|
||||
The ``Ptr`` class treats the wrapped object as a black box. The reference counter is allocated and
|
||||
managed separately. The only thing the pointer class needs to know about the object is how to
|
||||
deallocate it. This knowledge is encapsulated in the ``Ptr::delete_obj()`` method that is called when
|
||||
the reference counter becomes 0. If the object is a C++ class instance, no additional coding is
|
||||
needed, because the default implementation of this method calls ``delete obj;``. However, if the
|
||||
object is deallocated in a different way, the specialized method should be created. For example,
|
||||
if you want to wrap ``FILE``, the ``delete_obj`` may be implemented as follows: ::
|
||||
A ``Ptr`` is said to *own* a pointer - that is, for each ``Ptr`` there is a pointer that will be deleted
|
||||
once all ``Ptr`` instances that own it are destroyed. The owned pointer may be null, in which case nothing is deleted.
|
||||
Each ``Ptr`` also *stores* a pointer. The stored pointer is the pointer the ``Ptr`` pretends to be;
|
||||
that is, the one you get when you use :ocv:func:`Ptr::get` or the conversion to ``T*``. It's usually
|
||||
the same as the owned pointer, but if you use casts or the general shared-ownership constructor, the two may diverge:
|
||||
the ``Ptr`` will still own the original pointer, but will itself point to something else.
|
||||
|
||||
template<> inline void Ptr<FILE>::delete_obj()
|
||||
{
|
||||
fclose(obj); // no need to clear the pointer afterwards,
|
||||
// it is done externally.
|
||||
}
|
||||
...
|
||||
The owned pointer is treated as a black box. The only thing ``Ptr`` needs to know about it is how to
|
||||
delete it. This knowledge is encapsulated in the *deleter* - an auxiliary object that is associated
|
||||
with the owned pointer and shared between all ``Ptr`` instances that own it. The default deleter is
|
||||
an instance of ``DefaultDeleter``, which uses the standard C++ ``delete`` operator; as such it
|
||||
will work with any pointer allocated with the standard ``new`` operator.
|
||||
|
||||
// now use it:
|
||||
Ptr<FILE> f(fopen("myfile.txt", "r"));
|
||||
if(f.empty())
|
||||
throw ...;
|
||||
However, if the pointer must be deleted in a different way, you must specify a custom deleter upon
|
||||
``Ptr`` construction. A deleter is simply a callable object that accepts the pointer as its sole argument.
|
||||
For example, if you want to wrap ``FILE``, you may do so as follows::
|
||||
|
||||
Ptr<FILE> f(fopen("myfile.txt", "w"), fclose);
|
||||
if(!f) throw ...;
|
||||
fprintf(f, ....);
|
||||
...
|
||||
// the file will be closed automatically by the Ptr<FILE> destructor.
|
||||
// the file will be closed automatically by f's destructor.
|
||||
|
||||
Alternatively, if you want all pointers of a particular type to be deleted the same way,
|
||||
you can specialize ``DefaultDeleter<T>::operator()`` for that type, like this::
|
||||
|
||||
.. note:: The reference increment/decrement operations are implemented as atomic operations,
|
||||
and therefore it is normally safe to use the classes in multi-threaded applications.
|
||||
The same is true for :ocv:class:`Mat` and other C++ OpenCV classes that operate on
|
||||
the reference counters.
|
||||
namespace cv {
|
||||
template<> void DefaultDeleter<FILE>::operator ()(FILE * obj) const
|
||||
{
|
||||
fclose(obj);
|
||||
}
|
||||
}
|
||||
|
||||
Ptr::Ptr
|
||||
--------
|
||||
Various Ptr constructors.
|
||||
For convenience, the following types from the OpenCV C API already have such a specialization
|
||||
that calls the appropriate release function:
|
||||
|
||||
* ``CvCapture``
|
||||
* :ocv:struct:`CvDTreeSplit`
|
||||
* :ocv:struct:`CvFileStorage`
|
||||
* ``CvHaarClassifierCascade``
|
||||
* :ocv:struct:`CvMat`
|
||||
* :ocv:struct:`CvMatND`
|
||||
* :ocv:struct:`CvMemStorage`
|
||||
* :ocv:struct:`CvSparseMat`
|
||||
* ``CvVideoWriter``
|
||||
* :ocv:struct:`IplImage`
|
||||
|
||||
.. note:: The shared ownership mechanism is implemented with reference counting. As such,
|
||||
cyclic ownership (e.g. when object ``a`` contains a ``Ptr`` to object ``b``, which
|
||||
contains a ``Ptr`` to object ``a``) will lead to all involved objects never being
|
||||
cleaned up. Avoid such situations.
|
||||
|
||||
.. note:: It is safe to concurrently read (but not write) a ``Ptr`` instance from multiple threads
|
||||
and therefore it is normally safe to use it in multi-threaded applications.
|
||||
The same is true for :ocv:class:`Mat` and other C++ OpenCV classes that use internal
|
||||
reference counts.
|
||||
|
||||
Ptr::Ptr (null)
|
||||
------------------
|
||||
|
||||
.. ocv:function:: Ptr::Ptr()
|
||||
.. ocv:function:: Ptr::Ptr(_Tp* _obj)
|
||||
.. ocv:function:: Ptr::Ptr(const Ptr& ptr)
|
||||
|
||||
:param _obj: Object for copy.
|
||||
:param ptr: Object for copy.
|
||||
The default constructor creates a null ``Ptr`` - one that owns and stores a null pointer.
|
||||
|
||||
Ptr::Ptr (assuming ownership)
|
||||
-----------------------------
|
||||
|
||||
.. ocv:function:: template<typename Y> Ptr::Ptr(Y* p)
|
||||
.. ocv:function:: template<typename Y, typename D> Ptr::Ptr(Y* p, D d)
|
||||
|
||||
:param d: Deleter to use for the owned pointer.
|
||||
:param p: Pointer to own.
|
||||
|
||||
If ``p`` is null, these are equivalent to the default constructor.
|
||||
|
||||
Otherwise, these constructors assume ownership of ``p`` - that is, the created ``Ptr`` owns
|
||||
and stores ``p`` and assumes it is the sole owner of it. Don't use them if ``p`` is already
|
||||
owned by another ``Ptr``, or else ``p`` will get deleted twice.
|
||||
|
||||
With the first constructor, ``DefaultDeleter<Y>()`` becomes the associated deleter (so ``p``
|
||||
will eventually be deleted with the standard ``delete`` operator). ``Y`` must be a complete
|
||||
type at the point of invocation.
|
||||
|
||||
With the second constructor, ``d`` becomes the associated deleter.
|
||||
|
||||
``Y*`` must be convertible to ``T*``.
|
||||
|
||||
.. note:: It is often easier to use :ocv:func:`makePtr` instead.
|
||||
|
||||
Ptr::Ptr (sharing ownership)
|
||||
----------------------------
|
||||
|
||||
.. ocv:function:: Ptr::Ptr(const Ptr& o)
|
||||
.. ocv:function:: template<typename Y> Ptr::Ptr(const Ptr<Y>& o)
|
||||
.. ocv:function:: template<typename Y> Ptr::Ptr(const Ptr<Y>& o, T* p)
|
||||
|
||||
:param o: ``Ptr`` to share ownership with.
|
||||
:param p: Pointer to store.
|
||||
|
||||
These constructors create a ``Ptr`` that shares ownership with another ``Ptr`` - that is,
|
||||
own the same pointer as ``o``.
|
||||
|
||||
With the first two, the same pointer is stored, as well; for the second, ``Y*`` must be convertible to ``T*``.
|
||||
|
||||
With the third, ``p`` is stored, and ``Y`` may be any type. This constructor allows to have completely
|
||||
unrelated owned and stored pointers, and should be used with care to avoid confusion. A relatively
|
||||
benign use is to create a non-owning ``Ptr``, like this::
|
||||
|
||||
ptr = Ptr<T>(Ptr<T>(), dont_delete_me); // owns nothing; will not delete the pointer.
|
||||
|
||||
Ptr::~Ptr
|
||||
---------
|
||||
The Ptr destructor.
|
||||
|
||||
.. ocv:function:: Ptr::~Ptr()
|
||||
|
||||
The destructor is equivalent to calling :ocv:func:`Ptr::release`.
|
||||
|
||||
Ptr::operator =
|
||||
----------------
|
||||
Assignment operator.
|
||||
|
||||
.. ocv:function:: Ptr& Ptr::operator = (const Ptr& ptr)
|
||||
.. ocv:function:: Ptr& Ptr::operator = (const Ptr& o)
|
||||
.. ocv:function:: template<typename Y> Ptr& Ptr::operator = (const Ptr<Y>& o)
|
||||
|
||||
:param ptr: Object for assignment.
|
||||
:param o: ``Ptr`` to share ownership with.
|
||||
|
||||
Decrements own reference counter (with ``release()``) and increments ptr's reference counter.
|
||||
Assignment replaces the current ``Ptr`` instance with one that owns and stores same
|
||||
pointers as ``o`` and then destroys the old instance.
|
||||
|
||||
Ptr::addref
|
||||
-----------
|
||||
Increments reference counter.
|
||||
|
||||
.. ocv:function:: void Ptr::addref()
|
||||
|
||||
Ptr::release
|
||||
------------
|
||||
Decrements reference counter; when it becomes 0, ``delete_obj()`` is called.
|
||||
|
||||
.. ocv:function:: void Ptr::release()
|
||||
|
||||
Ptr::delete_obj
|
||||
---------------
|
||||
User-specified custom object deletion operation. By default, ``delete obj;`` is called.
|
||||
If no other ``Ptr`` instance owns the owned pointer, deletes it with the associated deleter.
|
||||
Then sets both the owned and the stored pointers to ``NULL``.
|
||||
|
||||
.. ocv:function:: void Ptr::delete_obj()
|
||||
|
||||
Ptr::reset
|
||||
----------
|
||||
|
||||
.. ocv:function:: template<typename Y> void Ptr::reset(Y* p)
|
||||
.. ocv:function:: template<typename Y, typename D> void Ptr::reset(Y* p, D d)
|
||||
|
||||
:param d: Deleter to use for the owned pointer.
|
||||
:param p: Pointer to own.
|
||||
|
||||
``ptr.reset(...)`` is equivalent to ``ptr = Ptr<T>(...)``.
|
||||
|
||||
Ptr::swap
|
||||
---------
|
||||
|
||||
.. ocv:function:: void Ptr::swap(Ptr& o)
|
||||
|
||||
:param o: ``Ptr`` to swap with.
|
||||
|
||||
Swaps the owned and stored pointers (and deleters, if any) of this and ``o``.
|
||||
|
||||
Ptr::get
|
||||
--------
|
||||
|
||||
.. ocv:function:: T* Ptr::get() const
|
||||
|
||||
Returns the stored pointer.
|
||||
|
||||
Ptr pointer emulation
|
||||
---------------------
|
||||
|
||||
.. ocv:function:: T& Ptr::operator * () const
|
||||
.. ocv:function:: T* Ptr::operator -> () const
|
||||
.. ocv:function:: Ptr::operator T* () const
|
||||
|
||||
These operators are what allows ``Ptr`` to pretend to be a pointer.
|
||||
|
||||
If ``ptr`` is a ``Ptr<T>``, then ``*ptr`` is equivalent to ``*ptr.get()``
|
||||
and ``ptr->foo`` is equivalent to ``ptr.get()->foo``. In addition, ``ptr``
|
||||
is implicitly convertible to ``T*``, and such conversion is equivalent to
|
||||
``ptr.get()``. As a corollary, ``if (ptr)`` is equivalent to ``if (ptr.get())``.
|
||||
In other words, a ``Ptr`` behaves as if it was its own stored pointer.
|
||||
|
||||
Ptr::empty
|
||||
----------
|
||||
Returns true if obj == 0;
|
||||
|
||||
bool empty() const;
|
||||
.. ocv:function:: bool Ptr::empty() const
|
||||
|
||||
Ptr::operator ->
|
||||
----------------
|
||||
Provide access to the object fields and methods.
|
||||
``ptr.empty()`` is equivalent to ``!ptr.get()``.
|
||||
|
||||
.. ocv:function:: template<typename _Tp> _Tp* Ptr::operator -> ()
|
||||
.. ocv:function:: template<typename _Tp> const _Tp* Ptr::operator -> () const
|
||||
Ptr casts
|
||||
---------
|
||||
|
||||
.. ocv:function:: template<typename Y> Ptr<Y> Ptr::staticCast() const
|
||||
.. ocv:function:: template<typename Y> Ptr<Y> Ptr::constCast() const
|
||||
.. ocv:function:: template<typename Y> Ptr<Y> Ptr::dynamicCast() const
|
||||
|
||||
Ptr::operator _Tp*
|
||||
------------------
|
||||
Returns the underlying object pointer. Thanks to the methods, the ``Ptr<_Tp>`` can be used instead
|
||||
of ``_Tp*``.
|
||||
If ``ptr`` is a ``Ptr``, then ``ptr.fooCast<Y>()`` is equivalent to
|
||||
``Ptr<Y>(ptr, foo_cast<Y>(ptr.get()))``. That is, these functions create
|
||||
a new ``Ptr`` with the same owned pointer and a cast stored pointer.
|
||||
|
||||
.. ocv:function:: template<typename _Tp> Ptr::operator _Tp* ()
|
||||
.. ocv:function:: template<typename _Tp> Ptr::operator const _Tp*() const
|
||||
Ptr global swap
|
||||
---------------
|
||||
|
||||
.. ocv:function:: template<typename T> void swap(Ptr<T>& ptr1, Ptr<T>& ptr2)
|
||||
|
||||
Equivalent to ``ptr1.swap(ptr2)``. Provided to help write generic algorithms.
|
||||
|
||||
Ptr comparisons
|
||||
---------------
|
||||
|
||||
.. ocv:function:: template<typename T> bool operator == (const Ptr<T>& ptr1, const Ptr<T>& ptr2)
|
||||
.. ocv:function:: template<typename T> bool operator != (const Ptr<T>& ptr1, const Ptr<T>& ptr2)
|
||||
|
||||
Return whether ``ptr1.get()`` and ``ptr2.get()`` are equal and not equal, respectively.
|
||||
|
||||
makePtr
|
||||
-------
|
||||
|
||||
.. ocv:function:: template<typename T> Ptr<T> makePtr()
|
||||
.. ocv:function:: template<typename T, typename A1> Ptr<T> makePtr(const A1& a1)
|
||||
.. ocv:function:: template<typename T, typename A1, typename A2> Ptr<T> makePtr(const A1& a1, const A2& a2)
|
||||
.. ocv:function:: template<typename T, typename A1, typename A2, typename A3> Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3)
|
||||
|
||||
(and so on...)
|
||||
|
||||
``makePtr<T>(...)`` is equivalent to ``Ptr<T>(new T(...))``. It is shorter than the latter, and
|
||||
it's marginally safer than using a constructor or :ocv:func:`Ptr::reset`, since it ensures that
|
||||
the owned pointer is new and thus not owned by any other ``Ptr`` instance.
|
||||
|
||||
Unfortunately, perfect forwarding is impossible to implement in C++03, and so ``makePtr`` is limited
|
||||
to constructors of ``T`` that have up to 10 arguments, none of which are non-const references.
|
||||
|
||||
Mat
|
||||
---
|
||||
@@ -2925,7 +3108,7 @@ Creates algorithm instance by name
|
||||
|
||||
:param name: The algorithm name, one of the names returned by ``Algorithm::getList()``.
|
||||
|
||||
This static method creates a new instance of the specified algorithm. If there is no such algorithm, the method will silently return null pointer (that can be checked by ``Ptr::empty()`` method). Also, you should specify the particular ``Algorithm`` subclass as ``_Tp`` (or simply ``Algorithm`` if you do not know it at that point). ::
|
||||
This static method creates a new instance of the specified algorithm. If there is no such algorithm, the method will silently return a null pointer. Also, you should specify the particular ``Algorithm`` subclass as ``_Tp`` (or simply ``Algorithm`` if you do not know it at that point). ::
|
||||
|
||||
Ptr<BackgroundSubtractor> bgfg = Algorithm::create<BackgroundSubtractor>("BackgroundSubtractor.MOG2");
|
||||
|
||||
|
||||
@@ -83,17 +83,22 @@ First of all, ``std::vector``, ``Mat``, and other data structures used by the fu
|
||||
// matrix will be deallocated, since it is not referenced by anyone
|
||||
C = C.clone();
|
||||
|
||||
You see that the use of ``Mat`` and other basic structures is simple. But what about high-level classes or even user data types created without taking automatic memory management into account? For them, OpenCV offers the ``Ptr<>`` template class that is similar to ``std::shared_ptr`` from C++ TR1. So, instead of using plain pointers::
|
||||
You see that the use of ``Mat`` and other basic structures is simple. But what about high-level classes or even user
|
||||
data types created without taking automatic memory management into account? For them, OpenCV offers the :ocv:class:`Ptr`
|
||||
template class that is similar to ``std::shared_ptr`` from C++11. So, instead of using plain pointers::
|
||||
|
||||
T* ptr = new T(...);
|
||||
|
||||
you can use::
|
||||
|
||||
Ptr<T> ptr = new T(...);
|
||||
Ptr<T> ptr(new T(...));
|
||||
|
||||
That is, ``Ptr<T> ptr`` encapsulates a pointer to a ``T`` instance and a reference counter associated with the pointer. See the
|
||||
:ocv:class:`Ptr`
|
||||
description for details.
|
||||
or::
|
||||
|
||||
Ptr<T> ptr = makePtr<T>(...);
|
||||
|
||||
``Ptr<T>`` encapsulates a pointer to a ``T`` instance and a reference counter associated with the pointer. See the
|
||||
:ocv:class:`Ptr` description for details.
|
||||
|
||||
.. _AutomaticAllocation:
|
||||
|
||||
|
||||
@@ -1882,13 +1882,13 @@ CV_EXPORTS void insertImageCOI(InputArray coiimg, CvArr* arr, int coi=-1);
|
||||
|
||||
|
||||
|
||||
//////// specializied implementations of Ptr::delete_obj() for classic OpenCV types ////////
|
||||
////// specialized implementations of DefaultDeleter::operator() for classic OpenCV types //////
|
||||
|
||||
template<> CV_EXPORTS void Ptr<CvMat>::delete_obj();
|
||||
template<> CV_EXPORTS void Ptr<IplImage>::delete_obj();
|
||||
template<> CV_EXPORTS void Ptr<CvMatND>::delete_obj();
|
||||
template<> CV_EXPORTS void Ptr<CvSparseMat>::delete_obj();
|
||||
template<> CV_EXPORTS void Ptr<CvMemStorage>::delete_obj();
|
||||
template<> CV_EXPORTS void DefaultDeleter<CvMat>::operator ()(CvMat* obj) const;
|
||||
template<> CV_EXPORTS void DefaultDeleter<IplImage>::operator ()(IplImage* obj) const;
|
||||
template<> CV_EXPORTS void DefaultDeleter<CvMatND>::operator ()(CvMatND* obj) const;
|
||||
template<> CV_EXPORTS void DefaultDeleter<CvSparseMat>::operator ()(CvSparseMat* obj) const;
|
||||
template<> CV_EXPORTS void DefaultDeleter<CvMemStorage>::operator ()(CvMemStorage* obj) const;
|
||||
|
||||
////////////// convenient wrappers for operating old-style dynamic structures //////////////
|
||||
|
||||
|
||||
@@ -666,12 +666,6 @@ CV_EXPORTS void printShortCudaDeviceInfo(int device);
|
||||
|
||||
}} // namespace cv { namespace cuda {
|
||||
|
||||
namespace cv {
|
||||
|
||||
template <> CV_EXPORTS void Ptr<cv::cuda::Stream::Impl>::delete_obj();
|
||||
template <> CV_EXPORTS void Ptr<cv::cuda::Event::Impl>::delete_obj();
|
||||
|
||||
}
|
||||
|
||||
#include "opencv2/core/cuda.inl.hpp"
|
||||
|
||||
|
||||
@@ -158,69 +158,176 @@ public:
|
||||
size_type max_size() const { return cv::max(static_cast<_Tp>(-1)/sizeof(_Tp), 1); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
//////////////////// generic_type ref-counting pointer class for C/C++ objects ////////////////////////
|
||||
|
||||
/*!
|
||||
Smart pointer to dynamically allocated objects.
|
||||
|
||||
This is template pointer-wrapping class that stores the associated reference counter along with the
|
||||
object pointer. The class is similar to std::smart_ptr<> from the recent addons to the C++ standard,
|
||||
but is shorter to write :) and self-contained (i.e. does add any dependency on the compiler or an external library).
|
||||
|
||||
Basically, you can use "Ptr<MyObjectType> ptr" (or faster "const Ptr<MyObjectType>& ptr" for read-only access)
|
||||
everywhere instead of "MyObjectType* ptr", where MyObjectType is some C structure or a C++ class.
|
||||
To make it all work, you need to specialize Ptr<>::delete_obj(), like:
|
||||
|
||||
\code
|
||||
template<> CV_EXPORTS void Ptr<MyObjectType>::delete_obj() { call_destructor_func(obj); }
|
||||
\endcode
|
||||
|
||||
\note{if MyObjectType is a C++ class with a destructor, you do not need to specialize delete_obj(),
|
||||
since the default implementation calls "delete obj;"}
|
||||
|
||||
\note{Another good property of the class is that the operations on the reference counter are atomic,
|
||||
i.e. it is safe to use the class in multi-threaded applications}
|
||||
*/
|
||||
template<typename _Tp> class Ptr
|
||||
namespace detail
|
||||
{
|
||||
public:
|
||||
//! empty constructor
|
||||
Ptr();
|
||||
//! take ownership of the pointer. The associated reference counter is allocated and set to 1
|
||||
Ptr(_Tp* _obj);
|
||||
//! calls release()
|
||||
~Ptr();
|
||||
//! copy constructor. Copies the members and calls addref()
|
||||
Ptr(const Ptr& ptr);
|
||||
template<typename _Tp2> Ptr(const Ptr<_Tp2>& ptr);
|
||||
//! copy operator. Calls ptr.addref() and release() before copying the members
|
||||
Ptr& operator = (const Ptr& ptr);
|
||||
//! increments the reference counter
|
||||
void addref();
|
||||
//! decrements the reference counter. If it reaches 0, delete_obj() is called
|
||||
void release();
|
||||
//! deletes the object. Override if needed
|
||||
void delete_obj();
|
||||
//! returns true iff obj==NULL
|
||||
bool empty() const;
|
||||
|
||||
//! cast pointer to another type
|
||||
template<typename _Tp2> Ptr<_Tp2> ptr();
|
||||
template<typename _Tp2> const Ptr<_Tp2> ptr() const;
|
||||
// Metafunction to avoid taking a reference to void.
|
||||
template<typename T>
|
||||
struct RefOrVoid { typedef T& type; };
|
||||
|
||||
//! helper operators making "Ptr<T> ptr" use very similar to "T* ptr".
|
||||
_Tp* operator -> ();
|
||||
const _Tp* operator -> () const;
|
||||
template<>
|
||||
struct RefOrVoid<void>{ typedef void type; };
|
||||
|
||||
operator _Tp* ();
|
||||
operator const _Tp*() const;
|
||||
template<>
|
||||
struct RefOrVoid<const void>{ typedef const void type; };
|
||||
|
||||
_Tp* obj; //< the object pointer.
|
||||
int* refcount; //< the associated reference counter
|
||||
template<>
|
||||
struct RefOrVoid<volatile void>{ typedef volatile void type; };
|
||||
|
||||
template<>
|
||||
struct RefOrVoid<const volatile void>{ typedef const volatile void type; };
|
||||
|
||||
// This class would be private to Ptr, if it didn't have to be a non-template.
|
||||
struct PtrOwner;
|
||||
|
||||
}
|
||||
|
||||
template<typename Y>
|
||||
struct DefaultDeleter
|
||||
{
|
||||
void operator () (Y* p) const;
|
||||
};
|
||||
|
||||
/*
|
||||
A smart shared pointer class with reference counting.
|
||||
|
||||
A Ptr<T> stores a pointer and owns a (potentially different) pointer.
|
||||
The stored pointer has type T and is the one returned by get() et al,
|
||||
while the owned pointer can have any type and is the one deleted
|
||||
when there are no more Ptrs that own it. You can't directly obtain the
|
||||
owned pointer.
|
||||
|
||||
The interface of this class is mostly a subset of that of C++11's
|
||||
std::shared_ptr.
|
||||
*/
|
||||
template<typename T>
|
||||
struct Ptr
|
||||
{
|
||||
/* Generic programming support. */
|
||||
typedef T element_type;
|
||||
|
||||
/* Ptr that owns NULL and stores NULL. */
|
||||
Ptr();
|
||||
|
||||
/* Ptr that owns p and stores p. The owned pointer will be deleted with
|
||||
DefaultDeleter<Y>. Y must be a complete type and Y* must be
|
||||
convertible to T*. */
|
||||
template<typename Y>
|
||||
explicit Ptr(Y* p);
|
||||
|
||||
/* Ptr that owns p and stores p. The owned pointer will be deleted by
|
||||
calling d(p). Y* must be convertible to T*. */
|
||||
template<typename Y, typename D>
|
||||
Ptr(Y* p, D d);
|
||||
|
||||
/* Same as the constructor below; it exists to suppress the generation
|
||||
of the implicit copy constructor. */
|
||||
Ptr(const Ptr& o);
|
||||
|
||||
/* Ptr that owns the same pointer as o and stores the same pointer as o,
|
||||
converted to T*. Naturally, Y* must be convertible to T*. */
|
||||
template<typename Y>
|
||||
Ptr(const Ptr<Y>& o);
|
||||
|
||||
/* Ptr that owns same pointer as o, and stores p. Useful for casts and
|
||||
creating non-owning Ptrs. */
|
||||
template<typename Y>
|
||||
Ptr(const Ptr<Y>& o, T* p);
|
||||
|
||||
/* Equivalent to release(). */
|
||||
~Ptr();
|
||||
|
||||
/* Same as assignment below; exists to suppress the generation of the
|
||||
implicit assignment operator. */
|
||||
Ptr& operator = (const Ptr& o);
|
||||
|
||||
template<typename Y>
|
||||
Ptr& operator = (const Ptr<Y>& o);
|
||||
|
||||
/* Resets both the owned and stored pointers to NULL. Deletes the owned
|
||||
pointer with the associated deleter if it's not owned by any other
|
||||
Ptr and is non-zero. It's called reset() in std::shared_ptr; here
|
||||
it is release() for compatibility with old OpenCV versions. */
|
||||
void release();
|
||||
|
||||
/* Equivalent to assigning from Ptr<T>(p). */
|
||||
template<typename Y>
|
||||
void reset(Y* p);
|
||||
|
||||
/* Equivalent to assigning from Ptr<T>(p, d). */
|
||||
template<typename Y, typename D>
|
||||
void reset(Y* p, D d);
|
||||
|
||||
/* Swaps the stored and owned pointers of this and o. */
|
||||
void swap(Ptr& o);
|
||||
|
||||
/* Returns the stored pointer. */
|
||||
T* get() const;
|
||||
|
||||
/* Ordinary pointer emulation. */
|
||||
typename detail::RefOrVoid<T>::type operator * () const;
|
||||
T* operator -> () const;
|
||||
|
||||
/* Equivalent to get(). */
|
||||
operator T* () const;
|
||||
|
||||
/* Equivalent to !*this. */
|
||||
bool empty() const;
|
||||
|
||||
/* Returns a Ptr that owns the same pointer as this, and stores the same
|
||||
pointer as this, except converted via static_cast to Y*. */
|
||||
template<typename Y>
|
||||
Ptr<Y> staticCast() const;
|
||||
|
||||
/* Ditto for const_cast. */
|
||||
template<typename Y>
|
||||
Ptr<Y> constCast() const;
|
||||
|
||||
/* Ditto for dynamic_cast. */
|
||||
template<typename Y>
|
||||
Ptr<Y> dynamicCast() const;
|
||||
|
||||
private:
|
||||
detail::PtrOwner* owner;
|
||||
T* stored;
|
||||
|
||||
template<typename Y>
|
||||
friend struct Ptr; // have to do this for the cross-type copy constructor
|
||||
};
|
||||
|
||||
/* Overload of the generic swap. */
|
||||
template<typename T>
|
||||
void swap(Ptr<T>& ptr1, Ptr<T>& ptr2);
|
||||
|
||||
/* Obvious comparisons. */
|
||||
template<typename T>
|
||||
bool operator == (const Ptr<T>& ptr1, const Ptr<T>& ptr2);
|
||||
template<typename T>
|
||||
bool operator != (const Ptr<T>& ptr1, const Ptr<T>& ptr2);
|
||||
|
||||
/* Convenience creation functions. In the far future, there may be variadic templates here. */
|
||||
template<typename T>
|
||||
Ptr<T> makePtr();
|
||||
template<typename T, typename A1>
|
||||
Ptr<T> makePtr(const A1& a1);
|
||||
template<typename T, typename A1, typename A2>
|
||||
Ptr<T> makePtr(const A1& a1, const A2& a2);
|
||||
template<typename T, typename A1, typename A2, typename A3>
|
||||
Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3);
|
||||
template<typename T, typename A1, typename A2, typename A3, typename A4>
|
||||
Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4);
|
||||
template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5>
|
||||
Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5);
|
||||
template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
|
||||
Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6);
|
||||
template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
|
||||
Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7);
|
||||
template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
|
||||
Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8);
|
||||
template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
|
||||
Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9);
|
||||
template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10>
|
||||
Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10);
|
||||
|
||||
|
||||
//////////////////////////////// string class ////////////////////////////////
|
||||
@@ -324,176 +431,6 @@ private:
|
||||
};
|
||||
|
||||
|
||||
|
||||
/////////////////////////// cv::Ptr implementation ///////////////////////////
|
||||
|
||||
template<typename _Tp> inline
|
||||
Ptr<_Tp>::Ptr()
|
||||
: obj(0), refcount(0) {}
|
||||
|
||||
template<typename _Tp> inline
|
||||
Ptr<_Tp>::Ptr(_Tp* _obj)
|
||||
: obj(_obj)
|
||||
{
|
||||
if(obj)
|
||||
{
|
||||
refcount = (int*)fastMalloc(sizeof(*refcount));
|
||||
*refcount = 1;
|
||||
}
|
||||
else
|
||||
refcount = 0;
|
||||
}
|
||||
|
||||
template<typename _Tp> template<typename _Tp2>
|
||||
Ptr<_Tp>::Ptr(const Ptr<_Tp2>& p)
|
||||
: obj(0), refcount(0)
|
||||
{
|
||||
if (p.empty())
|
||||
return;
|
||||
|
||||
_Tp* p_casted = dynamic_cast<_Tp*>(p.obj);
|
||||
if (!p_casted)
|
||||
return;
|
||||
|
||||
obj = p_casted;
|
||||
refcount = p.refcount;
|
||||
addref();
|
||||
}
|
||||
|
||||
template<typename _Tp> inline
|
||||
Ptr<_Tp>::~Ptr()
|
||||
{
|
||||
release();
|
||||
}
|
||||
|
||||
template<typename _Tp> inline
|
||||
void Ptr<_Tp>::addref()
|
||||
{
|
||||
if( refcount )
|
||||
CV_XADD(refcount, 1);
|
||||
}
|
||||
|
||||
template<typename _Tp> inline
|
||||
void Ptr<_Tp>::release()
|
||||
{
|
||||
if( refcount && CV_XADD(refcount, -1) == 1 )
|
||||
{
|
||||
delete_obj();
|
||||
fastFree(refcount);
|
||||
}
|
||||
refcount = 0;
|
||||
obj = 0;
|
||||
}
|
||||
|
||||
template<typename _Tp> inline
|
||||
void Ptr<_Tp>::delete_obj()
|
||||
{
|
||||
if( obj )
|
||||
delete obj;
|
||||
}
|
||||
|
||||
template<typename _Tp> inline
|
||||
Ptr<_Tp>::Ptr(const Ptr<_Tp>& _ptr)
|
||||
{
|
||||
obj = _ptr.obj;
|
||||
refcount = _ptr.refcount;
|
||||
addref();
|
||||
}
|
||||
|
||||
template<typename _Tp> inline
|
||||
Ptr<_Tp>& Ptr<_Tp>::operator = (const Ptr<_Tp>& _ptr)
|
||||
{
|
||||
int* _refcount = _ptr.refcount;
|
||||
if( _refcount )
|
||||
CV_XADD(_refcount, 1);
|
||||
release();
|
||||
obj = _ptr.obj;
|
||||
refcount = _refcount;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename _Tp> inline
|
||||
_Tp* Ptr<_Tp>::operator -> ()
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
|
||||
template<typename _Tp> inline
|
||||
const _Tp* Ptr<_Tp>::operator -> () const
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
|
||||
template<typename _Tp> inline
|
||||
Ptr<_Tp>::operator _Tp* ()
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
|
||||
template<typename _Tp> inline
|
||||
Ptr<_Tp>::operator const _Tp*() const
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
|
||||
template<typename _Tp> inline
|
||||
bool Ptr<_Tp>::empty() const
|
||||
{
|
||||
return obj == 0;
|
||||
}
|
||||
|
||||
template<typename _Tp> template<typename _Tp2> inline
|
||||
Ptr<_Tp2> Ptr<_Tp>::ptr()
|
||||
{
|
||||
Ptr<_Tp2> p;
|
||||
if( !obj )
|
||||
return p;
|
||||
|
||||
_Tp2* obj_casted = dynamic_cast<_Tp2*>(obj);
|
||||
if (!obj_casted)
|
||||
return p;
|
||||
|
||||
if( refcount )
|
||||
CV_XADD(refcount, 1);
|
||||
|
||||
p.obj = obj_casted;
|
||||
p.refcount = refcount;
|
||||
return p;
|
||||
}
|
||||
|
||||
template<typename _Tp> template<typename _Tp2> inline
|
||||
const Ptr<_Tp2> Ptr<_Tp>::ptr() const
|
||||
{
|
||||
Ptr<_Tp2> p;
|
||||
if( !obj )
|
||||
return p;
|
||||
|
||||
_Tp2* obj_casted = dynamic_cast<_Tp2*>(obj);
|
||||
if (!obj_casted)
|
||||
return p;
|
||||
|
||||
if( refcount )
|
||||
CV_XADD(refcount, 1);
|
||||
|
||||
p.obj = obj_casted;
|
||||
p.refcount = refcount;
|
||||
return p;
|
||||
}
|
||||
|
||||
template<class _Tp, class _Tp2> static inline
|
||||
bool operator == (const Ptr<_Tp>& a, const Ptr<_Tp2>& b)
|
||||
{
|
||||
return a.refcount == b.refcount;
|
||||
}
|
||||
|
||||
template<class _Tp, class _Tp2> static inline
|
||||
bool operator != (const Ptr<_Tp>& a, const Ptr<_Tp2>& b)
|
||||
{
|
||||
return a.refcount != b.refcount;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////// cv::String implementation /////////////////////////
|
||||
|
||||
inline
|
||||
@@ -940,4 +877,6 @@ namespace cv
|
||||
}
|
||||
}
|
||||
|
||||
#include "opencv2/core/ptr.inl.hpp"
|
||||
|
||||
#endif //__OPENCV_CORE_CVSTD_HPP__
|
||||
|
||||
@@ -283,12 +283,6 @@ CV_EXPORTS void setGlDevice(int device = 0);
|
||||
|
||||
}}
|
||||
|
||||
namespace cv {
|
||||
|
||||
template <> CV_EXPORTS void Ptr<cv::ogl::Buffer::Impl>::delete_obj();
|
||||
template <> CV_EXPORTS void Ptr<cv::ogl::Texture2D::Impl>::delete_obj();
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -445,14 +445,14 @@ int print(const Matx<_Tp, m, n>& matx, FILE* stream = stdout)
|
||||
template<typename _Tp> inline
|
||||
Ptr<_Tp> Algorithm::create(const String& name)
|
||||
{
|
||||
return _create(name).ptr<_Tp>();
|
||||
return _create(name).dynamicCast<_Tp>();
|
||||
}
|
||||
|
||||
template<typename _Tp> inline
|
||||
void Algorithm::set(const char* _name, const Ptr<_Tp>& value)
|
||||
{
|
||||
Ptr<Algorithm> algo_ptr = value. template ptr<cv::Algorithm>();
|
||||
if (algo_ptr.empty()) {
|
||||
Ptr<Algorithm> algo_ptr = value. template dynamicCast<cv::Algorithm>();
|
||||
if (!algo_ptr) {
|
||||
CV_Error( Error::StsUnsupportedFormat, "unknown/unsupported Ptr type of the second parameter of the method Algorithm::set");
|
||||
}
|
||||
info()->set(this, _name, ParamType<Algorithm>::type, &algo_ptr);
|
||||
@@ -468,7 +468,7 @@ template<typename _Tp> inline
|
||||
void Algorithm::setAlgorithm(const char* _name, const Ptr<_Tp>& value)
|
||||
{
|
||||
Ptr<Algorithm> algo_ptr = value. template ptr<cv::Algorithm>();
|
||||
if (algo_ptr.empty()) {
|
||||
if (!algo_ptr) {
|
||||
CV_Error( Error::StsUnsupportedFormat, "unknown/unsupported Ptr type of the second parameter of the method Algorithm::set");
|
||||
}
|
||||
info()->set(this, _name, ParamType<Algorithm>::type, &algo_ptr);
|
||||
|
||||
@@ -186,7 +186,7 @@ public:
|
||||
//! the full constructor that opens file storage for reading or writing
|
||||
CV_WRAP FileStorage(const String& source, int flags, const String& encoding=String());
|
||||
//! the constructor that takes pointer to the C FileStorage structure
|
||||
FileStorage(CvFileStorage* fs);
|
||||
FileStorage(CvFileStorage* fs, bool owning=true);
|
||||
//! the destructor. calls release()
|
||||
virtual ~FileStorage();
|
||||
|
||||
@@ -209,9 +209,9 @@ public:
|
||||
CV_WRAP FileNode operator[](const char* nodename) const;
|
||||
|
||||
//! returns pointer to the underlying C FileStorage structure
|
||||
CvFileStorage* operator *() { return fs; }
|
||||
CvFileStorage* operator *() { return fs.get(); }
|
||||
//! returns pointer to the underlying C FileStorage structure
|
||||
const CvFileStorage* operator *() const { return fs; }
|
||||
const CvFileStorage* operator *() const { return fs.get(); }
|
||||
//! writes one or more numbers of the specified format to the currently written structure
|
||||
void writeRaw( const String& fmt, const uchar* vec, size_t len );
|
||||
//! writes the registered C structure (CvMat, CvMatND, CvSeq). See cvWrite()
|
||||
@@ -226,7 +226,7 @@ public:
|
||||
int state; //!< the writer state
|
||||
};
|
||||
|
||||
template<> CV_EXPORTS void Ptr<CvFileStorage>::delete_obj();
|
||||
template<> CV_EXPORTS void DefaultDeleter<CvFileStorage>::operator ()(CvFileStorage* obj) const;
|
||||
|
||||
/*!
|
||||
File Storage Node class
|
||||
|
||||
@@ -128,12 +128,17 @@ namespace cv
|
||||
} //namespace cv
|
||||
|
||||
#define CV_INIT_ALGORITHM(classname, algname, memberinit) \
|
||||
static ::cv::Algorithm* create##classname##_hidden() \
|
||||
static inline ::cv::Algorithm* create##classname##_hidden() \
|
||||
{ \
|
||||
return new classname; \
|
||||
} \
|
||||
\
|
||||
static ::cv::AlgorithmInfo& classname##_info() \
|
||||
static inline ::cv::Ptr< ::cv::Algorithm> create##classname##_ptr_hidden() \
|
||||
{ \
|
||||
return ::cv::makePtr<classname>(); \
|
||||
} \
|
||||
\
|
||||
static inline ::cv::AlgorithmInfo& classname##_info() \
|
||||
{ \
|
||||
static ::cv::AlgorithmInfo classname##_info_var(algname, create##classname##_hidden); \
|
||||
return classname##_info_var; \
|
||||
|
||||
@@ -0,0 +1,338 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, NVIDIA Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the copyright holders or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __OPENCV_CORE_PTR_INL_HPP__
|
||||
#define __OPENCV_CORE_PTR_INL_HPP__
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace cv {
|
||||
|
||||
template<typename Y>
|
||||
void DefaultDeleter<Y>::operator () (Y* p) const
|
||||
{
|
||||
delete p;
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
struct PtrOwner
|
||||
{
|
||||
PtrOwner() : refCount(1)
|
||||
{}
|
||||
|
||||
void incRef()
|
||||
{
|
||||
CV_XADD(&refCount, 1);
|
||||
}
|
||||
|
||||
void decRef()
|
||||
{
|
||||
if (CV_XADD(&refCount, -1) == 1) deleteSelf();
|
||||
}
|
||||
|
||||
protected:
|
||||
/* This doesn't really need to be virtual, since PtrOwner is never deleted
|
||||
directly, but it doesn't hurt and it helps avoid warnings. */
|
||||
virtual ~PtrOwner()
|
||||
{}
|
||||
|
||||
virtual void deleteSelf() = 0;
|
||||
|
||||
private:
|
||||
unsigned int refCount;
|
||||
|
||||
// noncopyable
|
||||
PtrOwner(const PtrOwner&);
|
||||
PtrOwner& operator = (const PtrOwner&);
|
||||
};
|
||||
|
||||
template<typename Y, typename D>
|
||||
struct PtrOwnerImpl : PtrOwner
|
||||
{
|
||||
PtrOwnerImpl(Y* p, D d) : owned(p), deleter(d)
|
||||
{}
|
||||
|
||||
void deleteSelf()
|
||||
{
|
||||
deleter(owned);
|
||||
delete this;
|
||||
}
|
||||
|
||||
private:
|
||||
Y* owned;
|
||||
D deleter;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Ptr<T>::Ptr() : owner(NULL), stored(NULL)
|
||||
{}
|
||||
|
||||
template<typename T>
|
||||
template<typename Y>
|
||||
Ptr<T>::Ptr(Y* p)
|
||||
: owner(p
|
||||
? new detail::PtrOwnerImpl<Y, DefaultDeleter<Y> >(p, DefaultDeleter<Y>())
|
||||
: NULL),
|
||||
stored(p)
|
||||
{}
|
||||
|
||||
template<typename T>
|
||||
template<typename Y, typename D>
|
||||
Ptr<T>::Ptr(Y* p, D d)
|
||||
: owner(p
|
||||
? new detail::PtrOwnerImpl<Y, D>(p, d)
|
||||
: NULL),
|
||||
stored(p)
|
||||
{}
|
||||
|
||||
template<typename T>
|
||||
Ptr<T>::Ptr(const Ptr& o) : owner(o.owner), stored(o.stored)
|
||||
{
|
||||
if (owner) owner->incRef();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename Y>
|
||||
Ptr<T>::Ptr(const Ptr<Y>& o) : owner(o.owner), stored(o.stored)
|
||||
{
|
||||
if (owner) owner->incRef();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename Y>
|
||||
Ptr<T>::Ptr(const Ptr<Y>& o, T* p) : owner(o.owner), stored(p)
|
||||
{
|
||||
if (owner) owner->incRef();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Ptr<T>::~Ptr()
|
||||
{
|
||||
release();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Ptr<T>& Ptr<T>::operator = (const Ptr<T>& o)
|
||||
{
|
||||
Ptr(o).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename Y>
|
||||
Ptr<T>& Ptr<T>::operator = (const Ptr<Y>& o)
|
||||
{
|
||||
Ptr(o).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Ptr<T>::release()
|
||||
{
|
||||
if (owner) owner->decRef();
|
||||
owner = NULL;
|
||||
stored = NULL;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename Y>
|
||||
void Ptr<T>::reset(Y* p)
|
||||
{
|
||||
Ptr(p).swap(*this);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename Y, typename D>
|
||||
void Ptr<T>::reset(Y* p, D d)
|
||||
{
|
||||
Ptr(p, d).swap(*this);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Ptr<T>::swap(Ptr<T>& o)
|
||||
{
|
||||
std::swap(owner, o.owner);
|
||||
std::swap(stored, o.stored);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T* Ptr<T>::get() const
|
||||
{
|
||||
return stored;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename detail::RefOrVoid<T>::type Ptr<T>::operator * () const
|
||||
{
|
||||
return *stored;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T* Ptr<T>::operator -> () const
|
||||
{
|
||||
return stored;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Ptr<T>::operator T* () const
|
||||
{
|
||||
return stored;
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
bool Ptr<T>::empty() const
|
||||
{
|
||||
return !stored;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename Y>
|
||||
Ptr<Y> Ptr<T>::staticCast() const
|
||||
{
|
||||
return Ptr<Y>(*this, static_cast<Y*>(stored));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename Y>
|
||||
Ptr<Y> Ptr<T>::constCast() const
|
||||
{
|
||||
return Ptr<Y>(*this, const_cast<Y*>(stored));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename Y>
|
||||
Ptr<Y> Ptr<T>::dynamicCast() const
|
||||
{
|
||||
return Ptr<Y>(*this, dynamic_cast<Y*>(stored));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void swap(Ptr<T>& ptr1, Ptr<T>& ptr2){
|
||||
ptr1.swap(ptr2);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool operator == (const Ptr<T>& ptr1, const Ptr<T>& ptr2)
|
||||
{
|
||||
return ptr1.get() == ptr2.get();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool operator != (const Ptr<T>& ptr1, const Ptr<T>& ptr2)
|
||||
{
|
||||
return ptr1.get() != ptr2.get();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Ptr<T> makePtr()
|
||||
{
|
||||
return Ptr<T>(new T());
|
||||
}
|
||||
|
||||
template<typename T, typename A1>
|
||||
Ptr<T> makePtr(const A1& a1)
|
||||
{
|
||||
return Ptr<T>(new T(a1));
|
||||
}
|
||||
|
||||
template<typename T, typename A1, typename A2>
|
||||
Ptr<T> makePtr(const A1& a1, const A2& a2)
|
||||
{
|
||||
return Ptr<T>(new T(a1, a2));
|
||||
}
|
||||
|
||||
template<typename T, typename A1, typename A2, typename A3>
|
||||
Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3)
|
||||
{
|
||||
return Ptr<T>(new T(a1, a2, a3));
|
||||
}
|
||||
|
||||
template<typename T, typename A1, typename A2, typename A3, typename A4>
|
||||
Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4)
|
||||
{
|
||||
return Ptr<T>(new T(a1, a2, a3, a4));
|
||||
}
|
||||
|
||||
template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5>
|
||||
Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5)
|
||||
{
|
||||
return Ptr<T>(new T(a1, a2, a3, a4, a5));
|
||||
}
|
||||
|
||||
template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
|
||||
Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6)
|
||||
{
|
||||
return Ptr<T>(new T(a1, a2, a3, a4, a5, a6));
|
||||
}
|
||||
|
||||
template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
|
||||
Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7)
|
||||
{
|
||||
return Ptr<T>(new T(a1, a2, a3, a4, a5, a6, a7));
|
||||
}
|
||||
|
||||
template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
|
||||
Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8)
|
||||
{
|
||||
return Ptr<T>(new T(a1, a2, a3, a4, a5, a6, a7, a8));
|
||||
}
|
||||
|
||||
template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
|
||||
Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9)
|
||||
{
|
||||
return Ptr<T>(new T(a1, a2, a3, a4, a5, a6, a7, a8, a9));
|
||||
}
|
||||
|
||||
template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10>
|
||||
Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10)
|
||||
{
|
||||
return Ptr<T>(new T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10));
|
||||
}
|
||||
|
||||
} // namespace cv
|
||||
|
||||
#endif // __OPENCV_CORE_PTR_INL_HPP__
|
||||
@@ -551,18 +551,18 @@ public:
|
||||
size_t hash() const;
|
||||
|
||||
//! converts vector of keypoints to vector of points
|
||||
static void convert(const std::vector<KeyPoint>& keypoints,
|
||||
CV_OUT std::vector<Point2f>& points2f,
|
||||
const std::vector<int>& keypointIndexes=std::vector<int>());
|
||||
CV_WRAP static void convert(const std::vector<KeyPoint>& keypoints,
|
||||
CV_OUT std::vector<Point2f>& points2f,
|
||||
const std::vector<int>& keypointIndexes=std::vector<int>());
|
||||
//! converts vector of points to the vector of keypoints, where each keypoint is assigned the same size and the same orientation
|
||||
static void convert(const std::vector<Point2f>& points2f,
|
||||
CV_OUT std::vector<KeyPoint>& keypoints,
|
||||
float size=1, float response=1, int octave=0, int class_id=-1);
|
||||
CV_WRAP static void convert(const std::vector<Point2f>& points2f,
|
||||
CV_OUT std::vector<KeyPoint>& keypoints,
|
||||
float size=1, float response=1, int octave=0, int class_id=-1);
|
||||
|
||||
//! computes overlap for pair of keypoints;
|
||||
//! overlap is a ratio between area of keypoint regions intersection and
|
||||
//! area of keypoint regions union (now keypoint region is circle)
|
||||
static float overlap(const KeyPoint& kp1, const KeyPoint& kp2);
|
||||
CV_WRAP static float overlap(const KeyPoint& kp1, const KeyPoint& kp2);
|
||||
|
||||
CV_PROP_RW Point2f pt; //!< coordinates of the keypoints
|
||||
CV_PROP_RW float size; //!< diameter of the meaningful keypoint neighborhood
|
||||
|
||||
@@ -163,7 +163,7 @@ Ptr<Algorithm> Algorithm::_create(const String& name)
|
||||
Algorithm::Constructor c = 0;
|
||||
if( !alglist().find(name, c) )
|
||||
return Ptr<Algorithm>();
|
||||
return c();
|
||||
return Ptr<Algorithm>(c());
|
||||
}
|
||||
|
||||
Algorithm::Algorithm()
|
||||
@@ -490,7 +490,7 @@ void AlgorithmInfo::read(Algorithm* algo, const FileNode& fn) const
|
||||
else if( p.type == Param::ALGORITHM )
|
||||
{
|
||||
Ptr<Algorithm> nestedAlgo = Algorithm::_create((String)n["name"]);
|
||||
CV_Assert( !nestedAlgo.empty() );
|
||||
CV_Assert( nestedAlgo );
|
||||
nestedAlgo->read(n);
|
||||
info->set(algo, pname.c_str(), p.type, &nestedAlgo, true);
|
||||
}
|
||||
|
||||
@@ -3190,22 +3190,22 @@ cvCheckTermCriteria( CvTermCriteria criteria, double default_eps,
|
||||
namespace cv
|
||||
{
|
||||
|
||||
template<> void Ptr<CvMat>::delete_obj()
|
||||
template<> void DefaultDeleter<CvMat>::operator ()(CvMat* obj) const
|
||||
{ cvReleaseMat(&obj); }
|
||||
|
||||
template<> void Ptr<IplImage>::delete_obj()
|
||||
template<> void DefaultDeleter<IplImage>::operator ()(IplImage* obj) const
|
||||
{ cvReleaseImage(&obj); }
|
||||
|
||||
template<> void Ptr<CvMatND>::delete_obj()
|
||||
template<> void DefaultDeleter<CvMatND>::operator ()(CvMatND* obj) const
|
||||
{ cvReleaseMatND(&obj); }
|
||||
|
||||
template<> void Ptr<CvSparseMat>::delete_obj()
|
||||
template<> void DefaultDeleter<CvSparseMat>::operator ()(CvSparseMat* obj) const
|
||||
{ cvReleaseSparseMat(&obj); }
|
||||
|
||||
template<> void Ptr<CvMemStorage>::delete_obj()
|
||||
template<> void DefaultDeleter<CvMemStorage>::operator ()(CvMemStorage* obj) const
|
||||
{ cvReleaseMemStorage(&obj); }
|
||||
|
||||
template<> void Ptr<CvFileStorage>::delete_obj()
|
||||
template<> void DefaultDeleter<CvFileStorage>::operator ()(CvFileStorage* obj) const
|
||||
{ cvReleaseFileStorage(&obj); }
|
||||
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ cv::cuda::Stream::Stream()
|
||||
#ifndef HAVE_CUDA
|
||||
throw_no_cuda();
|
||||
#else
|
||||
impl_ = new Impl;
|
||||
impl_ = makePtr<Impl>();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -182,7 +182,7 @@ void cv::cuda::Stream::enqueueHostCallback(StreamCallback callback, void* userDa
|
||||
|
||||
Stream& cv::cuda::Stream::Null()
|
||||
{
|
||||
static Stream s(new Impl(0));
|
||||
static Stream s(Ptr<Impl>(new Impl(0)));
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -195,10 +195,6 @@ cv::cuda::Stream::operator bool_type() const
|
||||
#endif
|
||||
}
|
||||
|
||||
template <> void cv::Ptr<Stream::Impl>::delete_obj()
|
||||
{
|
||||
if (obj) delete obj;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Stream
|
||||
@@ -249,7 +245,7 @@ cv::cuda::Event::Event(CreateFlags flags)
|
||||
(void) flags;
|
||||
throw_no_cuda();
|
||||
#else
|
||||
impl_ = new Impl(flags);
|
||||
impl_ = makePtr<Impl>(flags);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -301,8 +297,3 @@ float cv::cuda::Event::elapsedTime(const Event& start, const Event& end)
|
||||
return ms;
|
||||
#endif
|
||||
}
|
||||
|
||||
template <> void cv::Ptr<Event::Impl>::delete_obj()
|
||||
{
|
||||
if (obj) delete obj;
|
||||
}
|
||||
|
||||
@@ -836,10 +836,6 @@ unsigned int cv::ogl::Buffer::bufId() const
|
||||
#endif
|
||||
}
|
||||
|
||||
template <> void cv::Ptr<cv::ogl::Buffer::Impl>::delete_obj()
|
||||
{
|
||||
if (obj) delete obj;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// ogl::Texture
|
||||
@@ -1243,10 +1239,6 @@ unsigned int cv::ogl::Texture2D::texId() const
|
||||
#endif
|
||||
}
|
||||
|
||||
template <> void cv::Ptr<cv::ogl::Texture2D::Impl>::delete_obj()
|
||||
{
|
||||
if (obj) delete obj;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// ogl::Arrays
|
||||
|
||||
+13
-11
@@ -256,7 +256,7 @@ namespace
|
||||
cv::Ptr<cv::Formatted> format(const cv::Mat& mtx) const
|
||||
{
|
||||
char braces[5] = {'\0', '\0', ';', '\0', '\0'};
|
||||
return new FormattedImpl("[", "]", mtx, braces,
|
||||
return cv::makePtr<FormattedImpl>("[", "]", mtx, &*braces,
|
||||
mtx.cols == 1 || !multiline, mtx.depth() == CV_64F ? prec64f : prec32f );
|
||||
}
|
||||
};
|
||||
@@ -270,7 +270,7 @@ namespace
|
||||
char braces[5] = {'[', ']', '\0', '[', ']'};
|
||||
if (mtx.cols == 1)
|
||||
braces[0] = braces[1] = '\0';
|
||||
return new FormattedImpl("[", "]", mtx, braces,
|
||||
return cv::makePtr<FormattedImpl>("[", "]", mtx, &*braces,
|
||||
mtx.cols*mtx.channels() == 1 || !multiline, mtx.depth() == CV_64F ? prec64f : prec32f );
|
||||
}
|
||||
};
|
||||
@@ -288,7 +288,8 @@ namespace
|
||||
char braces[5] = {'[', ']', '\0', '[', ']'};
|
||||
if (mtx.cols == 1)
|
||||
braces[0] = braces[1] = '\0';
|
||||
return new FormattedImpl("array([", cv::format("], type='%s')", numpyTypes[mtx.depth()]), mtx, braces,
|
||||
return cv::makePtr<FormattedImpl>("array([",
|
||||
cv::format("], type='%s')", numpyTypes[mtx.depth()]), mtx, &*braces,
|
||||
mtx.cols*mtx.channels() == 1 || !multiline, mtx.depth() == CV_64F ? prec64f : prec32f );
|
||||
}
|
||||
};
|
||||
@@ -300,7 +301,8 @@ namespace
|
||||
cv::Ptr<cv::Formatted> format(const cv::Mat& mtx) const
|
||||
{
|
||||
char braces[5] = {'\0', '\0', '\0', '\0', '\0'};
|
||||
return new FormattedImpl(cv::String(), mtx.rows > 1 ? cv::String("\n") : cv::String(), mtx, braces,
|
||||
return cv::makePtr<FormattedImpl>(cv::String(),
|
||||
mtx.rows > 1 ? cv::String("\n") : cv::String(), mtx, &*braces,
|
||||
mtx.cols*mtx.channels() == 1 || !multiline, mtx.depth() == CV_64F ? prec64f : prec32f );
|
||||
}
|
||||
};
|
||||
@@ -312,7 +314,7 @@ namespace
|
||||
cv::Ptr<cv::Formatted> format(const cv::Mat& mtx) const
|
||||
{
|
||||
char braces[5] = {'\0', '\0', ',', '\0', '\0'};
|
||||
return new FormattedImpl("{", "}", mtx, braces,
|
||||
return cv::makePtr<FormattedImpl>("{", "}", mtx, &*braces,
|
||||
mtx.cols == 1 || !multiline, mtx.depth() == CV_64F ? prec64f : prec32f );
|
||||
}
|
||||
};
|
||||
@@ -330,16 +332,16 @@ namespace cv
|
||||
switch(fmt)
|
||||
{
|
||||
case FMT_MATLAB:
|
||||
return new MatlabFormatter();
|
||||
return makePtr<MatlabFormatter>();
|
||||
case FMT_CSV:
|
||||
return new CSVFormatter();
|
||||
return makePtr<CSVFormatter>();
|
||||
case FMT_PYTHON:
|
||||
return new PythonFormatter();
|
||||
return makePtr<PythonFormatter>();
|
||||
case FMT_NUMPY:
|
||||
return new NumpyFormatter();
|
||||
return makePtr<NumpyFormatter>();
|
||||
case FMT_C:
|
||||
return new CFormatter();
|
||||
return makePtr<CFormatter>();
|
||||
}
|
||||
return new MatlabFormatter();
|
||||
return makePtr<MatlabFormatter>();
|
||||
}
|
||||
} // cv
|
||||
|
||||
@@ -5129,9 +5129,11 @@ FileStorage::FileStorage(const String& filename, int flags, const String& encodi
|
||||
open( filename, flags, encoding );
|
||||
}
|
||||
|
||||
FileStorage::FileStorage(CvFileStorage* _fs)
|
||||
FileStorage::FileStorage(CvFileStorage* _fs, bool owning)
|
||||
{
|
||||
fs = Ptr<CvFileStorage>(_fs);
|
||||
if (owning) fs.reset(_fs);
|
||||
else fs = Ptr<CvFileStorage>(Ptr<CvFileStorage>(), _fs);
|
||||
|
||||
state = _fs ? NAME_EXPECTED + INSIDE_MAP : UNDEFINED;
|
||||
}
|
||||
|
||||
@@ -5147,8 +5149,8 @@ FileStorage::~FileStorage()
|
||||
bool FileStorage::open(const String& filename, int flags, const String& encoding)
|
||||
{
|
||||
release();
|
||||
fs = Ptr<CvFileStorage>(cvOpenFileStorage( filename.c_str(), 0, flags,
|
||||
!encoding.empty() ? encoding.c_str() : 0));
|
||||
fs.reset(cvOpenFileStorage( filename.c_str(), 0, flags,
|
||||
!encoding.empty() ? encoding.c_str() : 0));
|
||||
bool ok = isOpened();
|
||||
state = ok ? NAME_EXPECTED + INSIDE_MAP : UNDEFINED;
|
||||
return ok;
|
||||
@@ -5156,7 +5158,7 @@ bool FileStorage::open(const String& filename, int flags, const String& encoding
|
||||
|
||||
bool FileStorage::isOpened() const
|
||||
{
|
||||
return !fs.empty() && fs.obj->is_opened;
|
||||
return fs && fs->is_opened;
|
||||
}
|
||||
|
||||
void FileStorage::release()
|
||||
@@ -5169,8 +5171,8 @@ void FileStorage::release()
|
||||
String FileStorage::releaseAndGetString()
|
||||
{
|
||||
String buf;
|
||||
if( fs.obj && fs.obj->outbuf )
|
||||
icvClose(fs.obj, &buf);
|
||||
if( fs && fs->outbuf )
|
||||
icvClose(fs, &buf);
|
||||
|
||||
release();
|
||||
return buf;
|
||||
@@ -5479,7 +5481,7 @@ void write( FileStorage& fs, const String& name, const Mat& value )
|
||||
// TODO: the 4 functions below need to be implemented more efficiently
|
||||
void write( FileStorage& fs, const String& name, const SparseMat& value )
|
||||
{
|
||||
Ptr<CvSparseMat> mat = cvCreateSparseMat(value);
|
||||
Ptr<CvSparseMat> mat(cvCreateSparseMat(value));
|
||||
cvWrite( *fs, name.size() ? name.c_str() : 0, mat );
|
||||
}
|
||||
|
||||
@@ -5529,8 +5531,8 @@ void read( const FileNode& node, SparseMat& mat, const SparseMat& default_mat )
|
||||
default_mat.copyTo(mat);
|
||||
return;
|
||||
}
|
||||
Ptr<CvSparseMat> m = (CvSparseMat*)cvRead((CvFileStorage*)node.fs, (CvFileNode*)*node);
|
||||
CV_Assert(CV_IS_SPARSE_MAT(m.obj));
|
||||
Ptr<CvSparseMat> m((CvSparseMat*)cvRead((CvFileStorage*)node.fs, (CvFileNode*)*node));
|
||||
CV_Assert(CV_IS_SPARSE_MAT(m));
|
||||
m->copyToSparseMat(mat);
|
||||
}
|
||||
|
||||
|
||||
@@ -358,8 +358,6 @@ Core_DynStructBaseTest::Core_DynStructBaseTest()
|
||||
iterations = max_struct_size*2;
|
||||
gen = struct_idx = iter = -1;
|
||||
test_progress = -1;
|
||||
|
||||
storage = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -999,7 +997,7 @@ void Core_SeqBaseTest::run( int )
|
||||
{
|
||||
t = cvtest::randReal(rng)*(max_log_storage_block_size - min_log_storage_block_size)
|
||||
+ min_log_storage_block_size;
|
||||
storage = cvCreateMemStorage( cvRound( exp(t * CV_LOG2) ) );
|
||||
storage.reset(cvCreateMemStorage( cvRound( exp(t * CV_LOG2) ) ));
|
||||
}
|
||||
|
||||
iter = struct_idx = -1;
|
||||
@@ -1083,11 +1081,11 @@ void Core_SeqSortInvTest::run( int )
|
||||
{
|
||||
struct_idx = iter = -1;
|
||||
|
||||
if( storage.empty() )
|
||||
if( !storage )
|
||||
{
|
||||
t = cvtest::randReal(rng)*(max_log_storage_block_size - min_log_storage_block_size)
|
||||
+ min_log_storage_block_size;
|
||||
storage = cvCreateMemStorage( cvRound( exp(t * CV_LOG2) ) );
|
||||
storage.reset(cvCreateMemStorage( cvRound( exp(t * CV_LOG2) ) ));
|
||||
}
|
||||
|
||||
for( iter = 0; iter < iterations/10; iter++ )
|
||||
@@ -1384,7 +1382,7 @@ void Core_SetTest::run( int )
|
||||
{
|
||||
struct_idx = iter = -1;
|
||||
t = cvtest::randReal(rng)*(max_log_storage_block_size - min_log_storage_block_size) + min_log_storage_block_size;
|
||||
storage = cvCreateMemStorage( cvRound( exp(t * CV_LOG2) ) );
|
||||
storage.reset(cvCreateMemStorage( cvRound( exp(t * CV_LOG2) ) ));
|
||||
|
||||
for( int i = 0; i < struct_count; i++ )
|
||||
{
|
||||
@@ -1398,7 +1396,7 @@ void Core_SetTest::run( int )
|
||||
|
||||
cvTsReleaseSimpleSet( (CvTsSimpleSet**)&simple_struct[i] );
|
||||
simple_struct[i] = cvTsCreateSimpleSet( max_struct_size, pure_elem_size );
|
||||
cxcore_struct[i] = cvCreateSet( 0, sizeof(CvSet), elem_size, storage );
|
||||
cxcore_struct[i] = cvCreateSet( 0, sizeof(CvSet), elem_size, storage );
|
||||
}
|
||||
|
||||
if( test_set_ops( iterations*100 ) < 0 )
|
||||
@@ -1811,7 +1809,7 @@ void Core_GraphTest::run( int )
|
||||
int block_size = cvRound( exp(t * CV_LOG2) );
|
||||
block_size = MAX(block_size, (int)(sizeof(CvGraph) + sizeof(CvMemBlock) + sizeof(CvSeqBlock)));
|
||||
|
||||
storage = cvCreateMemStorage(block_size);
|
||||
storage.reset(cvCreateMemStorage(block_size));
|
||||
|
||||
for( i = 0; i < struct_count; i++ )
|
||||
{
|
||||
@@ -1929,7 +1927,7 @@ void Core_GraphScanTest::run( int )
|
||||
storage_blocksize = MAX(storage_blocksize, (int)(sizeof(CvGraph) + sizeof(CvMemBlock) + sizeof(CvSeqBlock)));
|
||||
storage_blocksize = MAX(storage_blocksize, (int)(sizeof(CvGraphEdge) + sizeof(CvMemBlock) + sizeof(CvSeqBlock)));
|
||||
storage_blocksize = MAX(storage_blocksize, (int)(sizeof(CvGraphVtx) + sizeof(CvMemBlock) + sizeof(CvSeqBlock)));
|
||||
storage = cvCreateMemStorage(storage_blocksize);
|
||||
storage.reset(cvCreateMemStorage(storage_blocksize));
|
||||
|
||||
if( gen == 0 )
|
||||
{
|
||||
|
||||
@@ -270,16 +270,16 @@ protected:
|
||||
|
||||
cvRelease((void**)&m_nd);
|
||||
|
||||
Ptr<CvSparseMat> m_s = (CvSparseMat*)fs["test_sparse_mat"].readObj();
|
||||
Ptr<CvSparseMat> _test_sparse_ = cvCreateSparseMat(test_sparse_mat);
|
||||
Ptr<CvSparseMat> _test_sparse = (CvSparseMat*)cvClone(_test_sparse_);
|
||||
Ptr<CvSparseMat> m_s((CvSparseMat*)fs["test_sparse_mat"].readObj());
|
||||
Ptr<CvSparseMat> _test_sparse_(cvCreateSparseMat(test_sparse_mat));
|
||||
Ptr<CvSparseMat> _test_sparse((CvSparseMat*)cvClone(_test_sparse_));
|
||||
SparseMat m_s2;
|
||||
fs["test_sparse_mat"] >> m_s2;
|
||||
Ptr<CvSparseMat> _m_s2 = cvCreateSparseMat(m_s2);
|
||||
Ptr<CvSparseMat> _m_s2(cvCreateSparseMat(m_s2));
|
||||
|
||||
if( !m_s || !CV_IS_SPARSE_MAT(m_s) ||
|
||||
!cvTsCheckSparse(m_s, _test_sparse,0) ||
|
||||
!cvTsCheckSparse(_m_s2, _test_sparse,0))
|
||||
!cvTsCheckSparse(m_s, _test_sparse, 0) ||
|
||||
!cvTsCheckSparse(_m_s2, _test_sparse, 0))
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "the read sparse matrix is not correct\n" );
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
|
||||
|
||||
@@ -669,7 +669,7 @@ void Core_ArrayOpTest::run( int /* start_from */)
|
||||
cvSetReal3D(&matA, idx1[0], idx1[1], idx1[2], -val0);
|
||||
cvSetND(&matB, idx0, val1);
|
||||
cvSet3D(&matB, idx1[0], idx1[1], idx1[2], -val1);
|
||||
Ptr<CvMatND> matC = cvCloneMatND(&matB);
|
||||
Ptr<CvMatND> matC(cvCloneMatND(&matB));
|
||||
|
||||
if( A.at<float>(idx0[0], idx0[1], idx0[2]) != val0 ||
|
||||
A.at<float>(idx1[0], idx1[1], idx1[2]) != -val0 ||
|
||||
@@ -762,7 +762,7 @@ void Core_ArrayOpTest::run( int /* start_from */)
|
||||
}
|
||||
}
|
||||
|
||||
Ptr<CvSparseMat> M2 = cvCreateSparseMat(M);
|
||||
Ptr<CvSparseMat> M2(cvCreateSparseMat(M));
|
||||
MatND Md;
|
||||
M.copyTo(Md);
|
||||
SparseMat M3; SparseMat(Md).convertTo(M3, Md.type(), 2);
|
||||
|
||||
@@ -0,0 +1,389 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, NVIDIA Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the copyright holders or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
using namespace cv;
|
||||
|
||||
namespace {
|
||||
|
||||
struct Reporter {
|
||||
Reporter(bool* deleted) : deleted_(deleted)
|
||||
{ *deleted_ = false; }
|
||||
|
||||
// the destructor is virtual, so that we can test dynamic_cast later
|
||||
virtual ~Reporter()
|
||||
{ *deleted_ = true; }
|
||||
|
||||
private:
|
||||
bool* deleted_;
|
||||
|
||||
Reporter(const Reporter&);
|
||||
Reporter& operator = (const Reporter&);
|
||||
};
|
||||
|
||||
struct ReportingDeleter {
|
||||
ReportingDeleter(bool* deleted) : deleted_(deleted)
|
||||
{ *deleted_ = false; }
|
||||
|
||||
void operator()(void*)
|
||||
{ *deleted_ = true; }
|
||||
|
||||
private:
|
||||
bool* deleted_;
|
||||
};
|
||||
|
||||
int dummyObject;
|
||||
|
||||
}
|
||||
|
||||
TEST(Core_Ptr, default_ctor)
|
||||
{
|
||||
Ptr<int> p;
|
||||
EXPECT_EQ(NULL, p.get());
|
||||
}
|
||||
|
||||
TEST(Core_Ptr, owning_ctor)
|
||||
{
|
||||
bool deleted = false;
|
||||
|
||||
{
|
||||
Reporter* r = new Reporter(&deleted);
|
||||
Ptr<void> p(r);
|
||||
EXPECT_EQ(r, p.get());
|
||||
}
|
||||
|
||||
EXPECT_TRUE(deleted);
|
||||
|
||||
{
|
||||
Ptr<int> p(&dummyObject, ReportingDeleter(&deleted));
|
||||
EXPECT_EQ(&dummyObject, p.get());
|
||||
}
|
||||
|
||||
EXPECT_TRUE(deleted);
|
||||
|
||||
{
|
||||
Ptr<void> p((void*)0, ReportingDeleter(&deleted));
|
||||
EXPECT_EQ(NULL, p.get());
|
||||
}
|
||||
|
||||
EXPECT_FALSE(deleted);
|
||||
}
|
||||
|
||||
TEST(Core_Ptr, sharing_ctor)
|
||||
{
|
||||
bool deleted = false;
|
||||
|
||||
{
|
||||
Ptr<Reporter> p1(new Reporter(&deleted));
|
||||
Ptr<Reporter> p2(p1);
|
||||
EXPECT_EQ(p1.get(), p2.get());
|
||||
p1.release();
|
||||
EXPECT_FALSE(deleted);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(deleted);
|
||||
|
||||
{
|
||||
Ptr<Reporter> p1(new Reporter(&deleted));
|
||||
Ptr<void> p2(p1);
|
||||
EXPECT_EQ(p1.get(), p2.get());
|
||||
p1.release();
|
||||
EXPECT_FALSE(deleted);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(deleted);
|
||||
|
||||
{
|
||||
Ptr<Reporter> p1(new Reporter(&deleted));
|
||||
Ptr<int> p2(p1, &dummyObject);
|
||||
EXPECT_EQ(&dummyObject, p2.get());
|
||||
p1.release();
|
||||
EXPECT_FALSE(deleted);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(deleted);
|
||||
}
|
||||
|
||||
TEST(Core_Ptr, assignment)
|
||||
{
|
||||
bool deleted1 = false, deleted2 = false;
|
||||
|
||||
{
|
||||
Ptr<Reporter> p1(new Reporter(&deleted1));
|
||||
p1 = p1;
|
||||
EXPECT_FALSE(deleted1);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(deleted1);
|
||||
|
||||
{
|
||||
Ptr<Reporter> p1(new Reporter(&deleted1));
|
||||
Ptr<Reporter> p2(new Reporter(&deleted2));
|
||||
p2 = p1;
|
||||
EXPECT_TRUE(deleted2);
|
||||
EXPECT_EQ(p1.get(), p2.get());
|
||||
p1.release();
|
||||
EXPECT_FALSE(deleted1);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(deleted1);
|
||||
|
||||
{
|
||||
Ptr<Reporter> p1(new Reporter(&deleted1));
|
||||
Ptr<void> p2(new Reporter(&deleted2));
|
||||
p2 = p1;
|
||||
EXPECT_TRUE(deleted2);
|
||||
EXPECT_EQ(p1.get(), p2.get());
|
||||
p1.release();
|
||||
EXPECT_FALSE(deleted1);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(deleted1);
|
||||
}
|
||||
|
||||
TEST(Core_Ptr, release)
|
||||
{
|
||||
bool deleted = false;
|
||||
|
||||
Ptr<Reporter> p1(new Reporter(&deleted));
|
||||
p1.release();
|
||||
EXPECT_TRUE(deleted);
|
||||
EXPECT_EQ(NULL, p1.get());
|
||||
}
|
||||
|
||||
TEST(Core_Ptr, reset)
|
||||
{
|
||||
bool deleted_old = false, deleted_new = false;
|
||||
|
||||
{
|
||||
Ptr<void> p(new Reporter(&deleted_old));
|
||||
Reporter* r = new Reporter(&deleted_new);
|
||||
p.reset(r);
|
||||
EXPECT_TRUE(deleted_old);
|
||||
EXPECT_EQ(r, p.get());
|
||||
}
|
||||
|
||||
EXPECT_TRUE(deleted_new);
|
||||
|
||||
{
|
||||
Ptr<void> p(new Reporter(&deleted_old));
|
||||
p.reset(&dummyObject, ReportingDeleter(&deleted_new));
|
||||
EXPECT_TRUE(deleted_old);
|
||||
EXPECT_EQ(&dummyObject, p.get());
|
||||
}
|
||||
|
||||
EXPECT_TRUE(deleted_new);
|
||||
}
|
||||
|
||||
TEST(Core_Ptr, swap)
|
||||
{
|
||||
bool deleted1 = false, deleted2 = false;
|
||||
|
||||
{
|
||||
Reporter* r1 = new Reporter(&deleted1);
|
||||
Reporter* r2 = new Reporter(&deleted2);
|
||||
Ptr<Reporter> p1(r1), p2(r2);
|
||||
p1.swap(p2);
|
||||
EXPECT_EQ(r1, p2.get());
|
||||
EXPECT_EQ(r2, p1.get());
|
||||
EXPECT_FALSE(deleted1);
|
||||
EXPECT_FALSE(deleted2);
|
||||
p1.release();
|
||||
EXPECT_TRUE(deleted2);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(deleted1);
|
||||
|
||||
{
|
||||
Reporter* r1 = new Reporter(&deleted1);
|
||||
Reporter* r2 = new Reporter(&deleted2);
|
||||
Ptr<Reporter> p1(r1), p2(r2);
|
||||
swap(p1, p2);
|
||||
EXPECT_EQ(r1, p2.get());
|
||||
EXPECT_EQ(r2, p1.get());
|
||||
EXPECT_FALSE(deleted1);
|
||||
EXPECT_FALSE(deleted2);
|
||||
p1.release();
|
||||
EXPECT_TRUE(deleted2);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(deleted1);
|
||||
}
|
||||
|
||||
TEST(Core_Ptr, accessors)
|
||||
{
|
||||
{
|
||||
Ptr<int> p;
|
||||
EXPECT_EQ(NULL, static_cast<int*>(p));
|
||||
EXPECT_TRUE(p.empty());
|
||||
}
|
||||
|
||||
{
|
||||
Size* s = new Size();
|
||||
Ptr<Size> p(s);
|
||||
EXPECT_EQ(s, static_cast<Size*>(p));
|
||||
EXPECT_EQ(s, &*p);
|
||||
EXPECT_EQ(&s->width, &p->width);
|
||||
EXPECT_FALSE(p.empty());
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
struct SubReporterBase {
|
||||
virtual ~SubReporterBase() {}
|
||||
int padding;
|
||||
};
|
||||
|
||||
/* multiple inheritance, so that casts do something interesting */
|
||||
struct SubReporter : SubReporterBase, Reporter
|
||||
{
|
||||
SubReporter(bool* deleted) : Reporter(deleted)
|
||||
{}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
TEST(Core_Ptr, casts)
|
||||
{
|
||||
bool deleted = false;
|
||||
|
||||
{
|
||||
Ptr<const Reporter> p1(new Reporter(&deleted));
|
||||
Ptr<Reporter> p2 = p1.constCast<Reporter>();
|
||||
EXPECT_EQ(p1.get(), p2.get());
|
||||
p1.release();
|
||||
EXPECT_FALSE(deleted);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(deleted);
|
||||
|
||||
{
|
||||
SubReporter* sr = new SubReporter(&deleted);
|
||||
Ptr<Reporter> p1(sr);
|
||||
// This next check isn't really for Ptr itself; it checks that Reporter
|
||||
// is at a non-zero offset within SubReporter, so that the next
|
||||
// check will give us more confidence that the cast actually did something.
|
||||
EXPECT_NE(static_cast<void*>(sr), static_cast<void*>(p1.get()));
|
||||
Ptr<SubReporter> p2 = p1.staticCast<SubReporter>();
|
||||
EXPECT_EQ(sr, p2.get());
|
||||
p1.release();
|
||||
EXPECT_FALSE(deleted);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(deleted);
|
||||
|
||||
{
|
||||
SubReporter* sr = new SubReporter(&deleted);
|
||||
Ptr<Reporter> p1(sr);
|
||||
EXPECT_NE(static_cast<void*>(sr), static_cast<void*>(p1.get()));
|
||||
Ptr<void> p2 = p1.dynamicCast<void>();
|
||||
EXPECT_EQ(sr, p2.get());
|
||||
p1.release();
|
||||
EXPECT_FALSE(deleted);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(deleted);
|
||||
|
||||
{
|
||||
Ptr<Reporter> p1(new Reporter(&deleted));
|
||||
Ptr<SubReporter> p2 = p1.dynamicCast<SubReporter>();
|
||||
EXPECT_EQ(NULL, p2.get());
|
||||
p1.release();
|
||||
EXPECT_FALSE(deleted);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(deleted);
|
||||
}
|
||||
|
||||
TEST(Core_Ptr, comparisons)
|
||||
{
|
||||
Ptr<int> p1, p2(new int), p3(new int);
|
||||
Ptr<int> p4(p2, p3.get());
|
||||
|
||||
// Not using EXPECT_EQ here, since none of them are really "expected" or "actual".
|
||||
EXPECT_TRUE(p1 == p1);
|
||||
EXPECT_TRUE(p2 == p2);
|
||||
EXPECT_TRUE(p2 != p3);
|
||||
EXPECT_TRUE(p2 != p4);
|
||||
EXPECT_TRUE(p3 == p4);
|
||||
}
|
||||
|
||||
TEST(Core_Ptr, make)
|
||||
{
|
||||
bool deleted = true;
|
||||
|
||||
{
|
||||
Ptr<void> p = makePtr<Reporter>(&deleted);
|
||||
EXPECT_FALSE(deleted);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(deleted);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
struct SpeciallyDeletable
|
||||
{
|
||||
SpeciallyDeletable() : deleted(false)
|
||||
{}
|
||||
bool deleted;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace cv {
|
||||
|
||||
template<>
|
||||
void DefaultDeleter<SpeciallyDeletable>::operator()(SpeciallyDeletable * obj) const
|
||||
{ obj->deleted = true; }
|
||||
|
||||
}
|
||||
|
||||
TEST(Core_Ptr, specialized_deleter)
|
||||
{
|
||||
SpeciallyDeletable sd;
|
||||
|
||||
{ Ptr<void> p(&sd); }
|
||||
|
||||
ASSERT_TRUE(sd.deleted);
|
||||
}
|
||||
Reference in New Issue
Block a user