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), is_closure(false) {
92 DLLLOCAL QoreLValue(valtype_t t) : type(t), fixed_type(t != QV_Node), assigned(false), static_assignment(false), is_closure(false) {
101 DLLLOCAL QoreLValue(
const QoreTypeInfo* typeInfo) : assigned(false), static_assignment(false), is_closure(false) {
108 DLLLOCAL QoreLValue(
const QoreLValue<U>& old) : type(old.type), fixed_type(old.fixed_type), assigned(old.assigned), static_assignment(false), is_closure(old.is_closure) {
112 case QV_Bool: v.b = old.v.b;
break;
113 case QV_Int: v.i = old.v.i;
break;
114 case QV_Float: v.f = old.v.f;
break;
116 v.n = old.v.n ? old.v.n->refSelf() :
nullptr;
118 check_lvalue_object_in_out(v.n, 0);
120 default: assert(
false);
126 DLLLOCAL ~QoreLValue() {
127 assert(!assigned || type != QV_Node || !v.n);
131 DLLLOCAL
void setClosure() {
136 DLLLOCAL valtype_t getOptimizedType()
const {
137 return fixed_type ? type : QV_Node;
140 DLLLOCAL
bool optimized()
const {
141 return type != QV_Node && type != QV_Ref;
149 DLLLOCAL
typename detail::QoreValueCastHelper<T>::Result get() {
158 DLLLOCAL
typename detail::QoreValueCastHelper<const T>::Result get()
const {
162 DLLLOCAL
const char* getFixedTypeName()
const {
166 case QV_Int:
return "int";
167 case QV_Float:
return "float";
168 case QV_Bool:
return "bool";
174 DLLLOCAL
bool isInt() {
176 if (type != QV_Int) {
190 DLLLOCAL
bool isFloat() {
192 if (type != QV_Float) {
201 if (type == QV_Float)
207 assert(!fixed_type || type == QV_Int);
231 int64 i = v.n ? v.n->getAsBigInt() : 0;
236 check_lvalue_object_in_out(0, rv);
251 assert(!fixed_type || type == QV_Float);
275 double f = v.n ? v.n->getAsFloat() : 0.0;
280 check_lvalue_object_in_out(0, rv);
333 check_lvalue_object_in_out(0, rv);
349 assert(!static_assignment);
357 check_lvalue_object_in_out(0, v.n);
359 default: assert(
false);
365 DLLLOCAL
const QoreValue getValue()
const {
373 case QV_Node:
return v.n;
374 default: assert(
false);
388 case QV_Node:
return v.n;
389 default: assert(
false);
395 DLLLOCAL
QoreValue getReferencedValue()
const {
399 DLLLOCAL
bool needsScan()
const {
400 if (!assigned || type != QV_Node || !v.n)
403 return needs_scan(v.n);
407 DLLLOCAL
QoreValue getReferencedValue(
bool& needs_deref)
const {
413 if (type == QV_Node) {
424 default: assert(
false);
434 if (type == QV_Node && v.n) {
436 check_lvalue_object_in_out(0, v.n);
441 DLLLOCAL
bool hasValue()
const {
445 case QV_Bool:
return v.b;
446 case QV_Int:
return (
bool)v.i;
447 case QV_Float:
return (
bool)v.f;
449 default: assert(
false);
455 DLLLOCAL
void set(
const QoreTypeInfo* typeInfo) {
456 if (typeInfo == bigIntTypeInfo || typeInfo == softBigIntTypeInfo)
458 else if (typeInfo == floatTypeInfo || typeInfo == softFloatTypeInfo)
460 else if (typeInfo == boolTypeInfo || typeInfo == softBoolTypeInfo)
466 DLLLOCAL
void set(valtype_t t) {
467 assert(!assigned || type != QV_Node || !v.n);
469 fixed_type = (t != QV_Node);
482 case QV_Bool: v.b =
false;
return 0;
483 case QV_Int: v.i = (
int64)b;
return 0;
484 case QV_Float: v.f = (double)b;
return 0;
485 default: assert(
false);
492 if (type == QV_Node) {
494 check_lvalue_object_in_out(0, v.n);
516 case QV_Bool: v.b = (bool)i;
return 0;
517 case QV_Int: v.i = i;
return 0;
518 case QV_Float: v.f = (double)i;
return 0;
519 default: assert(
false);
526 if (type == QV_Node) {
528 check_lvalue_object_in_out(0, v.n);
550 case QV_Bool: v.b = (bool)f;
return 0;
551 case QV_Int: v.i = (
int64)f;
return 0;
552 case QV_Float: v.f = f;
return 0;
553 default: assert(
false);
560 if (type == QV_Node) {
562 check_lvalue_object_in_out(0, v.n);
583 DLLLOCAL
void assignSetTakeInitial(QoreLValue<U>& n,
QoreValue val) {
587 if (n.static_assignment) {
588 static_assignment = n.static_assignment;
589 n.static_assignment =
false;
600 assert(val.getType() ==
NT_INT);
616 n.v.n = val.takeNode();
625 DLLLOCAL
void assignSetTakeInitial(QoreLValue<U>& n) {
631 if (n.static_assignment) {
632 static_assignment = n.static_assignment;
633 n.static_assignment =
false;
636 case QV_Bool: v.b = n.v.b; n.v.b =
false;
break;
637 case QV_Int: v.i = n.v.i; n.v.i = 0;
break;
638 case QV_Float: v.f = n.v.f; n.v.f = 0;
break;
647 default: assert(
false);
657 assert(!static_assignment);
659 if (is_static_assignment)
660 static_assignment =
true;
661 return assignAssume(n);
664 DLLLOCAL
void assignInitial(
bool n) {
669 case QV_Bool: v.b = n;
return;
670 case QV_Int: v.i = (
int64)n;
return;
671 case QV_Float: v.f = (double)n;
return;
672 default: assert(
false);
680 DLLLOCAL
void assignInitial(
int64 n) {
685 case QV_Bool: v.b = (bool)n;
return;
686 case QV_Int: v.i = n;
return;
687 case QV_Float: v.f = (double)n;
return;
688 default: assert(
false);
696 DLLLOCAL
void assignInitial(
double n) {
701 case QV_Bool: v.b = (bool)n;
return;
702 case QV_Int: v.i = (
int64)n;
return;
703 case QV_Float: v.f = n;
return;
704 default: assert(
false);
718 v.b = n ? n->
getAsBool() :
false;
return n;
719 case QV_Int: v.i = n ? n->
getAsBigInt() : 0;
return n;
720 case QV_Float: v.f = n ? n->
getAsFloat() : 0;
return n;
721 default: assert(
false);
728 check_lvalue_object_in_out(v.n, 0);
734 return assignAssume(n);
743 case QV_Bool: v.b = val.getAsBool();
break;
744 case QV_Int: v.i = val.getAsBigInt();
break;
745 case QV_Float: v.f = val.getAsFloat();
break;
746 default: assert(
false);
754 if (type == QV_Node) {
756 check_lvalue_object_in_out(0, v.n);
768 case QV_Bool: v.b = val.v.b;
if (type != QV_Bool) type = QV_Bool;
break;
769 case QV_Int: v.i = val.v.i;
if (type != QV_Int) type = QV_Int;
break;
770 case QV_Float: v.f = val.v.f;
if (type != QV_Float) type = QV_Float;
break;
772 v.n = val.takeNode();
776 check_lvalue_object_in_out(v.n, 0);
778 default: assert(
false);
818 check_lvalue_object_in_out(n, v.n);
832 if (type == QV_Node) {
834 check_lvalue_object_in_out(0, v.n);
847 check_lvalue_object_in_out(v.n, 0);
854 DLLLOCAL
bool exists()
const {
855 return assigned && (type != QV_Node || !
is_nothing(v.n));
858 DLLLOCAL
bool getAsBool()
const {
861 case QV_Bool:
return v.b;
862 case QV_Int:
return (
bool)v.i;
863 case QV_Float:
return (
bool)v.f;
864 case QV_Node:
return v.n ? v.n->getAsBool() :
false;
865 default: assert(
false);
872 DLLLOCAL
int64 getAsBigInt()
const {
875 case QV_Bool:
return (
int64)v.b;
876 case QV_Int:
return v.i;
877 case QV_Float:
return (
int64)v.f;
878 case QV_Node:
return v.n ? v.n->getAsBigInt() : 0;
879 default: assert(
false);
886 DLLLOCAL
double getAsFloat()
const {
889 case QV_Bool:
return (
double)v.b;
890 case QV_Int:
return (
double)v.i;
891 case QV_Float:
return v.f;
892 case QV_Node:
return v.n ? v.n->getAsFloat() : 0.0;
893 default: assert(
false);
901 return assigned && type == QV_Node ? v.n :
nullptr;
908 case QV_Int:
return NT_INT;
910 case QV_Node:
return v.n ? v.n->getType() :
NT_NOTHING;
911 default: assert(
false);
917 DLLLOCAL
const char* getTypeName()
const {
920 case QV_Bool:
return qoreBoolTypeName;
921 case QV_Int:
return qoreIntTypeName;
922 case QV_Float:
return qoreFloatTypeName;
923 case QV_Node:
return get_type_name(v.n);
924 default: assert(
false);
932 assert(type == QV_Int);
952 assert(type == QV_Float);
972 assert(type == QV_Int);
992 assert(type == QV_Float);
1012 assert(type == QV_Int);
1032 assert(type == QV_Int);
1052 assert(type == QV_Int);
1060 return i ? v.i %= i : v.i = 0;
1072 assert(type == QV_Int);
1092 assert(type == QV_Int);
1113 assert(type == QV_Int);
1133 assert(type == QV_Int);
1153 assert(type == QV_Int);
1173 assert(type == QV_Int);
1197 assert(type == QV_Int);
1217 assert(type == QV_Int);
1238 assert(type == QV_Int);
1257 assert(type == QV_Float);
1278 assert(type == QV_Float);
1298 assert(type == QV_Float);
1319 assert(type == QV_Float);
1338 assert(type == QV_Float);
1358 assert(type == QV_Float);
1378 DLLLOCAL
QoreValue remove(
bool& was_static_assignment) {
1379 assert(!was_static_assignment);
1384 if (static_assignment) {
1385 static_assignment =
false;
1386 was_static_assignment =
true;
1398 check_lvalue_object_in_out(0, v.n);
1408 DLLLOCAL
void unassignIgnore() {
1411 if (static_assignment)
1412 static_assignment =
false;
1413 if (type == QV_Node && !is_closure)
1414 check_lvalue_object_in_out(0, v.n);
1418 DLLLOCAL
QoreValue removeValue(
bool for_del) {
1422 assert(!static_assignment);
1433 check_lvalue_object_in_out(0, v.n);
1443 typedef QoreLValue<> QoreLValueGeneric;