#ifndef HX_FIELD_REF_H #define HX_FIELD_REF_H namespace hx { // --- FieldRef ---------------------------------------------------------- // // This is used to provide syntaxe for setting fields by name. This is because // the field can't be returned by reference, because it may not exist as a dynamic. // // eg, consider class 'A' with variable 'x': // class A { int x; } // // And you have a Dynamic pointing to it: // Dynamic d = new A; Then you access x by name: // d->__Field("x") = 1; // // __Field can't return a Dynamic & because x is a int, not Dynamic. So I use this class. // Note that this may change if I fix the generator to create __SetField("x",1) directly. #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(); } \ 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 ); } #if HXCPP_API_LEVEL >= 330 inline operator hx::Val() const { return mObject ? mObject->__Field(mName, HX_PROP_DYNAMIC) : null(); } #endif 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; }; // We can define this one now... template inline FieldRef ObjectPtr::FieldRef(const String &inString) { return hx::FieldRef(mPtr,inString); } #define HX_FIELD_REF_OP(op,ret) \ template inline ret operator op (T &inT, const FieldRef &inA) \ { return inT op ( inA.operator Dynamic()); } HX_FIELD_REF_OP(==,bool) HX_FIELD_REF_OP(!=,bool) HX_FIELD_REF_OP(<,bool) HX_FIELD_REF_OP(<=,bool) HX_FIELD_REF_OP(>,bool) HX_FIELD_REF_OP(>=,bool) HX_FIELD_REF_OP(+,Dynamic) HX_FIELD_REF_OP(*,double) HX_FIELD_REF_OP(/,double) HX_FIELD_REF_OP(-,double) HX_FIELD_REF_OP(%,double) // --- IndexRef -------------------------------------------------------------- // // Like FieldRef, but for integer array access // #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; } 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; }; // We can define this one now... template inline IndexRef ObjectPtr::IndexRef(int inIndex) { return hx::IndexRef(mPtr,inIndex); } #define HX_INDEX_REF_OP(op,ret) \ template inline ret operator op (T &inT, const IndexRef &inA) \ { return inT op ( inA. operator Dynamic()); } HX_INDEX_REF_OP(==,bool) HX_INDEX_REF_OP(!=,bool) HX_INDEX_REF_OP(<,bool) HX_INDEX_REF_OP(<=,bool) HX_INDEX_REF_OP(>,bool) HX_INDEX_REF_OP(>=,bool) HX_INDEX_REF_OP(+,Dynamic) HX_INDEX_REF_OP(*,double) HX_INDEX_REF_OP(/,double) 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) \ inline ret operator op (const Dynamic &inT, const IndexRef &inA) \ { return inT op ( inA.operator Dynamic()); } HX_INDEX_REF_OP_DYNAMIC(==,bool) HX_INDEX_REF_OP_DYNAMIC(!=,bool) HX_INDEX_REF_OP_DYNAMIC(+,Dynamic) HX_INDEX_REF_OP_DYNAMIC(*,double) template class __TArrayImplRef { public: _OBJ mObject; int mIndex; explicit __TArrayImplRef(_OBJ inObj,int inIndex) : mObject(inObj), mIndex(inIndex) { } template inline operator _DATA() { return mObject->__get(mIndex); } template inline void operator=(_DATA inRHS) { mObject->__set(mIndex,inRHS); } }; template __TArrayImplRef<_OBJ> __ArrayImplRef(_OBJ inObj, int inIndex) { return __TArrayImplRef<_OBJ>(inObj,inIndex); } } // end namespace hx #endif