added Array::upsert(), Array::ensert().

enhanced ScopedPtr
This commit is contained in:
hyung-hwan 2015-03-10 06:25:15 +00:00
parent 8eadd34b9d
commit 15d76c28a1
4 changed files with 120 additions and 21 deletions

View File

@ -35,12 +35,12 @@
QSE_BEGIN_NAMESPACE(QSE) QSE_BEGIN_NAMESPACE(QSE)
///////////////////////////////// /////////////////////////////////
class Exception class QSE_EXPORT Exception
{ {
public: public:
Exception ( Exception (
const qse_char_t* name, const qse_char_t* msg, const qse_char_t* name, const qse_char_t* msg,
const qse_char_t* file, int line): const qse_char_t* file, qse_size_t line):
name(name), msg(msg) name(name), msg(msg)
#if !defined(QSE_NO_LOCATION_IN_EXCEPTION) #if !defined(QSE_NO_LOCATION_IN_EXCEPTION)
, file(file), line(line) , file(file), line(line)
@ -52,21 +52,21 @@ public:
const qse_char_t* msg; const qse_char_t* msg;
#if !defined(QSE_NO_LOCATION_IN_EXCEPTION) #if !defined(QSE_NO_LOCATION_IN_EXCEPTION)
const qse_char_t* file; const qse_char_t* file;
int line; qse_size_t line;
#endif #endif
}; };
#define QSE_THROW(ex_name) \ #define QSE_THROW(ex_name) \
throw ex_name(QSE_Q(ex_name),QSE_Q(ex_name), QSE_T(__FILE__), __LINE__) throw ex_name(QSE_Q(ex_name),QSE_Q(ex_name), QSE_T(__FILE__), (qse_size_t)__LINE__)
#define QSE_THROW_WITH_MSG(ex_name,msg) \ #define QSE_THROW_WITH_MSG(ex_name,msg) \
throw ex_name(QSE_Q(ex_name),msg, QSE_T(__FILE__), __LINE__) throw ex_name(QSE_Q(ex_name),msg, QSE_T(__FILE__), (qse_size_t)__LINE__)
#define QSE_EXCEPTION(ex_name) \ #define QSE_EXCEPTION(ex_name) \
class ex_name: public QSE::Exception \ class ex_name: public QSE::Exception \
{ \ { \
public: \ public: \
ex_name (const qse_char_t* name, const qse_char_t* msg, \ ex_name (const qse_char_t* name, const qse_char_t* msg, \
const qse_char_t* file, int line): \ const qse_char_t* file, qse_size_t line): \
QSE::Exception (name, msg, file, line) {} \ QSE::Exception (name, msg, file, line) {} \
} }

View File

