![]() |
Qore Programming Language 2.3.0
|
Data in Qore is handled with QoreValue, an 8-byte NaN-boxed value type that uses IEEE 754 double-precision NaN bit patterns to encode multiple value types in a single 64-bit word.
QoreValue uses NaN-boxing to efficiently store the following types inline (no heap allocation):
bool (true/false stored as special values)int64 (48-bit signed integers stored inline; larger integers use QoreBigIntNode)double (all IEEE 754 doubles including NaN, Inf, -0.0)This encoding provides significant performance benefits:
All complex values in Qore are descended from AbstractQoreNode.
The following are the basic data types in Qore, implemented as C++ classes descended from AbstractQoreNode, and their type codes, accessed via AbstractQoreNode::getType():
nullptr!)Additionally, the following classes are exposed in the library:
The fastest way to directly access data of a specific type is to use QoreValue::getType() and then the QoreValue::get() template as follows:
For inline types, use the type-specific fast extraction methods:
For class members, always use brace initialization in the member declaration:
The QoreStringNode (NT_STRING), DateTimeNode (NT_DATE), and BinaryNode (NT_BINARY) classes are reference counted and can only be dynamically allocated.
They are all descendents of SimpleQoreNode, meaning that dereferencing their objects cannot cause a Qore-language exception to be thrown (hence all support the SimpleQoreNode::deref() function), therefore the SimpleRefHolder class can be used to manage temporary references to objects of these types.
For example:
With NaN-boxing, NOTHING and NULL are stored as special inline bit patterns in QoreValue, not as pointers to singleton objects. This makes testing for these values very efficient.
For backward compatibility with code using AbstractQoreNode pointers, the QoreNullNode and QoreNothingNode classes still exist, but when stored in a QoreValue, they are converted to the inline representation.
val.isNothing() over is_nothing(val.getInternalNode()) as the former is much faster (single bit comparison vs function call and pointer dereference).The legacy global objects Null and Nothing still exist for compatibility with older code that works with AbstractQoreNode pointers directly.
The QoreHashNode (NT_HASH), QoreListNode (NT_LIST), and QoreObject (NT_OBJECT) classes define container types in Qore. QoreObject objects in particular could throw an exception when dereferenced (if the object goes out of scope and its destructor is run, the destructor could throw an exception). Because container types can hold any type, when they are deferenced it could cause a QoreObject to go out of scope, and therefore the possibility that a Qore-language exception could be thrown must be taken into consideration. Therefore, to dereference these objects a pointer to an ExceptionSink object must be passed to AbstractQoreNode::deref().
The ReferenceHolder class can be used to manage temporary reference counts as follows:
QoreObject objects have node type NT_OBJECT as returned by AbstractQoreNode::getType().
QoreObject is special in that the implementation for objects in Qore mirrors that of Java, in that objects are passed by reference when used as function or method arguments, unlike other types. However, like Java, the reference to the object is passed, and not the value, so, while an object passed as an argument to a function can be modified by that function (modifications are made to the original object), in order to write a swap method, for example, you would need to pass the variables by reference (or the lvalue expression by reference, as the case may be) to the swap function. Unlike Java, Qore does support passing arguments by reference.
Handling lvalue references is more complicated, as access to global variables and object member references must be made under the appropriate thread locks. However the QoreTypeSafeReferenceHelper class makes access to lvalue references much easier and takes care of all the locking, access to the lvalue expression, as well as type enforcement. With the QoreTypeSafeReferenceHelper class you can get the type of the lvalue expression's value, get a pointer to a node with a reference count of 1 for in-place modification, or assign a new value to the lvalue.
Here is an example of the use of QoreTypeSafeReferenceHelper: