32 #ifndef _QORE_QOREHASHNODEINTERN_H 34 #define _QORE_QOREHASHNODEINTERN_H 44 DLLLOCAL HashMember(
const char* n_key) : key(n_key) {
47 DLLLOCAL ~HashMember() {
51 typedef std::list<HashMember*> qhlist_t;
53 #ifdef HAVE_QORE_HASH_MAP 55 #include <qore/hash_map_include.h> 56 #include "qore/intern/xxhash.h" 58 typedef HASH_MAP<const char*, qhlist_t::iterator, qore_hash_str, eqstr> hm_hm_t;
60 typedef std::map<const char*, qhlist_t::iterator, ltstr> hm_hm_t;
69 DLLLOCAL qhi_priv() : val(false) {
72 DLLLOCAL qhi_priv(
const qhi_priv& old) : i(old.i), val(old.val) {
75 DLLLOCAL
bool valid()
const {
79 DLLLOCAL
bool next(qhlist_t& ml) {
82 if (ml.begin() != ml.end()) {
95 DLLLOCAL
bool prev(qhlist_t& ml) {
97 if (ml.begin() != ml.end()) {
112 DLLLOCAL
void reset() {
121 class qore_hash_private {
123 qhlist_t member_list;
127 const QoreTypeInfo* complexTypeInfo =
nullptr;
128 unsigned obj_count = 0;
133 DLLLOCAL qore_hash_private() {
138 DLLLOCAL ~qore_hash_private() {
139 assert(member_list.empty());
142 DLLLOCAL
QoreValue getKeyValueIntern(
const char* key)
const;
146 DLLLOCAL
QoreValue getKeyValueExistenceIntern(
const char* key,
bool& exists)
const;
148 DLLLOCAL
int checkKey(
const char* key,
ExceptionSink* xsink)
const;
150 DLLLOCAL
QoreValue getReferencedKeyValueIntern(
const char* key)
const {
152 return getReferencedKeyValueIntern(key, exists);
155 DLLLOCAL
QoreValue getReferencedKeyValueIntern(
const char* key,
bool& exists)
const {
158 hm_hm_t::const_iterator i = hm.find(key);
161 return (*(i->second))->val.refSelf();
168 DLLLOCAL
int64 getKeyAsBigInt(
const char* key,
bool &found)
const {
170 hm_hm_t::const_iterator i = hm.find(key);
174 return (*(i->second))->val.getAsBigInt();
181 DLLLOCAL
bool getKeyAsBool(
const char* key,
bool& found)
const {
183 hm_hm_t::const_iterator i = hm.find(key);
187 return (*(i->second))->val.getAsBool();
194 DLLLOCAL
bool existsKey(
const char* key)
const {
196 return hm.find(key) != hm.end();
199 DLLLOCAL
bool existsKeyValue(
const char* key)
const {
201 hm_hm_t::const_iterator i = hm.find(key);
204 return !(*(i->second))->val.isNothing();
207 DLLLOCAL HashMember* findMember(
const char* key) {
209 hm_hm_t::iterator i = hm.find(key);
210 return i != hm.end() ? (*(i->second)) :
nullptr;
213 DLLLOCAL HashMember* findCreateMember(
const char* key) {
215 HashMember* om = findMember(key);
219 om =
new HashMember(key);
220 assert(om->val.isNothing());
221 member_list.push_back(om);
224 qhlist_t::iterator i = member_list.end();
226 hm[om->key.c_str()] = i;
232 DLLLOCAL
QoreValue& getValueRef(
const char* key) {
233 return findCreateMember(key)->val;
238 DLLLOCAL
void internDeleteKey(qhlist_t::iterator i) {
241 member_list.erase(i);
247 DLLLOCAL
void deleteKey(
const char* key,
ExceptionSink *xsink) {
250 hm_hm_t::iterator i = hm.find(key);
255 qhlist_t::iterator li = i->second;
265 reinterpret_cast<QoreObject*>(n)->doDelete(xsink);
273 DLLLOCAL
void removeKey(
const char* key,
ExceptionSink *xsink) {
274 takeKeyValueIntern(key).discard(xsink);
277 DLLLOCAL
QoreValue takeKeyValueIntern(
const char* key) {
280 hm_hm_t::iterator i = hm.find(key);
285 qhlist_t::iterator li = i->second;
297 DLLLOCAL
const char* getFirstKey()
const {
298 return member_list.empty() ? nullptr : member_list.front()->key.c_str();
301 DLLLOCAL
const char* getLastKey()
const {
302 return member_list.empty() ? nullptr : member_list.back()->key.c_str();
307 DLLLOCAL
void merge(
const qore_hash_private& h,
ExceptionSink* xsink);
309 DLLLOCAL
int getLValue(
const char* key, LValueHelper& lvh,
bool for_remove,
ExceptionSink* xsink);
311 DLLLOCAL
void getTypeName(
QoreString& str)
const {
314 else if (complexTypeInfo)
315 str.
concat(QoreTypeInfo::getName(complexTypeInfo));
326 h->
priv->hashdecl = hashdecl;
328 h->
priv->complexTypeInfo = complexTypeInfo;
332 DLLLOCAL
QoreHashNode* getEmptyCopy(
bool is_value)
const {
335 h->
priv->hashdecl = hashdecl;
337 h->
priv->complexTypeInfo = complexTypeInfo;
341 DLLLOCAL
QoreHashNode* copyCheckNewType(
const qore_hash_private& other)
const {
343 if (hashdecl || other.hashdecl) {
344 if (!hashdecl || !other.hashdecl || !hashdecl->
equal(other.hashdecl)) {
345 rv->
priv->hashdecl =
nullptr;
346 rv->
priv->complexTypeInfo = autoHashTypeInfo;
349 const QoreTypeInfo* orig_ctype, * ctype;
350 orig_ctype = ctype = QoreTypeInfo::getUniqueReturnComplexHash(complexTypeInfo);
351 const QoreTypeInfo* newElementType = QoreTypeInfo::getUniqueReturnComplexHash(other.complexTypeInfo);
352 if ((!ctype || ctype == anyTypeInfo) && (!newElementType || newElementType == anyTypeInfo)) {
353 rv->
priv->complexTypeInfo =
nullptr;
354 }
else if (QoreTypeInfo::matchCommonType(ctype, newElementType)) {
355 rv->
priv->complexTypeInfo = ctype == orig_ctype ? complexTypeInfo : qore_get_complex_hash_type(ctype);
357 rv->
priv->complexTypeInfo = autoHashTypeInfo;
363 DLLLOCAL
QoreHashNode* copy(
const QoreTypeInfo* newComplexTypeInfo)
const {
365 h->
priv->complexTypeInfo = newComplexTypeInfo;
366 copyIntern(*h->
priv);
373 if (!strip || (!complexTypeInfo && !hashdecl)) {
375 copyIntern(*h->
priv);
380 for (
auto& i : member_list) {
381 hash_assignment_priv ha(*h, i->key.c_str());
382 QoreValue v = copy_strip_complex_types(i->val);
384 assert(ha.swap(v).isNothing());
393 DLLLOCAL
void copyIntern(qore_hash_private& h)
const {
395 for (
auto& i : member_list) {
396 hash_assignment_priv ha(h, i->key.c_str());
398 assert(ha.swap(i->val.refSelf()).isNothing());
400 ha.swap(i->val.refSelf());
410 return *xsink ? nullptr : rv.release();
416 for (qhlist_t::const_iterator i = member_list.begin(), e = member_list.end(); i != e; ++i) {
417 h->
priv->setKeyValue((*i)->key, (*i)->val.refSelf(), xsink);
425 DLLLOCAL
void setKeyValueIntern(
const char* key,
QoreValue v) {
426 hash_assignment_priv ha(*
this, key);
433 hash_assignment_priv ha(*
this, key);
434 ha.assign(val, xsink);
438 hash_assignment_priv ha(*
this, key.c_str());
439 ha.assign(val, xsink);
443 hash_assignment_priv ha(*
this, key,
false, o);
444 ha.assign(val, xsink);
447 DLLLOCAL
bool derefImpl(
ExceptionSink* xsink,
bool reverse =
false) {
449 for (qhlist_t::reverse_iterator i = member_list.rbegin(), e = member_list.rend(); i != e; ++i) {
450 (*i)->val.discard(xsink);
454 for (qhlist_t::iterator i = member_list.begin(), e = member_list.end(); i != e; ++i) {
455 (*i)->val.discard(xsink);
466 DLLLOCAL
QoreValue swapKeyValue(
const char* key,
QoreValue val, qore_object_private* o) {
469 hash_assignment_priv ha(*
this, key,
false, o);
474 derefImpl(xsink, reverse);
477 DLLLOCAL
size_t size()
const {
478 return member_list.size();
481 DLLLOCAL
bool empty()
const {
482 return member_list.empty();
485 DLLLOCAL
void incScanCount(
int dt) {
488 assert(obj_count || dt > 0);
493 DLLLOCAL
const QoreTypeInfo* getValueTypeInfo()
const {
494 return complexTypeInfo ? QoreTypeInfo::getComplexHashValueType(complexTypeInfo) : nullptr;
497 DLLLOCAL
const QoreTypeInfo* getTypeInfo()
const {
501 return complexTypeInfo;
510 if (!h->
priv->hashdecl && !h->
priv->complexTypeInfo)
514 return h->
priv->copy(
true);
519 rv->
priv->hashdecl = hd;
523 DLLLOCAL
static qore_hash_private*
get(
QoreHashNode& h) {
527 DLLLOCAL
static const qore_hash_private*
get(
const QoreHashNode& h) {
532 DLLLOCAL
static int parseInitHashInitialization(
const QoreProgramLocation* loc, LocalVar *oflag,
int pflag,
int& lvids, QoreParseListNode* args,
const QoreTypeInfo*& argTypeInfo,
QoreValue& arg);
534 DLLLOCAL
static int parseInitComplexHashInitialization(
const QoreProgramLocation* loc, LocalVar *oflag,
int pflag, QoreParseListNode* args,
const QoreTypeInfo* vti);
536 DLLLOCAL
static void parseCheckComplexHashInitialization(
const QoreProgramLocation* loc,
const QoreTypeInfo* typeInfo,
const QoreTypeInfo* expTypeInfo,
QoreValue exp,
const char* context_action,
bool strict_check =
true);
538 DLLLOCAL
static void parseCheckTypedAssignment(
const QoreProgramLocation* loc,
QoreValue arg,
const QoreTypeInfo* vti,
const char* context_action,
bool strict_check =
true);
540 DLLLOCAL
static QoreHashNode* newComplexHash(
const QoreTypeInfo* typeInfo,
const QoreParseListNode* args,
ExceptionSink* xsink);
544 DLLLOCAL
static unsigned getScanCount(
const QoreHashNode& h) {
545 assert(!h.
priv->is_obj);
546 return h.
priv->obj_count;
549 DLLLOCAL
static void incScanCount(
const QoreHashNode& h,
int dt) {
550 assert(!h.
priv->is_obj);
551 h.
priv->incScanCount(dt);
555 return h->
priv->member_list.empty() ?
QoreValue() : h->priv->member_list.front()->val;
559 return h->
priv->member_list.empty() ?
QoreValue() : h->priv->member_list.back()->val;
DLLLOCAL qore_type_t getType() const
returns the data type
Definition: AbstractQoreNode.h:172
DLLEXPORT const char * getName() const
returns the name of the typed hash
This is the hash or associative list container type in Qore, dynamically allocated only...
Definition: QoreHashNode.h:50
DLLEXPORT bool equal(const TypedHashDecl *other) const
returns true if the hashdecl passed as an arugment is equal to this hashdecl
DLLEXPORT int sprintf(const char *fmt,...)
this will concatentate a formatted string to the existing string according to the format string and t...
The base class for all value and parse types in Qore expression trees.
Definition: AbstractQoreNode.h:54
const qore_type_t NT_OBJECT
type value for QoreObject
Definition: node_types.h:52
class qore_hash_private * priv
private implementation of the class
Definition: QoreHashNode.h:69
Qore's string type supported by the QoreEncoding class.
Definition: QoreString.h:81
DLLEXPORT void concat(const QoreString *str, ExceptionSink *xsink)
concatenates a string and converts encodings if necessary
This is the list container type in Qore, dynamically allocated only, reference counted.
Definition: QoreListNode.h:52
The main value class in Qore, designed to be passed by value.
Definition: QoreValue.h:262
DLLEXPORT const QoreTypeInfo * getTypeInfo(bool or_nothing=false) const
returns the type info object for the hashdecl
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:46
DLLEXPORT void deref(ExceptionSink *xsink)
decrements the reference count and calls derefImpl() if there_can_be_only_one is false, otherwise does nothing
long long int64
64bit integer type, cannot use int64_t here since it breaks the API on some 64-bit systems due to equ...
Definition: common.h:260
typed hash declaration
Definition: TypedHashDecl.h:44
holds an object and dereferences it in the destructor
Definition: QoreValue.h:452
iterator class for QoreHashNode, to be only created on the stack
Definition: QoreHashNode.h:433