added Array::upsert(), Array::ensert().
enhanced ScopedPtr
This commit is contained in:
parent
8eadd34b9d
commit
15d76c28a1
@ -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) {} \
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
/////////////////////////////////
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user