added to StrBase a special constructor that doesn't allocation a buffer.
added PtrString classes added removeNode to HashList and HashTable. added findNode to HashTable
This commit is contained in:
parent
211f5b014e
commit
559f965aa5
@ -581,31 +581,44 @@ public:
|
|||||||
Node* np = this->heterofind_node<MT,MEQUALER> (datum, hc);
|
Node* np = this->heterofind_node<MT,MEQUALER> (datum, hc);
|
||||||
if (np)
|
if (np)
|
||||||
{
|
{
|
||||||
qse_size_t head, tail;
|
this->remove_node (np, hc);
|
||||||
|
|
||||||
head = hc << 1; tail = head + 1;
|
|
||||||
|
|
||||||
if (this->nodes[head] == this->nodes[tail])
|
|
||||||
{
|
|
||||||
QSE_ASSERT (np == this->nodes[head]);
|
|
||||||
this->nodes[head] = this->nodes[tail] = QSE_NULL;
|
|
||||||
}
|
|
||||||
else if (np == this->nodes[head])
|
|
||||||
{
|
|
||||||
this->nodes[head] = np->getNextNode();
|
|
||||||
}
|
|
||||||
else if (np == this->nodes[tail])
|
|
||||||
{
|
|
||||||
this->nodes[tail] = np->getPrevNode();
|
|
||||||
}
|
|
||||||
|
|
||||||
this->datum_list->remove (np);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void removeNode (Node* np)
|
||||||
|
{
|
||||||
|
T& datum = np->value;
|
||||||
|
qse_size_t hc = this->_hasher(datum) % this->node_capacity;
|
||||||
|
this->remove_node (np, hc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void remove_node (Node* np, qse_size_t hc)
|
||||||
|
{
|
||||||
|
qse_size_t head, tail;
|
||||||
|
head = hc << 1; tail = head + 1;
|
||||||
|
|
||||||
|
if (this->nodes[head] == this->nodes[tail])
|
||||||
|
{
|
||||||
|
QSE_ASSERT (np == this->nodes[head]);
|
||||||
|
this->nodes[head] = this->nodes[tail] = QSE_NULL;
|
||||||
|
}
|
||||||
|
else if (np == this->nodes[head])
|
||||||
|
{
|
||||||
|
this->nodes[head] = np->getNextNode();
|
||||||
|
}
|
||||||
|
else if (np == this->nodes[tail])
|
||||||
|
{
|
||||||
|
this->nodes[tail] = np->getPrevNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
this->datum_list->remove (np);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
void clear (bool clear_mpool = false)
|
void clear (bool clear_mpool = false)
|
||||||
{
|
{
|
||||||
for (qse_size_t i = 0; i < (this->node_capacity << 1); i++)
|
for (qse_size_t i = 0; i < (this->node_capacity << 1); i++)
|
||||||
|
@ -290,6 +290,16 @@ public:
|
|||||||
return this->pair_list.clear (clear_mpool);
|
return this->pair_list.clear (clear_mpool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void removeNode (PairNode* node)
|
||||||
|
{
|
||||||
|
this->pair_list.removeNode (node);
|
||||||
|
}
|
||||||
|
|
||||||
|
PairNode* findNode (const K& key)
|
||||||
|
{
|
||||||
|
return this->pair_list.findNode (key);
|
||||||
|
}
|
||||||
|
|
||||||
Iterator getIterator (qse_size_t index = 0)
|
Iterator getIterator (qse_size_t index = 0)
|
||||||
{
|
{
|
||||||
return this->pair_list.getIterator (index);
|
return this->pair_list.getIterator (index);
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
#ifndef _QSE_CMN_STRBASE_HPP_
|
#ifndef _QSE_CMN_STRBASE_HPP_
|
||||||
#define _QSE_CMN_STRBASE_HPP_
|
#define _QSE_CMN_STRBASE_HPP_
|
||||||
|
|
||||||
|
|
||||||
#include <qse/Hashable.hpp>
|
#include <qse/Hashable.hpp>
|
||||||
#include <qse/Growable.hpp>
|
#include <qse/Growable.hpp>
|
||||||
#include <qse/RefCounted.hpp>
|
#include <qse/RefCounted.hpp>
|
||||||
@ -182,6 +181,42 @@ public:
|
|||||||
this->ref_item ();
|
this->ref_item ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StrBase (int capacity): Mmged(QSE_NULL)
|
||||||
|
{
|
||||||
|
if (capacity <= -1)
|
||||||
|
{
|
||||||
|
// this is a special constructor to instanatiate a string with no buffer.
|
||||||
|
// it is intended to be followed by truncate() for actual buffer allocation.
|
||||||
|
// all other functions except the destructor and the truncation() function
|
||||||
|
// are not aware of this special condition.
|
||||||
|
//
|
||||||
|
// String x(0);
|
||||||
|
// try { x.truncate(10); } catch (...) { return -1; }
|
||||||
|
// x.append ("xxx");
|
||||||
|
//
|
||||||
|
this->_item = QSE_NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->_item = new(this->getMmgr()) StringItem (this->getMmgr(), this->round_capacity(capacity), (const CHAR_TYPE*)QSE_NULL, 0);
|
||||||
|
this->ref_item ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StrBase (Mmgr* mmgr, int capacity): Mmged(mmgr)
|
||||||
|
{
|
||||||
|
if (capacity <= -1)
|
||||||
|
{
|
||||||
|
// this is a special constructor to instanatiate a string with no buffer.
|
||||||
|
// it is intended to be followed by truncate() for actual buffer allocation.
|
||||||
|
this->_item = QSE_NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->_item = new(this->getMmgr()) StringItem (this->getMmgr(), this->round_capacity(capacity), (const CHAR_TYPE*)QSE_NULL, 0);
|
||||||
|
this->ref_item ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
StrBase (qse_size_t capacity): Mmged(QSE_NULL)
|
StrBase (qse_size_t capacity): Mmged(QSE_NULL)
|
||||||
{
|
{
|
||||||
this->_item = new(this->getMmgr()) StringItem (this->getMmgr(), this->round_capacity(capacity), (const CHAR_TYPE*)QSE_NULL, 0);
|
this->_item = new(this->getMmgr()) StringItem (this->getMmgr(), this->round_capacity(capacity), (const CHAR_TYPE*)QSE_NULL, 0);
|
||||||
@ -240,7 +275,7 @@ public:
|
|||||||
|
|
||||||
~StrBase ()
|
~StrBase ()
|
||||||
{
|
{
|
||||||
this->deref_item ();
|
if (this->_item) this->deref_item ();
|
||||||
}
|
}
|
||||||
|
|
||||||
SelfType& operator= (const SelfType& str)
|
SelfType& operator= (const SelfType& str)
|
||||||
@ -360,9 +395,14 @@ public:
|
|||||||
return this->_item->buffer;
|
return this->_item->buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CHAR_TYPE* getData() const
|
||||||
|
{
|
||||||
|
return this->_item->buffer;
|
||||||
|
}
|
||||||
|
|
||||||
qse_size_t getHashCode () const
|
qse_size_t getHashCode () const
|
||||||
{
|
{
|
||||||
// keep this in sync with getHashCode of BasePtrString<CHAR_TYPE>
|
// keep this in sync with getHashCode() of PtrStrBase<CHAR_TYPE>
|
||||||
return Hashable::getHashCode (
|
return Hashable::getHashCode (
|
||||||
this->_item->buffer, this->_item->size * QSE_SIZEOF(CHAR_TYPE));
|
this->_item->buffer, this->_item->size * QSE_SIZEOF(CHAR_TYPE));
|
||||||
}
|
}
|
||||||
@ -439,33 +479,45 @@ public:
|
|||||||
// you can call truncate twice. for instance,
|
// you can call truncate twice. for instance,
|
||||||
// str.truncate (1000).
|
// str.truncate (1000).
|
||||||
// str.truncate (100).
|
// str.truncate (100).
|
||||||
|
if (this->_item)
|
||||||
StringItem* old_item = QSE_NULL;
|
|
||||||
|
|
||||||
if (this->_item->isShared())
|
|
||||||
{
|
{
|
||||||
StringItem* t;
|
StringItem* old_item = QSE_NULL;
|
||||||
|
|
||||||
if (new_size > this->_item->capacity)
|
if (this->_item->isShared())
|
||||||
t = this->_item->copy (this->getMmgr(), this->adjust_desired_capacity(new_size));
|
{
|
||||||
else
|
StringItem* t;
|
||||||
t = this->_item->copy (this->getMmgr());
|
|
||||||
|
|
||||||
old_item = this->_item;
|
if (new_size > this->_item->capacity)
|
||||||
this->_item = t;
|
t = this->_item->copy (this->getMmgr(), this->adjust_desired_capacity(new_size));
|
||||||
|
else
|
||||||
|
t = this->_item->copy (this->getMmgr());
|
||||||
|
|
||||||
|
old_item = this->_item;
|
||||||
|
this->_item = t;
|
||||||
|
this->ref_item ();
|
||||||
|
}
|
||||||
|
else if (new_size > this->_item->capacity)
|
||||||
|
{
|
||||||
|
StringItem* t = this->_item->copy (this->getMmgr(), this->adjust_desired_capacity(new_size));
|
||||||
|
old_item = this->_item;
|
||||||
|
this->_item = t;
|
||||||
|
this->ref_item ();;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->_item->buffer[new_size] = NULL_CHAR;
|
||||||
|
this->_item->size = new_size;
|
||||||
|
if (old_item) this->deref_item (old_item);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// this is the only function that supports some use-cases
|
||||||
|
// of a string object created with no buffer at all.
|
||||||
|
// read comments in the special constructor
|
||||||
|
this->_item = new(this->getMmgr()) StringItem (this->getMmgr(), this->round_capacity(new_size), (const CHAR_TYPE*)QSE_NULL, 0);
|
||||||
this->ref_item ();
|
this->ref_item ();
|
||||||
|
this->_item->buffer[new_size] = NULL_CHAR;
|
||||||
|
this->_item->size = new_size;
|
||||||
}
|
}
|
||||||
else if (new_size > this->_item->capacity)
|
|
||||||
{
|
|
||||||
StringItem* t = this->_item->copy (this->getMmgr(), this->adjust_desired_capacity(new_size));
|
|
||||||
old_item = this->_item;
|
|
||||||
this->_item = t;
|
|
||||||
this->ref_item ();;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->_item->buffer[new_size] = NULL_CHAR;
|
|
||||||
this->_item->size = new_size;
|
|
||||||
if (old_item) this->deref_item (old_item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -992,7 +1044,6 @@ protected:
|
|||||||
OPSET _opset;
|
OPSET _opset;
|
||||||
RESIZER _resizer;
|
RESIZER _resizer;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
qse_size_t adjust_desired_capacity (qse_size_t new_desired_capacity)
|
qse_size_t adjust_desired_capacity (qse_size_t new_desired_capacity)
|
||||||
{
|
{
|
||||||
@ -1003,6 +1054,76 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <typename CHAR_TYPE, CHAR_TYPE NULL_CHAR, typename OPSET, typename RESIZER = StrBaseResizer>
|
||||||
|
class PtrStrBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef PtrStrBase<CHAR_TYPE,NULL_CHAR,OPSET,RESIZER> ThisType;
|
||||||
|
typedef StrBase<CHAR_TYPE,NULL_CHAR,OPSET,RESIZER> StringType;
|
||||||
|
|
||||||
|
PtrStrBase (): ptr (QSE_NULL), len (0) {}
|
||||||
|
|
||||||
|
PtrStrBase (const CHAR_TYPE* ptr): ptr (ptr)
|
||||||
|
{
|
||||||
|
this->len = this->_opset.getLength (ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
PtrStrBase (const CHAR_TYPE* ptr, qse_size_t len): ptr (ptr), len (len)
|
||||||
|
{
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_size_t getHashCode () const
|
||||||
|
{
|
||||||
|
// keep this in sync with hashCode of StringType(StrBase)
|
||||||
|
return Hashable::getHashCode (this->ptr, this->len * QSE_SIZEOF(CHAR_TYPE));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator== (const ThisType& ps) const
|
||||||
|
{
|
||||||
|
if (this->len != ps.len) return false;
|
||||||
|
return this->_opset.compare (this->ptr, ps.ptr, this->len) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!= (const ThisType& ps) const
|
||||||
|
{
|
||||||
|
return !this->operator== (ps);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator== (const StringType& s) const
|
||||||
|
{
|
||||||
|
if (this->len != s.getLength()) return false;
|
||||||
|
return this->_opset.compare (this->ptr, s.getBuffer(), this->len) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!= (const StringType& s) const
|
||||||
|
{
|
||||||
|
return !this->operator== (s);
|
||||||
|
}
|
||||||
|
|
||||||
|
operator const CHAR_TYPE* () const
|
||||||
|
{
|
||||||
|
return this->ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CHAR_TYPE* getData() const
|
||||||
|
{
|
||||||
|
return this->ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_size_t getLength() const
|
||||||
|
{
|
||||||
|
return this->len;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const CHAR_TYPE* ptr;
|
||||||
|
qse_size_t len;
|
||||||
|
|
||||||
|
OPSET _opset;
|
||||||
|
};
|
||||||
|
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
QSE_END_NAMESPACE(QSE)
|
QSE_END_NAMESPACE(QSE)
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
|
@ -181,11 +181,14 @@ struct MbStringOpset
|
|||||||
|
|
||||||
class WcString: public StrBase<qse_wchar_t, QSE_WT('\0'), WcStringOpset>
|
class WcString: public StrBase<qse_wchar_t, QSE_WT('\0'), WcStringOpset>
|
||||||
{
|
{
|
||||||
public:
|
private:
|
||||||
typedef StrBase<qse_wchar_t, QSE_WT('\0'), WcStringOpset> ParentType;
|
typedef StrBase<qse_wchar_t, QSE_WT('\0'), WcStringOpset> ParentType;
|
||||||
|
|
||||||
|
public:
|
||||||
WcString (): ParentType() {}
|
WcString (): ParentType() {}
|
||||||
WcString (Mmgr* mmgr): ParentType(mmgr) {}
|
WcString (Mmgr* mmgr): ParentType(mmgr) {}
|
||||||
|
WcString (int capacity): ParentType(capacity) {}
|
||||||
|
WcString (Mmgr* mmgr, int capacity): ParentType(mmgr, capacity) {}
|
||||||
WcString (qse_size_t capacity): ParentType(capacity) {}
|
WcString (qse_size_t capacity): ParentType(capacity) {}
|
||||||
WcString (Mmgr* mmgr, qse_size_t capacity): ParentType(mmgr, capacity) {}
|
WcString (Mmgr* mmgr, qse_size_t capacity): ParentType(mmgr, capacity) {}
|
||||||
WcString (const qse_wchar_t* str): ParentType(str) {}
|
WcString (const qse_wchar_t* str): ParentType(str) {}
|
||||||
@ -207,11 +210,14 @@ public:
|
|||||||
|
|
||||||
class MbString: public StrBase<qse_mchar_t, QSE_MT('\0'), MbStringOpset>
|
class MbString: public StrBase<qse_mchar_t, QSE_MT('\0'), MbStringOpset>
|
||||||
{
|
{
|
||||||
public:
|
private:
|
||||||
typedef StrBase<qse_mchar_t, QSE_MT('\0'), MbStringOpset> ParentType;
|
typedef StrBase<qse_mchar_t, QSE_MT('\0'), MbStringOpset> ParentType;
|
||||||
|
|
||||||
|
public:
|
||||||
MbString (): ParentType() {}
|
MbString (): ParentType() {}
|
||||||
MbString (Mmgr* mmgr): ParentType(mmgr) {}
|
MbString (Mmgr* mmgr): ParentType(mmgr) {}
|
||||||
|
MbString (int capacity): ParentType(capacity) {}
|
||||||
|
MbString (Mmgr* mmgr, int capacity): ParentType(mmgr, capacity) {}
|
||||||
MbString (qse_size_t capacity): ParentType(capacity) {}
|
MbString (qse_size_t capacity): ParentType(capacity) {}
|
||||||
MbString (Mmgr* mmgr, qse_size_t capacity): ParentType(mmgr, capacity) {}
|
MbString (Mmgr* mmgr, qse_size_t capacity): ParentType(mmgr, capacity) {}
|
||||||
MbString (const qse_mchar_t* str): ParentType(str) {}
|
MbString (const qse_mchar_t* str): ParentType(str) {}
|
||||||
@ -231,10 +237,38 @@ public:
|
|||||||
int formatv (const qse_mchar_t* fmt, va_list ap);
|
int formatv (const qse_mchar_t* fmt, va_list ap);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class WcPtrString: public PtrStrBase<qse_wchar_t, QSE_MT('\0'), WcStringOpset>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef PtrStrBase<qse_wchar_t, QSE_MT('\0'), WcStringOpset> ParentType;
|
||||||
|
|
||||||
|
public:
|
||||||
|
WcPtrString () {}
|
||||||
|
WcPtrString (const qse_wchar_t* ptr): ParentType(ptr) {}
|
||||||
|
WcPtrString (const qse_wchar_t* ptr, qse_size_t len): ParentType(ptr, len) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class MbPtrString: public PtrStrBase<qse_mchar_t, QSE_MT('\0'), MbStringOpset>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef PtrStrBase<qse_mchar_t, QSE_MT('\0'), MbStringOpset> ParentType;
|
||||||
|
|
||||||
|
public:
|
||||||
|
MbPtrString () {}
|
||||||
|
MbPtrString (const qse_mchar_t* ptr): ParentType(ptr) {}
|
||||||
|
MbPtrString (const qse_mchar_t* ptr, qse_size_t len): ParentType(ptr, len) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(QSE_CHAR_IS_MCHAR)
|
#if defined(QSE_CHAR_IS_MCHAR)
|
||||||
typedef MbString String;
|
typedef MbString String;
|
||||||
|
typedef MbPtrString PtrString;
|
||||||
#else
|
#else
|
||||||
typedef WcString String;
|
typedef WcString String;
|
||||||
|
typedef WcPtrString PtrString;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
|
Loading…
Reference in New Issue
Block a user