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);
|
||||
if (np)
|
||||
{
|
||||
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);
|
||||
this->remove_node (np, hc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
for (qse_size_t i = 0; i < (this->node_capacity << 1); i++)
|
||||
|
@ -290,6 +290,16 @@ public:
|
||||
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)
|
||||
{
|
||||
return this->pair_list.getIterator (index);
|
||||
|
@ -27,7 +27,6 @@
|
||||
#ifndef _QSE_CMN_STRBASE_HPP_
|
||||
#define _QSE_CMN_STRBASE_HPP_
|
||||
|
||||
|
||||
#include <qse/Hashable.hpp>
|
||||
#include <qse/Growable.hpp>
|
||||
#include <qse/RefCounted.hpp>
|
||||
@ -182,6 +181,42 @@ public:
|
||||
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)
|
||||
{
|
||||
this->_item = new(this->getMmgr()) StringItem (this->getMmgr(), this->round_capacity(capacity), (const CHAR_TYPE*)QSE_NULL, 0);
|
||||
@ -240,7 +275,7 @@ public:
|
||||
|
||||
~StrBase ()
|
||||
{
|
||||
this->deref_item ();
|
||||
if (this->_item) this->deref_item ();
|
||||
}
|
||||
|
||||
SelfType& operator= (const SelfType& str)
|
||||
@ -360,9 +395,14 @@ public:
|
||||
return this->_item->buffer;
|
||||
}
|
||||
|
||||
const CHAR_TYPE* getData() const
|
||||
{
|
||||
return this->_item->buffer;
|
||||
}
|
||||
|
||||
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 (
|
||||
this->_item->buffer, this->_item->size * QSE_SIZEOF(CHAR_TYPE));
|
||||
}
|
||||
@ -439,33 +479,45 @@ public:
|
||||
// you can call truncate twice. for instance,
|
||||
// str.truncate (1000).
|
||||
// str.truncate (100).
|
||||
|
||||
StringItem* old_item = QSE_NULL;
|
||||
|
||||
if (this->_item->isShared())
|
||||
if (this->_item)
|
||||
{
|
||||
StringItem* t;
|
||||
StringItem* old_item = QSE_NULL;
|
||||
|
||||
if (new_size > this->_item->capacity)
|
||||
t = this->_item->copy (this->getMmgr(), this->adjust_desired_capacity(new_size));
|
||||
else
|
||||
t = this->_item->copy (this->getMmgr());
|
||||
if (this->_item->isShared())
|
||||
{
|
||||
StringItem* t;
|
||||
|
||||
old_item = this->_item;
|
||||
this->_item = t;
|
||||
if (new_size > this->_item->capacity)
|
||||
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->_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);
|
||||
}
|
||||
|
||||
//
|
||||
@ -476,7 +528,7 @@ public:
|
||||
{
|
||||
if (size <= 0) return;
|
||||
if (index >= this->_item->size) index = this->_item->size;
|
||||
|
||||
|
||||
//
|
||||
// When the same instance is inserted as in n.insert(index, n) which
|
||||
// finally calls n.insert(index. n.this->_item->buffer, 0, n.this->_item->size),
|
||||
@ -992,7 +1044,6 @@ protected:
|
||||
OPSET _opset;
|
||||
RESIZER _resizer;
|
||||
|
||||
|
||||
private:
|
||||
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)
|
||||
/////////////////////////////////
|
||||
|
@ -181,11 +181,14 @@ struct MbStringOpset
|
||||
|
||||
class WcString: public StrBase<qse_wchar_t, QSE_WT('\0'), WcStringOpset>
|
||||
{
|
||||
public:
|
||||
private:
|
||||
typedef StrBase<qse_wchar_t, QSE_WT('\0'), WcStringOpset> ParentType;
|
||||
|
||||
public:
|
||||
WcString (): ParentType() {}
|
||||
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 (Mmgr* mmgr, qse_size_t capacity): ParentType(mmgr, capacity) {}
|
||||
WcString (const qse_wchar_t* str): ParentType(str) {}
|
||||
@ -207,11 +210,14 @@ public:
|
||||
|
||||
class MbString: public StrBase<qse_mchar_t, QSE_MT('\0'), MbStringOpset>
|
||||
{
|
||||
public:
|
||||
private:
|
||||
typedef StrBase<qse_mchar_t, QSE_MT('\0'), MbStringOpset> ParentType;
|
||||
|
||||
public:
|
||||
MbString (): ParentType() {}
|
||||
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 (Mmgr* mmgr, qse_size_t capacity): ParentType(mmgr, capacity) {}
|
||||
MbString (const qse_mchar_t* str): ParentType(str) {}
|
||||
@ -231,10 +237,38 @@ public:
|
||||
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)
|
||||
typedef MbString String;
|
||||
typedef MbPtrString PtrString;
|
||||
#else
|
||||
typedef WcString String;
|
||||
typedef WcPtrString PtrString;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////
|
||||
|
Loading…
Reference in New Issue
Block a user