From a62caf66be9f20b8761ee00d58754ded0752de3c Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Fri, 30 Jan 2026 22:12:27 +0000 Subject: [PATCH 1/4] Move stable sorter to implementation file Only used by non templated ArrayBase class --- include/Array.h | 74 --------------------------------------------- src/Array.cpp | 80 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 78 insertions(+), 76 deletions(-) diff --git a/include/Array.h b/include/Array.h index daada5320..801253ee8 100644 --- a/include/Array.h +++ b/include/Array.h @@ -1,7 +1,5 @@ #ifndef HX_ARRAY_H #define HX_ARRAY_H -#include -#include #include // --- hx::ReturnNull ------------------------------------------------------ @@ -59,78 +57,6 @@ template<> struct ArrayTraits { enum { StoreType = arrayObject }; }; template<> struct ArrayTraits { enum { StoreType = arrayString }; }; template<> struct ArrayTraits< ::cpp::Int64> { enum { StoreType = arrayInt64 }; }; -template -class SafeSorter -{ - typedef -#if (HXCPP_API_LEVEL>=500) - ::hx::Callable -#else - Dynamic -#endif - SorterFunc; - - struct ArraySorter - { - ELEM* mArray; - SorterFunc mSorter; - - ArraySorter(ELEM* inArray, SorterFunc inSorter) : mArray(inArray), mSorter(inSorter) {}; - - bool operator()(int inA, int inB) - { - return mSorter(mArray[inA], mArray[inB]) < 0; - } - }; - - template - static void SortImpl(ELEM* inArray, const int inLength, SorterFunc inSorter) - { - auto index = std::vector(inLength); - for (auto i = 0; i < inLength; i++) - { - index[i] = static_cast(i); - } - - std::stable_sort(index.begin(), index.end(), ArraySorter(inArray, inSorter)); - - // Put the results back ... - for (int i = 0; i < inLength; i++) - { - int from = index[i]; - while (from < i) - from = index[from]; - if (from != i) - { - std::swap(inArray[i], inArray[from]); - index[i] = from; - } - } - } - -public: - static void Sort(ELEM* base, const int length, SorterFunc sorter) - { - if (length < 2) - { - return; - } - - if (length <= std::numeric_limits::max()) - { - SortImpl(base, length, sorter); - } - else if (length <= std::numeric_limits::max()) - { - SortImpl(base, length, sorter); - } - else - { - SortImpl(base, length, sorter); - } - } -}; - } diff --git a/src/Array.cpp b/src/Array.cpp index b8f9ac35c..243806ce4 100644 --- a/src/Array.cpp +++ b/src/Array.cpp @@ -1,11 +1,87 @@ #include #include +#include #include #ifdef HXCPP_TELEMETRY extern void __hxt_new_array(void* obj, int size); #endif +namespace +{ + template + class SafeSorter + { + typedef +#if (HXCPP_API_LEVEL>=500) + ::hx::Callable +#else + Dynamic +#endif + SorterFunc; + + struct ArraySorter + { + ELEM* mArray; + SorterFunc mSorter; + + ArraySorter(ELEM* inArray, SorterFunc inSorter) : mArray(inArray), mSorter(inSorter) {}; + + bool operator()(int inA, int inB) + { + return mSorter(mArray[inA], mArray[inB]) < 0; + } + }; + + template + static void SortImpl(ELEM* inArray, const int inLength, SorterFunc inSorter) + { + auto index = std::vector(inLength); + for (auto i = 0; i < inLength; i++) + { + index[i] = static_cast(i); + } + + std::stable_sort(index.begin(), index.end(), ArraySorter(inArray, inSorter)); + + // Put the results back ... + for (int i = 0; i < inLength; i++) + { + int from = index[i]; + while (from < i) + from = index[from]; + if (from != i) + { + std::swap(inArray[i], inArray[from]); + index[i] = from; + } + } + } + + public: + static void Sort(ELEM* base, const int length, SorterFunc sorter) + { + if (length < 2) + { + return; + } + + if (length <= std::numeric_limits::max()) + { + SortImpl(base, length, sorter); + } + else if (length <= std::numeric_limits::max()) + { + SortImpl(base, length, sorter); + } + else + { + SortImpl(base, length, sorter); + } + } + }; +} + using namespace hx; @@ -492,9 +568,9 @@ String ArrayBase::joinArray(ArrayBase *inBase, String inSeparator) void ArrayBase::safeSort(DynamicSorterFunc inSorter, bool inIsString) { if (inIsString) - hx::SafeSorter::Sort((String *)mBase, length,inSorter); + SafeSorter::Sort((String *)mBase, length,inSorter); else - hx::SafeSorter::Sort((Dynamic *)mBase, length,inSorter); + SafeSorter::Sort((Dynamic *)mBase, length,inSorter); } From ddf922f74897bd805f1ea45be485782ab663acc1 Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Fri, 30 Jan 2026 22:13:24 +0000 Subject: [PATCH 2/4] Don't include telemetry header unless telemetry is defined All uses of this headers functions are already guarded behind that define. It has a surprising time cost due to std::vector. --- include/hx/Telemetry.h | 1 - include/hxcpp.h | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/include/hx/Telemetry.h b/include/hx/Telemetry.h index cf8657785..855443353 100644 --- a/include/hx/Telemetry.h +++ b/include/hx/Telemetry.h @@ -3,7 +3,6 @@ #define HX_TELEMETRY_VERSION 1 -#include #include struct TelemetryFrame diff --git a/include/hxcpp.h b/include/hxcpp.h index 80b67aae2..ae30db46b 100755 --- a/include/hxcpp.h +++ b/include/hxcpp.h @@ -346,7 +346,9 @@ typedef PropertyAccessMode PropertyAccess; #include #include "Enum.h" #include +#ifdef HXCPP_TELEMETRY #include +#endif #if defined(__OBJC__) && defined(HXCPP_OBJC) #include #endif From e2c779ca3f75bef9751fb7aeba3e58e4d90ff7ad Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Sat, 31 Jan 2026 15:45:41 +0000 Subject: [PATCH 3/4] try non templated field ref --- include/hx/FieldRef.h | 257 +++++++++++++------------------------- include/hx/Operators.h | 10 +- toolchain/haxe-target.xml | 2 + 3 files changed, 96 insertions(+), 173 deletions(-) diff --git a/include/hx/FieldRef.h b/include/hx/FieldRef.h index 3ba1fdcc5..c46377e89 100644 --- a/include/hx/FieldRef.h +++ b/include/hx/FieldRef.h @@ -21,92 +21,57 @@ namespace hx #define HX_FIELD_REF_MEM_OP(op,ret) \ -inline ret operator op (const FieldRef &inA) \ - { return this->operator Dynamic() op inA.operator Dynamic(); } \ -inline ret operator op (const IndexRef &inA); \ -template inline ret operator op (const T& inA) \ - { return this->operator Dynamic() op inA; } - -#define HX_FIELD_REF_IMPL_MEM_OP(op,ret) \ -inline ret hx::FieldRef::operator op (const IndexRef &inA) \ - { return this->operator Dynamic() op inA.operator Dynamic(); } \ + ret operator op (const FieldRef& inA); \ + ret operator op (const IndexRef& inA); \ + ret operator op (const hx::Val& inA); class FieldRef { public: - explicit FieldRef(hx::Object *inObj,const String &inName) : mObject(inObj), mName(inName) - { - } - - hx::Val operator=(const hx::Val &inRHS) - { - return mObject->__SetField(mName,inRHS, HX_PROP_DYNAMIC ); - } - inline operator hx::Val() const { return mObject ? mObject->__Field(mName, HX_PROP_DYNAMIC) : null(); } - inline operator Dynamic() const { return mObject ? Dynamic(mObject->__Field(mName, HX_PROP_DYNAMIC)) : null(); } - inline operator double() const { return mObject->__Field(mName, HX_PROP_DYNAMIC); } - inline operator float() const { return mObject->__Field(mName, HX_PROP_DYNAMIC); } - inline operator int() const { return mObject->__Field(mName, HX_PROP_DYNAMIC); } - inline operator cpp::UInt64() const { return mObject->__Field(mName, HX_PROP_DYNAMIC); } - inline operator cpp::Int64() const { return mObject->__Field(mName, HX_PROP_DYNAMIC); } - - - // post-increment - inline double operator++(int) - { - double d = mObject->__Field(mName, HX_PROP_DYNAMIC); - mObject->__SetField(mName,d+1, HX_PROP_DYNAMIC); - return d; - } - // pre-increment - inline double operator++() - { - double d = ((double)mObject->__Field(mName, HX_PROP_DYNAMIC)) + 1; - mObject->__SetField(mName,d, HX_PROP_DYNAMIC); - return d; - } - // post-decrement - inline double operator--(int) - { - double d = mObject->__Field(mName, HX_PROP_DYNAMIC); - mObject->__SetField(mName,d-1, HX_PROP_DYNAMIC); - return d; - } - // pre-decrement - inline double operator--() - { - double d = (double)(mObject->__Field(mName, HX_PROP_DYNAMIC)) - 1; - mObject->__SetField(mName,d, HX_PROP_DYNAMIC); - return d; - } - bool operator !() { return ! ((int)(mObject->__Field(mName, HX_PROP_DYNAMIC))); } - int operator ~() { return ~ ((int)mObject->__Field(mName, HX_PROP_DYNAMIC)); } - - inline bool operator==(const null &) const { return !mObject; } - inline bool operator!=(const null &) const { return mObject; } - - double operator -() { return - (double)(mObject->__Field(mName, HX_PROP_DYNAMIC)); } - - bool HasPointer() const { return mObject; } - - - HX_FIELD_REF_MEM_OP(==,bool) - HX_FIELD_REF_MEM_OP(!=,bool) - HX_FIELD_REF_MEM_OP(<,bool) - HX_FIELD_REF_MEM_OP(<=,bool) - HX_FIELD_REF_MEM_OP(>,bool) - HX_FIELD_REF_MEM_OP(>=,bool) - - HX_FIELD_REF_MEM_OP(+,Dynamic) - HX_FIELD_REF_MEM_OP(*,double) - HX_FIELD_REF_MEM_OP(/,double) - HX_FIELD_REF_MEM_OP(-,double) - HX_FIELD_REF_MEM_OP(%,double) - - - - String mName; - hx::Object *mObject; + explicit FieldRef(hx::Object* inObj, const String& inName); + + hx::Val operator=(const hx::Val& inRHS); + operator hx::Val(); + operator Dynamic() const; + operator double() const; + operator float() const; + operator int() const; + operator cpp::UInt64() const; + operator cpp::Int64() const; + + // post-increment + double operator++(int); + // pre-increment + double operator++(); + // post-decrement + double operator--(int); + // pre-decrement + double operator--(); + bool operator !(); + int operator ~(); + + bool operator==(const null&) const; + bool operator!=(const null&) const; + + double operator -(); + + bool HasPointer() const; + + HX_FIELD_REF_MEM_OP(==,bool) + HX_FIELD_REF_MEM_OP(!=,bool) + HX_FIELD_REF_MEM_OP(<,bool) + HX_FIELD_REF_MEM_OP(<=,bool) + HX_FIELD_REF_MEM_OP(>,bool) + HX_FIELD_REF_MEM_OP(>=,bool) + + HX_FIELD_REF_MEM_OP(+,Dynamic) + HX_FIELD_REF_MEM_OP(*,double) + HX_FIELD_REF_MEM_OP(/,double) + HX_FIELD_REF_MEM_OP(-,double) + HX_FIELD_REF_MEM_OP(%,double) + + String mName; + hx::Object *mObject; }; // We can define this one now... @@ -141,81 +106,53 @@ HX_FIELD_REF_OP(%,double) // #define HX_INDEX_REF_MEM_OP(op,ret) \ -inline ret operator op (const IndexRef &inA) \ - { return this->operator Dynamic() op inA.operator Dynamic(); } \ -inline ret operator op (const FieldRef &inA) \ - { return this->operator Dynamic() op inA.operator Dynamic(); } \ -template inline ret operator op (const T& inA) \ - { return this->operator Dynamic() op inA; } - + ret operator op (const IndexRef &inA); \ + ret operator op (const FieldRef &inA); \ + ret operator op (const hx::Val& inA); class IndexRef { public: - explicit IndexRef(hx::Object *inObj,int inIndex) : mObject(inObj), mIndex(inIndex) - { - } - - Dynamic operator=(const Dynamic &inRHS) - { - return mObject->__SetItem(mIndex,inRHS); - } - inline operator Dynamic() const { return mObject->__GetItem(mIndex); } - inline operator double() const { return mObject->__GetItem(mIndex); } - inline operator int() const { return mObject->__GetItem(mIndex); } - - // post-increment - inline double operator++(int) - { - double d = mObject->__GetItem(mIndex)->__ToDouble(); - mObject->__SetItem(mIndex,d+1); - return d; - } - // pre-increment - inline double operator++() - { - double d = mObject->__GetItem(mIndex)->__ToDouble() + 1; - mObject->__SetItem(mIndex,d); - return d; - } - // post-decrement - inline double operator--(int) - { - double d = mObject->__GetItem(mIndex)->__ToDouble(); - mObject->__SetItem(mIndex,d-1); - return d; - } - // pre-decrement - inline double operator--() - { - double d = mObject->__GetItem(mIndex)->__ToDouble() - 1; - mObject->__SetItem(mIndex,d); - return d; - } - bool operator !() { return ! mObject->__GetItem(mIndex)->__ToInt(); } - int operator ~() { return ~ mObject->__GetItem(mIndex)->__ToInt(); } - double operator -() { return - mObject->__GetItem(mIndex)->__ToDouble(); } - - inline bool operator==(const null &) const { return !mObject; } - inline bool operator!=(const null &) const { return mObject; } - - HX_INDEX_REF_MEM_OP(==,bool) - HX_INDEX_REF_MEM_OP(!=,bool) - HX_INDEX_REF_MEM_OP(<,bool) - HX_INDEX_REF_MEM_OP(<=,bool) - HX_INDEX_REF_MEM_OP(>,bool) - HX_INDEX_REF_MEM_OP(>=,bool) - - HX_INDEX_REF_MEM_OP(+,Dynamic) - HX_INDEX_REF_MEM_OP(*,double) - HX_INDEX_REF_MEM_OP(/,double) - HX_INDEX_REF_MEM_OP(-,double) - HX_INDEX_REF_MEM_OP(%,double) - - bool HasPointer() const { return mObject; } - - int mIndex; - hx::Object *mObject; + explicit IndexRef(hx::Object* inObj, int inIndex); + + Dynamic operator=(const Dynamic& inRHS); + operator Dynamic() const; + operator double() const; + operator int() const; + + // post-increment + double operator++(int); + // pre-increment + double operator++(); + // post-decrement + double operator--(int); + // pre-decrement + double operator--(); + + bool operator !(); + int operator ~(); + double operator -(); + + bool operator==(const null&) const; + bool operator!=(const null&) const; + + HX_INDEX_REF_MEM_OP(== , bool) + HX_INDEX_REF_MEM_OP(!= , bool) + HX_INDEX_REF_MEM_OP(< , bool) + HX_INDEX_REF_MEM_OP(<= , bool) + HX_INDEX_REF_MEM_OP(> , bool) + HX_INDEX_REF_MEM_OP(>= , bool) + + HX_INDEX_REF_MEM_OP(+, Dynamic) + HX_INDEX_REF_MEM_OP(*, double) + HX_INDEX_REF_MEM_OP(/ , double) + HX_INDEX_REF_MEM_OP(-, double) + HX_INDEX_REF_MEM_OP(%, double) + + bool HasPointer() const; + + int mIndex; + hx::Object *mObject; }; // We can define this one now... @@ -243,20 +180,6 @@ HX_INDEX_REF_OP(-,double) HX_INDEX_REF_OP(%,double) -// Implement once IndexRef has been defined. -HX_FIELD_REF_IMPL_MEM_OP(==,bool) -HX_FIELD_REF_IMPL_MEM_OP(!=,bool) -HX_FIELD_REF_IMPL_MEM_OP(<,bool) -HX_FIELD_REF_IMPL_MEM_OP(<=,bool) -HX_FIELD_REF_IMPL_MEM_OP(>,bool) -HX_FIELD_REF_IMPL_MEM_OP(>=,bool) - -HX_FIELD_REF_IMPL_MEM_OP(+,Dynamic) -HX_FIELD_REF_IMPL_MEM_OP(*,double) -HX_FIELD_REF_IMPL_MEM_OP(/,double) -HX_FIELD_REF_IMPL_MEM_OP(-,double) -HX_FIELD_REF_IMPL_MEM_OP(%,double) - // Disambiguate Dynamic operators... #define HX_INDEX_REF_OP_DYNAMIC(op,ret) \ diff --git a/include/hx/Operators.h b/include/hx/Operators.h index f5ffcbf8c..0c81e51b1 100644 --- a/include/hx/Operators.h +++ b/include/hx/Operators.h @@ -134,15 +134,14 @@ inline L& UShrEq(L &inLHS, R inRHS) { inLHS = hx::UShr(inLHS,inRHS); return inLH template inline L& ModEq(L &inLHS, R inRHS) { inLHS = DoubleMod(inLHS,inRHS); return inLHS; } -#if defined(__GNUC__) || defined(__SNC__) template -inline hx::FieldRef AddEq(hx::FieldRef inLHS, R inRHS) { inLHS = inLHS + inRHS; return inLHS; } +inline hx::FieldRef AddEq(hx::FieldRef inLHS, R inRHS) { inLHS = inLHS + hx::Val{ inRHS }; return inLHS; } template -inline hx::FieldRef MultEq(hx::FieldRef inLHS, R inRHS) { inLHS = inLHS * inRHS; return inLHS; } +inline hx::FieldRef MultEq(hx::FieldRef inLHS, R inRHS) { inLHS = inLHS * hx::Val{ inRHS }; return inLHS; } template inline hx::FieldRef DivEq(hx::FieldRef inLHS, R inRHS) { inLHS = (double)inLHS / (double)inRHS; return inLHS; } template -inline hx::FieldRef SubEq(hx::FieldRef inLHS, R inRHS) { inLHS = inLHS - inRHS; return inLHS; } +inline hx::FieldRef SubEq(hx::FieldRef inLHS, R inRHS) { inLHS = inLHS - hx::Val{ inRHS }; return inLHS; } template inline hx::FieldRef AndEq(hx::FieldRef inLHS, R inRHS) { inLHS = (int)inLHS & (int)inRHS; return inLHS; } template @@ -160,7 +159,7 @@ inline hx::FieldRef ModEq(hx::FieldRef inLHS, R inRHS) { inLHS = DoubleMod(inLHS template -inline hx::IndexRef AddEq(hx::IndexRef inLHS, R inRHS) { inLHS = inLHS + inRHS; return inLHS; } +inline hx::IndexRef AddEq(hx::IndexRef inLHS, R inRHS) { inLHS = inLHS + hx::Val{ inRHS }; return inLHS; } template inline hx::IndexRef MultEq(hx::IndexRef inLHS, R inRHS) { inLHS = (double)inLHS * (double)inRHS; return inLHS; } template @@ -184,7 +183,6 @@ inline hx::IndexRef ModEq(hx::IndexRef inLHS, R inRHS) { inLHS = DoubleMod(inLHS -#endif // __GNUC__ || __SNC__ template inline hx::__TArrayImplRef AddEq(hx::__TArrayImplRef ref, R inRHS) diff --git a/toolchain/haxe-target.xml b/toolchain/haxe-target.xml index 11dd88576..f759794e3 100644 --- a/toolchain/haxe-target.xml +++ b/toolchain/haxe-target.xml @@ -185,6 +185,8 @@ + +
From d7963fabf663cc23c2e7152335da2ca3590445c2 Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Sat, 31 Jan 2026 16:08:14 +0000 Subject: [PATCH 4/4] Commit missing files --- src/hx/FieldRef.cpp | 184 ++++++++++++++++++++++++++++++++++++++++++++ src/hx/IndexRef.cpp | 164 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 348 insertions(+) create mode 100644 src/hx/FieldRef.cpp create mode 100644 src/hx/IndexRef.cpp diff --git a/src/hx/FieldRef.cpp b/src/hx/FieldRef.cpp new file mode 100644 index 000000000..8918fb70f --- /dev/null +++ b/src/hx/FieldRef.cpp @@ -0,0 +1,184 @@ +#include + +#define HX_FIELD_REF_IMPL_MEM_OP(op,ret) \ + ret hx::FieldRef::operator op (const FieldRef& inA) { return this->operator Dynamic() op inA.operator Dynamic(); } \ + ret hx::FieldRef::operator op (const IndexRef& inA) { return this->operator Dynamic() op inA.operator Dynamic(); } \ + ret hx::FieldRef::operator op (const hx::Val& inA) { \ + switch (inA.type) { \ + case hx::Val::typeObject: return this->operator Dynamic() op Dynamic { inA.asDynamic() }; \ + case hx::Val::typeString: return this->operator Dynamic() op inA.asString(); \ + case hx::Val::typeDouble: return this->operator Dynamic() op inA.asDouble(); \ + case hx::Val::typeInt : return this->operator Dynamic() op inA.asInt(); \ + case hx::Val::typeInt64 : return this->operator Dynamic() op inA.asInt64(); \ + case hx::Val::typeBool : return this->operator Dynamic() op inA.asInt(); \ + } \ + } + +hx::FieldRef::FieldRef(hx::Object* inObj, const String& inName) : mObject(inObj), mName(inName) {} + +hx::Val hx::FieldRef::operator=(const hx::Val& inRHS) +{ + return mObject->__SetField(mName, inRHS, HX_PROP_DYNAMIC); +} + +hx::FieldRef::operator hx::Val() +{ + return mObject ? mObject->__Field(mName, HX_PROP_DYNAMIC) : null(); +} + +hx::FieldRef::operator Dynamic() const +{ + return mObject ? Dynamic(mObject->__Field(mName, HX_PROP_DYNAMIC)) : null(); +} + +hx::FieldRef::operator double() const +{ + return mObject->__Field(mName, HX_PROP_DYNAMIC); +} + +hx::FieldRef::operator float() const +{ + return mObject->__Field(mName, HX_PROP_DYNAMIC); +} + +hx::FieldRef::operator int() const +{ + return mObject->__Field(mName, HX_PROP_DYNAMIC); +} + +hx::FieldRef::operator cpp::UInt64() const +{ + return mObject->__Field(mName, HX_PROP_DYNAMIC); +} + +hx::FieldRef::operator cpp::Int64() const +{ + return mObject->__Field(mName, HX_PROP_DYNAMIC); +} + +double hx::FieldRef::operator++(int) +{ + double d = mObject->__Field(mName, HX_PROP_DYNAMIC); + mObject->__SetField(mName, d + 1, HX_PROP_DYNAMIC); + return d; +} + +double hx::FieldRef::operator++() +{ + double d = ((double)mObject->__Field(mName, HX_PROP_DYNAMIC)) + 1; + mObject->__SetField(mName, d, HX_PROP_DYNAMIC); + return d; +} + +double hx::FieldRef::operator--(int) +{ + double d = mObject->__Field(mName, HX_PROP_DYNAMIC); + mObject->__SetField(mName, d - 1, HX_PROP_DYNAMIC); + return d; +} + +double hx::FieldRef::operator--() +{ + double d = (double)(mObject->__Field(mName, HX_PROP_DYNAMIC)) - 1; + mObject->__SetField(mName, d, HX_PROP_DYNAMIC); + return d; +} + +bool hx::FieldRef::operator!() +{ + return !((int)(mObject->__Field(mName, HX_PROP_DYNAMIC))); +} + +int hx::FieldRef::operator~() +{ + return ~((int)mObject->__Field(mName, HX_PROP_DYNAMIC)); +} + +bool hx::FieldRef::operator==(const null&) const +{ + return !mObject; +} + +bool hx::FieldRef::operator!=(const null&) const +{ + return mObject; +} + +double hx::FieldRef::operator-() +{ + return -(double)(mObject->__Field(mName, HX_PROP_DYNAMIC)); +} + +bool hx::FieldRef::HasPointer() const +{ + return mObject; +} + +HX_FIELD_REF_IMPL_MEM_OP(== , bool) +HX_FIELD_REF_IMPL_MEM_OP(!= , bool) +HX_FIELD_REF_IMPL_MEM_OP(< , bool) +HX_FIELD_REF_IMPL_MEM_OP(<= , bool) +HX_FIELD_REF_IMPL_MEM_OP(> , bool) +HX_FIELD_REF_IMPL_MEM_OP(>= , bool) + +HX_FIELD_REF_IMPL_MEM_OP(+, Dynamic) + +// Below has the above macros expanded since some operators on some times aren't supported and need manual dynamic wrapping. +// There may be some sort of tagged dispatch which could be done in the macro instead to avoid this. + +double hx::FieldRef::operator * (const FieldRef& inA) { return this->operator Dynamic() * inA.operator Dynamic(); } +double hx::FieldRef::operator * (const IndexRef& inA) { return this->operator Dynamic() * inA.operator Dynamic(); } +double hx::FieldRef::operator * (const hx::Val& inA) +{ + switch (inA.type) + { + case hx::Val::typeObject: return this->operator double() * inA.asDouble(); + case hx::Val::typeString: return this->operator double() * inA.asDouble(); + case hx::Val::typeDouble: return this->operator double() * inA.asDouble(); + case hx::Val::typeInt: return this->operator double() * inA.asInt(); + case hx::Val::typeInt64: return this->operator double() * inA.asInt64(); + case hx::Val::typeBool: return this->operator double() * inA.asInt(); + } +} + +double hx::FieldRef::operator / (const FieldRef& inA) { return this->operator Dynamic() / inA.operator Dynamic(); } +double hx::FieldRef::operator / (const IndexRef& inA) { return this->operator Dynamic() / inA.operator Dynamic(); } +double hx::FieldRef::operator / (const hx::Val& inA) +{ + switch (inA.type) { + case hx::Val::typeObject: return this->operator double() / inA.asDouble(); + case hx::Val::typeString: return this->operator double() / inA.asDouble(); + case hx::Val::typeDouble: return this->operator double() / inA.asDouble(); + case hx::Val::typeInt: return this->operator double() / inA.asInt(); + case hx::Val::typeInt64: return this->operator double() / inA.asInt64(); + case hx::Val::typeBool: return this->operator double() / inA.asInt(); + } +} + +double hx::FieldRef::operator - (const FieldRef& inA) { return this->operator Dynamic() - inA.operator Dynamic(); } +double hx::FieldRef::operator - (const IndexRef& inA) { return this->operator Dynamic() - inA.operator Dynamic(); } +double hx::FieldRef::operator - (const hx::Val& inA) +{ + switch (inA.type) { + case hx::Val::typeObject: return this->operator double() - inA.asDouble(); + case hx::Val::typeString: return this->operator double() - inA.asDouble(); + case hx::Val::typeDouble: return this->operator double() - inA.asDouble(); + case hx::Val::typeInt: return this->operator double() - inA.asInt(); + case hx::Val::typeInt64: return this->operator double() - inA.asInt64(); + case hx::Val::typeBool: return this->operator double() - inA.asInt(); + } +} + +double hx::FieldRef::operator % (const FieldRef& inA) { return this->operator Dynamic() % inA.operator Dynamic(); } +double hx::FieldRef::operator % (const IndexRef& inA) { return this->operator Dynamic() % inA.operator Dynamic(); } +double hx::FieldRef::operator % (const hx::Val& inA) +{ + switch (inA.type) { + case hx::Val::typeObject: return this->operator int() % inA.asInt(); + case hx::Val::typeString: return this->operator int() % inA.asInt(); + case hx::Val::typeDouble: return this->operator int() % inA.asInt(); + case hx::Val::typeInt: return this->operator int() % inA.asInt(); + case hx::Val::typeInt64: return this->operator int() % inA.asInt64(); + case hx::Val::typeBool: return this->operator int() % inA.asInt(); + } +} diff --git a/src/hx/IndexRef.cpp b/src/hx/IndexRef.cpp new file mode 100644 index 000000000..d322b9234 --- /dev/null +++ b/src/hx/IndexRef.cpp @@ -0,0 +1,164 @@ +#include + +#define HX_INDEX_REF_IMPL_MEM_OP(op,ret) \ + ret hx::IndexRef::operator op (const FieldRef& inA) { return this->operator Dynamic() op inA.operator Dynamic(); } \ + ret hx::IndexRef::operator op (const IndexRef& inA) { return this->operator Dynamic() op inA.operator Dynamic(); } \ + ret hx::IndexRef::operator op (const hx::Val& inA) { \ + switch (inA.type) { \ + case hx::Val::typeObject: return this->operator Dynamic() op Dynamic { inA.asDynamic() }; \ + case hx::Val::typeString: return this->operator Dynamic() op inA.asString(); \ + case hx::Val::typeDouble: return this->operator Dynamic() op inA.asDouble(); \ + case hx::Val::typeInt : return this->operator Dynamic() op inA.asInt(); \ + case hx::Val::typeInt64 : return this->operator Dynamic() op inA.asInt64(); \ + case hx::Val::typeBool : return this->operator Dynamic() op inA.asInt(); \ + } \ + } + +hx::IndexRef::IndexRef(hx::Object* inObj, int inIndex) : mObject(inObj), mIndex(inIndex) {} + +Dynamic hx::IndexRef::operator=(const Dynamic& inRHS) +{ + return mObject->__SetItem(mIndex, inRHS); +} + +hx::IndexRef::operator Dynamic() const +{ + return mObject->__GetItem(mIndex); +} + +hx::IndexRef::operator double() const +{ + return mObject->__GetItem(mIndex); +} + +hx::IndexRef::operator int() const +{ + return mObject->__GetItem(mIndex); +} + +double hx::IndexRef::operator ++(int) +{ + double d = mObject->__GetItem(mIndex)->__ToDouble(); + mObject->__SetItem(mIndex, d + 1); + return d; +} + +double hx::IndexRef::operator ++() +{ + double d = mObject->__GetItem(mIndex)->__ToDouble() + 1; + mObject->__SetItem(mIndex, d); + return d; +} + +double hx::IndexRef::operator --(int) +{ + double d = mObject->__GetItem(mIndex)->__ToDouble(); + mObject->__SetItem(mIndex, d - 1); + return d; +} + +double hx::IndexRef::operator --() +{ + double d = mObject->__GetItem(mIndex)->__ToDouble() - 1; + mObject->__SetItem(mIndex, d); + return d; +} + +bool hx::IndexRef::operator !() +{ + return !mObject->__GetItem(mIndex)->__ToInt(); +} + +int hx::IndexRef::operator ~() +{ + return ~mObject->__GetItem(mIndex)->__ToInt(); +} + +double hx::IndexRef::operator -() +{ + return -mObject->__GetItem(mIndex)->__ToDouble(); +} + +bool hx::IndexRef::operator ==(const null&) const +{ + return !mObject; +} + +bool hx::IndexRef::operator !=(const null&) const +{ + return mObject; +} + +bool hx::IndexRef::HasPointer() const +{ + return mObject; +} + +HX_INDEX_REF_IMPL_MEM_OP(== , bool) +HX_INDEX_REF_IMPL_MEM_OP(!= , bool) +HX_INDEX_REF_IMPL_MEM_OP(< , bool) +HX_INDEX_REF_IMPL_MEM_OP(<= , bool) +HX_INDEX_REF_IMPL_MEM_OP(> , bool) +HX_INDEX_REF_IMPL_MEM_OP(>= , bool) + +HX_INDEX_REF_IMPL_MEM_OP(+, Dynamic) + +// Below has the above macros expanded since some operators on some times aren't supported and need manual dynamic wrapping. +// There may be some sort of tagged dispatch which could be done in the macro instead to avoid this. + +double hx::IndexRef::operator * (const FieldRef& inA) { return this->operator Dynamic() * inA.operator Dynamic(); } +double hx::IndexRef::operator * (const IndexRef& inA) { return this->operator Dynamic() * inA.operator Dynamic(); } +double hx::IndexRef::operator * (const hx::Val& inA) +{ + switch (inA.type) + { + case hx::Val::typeObject: return this->operator double() * inA.asDouble(); + case hx::Val::typeString: return this->operator double() * inA.asDouble(); + case hx::Val::typeDouble: return this->operator double() * inA.asDouble(); + case hx::Val::typeInt: return this->operator double() * inA.asInt(); + case hx::Val::typeInt64: return this->operator double() * inA.asInt64(); + case hx::Val::typeBool: return this->operator double() * inA.asInt(); + } +} + +double hx::IndexRef::operator / (const FieldRef& inA) { return this->operator Dynamic() / inA.operator Dynamic(); } +double hx::IndexRef::operator / (const IndexRef& inA) { return this->operator Dynamic() / inA.operator Dynamic(); } +double hx::IndexRef::operator / (const hx::Val& inA) +{ + switch (inA.type) { + case hx::Val::typeObject: return this->operator double() / inA.asDouble(); + case hx::Val::typeString: return this->operator double() / inA.asDouble(); + case hx::Val::typeDouble: return this->operator double() / inA.asDouble(); + case hx::Val::typeInt: return this->operator double() / inA.asInt(); + case hx::Val::typeInt64: return this->operator double() / inA.asInt64(); + case hx::Val::typeBool: return this->operator double() / inA.asInt(); + } +} + +double hx::IndexRef::operator - (const FieldRef& inA) { return this->operator Dynamic() - inA.operator Dynamic(); } +double hx::IndexRef::operator - (const IndexRef& inA) { return this->operator Dynamic() - inA.operator Dynamic(); } +double hx::IndexRef::operator - (const hx::Val& inA) +{ + switch (inA.type) { + case hx::Val::typeObject: return this->operator double() - inA.asDouble(); + case hx::Val::typeString: return this->operator double() - inA.asDouble(); + case hx::Val::typeDouble: return this->operator double() - inA.asDouble(); + case hx::Val::typeInt: return this->operator double() - inA.asInt(); + case hx::Val::typeInt64: return this->operator double() - inA.asInt64(); + case hx::Val::typeBool: return this->operator double() - inA.asInt(); + } +} + +double hx::IndexRef::operator % (const FieldRef& inA) { return this->operator Dynamic() % inA.operator Dynamic(); } +double hx::IndexRef::operator % (const IndexRef& inA) { return this->operator Dynamic() % inA.operator Dynamic(); } +double hx::IndexRef::operator % (const hx::Val& inA) +{ + switch (inA.type) { + case hx::Val::typeObject: return this->operator int() % inA.asInt(); + case hx::Val::typeString: return this->operator int() % inA.asInt(); + case hx::Val::typeDouble: return this->operator int() % inA.asInt(); + case hx::Val::typeInt: return this->operator int() % inA.asInt(); + case hx::Val::typeInt64: return this->operator int() % inA.asInt64(); + case hx::Val::typeBool: return this->operator int() % inA.asInt(); + } +} \ No newline at end of file