📄 brewvector.h
字号:
/*
* Copyright (C) 2003 Radu Braniste (rbraniste@epicad.com)
* All Rights Reserved
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions 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.
* 3. Neither the name of the Author nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
*/
#ifndef BREW_VECTOR_H
#define BREW_VECTOR_H
struct ReallocPolicy_100
{
static UINT setSize(UINT size)
{
if (size < 100)
return 2*size;
return size+10;
}
};
struct ReallocPolicy_2
{
static UINT setSize(UINT size)
{
if (size < 1000000)
return 2*size;
return size+100;
}
};
#define length_ pData_->length
#define capacity_ pData_->capacity
#define buffer_ pData_->buffer
template <class T, class ReallocPolicy = ReallocPolicy_100 >
class BrewVector
{
private:
typedef BrewVector<T, ReallocPolicy> BV;
//const BV &
//operator=( const BrewVector &rhs );
public:
typedef T VALUE_TYPE;
template <class U>
BrewVector( const U& rhs , UINT sz = 0): pData_(0)
{
CopyCtorImpl(rhs, sz);
}
BrewVector( const BrewVector &rhs ): pData_(0)
{
CopyCtorImpl(rhs, 0);
}
template <class U, class V>
BrewVector (const U& lhs, UINT lnl, const V& rhs, UINT lnr): pData_(0)
{
ensureCapacity(lnr + lnl );
cpyImpl(getBuf(lhs), lnl);
cpyImpl(getBuf(rhs), lnr, lnl);
length_=capacity_ ;
}
BrewVector( ) : pData_(0)
{
}
const BV &
operator=( const BrewVector &rhs )
{
if (pData_ || rhs.pData_)
opEqImpl(rhs, 0);
return *this;
}
~BrewVector()
{
release(pData_);
}
template <class U>
void assign( const U& rhs , UINT sz = 0)
{
opEqImpl(rhs, sz);
}
template <class U>
UINT append( const U& rhs , UINT sz = 0)
{
UINT newLen = getNewLen(getLen(rhs), sz);
cat(getBuf(rhs), sz);
length_ = newLen;
return length_;
}
template <class U>
void insert ( const U& u, UINT pos, UINT sz)
{
if (!pData_ || pos >= length_) return;
UINT newLen = getNewLen(getLen(u), sz);
T* src = buffer_ + length_ - 1;
T* strt = buffer_ + newLen - 1 ;
while( (src - buffer_) >= pos && (src >= buffer_) )
{
*(strt--) = *(src--);
}
cpyImpl(getBuf(u), sz, pos);
length_ = newLen;
}
void remove (UINT pos, UINT elements)
{
if (!pData_ || pos >= length_) return;
T* strt = buffer_ + pos;
T* src = strt + elements;
deleteRange(pData_, pos, pos + elements);
MEMSET(buffer_ + pos, 0, elements*sizeof(T));
if ((src - buffer_) < length_)
{
while( (src - buffer_) < length_ )
{
*(strt++) = *(src++);
}
int elems = length_ - elements;
deleteRange(pData_, elems);
MEMSET(buffer_ + elems,0, elements*sizeof(T));
}
length_ -= elements;
}
T& operator[]( UINT idx )
{
return *(buffer_+idx);
}
const T& operator[]( UINT idx ) const
{
return *(buffer_+idx);
}
const T* toArray() const
{ return bufferImpl();}
const UINT size( ) const
{ return lengthImpl(); }
const UINT capacity( ) const
{ return capacityImpl(); }
const bool isEmpty() const
{return lengthImpl()==0;}
/* template <class F >
F forEach(F func, UINT strt = 0, UINT end =0 )
{
return forEach<T&>(func, strt, end); //T& IS KEY - otherwise temporary created in func
}
template <class Type, class F >
F forEach(F func, UINT strt = 0, UINT end =0 )
{
if (end == 0) end = lengthImpl();
if (bufferImpl() && end <= lengthImpl() && strt < end)
{
for (UINT i = strt; i < end; ++i)
{
func(static_cast<Type>(*(buffer_+i))); //TEMPORARY CREATED HERE IF... SEE Type WAS NOT SET Type&
}
}
return func;
}
*/
template < class F >
F forEach(F func, UINT strt = 0, UINT end =0 )
{
if (end == 0) end = lengthImpl();
if (bufferImpl() && end <= lengthImpl() && strt < end)
{
for (UINT i = strt; i < end; ++i)
{
func((*(buffer_+i)));
}
}
return func;
}
UINT ensureCapacity(UINT sz)
{
if (!pData_)
{
return increaseBuffer(sz);
}
int l = sz - length_;
UINT newLen = l>0 ? l : length_;
return increaseBuffer(newLen);
}
/* UINT setSize(UINT sz) LEAKS
{
if (sz <= lengthImpl())
{
length_ = sz;
capacity_ = sz;
return sz;
}
else
{
return increaseBuffer(sz - lengthImpl());
}
}*/
private:
struct DATA
{
UINT length;
UINT capacity;
T buffer[1];
};
void setBuffer(UINT sz)
{
pData_ = static_cast<DATA*>(MALLOC(sizeof(DATA) + (sz-1)*sizeof(T)));
if (pData_)
{
MEMSET(buffer_, 0, sz*sizeof(T));
capacity_ = sz;
}
}
void deleteRange(DATA* data, UINT strt = 0, UINT end =0)
{
UINT l = data?data->length:0;
if (end == 0) end = l;
if (data && end <= l && strt < end)
{
for (UINT i = strt; i < end; ++i)
{
(*(data->buffer+i)).~T();
}
}
}
void release(DATA* data, UINT strt = 0, UINT end =0 )
{
deleteRange(data, strt, end);
FREE(data);
}
UINT increaseBuffer(UINT sz)
{
if (!pData_)
{
setBuffer( sz );
if (!pData_)
return 0;
length_ = 0;
return sz;
}
UINT newLen = length_ + sz;
if (newLen > capacity_)
{
DATA *temp = pData_;
UINT oldLength = length_;
setBuffer( ReallocPolicy::setSize(newLen) );
if (!pData_)
return 0;
length_ = newLen - sz;
cpy( temp->buffer);
release (temp, 0, oldLength);
if (!buffer_) return 0;
}
return newLen;
}
bool isIndexOutOfBounds( UINT index ) const
{
return (( index >= lengthImpl() ) || ( index <0 ) );
}
UINT getLen(const BrewVector& s) const
{ return s.pData_?s.length_:0;}
UINT getLen(const T& ch) const
{ return 1;}
UINT getLen(const T* ch) const
{ return -1;}
const T* getBuf(const BrewVector& s) const
{ return s.buffer_;}
const T* getBuf(const T* ch) const
{ return ch;}
const T* getBuf(const T& ch) const
{ return &ch;}
template <class U>
void
opEqImpl( const U &rhs, UINT sz )
{
UINT ln = getLen(rhs);
sz = (sz == 0) || (sz > ln)? ln : sz;
if (!pData_ || sz > capacityImpl() )
{
release( pData_);
setBuffer( sz );
}
else
{
deleteRange(pData_);
MEMSET(buffer_, 0, length_*sizeof(T));
}
length_ = sz;
cpy( getBuf(rhs) );
}
template <class U>
void CopyCtorImpl( const U &rhs, UINT sz)
{
UINT ln = getLen(rhs);
if (ln == 0) return;
sz = (sz == 0) || (sz > ln)? ln : sz;
setBuffer( sz );
length_ = sz;
cpy( getBuf(rhs) );
}
UINT getNewLen(UINT ln, UINT& sz )
{
sz = (sz == 0) || (sz > ln)? ln : sz;
return increaseBuffer(sz);
}
void cpy(const T* rhs)
{
if (pData_ && buffer_ && rhs)
{
cpyImpl(rhs, length_ );
}
}
void cat(const T* rhs, UINT sz )
{
if (pData_ && buffer_ && rhs)
{
cpyImpl(rhs, sz, length_ );
}
}
void cpyImpl( const T* rhs, UINT sz, UINT pos = 0) const
{
T* p = buffer_+ pos;
for (UINT i = 0; i < sz; ++i)
*(p+i) = *(rhs + i);
}
T* bufferImpl() const
{
return pData_?buffer_:0;
}
UINT lengthImpl() const
{
return pData_?length_:0;
}
UINT capacityImpl() const
{
return pData_?capacity_:0;
}
friend BrewVector operator+ ( const BrewVector<T, ReallocPolicy> & lhs, const BrewVector<T, ReallocPolicy> & rhs )
{
BrewVector<T, ReallocPolicy> t;
UINT lnl = t.getLen(lhs);
UINT lnr = t.getLen(rhs);
return BrewVector<T>(lhs, lnl, rhs, lnr);
}
private:
DATA* pData_;
};
template <class T, class ReallocPolicy = ReallocPolicy_100 >
class BrewPVector : private BrewVector<void*, ReallocPolicy>
{
private:
typedef BrewVector<void*, ReallocPolicy > BVV;
public:
typedef T* VALUE_TYPE;
BrewPVector() : BVV()
{}
~BrewPVector()
{ }
T* operator[]( UINT idx )
{
return static_cast<T*>(BVV::operator[](idx));;
}
void setAt(const T* lhs, UINT idx)
{
UINT length = BVV::size( );;
idx = idx < length? idx: length - 1;
BVV::operator[](idx) = (void*)lhs;
}
UINT
append( const T* rhs )
{
return BVV::append((void*)(rhs));
}
void insert (const T* u, UINT pos)
{
if (pos < BVV::size())
BVV::insert( (void*)(u), pos, 1);
else
BVV::append((void*)(u));
}
const T* toArray() const
{ return BVV::toArray();}
const UINT size( ) const
{ return BVV::size( ); }
const UINT capacity( ) const
{ return capacity(); }
const bool isEmpty() const
{return BVV::isEmpty();}
void ensureCapacity(UINT sz)
{
BVV::ensureCapacity(sz);
}
/* template <class F >
F forEach(F func, UINT strt = 0, UINT end =0 )
{
return BVV::forEach<T*>(func, strt, end);
}
*/
template < class F >
F forEach(F func, UINT strt = 0, UINT end =0 )
{
if (end == 0) end = BVV::size( );
if (BVV::toArray() && end <= BVV::size( ) && strt < end)
{
for (UINT i = strt; i < end; ++i)
{
func(static_cast<T*>(BVV::operator[](i)));
}
}
return func;
}
BrewPVector( const BrewPVector &rhs ): BVV(static_cast<const BVV&>(rhs))
{}
private:
// BrewPVector( const BrewPVector &rhs );
const BrewPVector<T, ReallocPolicy> &
operator=( const BrewPVector &rhs );
};
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -