32 #ifndef _QORE_INTERN_QORELVALUE_H
34 #define _QORE_INTERN_QORELVALUE_H
38 template <
typename U = qore_value_u>
42 template <
class T,
typename t,
int nt>
44 assert(type == QV_Node);
49 return reinterpret_cast<T*
>(v.n =
new T);
51 if (v.n->getType() != nt) {
52 t i = T::getValue(v.n);
54 return reinterpret_cast<T*
>(v.n =
new T(i));
58 return reinterpret_cast<T*
>(v.n);
61 return reinterpret_cast<T*
>((v.n = old->
realCopy()));
64 DLLLOCAL
void reset() {
65 assert(!assigned || type != QV_Node || !v.n);
68 assert(!static_assignment);
80 bool static_assignment : 1;
85 DLLLOCAL QoreLValue() : type(QV_Node), fixed_type(false), assigned(false), static_assignment(false),
93 DLLLOCAL QoreLValue(valtype_t t) : type(t), fixed_type(t != QV_Node), assigned(false), static_assignment(false),
103 DLLLOCAL QoreLValue(
const QoreTypeInfo* typeInfo) : assigned(false), static_assignment(false), is_closure(false) {
110 DLLLOCAL QoreLValue(
const QoreLValue<U>& old) : type(old.type), fixed_type(old.fixed_type),
111 assigned(old.assigned), static_assignment(false), is_closure(old.is_closure) {
115 case QV_Bool: v.b = old.v.b;
break;
116 case QV_Int: v.i = old.v.i;
break;
117 case QV_Float: v.f = old.v.f;
break;
119 v.n = old.v.n ? old.v.n->refSelf() :
nullptr;
121 check_lvalue_object_in_out(v.n, 0);
123 default: assert(
false);
129 DLLLOCAL ~QoreLValue() {
130 assert(!assigned || type != QV_Node || !v.n);
134 DLLLOCAL
void setClosure() {
139 DLLLOCAL valtype_t getOptimizedType()
const {
140 return fixed_type ? type : QV_Node;
143 DLLLOCAL
bool optimized()
const {
144 return type != QV_Node && type != QV_Ref;
152 DLLLOCAL
typename detail::QoreValueCastHelper<T>::Result get() {
161 DLLLOCAL
typename detail::QoreValueCastHelper<const T>::Result get()
const {
165 DLLLOCAL
const char* getFixedTypeName()
const {
169 case QV_Int:
return "int";
170 case QV_Float:
return "float";
171 case QV_Bool:
return "bool";
177 DLLLOCAL
bool isInt() {
179 if (type != QV_Int) {
193 DLLLOCAL
bool isFloat() {
195 if (type != QV_Float) {
204 if (type == QV_Float)
210 assert(!fixed_type || type == QV_Int);
234 int64 i = v.n ? v.n->getAsBigInt() : 0;
239 check_lvalue_object_in_out(0, rv);
254 assert(!fixed_type || type == QV_Float);
278 double f = v.n ? v.n->getAsFloat() : 0.0;
283 check_lvalue_object_in_out(0, rv);
336 check_lvalue_object_in_out(0, rv);
352 assert(!static_assignment);
360 check_lvalue_object_in_out(0, v.n);
362 default: assert(
false);
368 DLLLOCAL
const QoreValue getValue()
const {
376 case QV_Node:
return v.n;
377 default: assert(
false);
391 case QV_Node:
return v.n;
392 default: assert(
false);
398 DLLLOCAL
QoreValue getReferencedValue()
const {
402 DLLLOCAL
bool needsScan()
const {
403 if (!assigned || type != QV_Node || !v.n)
406 return needs_scan(v.n);
410 DLLLOCAL
QoreValue getReferencedValue(
bool& needs_deref)
const {
416 if (type == QV_Node) {
427 default: assert(
false);
437 if (type == QV_Node && v.n) {
439 check_lvalue_object_in_out(0, v.n);
445 DLLLOCAL
bool hasValue()
const {
449 case QV_Bool:
return v.b;
450 case QV_Int:
return (
bool)v.i;
451 case QV_Float:
return (
bool)v.f;
453 default: assert(
false);
459 DLLLOCAL
void set(
const QoreTypeInfo* typeInfo) {
460 if (typeInfo == bigIntTypeInfo || typeInfo == softBigIntTypeInfo)
462 else if (typeInfo == floatTypeInfo || typeInfo == softFloatTypeInfo)
464 else if (typeInfo == boolTypeInfo || typeInfo == softBoolTypeInfo)
470 DLLLOCAL
void set(valtype_t t) {
471 assert(!assigned || type != QV_Node || !v.n);
473 fixed_type = (t != QV_Node);
486 case QV_Bool: v.b =
false;
return 0;
487 case QV_Int: v.i = (
int64)b;
return 0;
488 case QV_Float: v.f = (double)b;
return 0;
489 default: assert(
false);
496 if (type == QV_Node) {
498 check_lvalue_object_in_out(0, v.n);
520 case QV_Bool: v.b = (bool)i;
return 0;
521 case QV_Int: v.i = i;
return 0;
522 case QV_Float: v.f = (double)i;
return 0;
523 default: assert(
false);
530 if (type == QV_Node) {
532 check_lvalue_object_in_out(0, v.n);
554 case QV_Bool: v.b = (bool)f;
return 0;
555 case QV_Int: v.i = (
int64)f;
return 0;
556 case QV_Float: v.f = f;
return 0;
557 default: assert(
false);
564 if (type == QV_Node) {
566 check_lvalue_object_in_out(0, v.n);
587 DLLLOCAL
void assignSetTakeInitial(QoreLValue<U>& n,
QoreValue val) {
591 if (n.static_assignment) {
592 static_assignment = n.static_assignment;
593 n.static_assignment =
false;
604 assert(val.getType() ==
NT_INT);
620 n.v.n = val.takeNode();
629 DLLLOCAL
void assignSetTakeInitial(QoreLValue<U>& n) {
635 if (n.static_assignment) {
636 static_assignment = n.static_assignment;
637 n.static_assignment =
false;
640 case QV_Bool: v.b = n.v.b; n.v.b =
false;
break;
641 case QV_Int: v.i = n.v.i; n.v.i = 0;
break;
642 case QV_Float: v.f = n.v.f; n.v.f = 0;
break;
651 default: assert(
false);
661 assert(!static_assignment);
663 if (is_static_assignment)
664 static_assignment =
true;
665 return assignAssume(n);
668 DLLLOCAL
void assignInitial(
bool n) {
673 case QV_Bool: v.b = n;
return;
674 case QV_Int: v.i = (
int64)n;
return;
675 case QV_Float: v.f = (double)n;
return;
676 default: assert(
false);
684 DLLLOCAL
void assignInitial(
int64 n) {
689 case QV_Bool: v.b = (bool)n;
return;
690 case QV_Int: v.i = n;
return;
691 case QV_Float: v.f = (double)n;
return;
692 default: assert(
false);
700 DLLLOCAL
void assignInitial(
double n) {
705 case QV_Bool: v.b = (bool)n;
return;
706 case QV_Int: v.i = (
int64)n;
return;
707 case QV_Float: v.f = n;
return;
708 default: assert(
false);
722 v.b = n ? n->
getAsBool() :
false;
return n;
723 case QV_Int: v.i = n ? n->
getAsBigInt() : 0;
return n;
724 case QV_Float: v.f = n ? n->
getAsFloat() : 0;
return n;
725 default: assert(
false);
732 check_lvalue_object_in_out(v.n, 0);
738 return assignAssume(n);
747 case QV_Bool: v.b = val.getAsBool();
break;
748 case QV_Int: v.i = val.getAsBigInt();
break;
749 case QV_Float: v.f = val.getAsFloat();
break;
750 default: assert(
false);
758 if (type == QV_Node) {
760 check_lvalue_object_in_out(0, v.n);
772 case QV_Bool: v.b = val.v.b;
if (type != QV_Bool) type = QV_Bool;
break;
773 case QV_Int: v.i = val.v.i;
if (type != QV_Int) type = QV_Int;
break;
774 case QV_Float: v.f = val.v.f;
if (type != QV_Float) type = QV_Float;
break;
776 v.n = val.takeNode();
780 check_lvalue_object_in_out(v.n, 0);
782 default: assert(
false);
822 check_lvalue_object_in_out(n, v.n);
836 if (type == QV_Node) {
838 check_lvalue_object_in_out(0, v.n);
851 check_lvalue_object_in_out(v.n, 0);
858 DLLLOCAL
bool exists()
const {
859 return assigned && (type != QV_Node || !
is_nothing(v.n));
862 DLLLOCAL
bool getAsBool()
const {
865 case QV_Bool:
return v.b;
866 case QV_Int:
return (
bool)v.i;
867 case QV_Float:
return (
bool)v.f;
868 case QV_Node:
return v.n ? v.n->getAsBool() :
false;
869 default: assert(
false);
876 DLLLOCAL
int64 getAsBigInt()
const {
879 case QV_Bool:
return (
int64)v.b;
880 case QV_Int:
return v.i;
881 case QV_Float:
return (
int64)v.f;
882 case QV_Node:
return v.n ? v.n->getAsBigInt() : 0;
883 default: assert(
false);
890 DLLLOCAL
double getAsFloat()
const {
893 case QV_Bool:
return (
double)v.b;
894 case QV_Int:
return (
double)v.i;
895 case QV_Float:
return v.f;
896 case QV_Node:
return v.n ? v.n->getAsFloat() : 0.0;
897 default: assert(
false);
905 return assigned && type == QV_Node ? v.n :
nullptr;
912 case QV_Int:
return NT_INT;
914 case QV_Node:
return v.n ? v.n->getType() :
NT_NOTHING;
915 default: assert(
false);
921 DLLLOCAL
const char* getTypeName()
const {
924 case QV_Bool:
return qoreBoolTypeName;
925 case QV_Int:
return qoreIntTypeName;
926 case QV_Float:
return qoreFloatTypeName;
927 case QV_Node:
return get_type_name(v.n);
928 default: assert(
false);
936 assert(type == QV_Int);
956 assert(type == QV_Float);
976 assert(type == QV_Int);
996 assert(type == QV_Float);
1016 assert(type == QV_Int);
1036 assert(type == QV_Int);
1056 assert(type == QV_Int);
1064 return i ? v.i %= i : v.i = 0;
1076 assert(type == QV_Int);
1096 assert(type == QV_Int);
1117 assert(type == QV_Int);
1137 assert(type == QV_Int);
1157 assert(type == QV_Int);
1177 assert(type == QV_Int);
1201 assert(type == QV_Int);
1221 assert(type == QV_Int);
1242 assert(type == QV_Int);
1261 assert(type == QV_Float);
1282 assert(type == QV_Float);
1302 assert(type == QV_Float);
1323 assert(type == QV_Float);
1342 assert(type == QV_Float);
1362 assert(type == QV_Float);
1382 DLLLOCAL
QoreValue remove(
bool& was_static_assignment) {
1383 assert(!was_static_assignment);
1388 if (static_assignment) {
1389 static_assignment =
false;
1390 was_static_assignment =
true;
1402 check_lvalue_object_in_out(0, v.n);
1412 DLLLOCAL
void unassignIgnore() {
1415 if (static_assignment)
1416 static_assignment =
false;
1417 if (type == QV_Node && !is_closure)
1418 check_lvalue_object_in_out(0, v.n);
1422 DLLLOCAL
QoreValue removeValue(
bool for_del) {
1426 assert(!static_assignment);
1437 check_lvalue_object_in_out(0, v.n);
1447 typedef QoreLValue<> QoreLValueGeneric;
static void discard(AbstractQoreNode *n, ExceptionSink *xsink)
to deref an AbstractQoreNode (when the pointer may be 0)
Definition: QoreLib.h:324
static bool is_nothing(const AbstractQoreNode *n)
to check if an AbstractQoreNode object is NOTHING
Definition: QoreLib.h:316
The base class for all value and parse types in Qore expression trees.
Definition: AbstractQoreNode.h:57
virtual DLLEXPORT AbstractQoreNode * realCopy() const =0
returns a copy of the object; the caller owns the reference count
DLLEXPORT int64 getAsBigInt() const
returns the 64-bit integer value of the object
DLLEXPORT double getAsFloat() const
returns the float value of the object
DLLEXPORT bool getAsBool() const
returns the boolean value of the object
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:48
Qore's arbitrary-precision number value type, dynamically-allocated only, reference counted.
Definition: QoreNumberNode.h:51
int16_t qore_type_t
used to identify unique Qore data and parse types (descendents of AbstractQoreNode)
Definition: common.h:70
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
const qore_type_t NT_BOOLEAN
type value for bools (QoreValue only)
Definition: node_types.h:47
const qore_type_t NT_NUMBER
type value for QoreNumberNode
Definition: node_types.h:53
const qore_type_t NT_INT
type value for integers (QoreValue only)
Definition: node_types.h:43
const qore_type_t NT_FLOAT
type value for floating-point values (QoreValue only)
Definition: node_types.h:44
const qore_type_t NT_NOTHING
type value for QoreNothingNode
Definition: node_types.h:42
The main value class in Qore, designed to be passed by value.
Definition: QoreValue.h:275
DLLEXPORT AbstractQoreNode * takeIfNode()
returns a referenced value; leaving the "this" untouched; the caller owns the reference returned
DLLEXPORT QoreValue refSelf() const
references the contained value if type == QV_Node, returns itself
used in QoreValue::get()
Definition: QoreValue.h:67