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)
/////////////////////////////////
class Exception
class QSE_EXPORT Exception
{
public:
Exception (
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)
#if !defined(QSE_NO_LOCATION_IN_EXCEPTION)
, file(file), line(line)
@ -52,21 +52,21 @@ public:
const qse_char_t* msg;
#if !defined(QSE_NO_LOCATION_IN_EXCEPTION)
const qse_char_t* file;
int line;
qse_size_t line;
#endif
};
#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) \
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) \
class ex_name: public QSE::Exception \
{ \
public: \
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) {} \
}

View File

@ -33,31 +33,83 @@
QSE_BEGIN_NAMESPACE(QSE)
/////////////////////////////////
class ScopedPtrType
template <typename T>
struct ScopedPtrDeleter
{
public:
enum Value
void operator() (T* ptr, void* arg)
{
SINGLETON = 0,
ARRAY = 1
};
delete ptr;
}
};
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
{
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 ()
{
if (this->_ptr)
{
if (type == ScopedPtrType::SINGLETON) delete this->_ptr;
else delete[] this->_ptr;
this->deleter (this->_ptr, this->_darg);
}
}
@ -110,22 +162,25 @@ public:
{
T* t = this->_ptr;
this->_ptr = (T*)QSE_NULL;
this->_darg = QSE_NULL;
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 (type == ScopedPtrType::SINGLETON) delete this->_ptr;
else delete[] this->_ptr;
this->deleter (this->_ptr, this->_darg);
}
this->_ptr = p;
this->_ptr = ptr;
this->_darg = darg;
}
protected:
T* _ptr;
void* _darg;
DELETER deleter;
};
/////////////////////////////////

View File

@ -284,6 +284,12 @@ public:
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)
{
// the position to add the element is beyond the
@ -339,6 +345,22 @@ public:
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)
{
this->remove (index, index);
@ -409,7 +431,9 @@ public:
if (purge_buffer && this->buffer)
{
QSE_ASSERT (this->count <= 0);
QSE_ASSERT (this->capacity > 0);
::operator delete (this->buffer, this->getMmgr());
this->capacity = 0;
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);
#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