added SharedPtr and MmgedSharedPtr
This commit is contained in:
@ -111,12 +111,15 @@ public:
|
||||
|
||||
SelfType& operator= (const SelfType& array)
|
||||
{
|
||||
this->clear (true);
|
||||
if (array.buffer)
|
||||
if (this != &array)
|
||||
{
|
||||
this->buffer = this->clone_buffer (array, array.capacity, array.count);
|
||||
this->count = array.count;
|
||||
this->capacity = array.capacity;
|
||||
this->clear (true);
|
||||
if (array.buffer)
|
||||
{
|
||||
this->buffer = this->clone_buffer (array, array.capacity, array.count);
|
||||
this->count = array.count;
|
||||
this->capacity = array.capacity;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
@ -132,7 +132,10 @@ public:
|
||||
|
||||
SelfType& operator= (const SelfType& heap)
|
||||
{
|
||||
ParentType::operator= (heap);
|
||||
if (this != &heap)
|
||||
{
|
||||
ParentType::operator= (heap);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -220,25 +220,28 @@ public:
|
||||
|
||||
SelfType& operator= (const SelfType& list)
|
||||
{
|
||||
this->clear (false);
|
||||
|
||||
// note that the memory pool itself is not copied.
|
||||
|
||||
for (qse_size_t i = 0; i < list.node_capacity; i++)
|
||||
if (this != &list)
|
||||
{
|
||||
qse_size_t head = i << 1;
|
||||
qse_size_t tail = head + 1;
|
||||
this->clear (false);
|
||||
|
||||
Node* np = list.nodes[head];
|
||||
if (np == QSE_NULL) continue;
|
||||
|
||||
do
|
||||
// note that the memory pool itself is not copied.
|
||||
|
||||
for (qse_size_t i = 0; i < list.node_capacity; i++)
|
||||
{
|
||||
this->copy_datum (np, this->node_capacity, this->nodes, this->datum_list);
|
||||
if (np == list.nodes[tail]) break;
|
||||
np = np->getNextNode ();
|
||||
}
|
||||
while (1);
|
||||
qse_size_t head = i << 1;
|
||||
qse_size_t tail = head + 1;
|
||||
|
||||
Node* np = list.nodes[head];
|
||||
if (np == QSE_NULL) continue;
|
||||
|
||||
do
|
||||
{
|
||||
this->copy_datum (np, this->node_capacity, this->nodes, this->datum_list);
|
||||
if (np == list.nodes[tail]) break;
|
||||
np = np->getNextNode ();
|
||||
}
|
||||
while (1);
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
|
@ -131,7 +131,10 @@ public:
|
||||
|
||||
SelfType& operator= (const SelfType& table)
|
||||
{
|
||||
this->pair_list = table.pair_list;
|
||||
if (this != &table)
|
||||
{
|
||||
this->pair_list = table.pair_list;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -231,10 +231,13 @@ public:
|
||||
|
||||
SelfType& operator= (const SelfType& ll)
|
||||
{
|
||||
this->clear ();
|
||||
// note that the memory pool itself is not copied.
|
||||
for (Node* p = ll.head_node; p != QSE_NULL; p = p->next)
|
||||
this->append (p->value);
|
||||
if (this != &ll)
|
||||
{
|
||||
this->clear ();
|
||||
// note that the memory pool itself is not copied.
|
||||
for (Node* p = ll.head_node; p != QSE_NULL; p = p->next)
|
||||
this->append (p->value);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ pkginclude_HEADERS = \
|
||||
|
||||
if ENABLE_CXX
|
||||
pkginclude_HEADERS += \
|
||||
Mmgr.hpp StdMmgr.hpp HeapMmgr.hpp Mmged.hpp \
|
||||
Mmgr.hpp StdMmgr.hpp HeapMmgr.hpp Mmged.hpp MmgedSharedPtr.hpp \
|
||||
Mpool.hpp Association.hpp LinkedList.hpp HashList.hpp HashTable.hpp \
|
||||
RedBlackTree.hpp RedBlackTable.hpp \
|
||||
Array.hpp BinaryHeap.hpp
|
||||
|
@ -51,7 +51,7 @@ POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
@ENABLE_CXX_TRUE@am__append_1 = \
|
||||
@ENABLE_CXX_TRUE@ Mmgr.hpp StdMmgr.hpp HeapMmgr.hpp Mmged.hpp \
|
||||
@ENABLE_CXX_TRUE@ Mmgr.hpp StdMmgr.hpp HeapMmgr.hpp Mmged.hpp MmgedSharedPtr.hpp \
|
||||
@ENABLE_CXX_TRUE@ Mpool.hpp Association.hpp LinkedList.hpp HashList.hpp HashTable.hpp \
|
||||
@ENABLE_CXX_TRUE@ RedBlackTree.hpp RedBlackTable.hpp \
|
||||
@ENABLE_CXX_TRUE@ Array.hpp BinaryHeap.hpp
|
||||
@ -93,9 +93,9 @@ am__pkginclude_HEADERS_DIST = alg.h chr.h cp949.h cp950.h dir.h dll.h \
|
||||
nwio.h oht.h opt.h path.h pio.h pma.h rbt.h rex.h sck.h sio.h \
|
||||
sll.h slmb.h str.h task.h time.h tio.h tmr.h tre.h uni.h uri.h \
|
||||
utf8.h xma.h Mmgr.hpp StdMmgr.hpp HeapMmgr.hpp Mmged.hpp \
|
||||
Mpool.hpp Association.hpp LinkedList.hpp HashList.hpp \
|
||||
HashTable.hpp RedBlackTree.hpp RedBlackTable.hpp Array.hpp \
|
||||
BinaryHeap.hpp
|
||||
MmgedSharedPtr.hpp Mpool.hpp Association.hpp LinkedList.hpp \
|
||||
HashList.hpp HashTable.hpp RedBlackTree.hpp RedBlackTable.hpp \
|
||||
Array.hpp BinaryHeap.hpp
|
||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||
am__vpath_adj = case $$p in \
|
||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
|
173
qse/include/qse/cmn/MmgedSharedPtr.hpp
Normal file
173
qse/include/qse/cmn/MmgedSharedPtr.hpp
Normal file
@ -0,0 +1,173 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _QSE_CMN_MMGEDSHAREDPTR_HPP_
|
||||
#define _QSE_CMN_MMGEDSHAREDPTR_HPP_
|
||||
|
||||
#include <qse/cmn/Mmged.hpp>
|
||||
|
||||
/////////////////////////////////
|
||||
QSE_BEGIN_NAMESPACE(QSE)
|
||||
/////////////////////////////////
|
||||
|
||||
template <typename T>
|
||||
struct MmgedSharedPtrDeleter
|
||||
{
|
||||
void operator() (T* ptr, void* arg)
|
||||
{
|
||||
delete ptr;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct MmgedSharedPtrArrayDeleter
|
||||
{
|
||||
void operator() (T* ptr, void* arg)
|
||||
{
|
||||
delete[] ptr;
|
||||
}
|
||||
};
|
||||
|
||||
///
|
||||
/// The MmgedSharedPtr class is similar to SharedPtr except that i
|
||||
/// accepts a pointer to a memory manager to allocate the space for
|
||||
/// shared reference count.
|
||||
///
|
||||
template<typename T, typename DELETER = MmgedSharedPtrDeleter<T> >
|
||||
class QSE_EXPORT MmgedSharedPtr: public Mmged
|
||||
{
|
||||
public:
|
||||
typedef MmgedSharedPtr<T,DELETER> SelfType;
|
||||
|
||||
typedef MmgedSharedPtrDeleter<T> DefaultDeleter;
|
||||
|
||||
MmgedSharedPtr (T* ptr = (T*)QSE_NULL, void* darg = (void*)QSE_NULL): Mmged(QSE_NULL), _ptr(ptr), _darg(darg)
|
||||
{
|
||||
this->_ref = new(this->getMmgr()) qse_size_t;
|
||||
(*this->_ref) = 1;
|
||||
}
|
||||
|
||||
MmgedSharedPtr (Mmgr* mmgr, T* ptr = (T*)QSE_NULL, void* darg = (void*)QSE_NULL): Mmged(mmgr), _ptr(ptr), _darg(darg)
|
||||
{
|
||||
this->_ref = new(this->getMmgr()) qse_size_t;
|
||||
(*this->_ref) = 1;
|
||||
}
|
||||
|
||||
MmgedSharedPtr (const SelfType& ptr): Mmged(ptr), _ref(ptr._ref), _ptr (ptr._ptr), _darg (ptr._darg)
|
||||
{
|
||||
(*this->_ref)++;
|
||||
}
|
||||
|
||||
~MmgedSharedPtr ()
|
||||
{
|
||||
(*this->_ref)--;
|
||||
if (*this->_ref <= 0)
|
||||
{
|
||||
if (this->_ptr) this->deleter (this->_ptr, this->_darg);
|
||||
// no destructor as *this->_ref is a plain type.
|
||||
::operator delete (this->_ref, this->getMmgr());
|
||||
}
|
||||
}
|
||||
|
||||
SelfType& operator= (const SelfType& ptr)
|
||||
{
|
||||
if (this != &ptr)
|
||||
{
|
||||
(*this->_ref)--;
|
||||
if (*this->_ref <= 0)
|
||||
{
|
||||
if (this->_ptr) this->deleter (this->_ptr, this->_darg);
|
||||
// no destructor as *this->_ref is a plain type.
|
||||
::operator delete (this->_ref, this->getMmgr());
|
||||
}
|
||||
|
||||
this->mmgr = ptr.getMmgr(); // memory manager must be copied
|
||||
this->_ptr = ptr._ptr;
|
||||
this->_darg = ptr._darg;
|
||||
this->_ref = ptr._ref;
|
||||
(*this->_ref)++;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
T& operator* ()
|
||||
{
|
||||
QSE_ASSERT (this->_ptr != (T*)QSE_NULL);
|
||||
return *this->_ptr;
|
||||
}
|
||||
|
||||
const T& operator* () const
|
||||
{
|
||||
QSE_ASSERT (this->_ptr != (T*)QSE_NULL);
|
||||
return *this->_ptr;
|
||||
}
|
||||
|
||||
T* operator-> ()
|
||||
{
|
||||
QSE_ASSERT (this->_ptr != (T*)QSE_NULL);
|
||||
return this->_ptr;
|
||||
}
|
||||
|
||||
const T* operator-> () const
|
||||
{
|
||||
QSE_ASSERT (this->_ptr != (T*)QSE_NULL);
|
||||
return this->_ptr;
|
||||
}
|
||||
|
||||
bool operator! () const
|
||||
{
|
||||
return this->_ptr == (T*)QSE_NULL;
|
||||
}
|
||||
|
||||
T& operator[] (qse_size_t idx)
|
||||
{
|
||||
QSE_ASSERT (this->_ptr != (T*)QSE_NULL);
|
||||
return this->_ptr[idx];
|
||||
}
|
||||
|
||||
T* get ()
|
||||
{
|
||||
return this->_ptr;
|
||||
}
|
||||
|
||||
const T* get () const
|
||||
{
|
||||
return this->_ptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
qse_size_t* _ref;
|
||||
T* _ptr;
|
||||
void* _darg;
|
||||
DELETER deleter;
|
||||
};
|
||||
|
||||
/////////////////////////////////
|
||||
QSE_END_NAMESPACE(QSE)
|
||||
/////////////////////////////////
|
||||
|
||||
#endif
|
@ -209,6 +209,27 @@ struct ScopedPtrMmgrDeleter
|
||||
}
|
||||
};
|
||||
|
||||
// Customized deleter for SharedPtr
|
||||
template <typename T>
|
||||
struct SharedPtrMmgrDeleter
|
||||
{
|
||||
void operator() (T* ptr, void* arg)
|
||||
{
|
||||
ptr->~T ();
|
||||
::operator delete (ptr, (QSE::Mmgr*)arg);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct MmgedSharedPtrMmgrDeleter
|
||||
{
|
||||
void operator() (T* ptr, void* arg)
|
||||
{
|
||||
ptr->~T ();
|
||||
::operator delete (ptr, (QSE::Mmgr*)arg);
|
||||
}
|
||||
};
|
||||
|
||||
/////////////////////////////////
|
||||
QSE_END_NAMESPACE(QSE)
|
||||
/////////////////////////////////
|
||||
|
@ -102,7 +102,10 @@ public:
|
||||
|
||||
SelfType& operator= (const SelfType& table)
|
||||
{
|
||||
this->pair_tree = table.pair_tree;
|
||||
if (this != &table)
|
||||
{
|
||||
this->pair_tree = table.pair_tree;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -380,14 +380,17 @@ public:
|
||||
|
||||
SelfType& operator= (const SelfType& rbt)
|
||||
{
|
||||
this->clear (false);
|
||||
|
||||
// TODO: do the level-order traversal to minimize rebalancing.
|
||||
Iterator it = rbt.getIterator();
|
||||
while (it.isLegit())
|
||||
if (this != &rbt)
|
||||
{
|
||||
this->insert (*it);
|
||||
++it;
|
||||
this->clear (false);
|
||||
|
||||
// TODO: do the level-order traversal to minimize rebalancing.
|
||||
Iterator it = rbt.getIterator();
|
||||
while (it.isLegit())
|
||||
{
|
||||
this->insert (*it);
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
|
Reference in New Issue
Block a user