@ -33,31 +33,83 @@
QSE_BEGIN_NAMESPACE(QSE) QSE_BEGIN_NAMESPACE(QSE)
///////////////////////////////// /////////////////////////////////
class ScopedPtrType template <typename T>
struct ScopedPtrDeleter
{ {
public: void operator() (T* ptr, void* arg)
enum Value
{ {
SINGLETON = 0, delete ptr;
ARRAY = 1 }
};
}; };
template<class T, ScopedPtrType::Value type = ScopedPtrType::SINGLETON> template <typename T>
struct ScopedPtrArrayDeleter
{
void operator() (T* ptr, void* arg)
{
delete[] ptr;
}
};
/// The ScopedPtr class is a template class that destroys the object the
/// pointer points to when its destructor is called. You can use this class
/// to free a certain resource associated to the pointer when it goes out
/// of the current scope.
///
/// \code
/// #include <stdio.h>
/// #include <qse/ScopedPtr.hpp>
/// #include <qse/cmn/HeapMmgr.hpp>
///
///
/// class X
/// {
/// public:
/// X() { printf ("X constructured\n"); }
/// ~X() { printf ("X destructed\n"); }
/// };
///
/// struct destroy_x_in_mmgr
/// {
/// void operator() (X* x, void* arg)
/// {
/// x->~X();
/// ::operator delete (x, (QSE::Mmgr*)arg);
/// }
/// };
///
/// int main ()
/// {
/// QSE::HeapMmgr heap_mmgr (QSE::Mmgr::getDFL(), 30000);
///
/// {
/// QSE::ScopedPtr<X> x1 (new X);
/// QSE::ScopedPtr<X,QSE::ScopedPtrArrayDeleter<X> > x3 (new X[10]);
/// QSE::ScopedPtr<X,destroy_x_in_mmgr> x2 (new(&heap_mmgr) X, &heap_mmgr);
/// }
///
/// return 0;
/// }
/// \endcode
///
template<typename T, typename DELETER = ScopedPtrDeleter<T> >
class QSE_EXPORT ScopedPtr: public Uncopyable class QSE_EXPORT ScopedPtr: public Uncopyable
{ {
public: public:
ScopedPtr (T* p = (T*)QSE_NULL) typedef ScopedPtrDeleter<T> DefaultDeleter;
ScopedPtr (T* ptr = (T*)QSE_NULL, void* darg = (void*)QSE_NULL)
{ {
this->_ptr = p; this->_ptr = ptr;
this->_darg = darg;
} }
~ScopedPtr () ~ScopedPtr ()
{ {
if (this->_ptr) if (this->_ptr)
{ {
if (type == ScopedPtrType::SINGLETON) delete this->_ptr; this->deleter (this->_ptr, this->_darg);
else delete[] this->_ptr;
} }
} }
@ -110,22 +162,25 @@ public:
{ {
T* t = this->_ptr; T* t = this->_ptr;
this->_ptr = (T*)QSE_NULL; this->_ptr = (T*)QSE_NULL;
this->_darg = QSE_NULL;
return t; return t;
} }
void reset (T* p = (T*)QSE_NULL) void reset (T* ptr = (T*)QSE_NULL, void* darg = (T*)QSE_NULL)
{ {
if (this->_ptr) if (this->_ptr)
{ {
if (type == ScopedPtrType::SINGLETON) delete this->_ptr; this->deleter (this->_ptr, this->_darg);
else delete[] this->_ptr;
} }
this->_ptr = p; this->_ptr = ptr;
this->_darg = darg;
} }
protected: protected:
T* _ptr; T* _ptr;
void* _darg;
DELETER deleter;
}; };
///////////////////////////////// /////////////////////////////////

View File

@ -284,6 +284,12 @@ public:
qse_size_t insert (qse_size_t index, const T& value) qse_size_t insert (qse_size_t index, const T& value)
{ {
// Unlike insert() in RedBlackTree and HashList,
// it inserts an item when index exists in the existing array.
// It is because array allows duplicate items.
// RedBlckTree::insert() and HashList::insert() return failure
// if existing item exists.
if (index >= this->capacity) if (index >= this->capacity)
{ {
// the position to add the element is beyond the // the position to add the element is beyond the
@ -339,6 +345,22 @@ public:
return index; return index;
} }
qse_size_t upsert (qse_size_t index, const T& value)
{
if (index < this->count)
return this->update (index, value);
else
return this->insert (index, value);
}
qse_size_t ensert (qse_size_t index, const T& value)
{
if (index < this->count)
return index; // no update
else
return this->insert (index, value);
}
void remove (qse_size_t index) void remove (qse_size_t index)
{ {
this->remove (index, index); this->remove (index, index);
@ -409,7 +431,9 @@ public:
if (purge_buffer && this->buffer) if (purge_buffer && this->buffer)
{ {
QSE_ASSERT (this->count <= 0);
QSE_ASSERT (this->capacity > 0); QSE_ASSERT (this->capacity > 0);
::operator delete (this->buffer, this->getMmgr()); ::operator delete (this->buffer, this->getMmgr());
this->capacity = 0; this->capacity = 0;
this->buffer = QSE_NULL; this->buffer = QSE_NULL;

View File

@ -193,4 +193,24 @@ void* operator new[] (qse_size_t size, QSE::Mmgr* mmgr);
void operator delete[] (void* ptr, QSE::Mmgr* mmgr); void operator delete[] (void* ptr, QSE::Mmgr* mmgr);
#endif #endif
/////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE)
/////////////////////////////////
// Customized deleter for ScopedPtr
template <typename T>
struct ScopedPtrMmgrDeleter
{
void operator() (T* ptr, void* arg)
{
ptr->~T ();
::operator delete (ptr, (QSE::Mmgr*)arg);
}
};
/////////////////////////////////
QSE_END_NAMESPACE(QSE)
/////////////////////////////////
#endif #endif