//如果所需内存少于fixed_size,则使用 _Tp buf[(fixed_size > 0) ? fixed_size : 1];固定大小的静态内存,否则使用new 的动态内存
//实现的主要逻辑在reize方法,可以看出动态内存扩容重新new 并拷贝之前的内容相比静态内存效率低
template<typename _Tp, size_t fixed_size = 1024/sizeof(_Tp)+8> class AutoBuffer
{
public:
typedef _Tp value_type;
//! the default constructor
AutoBuffer();
//! constructor taking the real buffer size
explicit AutoBuffer(size_t _size);
//! the copy constructor
AutoBuffer(const AutoBuffer<_Tp, fixed_size>& buf);
//! the assignment operator
AutoBuffer<_Tp, fixed_size>& operator = (const AutoBuffer<_Tp, fixed_size>& buf);
//! destructor. calls deallocate()
~AutoBuffer();
//! allocates the new buffer of size _size. if the _size is small enough, stack-allocated buffer is used
void allocate(size_t _size);
//! deallocates the buffer if it was dynamically allocated
void deallocate();
//! resizes the buffer and preserves the content
void resize(size_t _size);
//! returns the current buffer size
size_t size() const;
//! returns pointer to the real buffer, stack-allocated or heap-allocated
inline _Tp* data() { return ptr; }
//! returns read-only pointer to the real buffer, stack-allocated or heap-allocated
inline const _Tp* data() const { return ptr; }
#if !defined(OPENCV_DISABLE_DEPRECATED_COMPATIBILITY) // use to .data() calls instead
//! returns pointer to the real buffer, stack-allocated or heap-allocated
operator _Tp* () { return ptr; }
//! returns read-only pointer to the real buffer, stack-allocated or heap-allocated
operator const _Tp* () const { return ptr; }
#else
//! returns a reference to the element at specified location. No bounds checking is performed in Release builds.
inline _Tp& operator[] (size_t i) { CV_DbgCheckLT(i, sz, "out of range"); return ptr[i]; }
//! returns a reference to the element at specified location. No bounds checking is performed in Release builds.
inline const _Tp& operator[] (size_t i) const { CV_DbgCheckLT(i, sz, "out of range"); return ptr[i]; }
#endif
protected:
//! pointer to the real buffer, can point to buf if the buffer is small enough
_Tp* ptr;
//! size of the real buffer
size_t sz;
//! pre-allocated buffer. At least 1 element to confirm C++ standard requirements
_Tp buf[(fixed_size > 0) ? fixed_size : 1];
};
template<typename _Tp, size_t fixed_size> inline void
AutoBuffer<_Tp, fixed_size>::resize(size_t _size)
{
if(_size <= sz)
{
sz = _size;
return;
}
size_t i, prevsize = sz, minsize = MIN(prevsize, _size);
_Tp* prevptr = ptr;
ptr = _size > fixed_size ? new _Tp[_size] : buf;
sz = _size;
if( ptr != prevptr )
for( i = 0; i < minsize; i++ )
ptr[i] = prevptr[i];
for( i = prevsize; i < _size; i++ )
ptr[i] = _Tp();
if( prevptr != buf )
delete[] prevptr;
}