From 3d1d219561698a453a0f5519b1de74399dfa19d4 Mon Sep 17 00:00:00 2001 From: Andrey Kamaev Date: Thu, 28 Mar 2013 16:47:45 +0400 Subject: [PATCH] Move cv::fastMalloc, cv::fastFree and cv::Ptr out of core.hpp --- modules/core/include/opencv2/core.hpp | 132 +--------- modules/core/include/opencv2/core/base.hpp | 1 + modules/core/include/opencv2/core/cvstd.hpp | 296 ++++++++++++++++++++++- modules/core/include/opencv2/core/operations.hpp | 116 --------- 4 files changed, 297 insertions(+), 248 deletions(-) diff --git a/modules/core/include/opencv2/core.hpp b/modules/core/include/opencv2/core.hpp index 5607a22..75d857e 100644 --- a/modules/core/include/opencv2/core.hpp +++ b/modules/core/include/opencv2/core.hpp @@ -128,143 +128,13 @@ public: \param exc the exception raisen. */ +//TODO: drop this version CV_EXPORTS void error( const Exception& exc ); -/*! - Allocates memory buffer - - This is specialized OpenCV memory allocation function that returns properly aligned memory buffers. - The usage is identical to malloc(). The allocated buffers must be freed with cv::fastFree(). - If there is not enough memory, the function calls cv::error(), which raises an exception. - - \param bufSize buffer size in bytes - \return the allocated memory buffer. -*/ -CV_EXPORTS void* fastMalloc(size_t bufSize); - -/*! - Frees the memory allocated with cv::fastMalloc - - This is the corresponding deallocation function for cv::fastMalloc(). - When ptr==NULL, the function has no effect. -*/ -CV_EXPORTS void fastFree(void* ptr); - -template static inline _Tp* allocate(size_t n) -{ - return new _Tp[n]; -} - -template static inline void deallocate(_Tp* ptr, size_t) -{ - delete[] ptr; -} - -/*! - The STL-compilant memory Allocator based on cv::fastMalloc() and cv::fastFree() -*/ -template class CV_EXPORTS Allocator -{ -public: - typedef _Tp value_type; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - template class rebind { typedef Allocator other; }; - - explicit Allocator() {} - ~Allocator() {} - explicit Allocator(Allocator const&) {} - template - explicit Allocator(Allocator const&) {} - - // address - pointer address(reference r) { return &r; } - const_pointer address(const_reference r) { return &r; } - - pointer allocate(size_type count, const void* =0) - { return reinterpret_cast(fastMalloc(count * sizeof (_Tp))); } - - void deallocate(pointer p, size_type) {fastFree(p); } - - size_type max_size() const - { return max(static_cast<_Tp>(-1)/sizeof(_Tp), 1); } - - void construct(pointer p, const _Tp& v) { new(static_cast(p)) _Tp(v); } - void destroy(pointer p) { p->~_Tp(); } -}; CV_EXPORTS void scalarToRawData(const Scalar& s, void* buf, int type, int unroll_to=0); -//////////////////// 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 ptr" (or faster "const Ptr& 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<> void Ptr::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 class CV_EXPORTS Ptr -{ -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 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 Ptr<_Tp2> ptr(); - template const Ptr<_Tp2> ptr() const; - - //! helper operators making "Ptr ptr" use very similar to "T* ptr". - _Tp* operator -> (); - const _Tp* operator -> () const; - - operator _Tp* (); - operator const _Tp*() const; - - _Tp* obj; //< the object pointer. - int* refcount; //< the associated reference counter -}; - -template bool operator==(Ptr const & a, Ptr const & b); -template bool operator!=(Ptr const & a, Ptr const & b); - - //////////////////////// Input/Output Array Arguments ///////////////////////////////// /*! diff --git a/modules/core/include/opencv2/core/base.hpp b/modules/core/include/opencv2/core/base.hpp index 4d64f25..0c5d91a 100644 --- a/modules/core/include/opencv2/core/base.hpp +++ b/modules/core/include/opencv2/core/base.hpp @@ -270,6 +270,7 @@ template<> inline unsigned saturate_cast(double v) { return cvRound(v) //////////////////////////////// low-level functions //////////////////////////////// + CV_EXPORTS int LU(float* A, size_t astep, int m, float* b, size_t bstep, int n); CV_EXPORTS int LU(double* A, size_t astep, int m, double* b, size_t bstep, int n); CV_EXPORTS bool Cholesky(float* A, size_t astep, int m, float* b, size_t bstep, int n); diff --git a/modules/core/include/opencv2/core/cvstd.hpp b/modules/core/include/opencv2/core/cvstd.hpp index 1c8bcd2..968d266 100644 --- a/modules/core/include/opencv2/core/cvstd.hpp +++ b/modules/core/include/opencv2/core/cvstd.hpp @@ -89,6 +89,129 @@ namespace cv namespace cv { +//////////////////////////// memory management functions //////////////////////////// + +/*! + Allocates memory buffer + + This is specialized OpenCV memory allocation function that returns properly aligned memory buffers. + The usage is identical to malloc(). The allocated buffers must be freed with cv::fastFree(). + If there is not enough memory, the function calls cv::error(), which raises an exception. + + \param bufSize buffer size in bytes + \return the allocated memory buffer. +*/ +CV_EXPORTS void* fastMalloc(size_t bufSize); + +/*! + Frees the memory allocated with cv::fastMalloc + + This is the corresponding deallocation function for cv::fastMalloc(). + When ptr==NULL, the function has no effect. +*/ +CV_EXPORTS void fastFree(void* ptr); + +/*! + The STL-compilant memory Allocator based on cv::fastMalloc() and cv::fastFree() +*/ +template class CV_EXPORTS Allocator +{ +public: + typedef _Tp value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + template class rebind { typedef Allocator other; }; + + explicit Allocator() {} + ~Allocator() {} + explicit Allocator(Allocator const&) {} + template + explicit Allocator(Allocator const&) {} + + // address + pointer address(reference r) { return &r; } + const_pointer address(const_reference r) { return &r; } + + pointer allocate(size_type count, const void* =0) { return reinterpret_cast(fastMalloc(count * sizeof (_Tp))); } + void deallocate(pointer p, size_type) { fastFree(p); } + + void construct(pointer p, const _Tp& v) { new(static_cast(p)) _Tp(v); } + void destroy(pointer p) { p->~_Tp(); } + + 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 ptr" (or faster "const Ptr& 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<> void Ptr::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 class CV_EXPORTS Ptr +{ +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 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 Ptr<_Tp2> ptr(); + template const Ptr<_Tp2> ptr() const; + + //! helper operators making "Ptr ptr" use very similar to "T* ptr". + _Tp* operator -> (); + const _Tp* operator -> () const; + + operator _Tp* (); + operator const _Tp*() const; + + _Tp* obj; //< the object pointer. + int* refcount; //< the associated reference counter +}; + + + +//////////////////////////////// string class //////////////////////////////// + class CV_EXPORTS FileNode; //for string constructor from FileNode class CV_EXPORTS String @@ -187,7 +310,178 @@ private: void deallocate(); }; -// **************************** cv::String implementation **************************** + + +/////////////////////////// cv::Ptr implementation /////////////////////////// + +template inline +Ptr<_Tp>::Ptr() + : obj(0), refcount(0) {} + +template inline +Ptr<_Tp>::Ptr(_Tp* _obj) + : obj(_obj) +{ + if(obj) + { + refcount = (int*)fastMalloc(sizeof(*refcount)); + *refcount = 1; + } + else + refcount = 0; +} + +template template +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 inline +Ptr<_Tp>::~Ptr() +{ + release(); +} + +template inline +void Ptr<_Tp>::addref() +{ + if( refcount ) + CV_XADD(refcount, 1); +} + +template inline +void Ptr<_Tp>::release() +{ + if( refcount && CV_XADD(refcount, -1) == 1 ) + { + delete_obj(); + fastFree(refcount); + } + refcount = 0; + obj = 0; +} + +template inline +void Ptr<_Tp>::delete_obj() +{ + if( obj ) + delete obj; +} + +template inline +Ptr<_Tp>::Ptr(const Ptr<_Tp>& _ptr) +{ + obj = _ptr.obj; + refcount = _ptr.refcount; + addref(); +} + +template 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 inline +_Tp* Ptr<_Tp>::operator -> () +{ + return obj; +} + +template inline +const _Tp* Ptr<_Tp>::operator -> () const +{ + return obj; +} + +template inline +Ptr<_Tp>::operator _Tp* () +{ + return obj; +} + +template inline +Ptr<_Tp>::operator const _Tp*() const +{ + return obj; +} + +template inline +bool Ptr<_Tp>::empty() const +{ + return obj == 0; +} + +template template 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 template 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 static inline +bool operator == (const Ptr<_Tp>& a, const Ptr<_Tp2>& b) +{ + return a.refcount == b.refcount; +} + +template static inline +bool operator != (const Ptr<_Tp>& a, const Ptr<_Tp2>& b) +{ + return a.refcount != b.refcount; +} + + + +////////////////////////// cv::String implementation ///////////////////////// inline String::String() : cstr_(0), len_(0) { diff --git a/modules/core/include/opencv2/core/operations.hpp b/modules/core/include/opencv2/core/operations.hpp index 30d6caa..f7a07a9 100644 --- a/modules/core/include/opencv2/core/operations.hpp +++ b/modules/core/include/opencv2/core/operations.hpp @@ -506,122 +506,6 @@ inline Point LineIterator::pos() const return p; } -/////////////////////////////////// Ptr //////////////////////////////////////// - -template inline Ptr<_Tp>::Ptr() : obj(0), refcount(0) {} -template inline Ptr<_Tp>::Ptr(_Tp* _obj) : obj(_obj) -{ - if(obj) - { - refcount = (int*)fastMalloc(sizeof(*refcount)); - *refcount = 1; - } - else - refcount = 0; -} - -template inline void Ptr<_Tp>::addref() -{ if( refcount ) CV_XADD(refcount, 1); } - -template inline void Ptr<_Tp>::release() -{ - if( refcount && CV_XADD(refcount, -1) == 1 ) - { - delete_obj(); - fastFree(refcount); - } - refcount = 0; - obj = 0; -} - -template inline void Ptr<_Tp>::delete_obj() -{ - if( obj ) delete obj; -} - -template inline Ptr<_Tp>::~Ptr() { release(); } - -template inline Ptr<_Tp>::Ptr(const Ptr<_Tp>& _ptr) -{ - obj = _ptr.obj; - refcount = _ptr.refcount; - addref(); -} - -template 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 inline _Tp* Ptr<_Tp>::operator -> () { return obj; } -template inline const _Tp* Ptr<_Tp>::operator -> () const { return obj; } - -template inline Ptr<_Tp>::operator _Tp* () { return obj; } -template inline Ptr<_Tp>::operator const _Tp*() const { return obj; } - -template inline bool Ptr<_Tp>::empty() const { return obj == 0; } - -template template 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 template 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 template 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 inline bool operator==(const Ptr<_Tp>& a, const Ptr<_Tp2>& b) { return a.refcount == b.refcount; } -template inline bool operator!=(const Ptr<_Tp>& a, const Ptr<_Tp2>& b) { return a.refcount != b.refcount; } - - //////////////////////////////////////// XML & YAML I/O //////////////////////////////////// CV_EXPORTS_W void write( FileStorage& fs, const String& name, int value ); -- 2.7.4