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