fixed a bug in void* operator new (qse_size_t size, QSE::Mpool* mp)
removed Mpool from Array
This commit is contained in:
parent
bdf3e2652d
commit
dda5db6257
@ -28,7 +28,7 @@
|
||||
#define _QSE_CMN_ARRAY_HPP_
|
||||
|
||||
#include <qse/Types.hpp>
|
||||
#include <qse/cmn/Mpool.hpp>
|
||||
#include <qse/cmn/Mmged.hpp>
|
||||
|
||||
/////////////////////////////////
|
||||
QSE_BEGIN_NAMESPACE(QSE)
|
||||
@ -48,24 +48,14 @@ struct ArrayResizer
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct ArrayAssigner
|
||||
{
|
||||
// The assignment proxy is used to get the value informed of its position
|
||||
// within the heap. This default implmentation, however, doesn't utilize
|
||||
// the position (index).
|
||||
T& operator() (T& v1, const T& v2, qse_size_t index) const
|
||||
{
|
||||
v1 = v2;
|
||||
return v1;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename ASSIGNER = ArrayAssigner<T>, typename RESIZER = ArrayResizer >
|
||||
///
|
||||
/// The Array class provides a dynamically resized array.
|
||||
///
|
||||
template <typename T, typename RESIZER = ArrayResizer >
|
||||
class Array: public Mmged
|
||||
{
|
||||
public:
|
||||
typedef Array<T,ASSIGNER,RESIZER> SelfType;
|
||||
typedef Array<T,RESIZER> SelfType;
|
||||
|
||||
enum
|
||||
{
|
||||
@ -73,11 +63,7 @@ public:
|
||||
INVALID_INDEX = ~(qse_size_t)0
|
||||
};
|
||||
|
||||
Array (Mmgr* mmgr = QSE_NULL,
|
||||
qse_size_t capacity = DEFAULT_CAPACITY,
|
||||
qse_size_t mpb_size = 0):
|
||||
Mmged (mmgr),
|
||||
mp (mmgr, QSE_SIZEOF(T), mpb_size)
|
||||
Array (Mmgr* mmgr = QSE_NULL, qse_size_t capacity = DEFAULT_CAPACITY): Mmged (mmgr)
|
||||
{
|
||||
if (capacity <= 0)
|
||||
{
|
||||
@ -87,7 +73,7 @@ public:
|
||||
else
|
||||
{
|
||||
//this->buffer = new T[capacity];
|
||||
this->buffer = (T*)::operator new (capacity * QSE_SIZEOF(*this->buffer), &this->mp);
|
||||
this->buffer = (T*)::operator new (capacity * QSE_SIZEOF(*this->buffer), this->getMmgr());
|
||||
this->capacity = capacity;
|
||||
}
|
||||
|
||||
@ -96,12 +82,11 @@ public:
|
||||
|
||||
Array (const SelfType& array):
|
||||
Mmged (array.getMmgr()),
|
||||
mp (array.getMmgr(), array.mp.getDatumSize(), array.mp.getBlockSize()),
|
||||
count (0), capacity (0), buffer (QSE_NULL)
|
||||
{
|
||||
if (array.buffer)
|
||||
{
|
||||
this->buffer = this->clone_buffer (array, array.capacity, array.count);
|
||||
this->buffer = this->clone_buffer (array.buffer, array.capacity, array.count);
|
||||
this->count = array.count;
|
||||
this->capacity = array.capacity;
|
||||
}
|
||||
@ -125,23 +110,22 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
T* clone_buffer (const T* srcbuf, qse_size_t capa, qse_size_t count)
|
||||
T* clone_buffer (const T* srcbuf, qse_size_t capa, qse_size_t cnt)
|
||||
{
|
||||
QSE_ASSERT (capa > 0);
|
||||
QSE_ASSERT (count <= capa);
|
||||
QSE_ASSERT (cnt <= capa);
|
||||
|
||||
qse_size_t index;
|
||||
|
||||
//T* tmp = new T[capa];
|
||||
T* tmp = (T*)::operator new (capa * QSE_SIZEOF(*tmp), &this->mp);
|
||||
T* tmp = (T*)::operator new (capa * QSE_SIZEOF(*tmp), this->getMmgr());
|
||||
|
||||
try
|
||||
{
|
||||
for (index = 0; index < count; index++)
|
||||
for (index = 0; index < cnt; index++)
|
||||
{
|
||||
//tmp[index] = srcbuf[index];
|
||||
// copy-construct each element.
|
||||
new((QSE::Mpool*)QSE_NULL, &tmp[index]) T(srcbuf[index]);
|
||||
new((QSE::Mmgr*)QSE_NULL, &tmp[index]) T(srcbuf[index]);
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
@ -153,7 +137,7 @@ protected:
|
||||
--index;
|
||||
tmp[index].~T ();
|
||||
}
|
||||
::operator delete (tmp, &this->mp);
|
||||
::operator delete (tmp, this->getMmgr());
|
||||
throw;
|
||||
}
|
||||
|
||||
@ -166,13 +150,12 @@ protected:
|
||||
{
|
||||
// no value exists in the given position.
|
||||
// i can copy-construct the value.
|
||||
new((QSE::Mpool*)QSE_NULL, &this->buffer[index]) T(value);
|
||||
//this->notify_position (this->buffer[index], index);
|
||||
new((QSE::Mmgr*)QSE_NULL, &this->buffer[index]) T(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
// there is an old value in the position.
|
||||
this->assigner (this->buffer[index], value, index);
|
||||
this->buffer[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
@ -212,9 +195,18 @@ public:
|
||||
return this->buffer;
|
||||
}
|
||||
|
||||
/// The getBufferIndex() function returns the index of the
|
||||
/// given value \a v if it is one of the values of the array.
|
||||
/// It returns #INVALID_INDEX if not.
|
||||
/// The getIndex() function returns the index of the given value \a v
|
||||
/// if it belongs to the array. It returns #INVALID_INDEX if not.
|
||||
/// Note that this is not a search function.
|
||||
///
|
||||
/// \code
|
||||
/// QSE::Array<int> a;
|
||||
/// a.insert (0, 10);
|
||||
/// a.insert (0, 20);
|
||||
/// a.insert (0, 30);
|
||||
/// const int& t = a[2];
|
||||
/// printf ("%lu\n", (unsigned long int)a.getIndex(t)); // print 2
|
||||
/// \endcode
|
||||
qse_size_t getIndex (const T& v)
|
||||
{
|
||||
if (&v >= &this->buffer[0] && &v < &this->buffer[this->count])
|
||||
@ -291,7 +283,7 @@ public:
|
||||
// fill the gap with a default value.
|
||||
for (qse_size_t i = this->count; i < index; i++)
|
||||
{
|
||||
new((QSE::Mpool*)QSE_NULL, &this->buffer[i]) T();
|
||||
new((QSE::Mmgr*)QSE_NULL, &this->buffer[i]) T();
|
||||
}
|
||||
}
|
||||
|
||||
@ -319,8 +311,7 @@ public:
|
||||
// replace deleted elements by surviving elements at the back
|
||||
while (i < this->count)
|
||||
{
|
||||
//this->buffer[j++] = this->buffer[i++];
|
||||
this->assigner (this->buffer[j], this->buffer[i], j);
|
||||
this->buffer[j] = this->buffer[i];
|
||||
j++; i++;
|
||||
}
|
||||
|
||||
@ -350,25 +341,18 @@ protected:
|
||||
}
|
||||
|
||||
public:
|
||||
void clear (bool clear_mpool = false)
|
||||
void clear (bool purge_buffer = false)
|
||||
{
|
||||
this->clear_all_items ();
|
||||
|
||||
if (clear_mpool)
|
||||
if (purge_buffer && this->buffer)
|
||||
{
|
||||
if (this->buffer)
|
||||
{
|
||||
// the buffer has been allocated using the memory pool.
|
||||
// if the memory pool should be cleared, the buffer must
|
||||
// not be left over either.
|
||||
QSE_ASSERT (this->capacity > 0);
|
||||
::operator delete (this->buffer, &this->mp);
|
||||
this->capacity = 0;
|
||||
this->buffer = QSE_NULL;
|
||||
}
|
||||
QSE_ASSERT (this->capacity > 0);
|
||||
::operator delete (this->buffer, this->getMmgr());
|
||||
this->capacity = 0;
|
||||
this->buffer = QSE_NULL;
|
||||
|
||||
QSE_ASSERT (this->capacity == 0);
|
||||
this->mp.dispose ();
|
||||
}
|
||||
}
|
||||
|
||||
@ -390,43 +374,48 @@ public:
|
||||
for (qse_size_t i = this->count; i < size; ++i)
|
||||
{
|
||||
// use the default contructor to set the value.
|
||||
new((QSE::Mpool*)QSE_NULL, &this->buffer[i]) T();
|
||||
new((QSE::Mmgr*)QSE_NULL, &this->buffer[i]) T();
|
||||
}
|
||||
|
||||
this->count = size;
|
||||
}
|
||||
}
|
||||
|
||||
void setCapacity (qse_size_t capacity)
|
||||
void setCapacity (qse_size_t capa)
|
||||
{
|
||||
if (capacity <= 0)
|
||||
if (capa <= 0)
|
||||
{
|
||||
this->clear (true);
|
||||
}
|
||||
else
|
||||
else if (this->buffer)
|
||||
{
|
||||
QSE_ASSERT (this->capacity > 0);
|
||||
|
||||
qse_size_t cnt = this->count;
|
||||
if (cnt > capacity) cnt = capacity;
|
||||
if (cnt > capa) cnt = capa;
|
||||
|
||||
T* tmp = clone_buffer (*this, capacity, cnt);
|
||||
T* tmp = this->clone_buffer (this->buffer, capa, cnt);
|
||||
|
||||
if (this->buffer)
|
||||
{
|
||||
// don't call this->clear (true) here. clear items only.
|
||||
// the memory pool may destory the cloned buffer as well.
|
||||
this->clear_all_items ();
|
||||
// don't call this->clear(true) here. clear items only.
|
||||
this->clear_all_items ();
|
||||
|
||||
// deallocate the current buffer;
|
||||
::operator delete (this->buffer, &this->mp);
|
||||
this->capacity = 0;
|
||||
this->buffer = QSE_NULL;
|
||||
}
|
||||
// deallocate the current buffer;
|
||||
::operator delete (this->buffer, this->getMmgr());
|
||||
this->capacity = 0;
|
||||
this->buffer = QSE_NULL;
|
||||
|
||||
this->buffer = tmp;
|
||||
this->capacity = capacity;
|
||||
this->capacity = capa;
|
||||
this->count = cnt;
|
||||
}
|
||||
else
|
||||
{
|
||||
QSE_ASSERT (this->capacity <= 0);
|
||||
QSE_ASSERT (this->count <= 0);
|
||||
|
||||
this->buffer = (T*)::operator new (capa * QSE_SIZEOF(*this->buffer), this->getMmgr());
|
||||
this->capacity = capa;
|
||||
}
|
||||
}
|
||||
|
||||
void trimToSize ()
|
||||
@ -488,31 +477,25 @@ public:
|
||||
{
|
||||
last = first + nk;
|
||||
index = first;
|
||||
//c = this->buffer[first];
|
||||
this->assigner (c, this->buffer[first], INVALID_INDEX);
|
||||
c = this->buffer[first];
|
||||
while (1)
|
||||
{
|
||||
cnt++;
|
||||
while (index < nk)
|
||||
{
|
||||
//this->buffer[index] = this->buffer[index + n];
|
||||
this->assigner (this->buffer[index], this->buffer[index + n], index);
|
||||
this->buffer[index] = this->buffer[index + n];
|
||||
index += n;
|
||||
}
|
||||
if (index == last) break;
|
||||
//this->buffer[index] = this->buffer[index - nk];
|
||||
this->assigner (this->buffer[index], this->buffer[index - nk], index);
|
||||
this->buffer[index] = this->buffer[index - nk];
|
||||
index -= nk;
|
||||
}
|
||||
//this->buffer[last] = c;
|
||||
this->assigner (this->buffer[last], c, last);
|
||||
this->buffer[last] = c;
|
||||
first++;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
Mpool mp;
|
||||
ASSIGNER assigner;
|
||||
RESIZER resizer;
|
||||
|
||||
qse_size_t count;
|
||||
|
@ -55,6 +55,7 @@ public:
|
||||
typedef qse_mmgr_t mmgr_t;
|
||||
|
||||
QSE_EXCEPTION (MemoryError);
|
||||
QSE_EXCEPTION (InvalidArgumentError);
|
||||
|
||||
protected:
|
||||
bool raise_exception;
|
||||
|
@ -182,7 +182,24 @@ QSE_END_NAMESPACE(QSE)
|
||||
|
||||
void* operator new (qse_size_t size, QSE::Mpool* mp)
|
||||
{
|
||||
return mp->isEnabled()? mp->allocate(): ::operator new(size, mp->getMmgr());
|
||||
if (mp->isEnabled())
|
||||
{
|
||||
QSE_ASSERT (size == mp->getDatumSize());
|
||||
// the size argument is not really used. you must make sure that
|
||||
// the given size matches the datum size of the memory pool.
|
||||
if (size != mp->getDatumSize())
|
||||
{
|
||||
//QSE::Mmgr* mmgr = mp->getMmgr();
|
||||
QSE_THROW (QSE::Mmgr::InvalidArgumentError);
|
||||
}
|
||||
return mp->allocate ();
|
||||
}
|
||||
else
|
||||
{
|
||||
// but when the memory pool is not enabled, it goes through
|
||||
// the memory manager directly and it honors the size argument.
|
||||
return ::operator new(size, mp->getMmgr());
|
||||
}
|
||||
}
|
||||
|
||||
void operator delete (void* ptr, QSE::Mpool* mp)
|
||||
|
Loading…
x
Reference in New Issue
Block a user