#ifndef HX_ARRAY_H #define HX_ARRAY_H #include // --- hx::ReturnNull ------------------------------------------------------ // // Provides an "Null" of given type. For types that can't actually be null, Dynamic is used. namespace hx { enum ArrayStore { arrayNull = 0, arrayEmpty, arrayFixed, arrayBool, arrayInt, arrayFloat, arrayString, arrayObject, arrayInt64 }; enum ArrayConvertId { aciAlwaysConvert = -4, aciVirtualArray = -3, aciStringArray = -2, aciObjectArray = -1, aciNotArray = 0, aciPodBase = 1, }; template struct ReturnNull { typedef T type; }; template<> struct ReturnNull { typedef Dynamic type; }; template<> struct ReturnNull { typedef Dynamic type; }; template<> struct ReturnNull { typedef Dynamic type; }; template<> struct ReturnNull { typedef Dynamic type; }; template<> struct ReturnNull { typedef Dynamic type; }; template<> struct ReturnNull { typedef Dynamic type; }; template<> struct ReturnNull { typedef Dynamic type; }; template<> struct ReturnNull { typedef Dynamic type; }; template<> struct ReturnNull { typedef Dynamic type; }; template<> struct ReturnNull { typedef Dynamic type; }; template<> struct ReturnNull< ::cpp::Int64> { typedef Dynamic type; }; template struct ArrayTraits { enum { StoreType = arrayObject }; }; template<> struct ArrayTraits { enum { StoreType = arrayInt }; }; template<> struct ArrayTraits { enum { StoreType = arrayFloat}; }; template<> struct ArrayTraits { enum { StoreType = arrayFloat}; }; template<> struct ArrayTraits { enum { StoreType = arrayObject }; }; template<> struct ArrayTraits { enum { StoreType = arrayString }; }; template<> struct ArrayTraits< ::cpp::Int64> { enum { StoreType = arrayInt64 }; }; } namespace hx { // --- ArrayIterator ------------------------------------------- // // An object that conforms to the standard iterator interface for arrays template class ArrayIterator : public cpp::FastIterator_obj { public: HX_IS_INSTANCE_OF enum { _hx_ClassId = hx::clsIdArrayIterator }; ArrayIterator(Array inArray) : mArray(inArray), mIdx(0) { } // Fast versions ... bool hasNext() { return mIdx < mArray->length; } inline TO toTo(const Dynamic &inD) { return inD.StaticCast(); } template inline TO toTo(T inT) { return inT; } TO next() { return toTo(mArray->__get(mIdx++)); } void __Mark(hx::MarkContext *__inCtx) { HX_MARK_MEMBER_NAME(mArray,"mArray"); } #ifdef HXCPP_VISIT_ALLOCS void __Visit(hx::VisitContext *__inCtx) { HX_VISIT_MEMBER_NAME(mArray,"mArray"); } #endif int mIdx; Array mArray; }; // --- ArrayKeyValueIterator ------------------------------------------- template class ArrayKeyValueIterator : public cpp::FastIterator_obj { public: HX_IS_INSTANCE_OF enum { _hx_ClassId = hx::clsIdArrayIterator }; ArrayKeyValueIterator(Array inArray) : mArray(inArray), mIdx(0) { } bool hasNext() { return mIdx < mArray->length; } inline TO toTo(const Dynamic &inD) { return inD.StaticCast(); } template inline TO toTo(T inT) { return inT; } Dynamic next(); void __Mark(hx::MarkContext *__inCtx) { HX_MARK_MEMBER_NAME(mArray,"mArray"); } #ifdef HXCPP_VISIT_ALLOCS void __Visit(hx::VisitContext *__inCtx) { HX_VISIT_MEMBER_NAME(mArray,"mArray"); } #endif int mIdx; Array mArray; }; } namespace hx { // Also used by cpp::VirtualArray class HXCPP_EXTERN_CLASS_ATTRIBUTES ArrayCommon : public hx::Object { protected: int mArrayConvertId; public: // Plain old data element size - or 0 if not plain-old-data int getArrayConvertId() const { return mArrayConvertId; } #if (HXCPP_API_LEVEL>330) virtual hx::Object *__GetRealObject() { return this; } #endif }; // --- hx::ArrayBase ---------------------------------------------------- // // Base class that treats array contents as a slab of bytes. // The derived "Array_obj" adds strong typing to the "[]" operator class HXCPP_EXTERN_CLASS_ATTRIBUTES ArrayBase : public ArrayCommon { public: ArrayBase(int inSize,int inReserve,int inElementSize,bool inAtomic); // Defined later so we can use "Array" static Array __new(int inSize=0,int inReserve=0); static void __boot(); typedef hx::Object super; HX_IS_INSTANCE_OF enum { _hx_ClassId = hx::clsIdArrayBase }; // Used by cpp.ArrayBase inline int getElementSize() const { return GetElementSize(); } inline int getByteCount() const { return GetElementSize()*length; } inline char * getBase() const { return mBase; } hx::Val __SetField(const String &inString,const hx::Val &inValue ,hx::PropertyAccess inCallProp) { return null(); } static hx::Class __mClass; static hx::Class &__SGetClass() { return __mClass; } hx::Class __GetClass() const { return __mClass; } String toString(); String __ToString() const; #if (HXCPP_API_LEVEL>330) int __Compare(const hx::Object *inRHS) const; #endif void setData(void *inData, int inElements) { mBase = (char *)inData; length = inElements; mAlloc = inElements; HX_OBJ_WB_PESSIMISTIC_GET(this); } void setUnmanagedData(void *inData, int inElements) { mBase = (char *)inData; length = inElements; mAlloc = -1; } int __GetType() const { return vtArray; } inline size_t size() const { return length; } inline int __length() const { return (int)length; } virtual String ItemString(int inI) = 0; const char * __CStr() const { return mBase; } inline const char *GetBase() const { return mBase; } inline char *GetBase() { return mBase; } virtual int GetElementSize() const = 0; inline void resize(int inSize) { if (inSizelength) { EnsureSize(inSize); length = inSize; } } inline void __SetSize(int inLen) { resize(inLen); } void __SetSizeExact(int inLen=0); Dynamic __unsafe_get(const Dynamic &i); Dynamic __unsafe_set(const Dynamic &i, const Dynamic &val); void safeSort(Dynamic sorter, bool isString); inline void __unsafeStringReference(String inString) { mBase = (char *)inString.raw_ptr(); length = inString.length / GetElementSize(); mAlloc = length; HX_OBJ_WB_PESSIMISTIC_GET(this); } virtual hx::ArrayStore getStoreType() const = 0; // Dynamic interface hx::Val __Field(const String &inString ,hx::PropertyAccess inCallProp); #if (HXCPP_API_LEVEL < 330) virtual Dynamic __concat(const Dynamic &a0) = 0; virtual Dynamic __copy() = 0; virtual Dynamic __insert(const Dynamic &a0,const Dynamic &a1) = 0; virtual Dynamic __iterator() = 0; virtual Dynamic __keyValueIterator() = 0; virtual Dynamic __join(const Dynamic &a0) = 0; virtual Dynamic __pop() = 0; virtual Dynamic __push(const Dynamic &a0) = 0; virtual Dynamic __remove(const Dynamic &a0) = 0; virtual Dynamic __removeAt(const Dynamic &a0) = 0; virtual Dynamic __indexOf(const Dynamic &a0,const Dynamic &a1) = 0; virtual Dynamic __lastIndexOf(const Dynamic &a0,const Dynamic &a1) = 0; virtual Dynamic __reverse() = 0; virtual Dynamic __shift() = 0; virtual Dynamic __slice(const Dynamic &a0,const Dynamic &a1) = 0; virtual Dynamic __splice(const Dynamic &a0,const Dynamic &a1) =0; virtual Dynamic __sort(const Dynamic &a0) = 0; virtual Dynamic __toString() = 0; virtual Dynamic __unshift(const Dynamic &a0) = 0; virtual Dynamic __map(const Dynamic &func) = 0; virtual Dynamic __filter(const Dynamic &func) = 0; inline Dynamic ____SetSize(const Dynamic &len) { resize(len); return this; } inline Dynamic ____SetSizeExact(const Dynamic &len) { __SetSizeExact(len); return this; } inline Dynamic ____unsafe_set(const Dynamic &i, const Dynamic &val) { return __SetItem(i,val); } inline Dynamic ____unsafe_get(const Dynamic &i) { return __GetItem(i); } virtual Dynamic __blit(const Dynamic &a0,const Dynamic &a1,const Dynamic &a2,const Dynamic &a3) = 0; inline Dynamic __zero(const Dynamic &a0,const Dynamic &a1) { zero(a0,a1); return null(); } virtual Dynamic __memcmp(const Dynamic &a0) = 0; virtual void __qsort(Dynamic inCompare) = 0; virtual Dynamic __resize(const Dynamic &a0) = 0; #else inline void ____SetSize(int len) { resize(len); } inline void ____SetSizeExact(int len) { __SetSizeExact(len); } inline Dynamic ____unsafe_set(const Dynamic &i, const Dynamic &val) { return __SetItem(i,val); } inline Dynamic ____unsafe_get(const Dynamic &i) { return __GetItem(i); } virtual hx::ArrayBase *__concat(const cpp::VirtualArray &a0) = 0; virtual hx::ArrayBase *__copy() = 0; virtual void __insert(int inIndex,const Dynamic &a1) = 0; virtual Dynamic __iterator() = 0; virtual Dynamic __keyValueIterator() = 0; virtual ::String __join(::String a0) = 0; virtual Dynamic __pop() = 0; virtual int __push(const Dynamic &a0) = 0; virtual bool __contains(const Dynamic &a0) = 0; virtual bool __remove(const Dynamic &a0) = 0; virtual bool __removeAt(int inIndex) = 0; virtual int __indexOf(const Dynamic &a0,const Dynamic &a1) = 0; virtual int __lastIndexOf(const Dynamic &a0,const Dynamic &a1) = 0; virtual void __reverse() = 0; virtual Dynamic __shift() = 0; virtual hx::ArrayBase *__slice(const Dynamic &a0,const Dynamic &a1) = 0; virtual hx::ArrayBase *__splice(const Dynamic &a0,const Dynamic &a1) = 0; virtual void __sort(const Dynamic &a0) = 0; virtual ::String __toString() = 0; virtual void __unshift(const Dynamic &a0) = 0; virtual cpp::VirtualArray_obj *__map(const Dynamic &func) = 0; virtual hx::ArrayBase *__filter(const Dynamic &func) = 0; virtual void __blit(int inDestElement,const cpp::VirtualArray &inSourceArray,int inSourceElement,int inElementCount) = 0; virtual int __memcmp(const cpp::VirtualArray &a0) = 0; inline void __zero(const Dynamic &a0,const Dynamic &a1) { zero(a0,a1); } virtual void __qsort(Dynamic inCompare) = 0; virtual void __resize(int inLen) = 0; virtual void set(int inIdx, const cpp::Variant &inValue) = 0; virtual void setUnsafe(int inIdx, const cpp::Variant &inValue) = 0; #endif Dynamic concat_dyn(); Dynamic copy_dyn(); Dynamic insert_dyn(); Dynamic iterator_dyn(); Dynamic keyValueIterator_dyn(); Dynamic join_dyn(); Dynamic pop_dyn(); Dynamic push_dyn(); Dynamic contains_dyn(); Dynamic remove_dyn(); Dynamic removeAt_dyn(); Dynamic indexOf_dyn(); Dynamic lastIndexOf_dyn(); Dynamic reverse_dyn(); Dynamic shift_dyn(); Dynamic slice_dyn(); Dynamic splice_dyn(); Dynamic sort_dyn(); Dynamic toString_dyn(); Dynamic unshift_dyn(); Dynamic map_dyn(); Dynamic filter_dyn(); Dynamic __SetSize_dyn(); Dynamic __SetSizeExact_dyn(); Dynamic __unsafe_get_dyn(); Dynamic __unsafe_set_dyn(); Dynamic blit_dyn(); Dynamic zero_dyn(); Dynamic memcmp_dyn(); Dynamic resize_dyn(); void Realloc(int inLen) const; inline void EnsureSize(int inLen) const { if (inLen>length) { if (inLen>mAlloc) Realloc(inLen); length = inLen; } } void RemoveElement(int inIndex); void Insert(int inPos); void Splice(hx::ArrayBase *outResult,int inPos,int inLen); void Slice(hx::ArrayBase *outResult,int inPos,int inEnd); void Concat(hx::ArrayBase *outResult,const char *inEnd, int inLen); void reserve(int inN) const; inline int capacity() const { return mAlloc; } // Set numeric values to 0, pointers to null, bools to false void zero(Dynamic inFirst, Dynamic inCount); int Memcmp(ArrayBase *inArray); // Copy section of other array. void Blit(int inDestElement, ArrayBase *inSourceArray, int inSourceElement, int inElementCount); static String joinArray(hx::ArrayBase *inBase, String inSeparator); static String joinArray(Array_obj *inArray, String inSeparator); virtual bool AllocAtomic() const { return false; } inline bool IsByteArray() const { return getStoreType()==arrayBool; } inline Dynamic __get(int inIndex) const { return __GetItem(inIndex); } // Plain old data element size - or 0 if not plain-old-data int getArrayConvertId() const { return mArrayConvertId; } mutable int length; static inline int baseOffset() { return (int)offsetof(ArrayBase,mBase); } static inline int allocOffset() { return (int)offsetof(ArrayBase,mAlloc); } static inline int lengthOffset() { return (int)offsetof(ArrayBase,length); } protected: mutable int mAlloc; mutable char *mBase; }; } // end namespace hx for ArrayBase namespace cpp { typedef hx::ArrayBase ArrayBase_obj; // Use by cpp.ArrayBase extern typedef hx::ObjectPtr ArrayBase; } #if (HXCPP_API_LEVEL>=330) #include "cpp/VirtualArray.h" #endif // --- Array_obj ------------------------------------------------------------------ // // The Array_obj specialises the ArrayBase, adding typing where required namespace hx { // This is to determine is we need to include our slab of bytes in garbage collection template inline bool TypeContainsPointers(T *) { return true; } template<> inline bool TypeContainsPointers(bool *) { return false; } template<> inline bool TypeContainsPointers(int *) { return false; } template<> inline bool TypeContainsPointers(double *) { return false; } template<> inline bool TypeContainsPointers(float *) { return false; } template<> inline bool TypeContainsPointers(short *) { return false; } template<> inline bool TypeContainsPointers(unsigned char *) { return false; } template<> inline bool TypeContainsPointers(::cpp::Int64 *) { return false; } template inline bool ContainsPointers() { return TypeContainsPointers( (TYPE *)0 ); } struct TNonGcStringSet; //template inline const void *PointerOf(hx::ObjectPtr &o) { return o.mPtr; } //inline const void *PointerOf(String &s) { return s.raw_ptr(); } inline const void *PointerOf(hx::TNonGcStringSet &set) { return 0; } //inline const void *PointerOf(...) { return 0; } // For returning "null" when out of bounds ... template inline TYPE *NewNull() { Dynamic d; return (TYPE *)hx::NewGCBytes(&d,sizeof(d)); } template<> inline int *NewNull() { int i=0; return (int *)hx::NewGCPrivate(&i,sizeof(i)); } template<> inline bool *NewNull() { bool b=0; return (bool *)hx::NewGCPrivate(&b,sizeof(b)); } template<> inline double *NewNull() { double d=0.0; return (double *)hx::NewGCPrivate(&d,sizeof(d)); } template<> inline float *NewNull() { float d=0.0f; return (float *)hx::NewGCPrivate(&d,sizeof(d)); } template<> inline unsigned char *NewNull() { unsigned char u=0; return (unsigned char *)hx::NewGCPrivate(&u,sizeof(u)); } template<> inline ::cpp::Int64 *NewNull< ::cpp::Int64>() { ::cpp::Int64 i=0; return (::cpp::Int64 *)hx::NewGCPrivate(&i,sizeof(i)); } bool DynamicEq(const Dynamic &a, const Dynamic &b); } template struct ArrayClassId { enum { id=hx::clsIdArrayObject }; }; template<> struct ArrayClassId { enum { id=hx::clsIdArrayByte }; }; template<> struct ArrayClassId { enum { id=hx::clsIdArrayByte }; }; template<> struct ArrayClassId { enum { id=hx::clsIdArrayShort }; }; template<> struct ArrayClassId { enum { id=hx::clsIdArrayShort }; }; template<> struct ArrayClassId { enum { id=hx::clsIdArrayInt }; }; template<> struct ArrayClassId { enum { id=hx::clsIdArrayInt }; }; template<> struct ArrayClassId { enum { id=hx::clsIdArrayFloat32 }; }; template<> struct ArrayClassId { enum { id=hx::clsIdArrayFloat64 }; }; template<> struct ArrayClassId { enum { id=hx::clsIdArrayString }; }; template<> struct ArrayClassId< ::cpp::Int64> { enum { id=hx::clsIdArrayInt64 }; }; // sort... #include namespace hx { template inline bool arrayElemEq(const T &a, const T &b) { return a==b; } template<> inline bool arrayElemEq(const Dynamic &a, const Dynamic &b) { return hx::DynamicEq(a,b); } } template class Array_obj : public hx::ArrayBase { typedef ELEM_ Elem; typedef hx::ObjectPtr< Array_obj > ObjPtr; typedef typename hx::ReturnNull::type NullType; public: enum { _hx_ClassId = ArrayClassId::id }; Array_obj(int inSize,int inReserve) : hx::ArrayBase(inSize,inReserve,sizeof(ELEM_),!hx::ContainsPointers()) { } // Defined later so we can use "Array" static Array __new(int inSize=0,int inReserve=0); static Array __newConstWrapper(ELEM_ *inData,int inSize); static Array fromData(const ELEM_ *inData,int inCount); #if (HXCPP_API_LEVEL>331) bool _hx_isInstanceOf(int inClassId) { return inClassId==1 || inClassId==(int)hx::clsIdArrayBase || inClassId==(int)_hx_ClassId; } #endif virtual bool AllocAtomic() const { return !hx::ContainsPointers(); } virtual Dynamic __GetItem(int inIndex) const { return __get(inIndex); } virtual Dynamic __SetItem(int inIndex,Dynamic inValue) { ELEM_ &elem = Item(inIndex); elem = inValue; if (hx::ContainsPointers()) { HX_OBJ_WB_GET(this,hx::PointerOf(elem)); } return inValue; } inline ELEM_ *Pointer() { return (ELEM_ *)mBase; } inline ELEM_ &Item(int inIndex) { if (inIndex>=(int)length) EnsureSize(inIndex+1); else if (inIndex<0) { return * hx::NewNull(); } return * (ELEM_ *)(mBase + inIndex*sizeof(ELEM_)); } inline ELEM_ __get(int inIndex) const { if ((unsigned int)inIndex>=(unsigned int)length ) return null(); return * (ELEM_ *)(mBase + inIndex*sizeof(ELEM_)); } // Does not check for size valid - use with care inline ELEM_ &__unsafe_get(int inIndex) { return * (ELEM_ *)(mBase + inIndex*sizeof(ELEM_)); } inline ELEM_ & __unsafe_set(int inIndex, ELEM_ inValue) { ELEM_ &elem = *(ELEM_*)(mBase + inIndex*sizeof(ELEM_)); elem = inValue; if (hx::ContainsPointers()) { HX_OBJ_WB_GET(this, hx::PointerOf(elem)); } return elem; } inline int memcmp(Array inOther) { return ArrayBase::Memcmp(inOther.GetPtr()); } inline void memcpy(int inStart, const ELEM_ *inData, int inElements) { EnsureSize(inStart+inElements); int s = GetElementSize(); ::memcpy(mBase + s*inStart, inData, s*inElements); if (hx::ContainsPointers()) { HX_OBJ_WB_PESSIMISTIC_GET(this); } } inline void blit(int inDestElement, Array inSourceArray, int inSourceElement, int inElementCount) { ArrayBase::Blit(inDestElement, inSourceArray.GetPtr(), inSourceElement, inElementCount); } void __Mark(hx::MarkContext *__inCtx) { if (mAlloc>0) hx::MarkAlloc((void *)mBase, __inCtx ); if (length && hx::ContainsPointers()) { ELEM_ *ptr = (ELEM_ *)mBase; HX_MARK_MEMBER_ARRAY(ptr,length); } } #ifdef HXCPP_VISIT_ALLOCS void __Visit(hx::VisitContext *__inCtx) { if (mAlloc>0) __inCtx->visitAlloc((void **)&mBase); if (hx::ContainsPointers()) { ELEM_ *ptr = (ELEM_ *)mBase; for(int i=0;i __SetSizeExact(int inLen); int GetElementSize() const { return sizeof(ELEM_); } String ItemString(int inI) { String result(__get(inI)); if (result==null()) return HX_CSTRING("null"); return result; } Array_obj *Add(const ELEM_ &inItem) { push(inItem); return this; } Array init(int inIndex, ELEM_ inValue) { * (ELEM_ *)(mBase + inIndex*sizeof(ELEM_)) = inValue; #ifdef HXCPP_GC_GENERATIONAL if (hx::ContainsPointers()) { HX_OBJ_WB_GET(this, hx::PointerOf(inValue)); } #endif return this; } #ifdef HXCPP_GC_GENERATIONAL inline int pushCtx(hx::StackContext *_hx_ctx, ELEM_ inVal ) { int l = length; EnsureSize((int)l+1); * (ELEM_ *)(mBase + l*sizeof(ELEM_)) = inVal; if (hx::ContainsPointers()) { HX_ARRAY_WB(this,inIdx, hx::PointerOf(inVal) ); } return length; } #endif // Haxe API inline int push( ELEM_ inVal ) { #ifdef HXCPP_GC_GENERATIONAL if (hx::ContainsPointers()) return pushCtx(HX_CTX_GET,inVal); #endif int l = length; EnsureSize((int)l+1); * (ELEM_ *)(mBase + l*sizeof(ELEM_)) = inVal; return length; } inline NullType pop( ) { if (!length) return null(); ELEM_ result = __get((int)length-1); resize((int)length-1); return result; } int Find(ELEM_ inValue) { ELEM_ *e = (ELEM_ *)mBase; for(int i=0;i=length || idx<0) return false; RemoveElement(idx); return true; } int indexOf(ELEM_ inValue, Dynamic fromIndex = null()) { int len = length; int i = fromIndex==null() ? 0 : fromIndex->__ToInt(); ELEM_ *e = (ELEM_ *)mBase; if (i < 0) { i += len; if (i < 0) i = 0; } while(i__ToInt(); ELEM_ *e = (ELEM_ *)mBase; if (i >= len) i = len - 1; else if (i < 0) i += len; while(i>=0) { if (hx::arrayElemEq(e[i],inValue)) return i; i--; } return -1; } NullType shift() { if (length==0) return null(); ELEM_ result = __get(0); RemoveElement(0); return result; } String join(String inSeparator) { return ArrayBase::joinArray(this, inSeparator); } Array concat( Array inTail ); Array copy( ); Array slice(int inPos, Dynamic end = null()); Array splice(int inPos, int len); inline void removeRange(int inPos, int len) { hx::ArrayBase::Splice(0,inPos,len); } #if HXCPP_API_LEVEL>=330 cpp::VirtualArray map(Dynamic inFunc); #else Dynamic map(Dynamic inFunc); #endif Array filter(Dynamic inFunc); void insert(int inPos, ELEM_ inValue) { if (inPos<0) { inPos+=length; if (inPos<0) inPos = 0; } else if (inPos>length) inPos = length; hx::ArrayBase::Insert(inPos); Item(inPos) = inValue; #ifdef HXCPP_GC_GENERATIONAL if (hx::ContainsPointers()) { HX_OBJ_WB_GET(this,hx::PointerOf(inValue)); } #endif } void unshift(ELEM_ inValue) { insert(0,inValue); } void reverse() { int half = length/2; ELEM_ *e = (ELEM_ *)mBase; for(int i=0;i__ToInt() < 0; } Dynamic mFunc; }; inline void qsort(Dynamic inSorter) { ELEM_ *e = (ELEM_ *)mBase; std::sort(e, e+length, Sorter(inSorter) ); } void sort(Dynamic inSorter) { if ( (int)hx::ArrayTraits::StoreType==(int)hx::arrayObject || (int)hx::ArrayTraits::StoreType==(int)hx::arrayString) { // Keep references from being hidden inside sorters buffers safeSort(inSorter, (int)hx::ArrayTraits::StoreType==(int)hx::arrayString); } else { ELEM_ *e = (ELEM_ *)mBase; std::stable_sort(e, e+length, Sorter(inSorter) ); } } Dynamic iterator() { return new hx::ArrayIterator(this); } Dynamic keyValueIterator() { return new hx::ArrayKeyValueIterator(this); } template Dynamic iteratorFast() { return new hx::ArrayIterator(this); } template Dynamic keyValueIteratorFast() { return new hx::ArrayKeyValueIterator(this); } virtual hx::ArrayStore getStoreType() const { return (hx::ArrayStore) hx::ArrayTraits::StoreType; } inline ELEM_ &setCtx(hx::StackContext *_hx_ctx, int inIdx, ELEM_ inValue) { ELEM_ &elem = Item(inIdx); HX_ARRAY_WB(this,inIdx, hx::PointerOf(inValue) ); return elem = inValue; } // Dynamic interface #if (HXCPP_API_LEVEL < 330) virtual Dynamic __concat(const Dynamic &a0) { return concat(a0); } virtual Dynamic __copy() { return copy(); } virtual Dynamic __insert(const Dynamic &a0,const Dynamic &a1) { insert(a0,a1); return null(); } virtual Dynamic __iterator() { return iterator(); } virtual Dynamic __keyValueIterator() { return keyValueIterator(); } virtual Dynamic __join(const Dynamic &a0) { return join(a0); } virtual Dynamic __pop() { return pop(); } virtual Dynamic __push(const Dynamic &a0) { return push(a0);} virtual Dynamic __remove(const Dynamic &a0) { return remove(a0); } virtual Dynamic __removeAt(const Dynamic &a0) { return removeAt(a0); } virtual Dynamic __indexOf(const Dynamic &a0,const Dynamic &a1) { return indexOf(a0, a1); } virtual Dynamic __lastIndexOf(const Dynamic &a0,const Dynamic &a1) { return lastIndexOf(a0, a1); } virtual Dynamic __reverse() { reverse(); return null(); } virtual Dynamic __shift() { return shift(); } virtual Dynamic __slice(const Dynamic &a0,const Dynamic &a1) { return slice(a0,a1); } virtual Dynamic __splice(const Dynamic &a0,const Dynamic &a1) { return splice(a0,a1); } virtual Dynamic __sort(const Dynamic &a0) { sort(a0); return null(); } virtual Dynamic __toString() { return toString(); } virtual Dynamic __unshift(const Dynamic &a0) { unshift(a0); return null(); } virtual Dynamic __map(const Dynamic &func) { return map(func); } virtual Dynamic __filter(const Dynamic &func) { return filter(func); } virtual Dynamic __blit(const Dynamic &a0,const Dynamic &a1,const Dynamic &a2,const Dynamic &a3) { blit(a0,a1,a2,a3); return null(); } virtual Dynamic __memcmp(const Dynamic &a0) { return memcmp(a0); } virtual Dynamic __resize(const Dynamic &a0) { resize(a0); return null(); } virtual void __qsort(Dynamic inCompare) { this->qsort(inCompare); }; #else //(HXCPP_API_LEVEL < 330) virtual hx::ArrayBase *__concat(const cpp::VirtualArray &a0) { return concat(a0).mPtr; } virtual hx::ArrayBase *__copy() { return copy().mPtr; } virtual void __insert(int inIndex,const Dynamic &a1) { insert(inIndex,a1);} virtual Dynamic __iterator() { return iterator(); } virtual Dynamic __keyValueIterator() { return keyValueIterator(); } virtual ::String __join(::String a0) { return join(a0); } virtual Dynamic __pop() { return pop(); } virtual int __push(const Dynamic &a0) { return push(a0);} virtual bool __contains(const Dynamic &a0) { return contains(a0); } virtual bool __remove(const Dynamic &a0) { return remove(a0); } virtual bool __removeAt(int inIndex) { return removeAt(inIndex); } virtual int __indexOf(const Dynamic &a0,const Dynamic &a1) { return indexOf(a0, a1); } virtual int __lastIndexOf(const Dynamic &a0,const Dynamic &a1) { return lastIndexOf(a0, a1); } virtual void __reverse() { reverse(); } virtual Dynamic __shift() { return shift(); } virtual hx::ArrayBase *__slice(const Dynamic &a0,const Dynamic &a1) { return slice(a0,a1).mPtr; } virtual hx::ArrayBase *__splice(const Dynamic &a0,const Dynamic &a1) { return splice(a0,a1).mPtr; } virtual void __sort(const Dynamic &a0) { sort(a0); } virtual ::String __toString() { return toString(); } virtual void __unshift(const Dynamic &a0) { unshift(a0); } virtual cpp::VirtualArray_obj *__map(const Dynamic &func) { return map(func).mPtr; } virtual void __resize(int inLen) { resize(inLen); } virtual hx::ArrayBase *__filter(const Dynamic &func) { return filter(func).mPtr; } virtual void __blit(int inDestElement,const cpp::VirtualArray &inSourceArray,int inSourceElement,int inElementCount) { blit(inDestElement,inSourceArray,inSourceElement,inElementCount); } virtual int __memcmp(const cpp::VirtualArray &a0) { return memcmp(a0); } virtual void __qsort(Dynamic inCompare) { this->qsort(inCompare); }; virtual void set(int inIndex, const cpp::Variant &inValue) { ELEM_ &elem = Item(inIndex); elem = ELEM_(inValue); if (hx::ContainsPointers()) { HX_OBJ_WB_GET(this, hx::PointerOf(elem)); } } virtual void setUnsafe(int inIndex, const cpp::Variant &inValue) { ELEM_ &elem = *(ELEM_ *)(mBase + inIndex*sizeof(ELEM_)); elem = ELEM_(inValue); if (hx::ContainsPointers()) { HX_OBJ_WB_GET(this,hx::PointerOf(elem)); } } #endif }; // --- Array --------------------------------------------------------------- // // The array class adds object syntax to the Array_obj pointer template class Array : public hx::ObjectPtr< Array_obj > { typedef hx::ObjectPtr< Array_obj > super; typedef Array_obj OBJ_; public: typedef ELEM_ Elem; typedef Array_obj *Ptr; using super::mPtr; using super::GetPtr; Array() { } Array(int inSize,int inReserve) : super( OBJ_::__new(inSize,inReserve) ) { } Array(const null &inNull) : super(0) { } Array(Ptr inPtr) : super(inPtr) { } #ifdef HXCPP_CHECK_POINTER inline OBJ_ *CheckGetPtr() const { if (!mPtr) hx::NullReference("Array", true); // The handler might have fixed up the null value if (!mPtr) hx::NullReference("Array", false); return mPtr; } #else inline OBJ_ *CheckGetPtr() const { return mPtr; } #endif // Construct from our type ... Array ( const hx::ObjectPtr< OBJ_ > &inArray ) : hx::ObjectPtr< OBJ_ >(inArray) { } Array(const Array &inArray) : super(inArray.GetPtr()) { } // Build dynamic array from foreign array template Array( const Array &inRHS ) : super(0) { Array_obj *ptr = inRHS.GetPtr(); if (ptr) { OBJ_ *arr = dynamic_cast(ptr); if (!arr) { // Non-identical type (syntactically, should be creating from Array) // Copy elements one-by-one // Not quite right, but is the best we can do... int n = ptr->__length(); *this = Array_obj::__new(n); for(int i=0;i__unsafe_set(i,ptr->__GetItem(i)); } else mPtr = arr; } } #ifdef HX_VARRAY_DEFINED // From VirtualArray Array( const cpp::VirtualArray &inVArray) { fromVArray(inVArray.mPtr); } void fromVArray(cpp::VirtualArray_obj *inVArray) { if (!inVArray || inVArray->store==hx::arrayNull) { mPtr = 0; return; } inVArray->fixType(); // Switch on type? setDynamic(inVArray->base,true); } Array &operator=( const cpp::VirtualArray &inRHS ) { fromVArray(inRHS.mPtr); return *this; } #endif inline void setDynamic( const Dynamic &inRHS, bool inIgnoreVirtualArray=false ) { hx::Object *ptr = inRHS.GetPtr(); if (ptr) { OBJ_ *arr = dynamic_cast(ptr); if (!arr && ptr->__GetClass().mPtr == super::__SGetClass().mPtr ) { #ifdef HX_VARRAY_DEFINED cpp::VirtualArray_obj *varray = inIgnoreVirtualArray ? 0 : dynamic_cast(ptr); if (varray) fromVArray(varray); else #endif { // Non-identical type. // Copy elements one-by-one // Not quite right, but is the best we can do... int n = ptr->__length(); *this = Array_obj::__new(n); for(int i=0;i__unsafe_set(i,ptr->__GetItem(i)); } } else mPtr = arr; } } Array( const Dynamic &inRHS ) : super(0) { setDynamic(inRHS); } Array( const cpp::ArrayBase &inRHS ) : super(0) { setDynamic(inRHS); } inline Array(const ::cpp::Variant &inVariant) : super(0) { setDynamic(inVariant.asObject()); } // operator= exact match... Array &operator=( Array inRHS ) { mPtr = inRHS.GetPtr(); return *this; } // Foreign array template Array &operator=( const Array &inRHS ) { *this = Array(inRHS); return *this; } Array &operator=( const Dynamic &inRHS ) { setDynamic(inRHS); return *this; } Array &operator=( const cpp::ArrayBase &inRHS ) { setDynamic(inRHS); return *this; } Array &operator=( const cpp::Variant &inRHS ) { if (inRHS.type!=cpp::Variant::typeObject) setDynamic( null() ); else setDynamic(inRHS.valObject); return *this; } Array &operator=( const null &inNull ) { mPtr = 0; return *this; } #if (HXCPP_API_LEVEL >= 330) inline bool operator==(const cpp::VirtualArray &varray) const { return varray==*this; } inline bool operator!=(const cpp::VirtualArray &varray) const { return varray!=*this; } #endif inline ELEM_ &operator[](int inIdx) { return CheckGetPtr()->Item(inIdx); } inline ELEM_ operator[](int inIdx) const { return CheckGetPtr()->__get(inIdx); } //inline ELEM_ __get(int inIdx) const { return CheckGetPtr()->__get(inIdx); } inline int __length() const { return CheckGetPtr()->__length(); } inline Array &Add(const ELEM_ &inElem) { CheckGetPtr()->Add(inElem); return *this; } inline Array & operator<<(const ELEM_ &inElem) { CheckGetPtr()->Add(inElem); return *this; } }; // Now that the "Array" object is defined, we can implement this function .... template Array Array_obj::__new(int inSize,int inReserve) { return Array(new Array_obj(inSize,inReserve)); } template Array Array_obj::__newConstWrapper(ELEM_ *inData,int inSize) { Array_obj temp(0,0); Array_obj *result = (Array_obj *)hx::InternalCreateConstBuffer(&temp,sizeof(temp)); result->setUnmanagedData(inData, inSize); return result; } template Array Array_obj::fromData(const ELEM_ *inData,int inCount) { Array result = new Array_obj(inCount,inCount); if (inCount) result->memcpy(0, inData, inCount); return result; } template<> inline bool Dynamic::IsClass >() { return mPtr && mPtr->__GetClass()== hx::ArrayBase::__mClass; } template Array Array_obj::concat( Array inTail ) { Array_obj *result = new Array_obj(inTail->__length()+(int)length,0); hx::ArrayBase::Concat(result,inTail->GetBase(),inTail->__length()); return result; } template Array Array_obj::copy( ) { Array_obj *result = new Array_obj((int)length,0); ::memcpy(result->GetBase(),GetBase(),length*sizeof(ELEM_)); return result; } // Copies the range of the array starting at pos up to, but not including, end. // Both pos and end can be negative to count from the end: -1 is the last item in the array. template Array Array_obj::slice(int inPos, Dynamic end) { int e = end==null() ? length : end->__ToInt(); Array_obj *result = new Array_obj(0,0); hx::ArrayBase::Slice(result,inPos,(int)e); return result; } template Array Array_obj::splice(int inPos, int len) { Array_obj * result = new Array_obj(0,0); hx::ArrayBase::Splice(result,inPos,len); return result; } template Array Array_obj::filter(Dynamic inFunc) { Array_obj *result = new Array_obj(0,0); for(int i=0;ipush(__unsafe_get(i)); return result; } template Array Array_obj::__SetSizeExact(int inLen) { ArrayBase::__SetSizeExact(inLen); return this; } // Static externs template inline ARRAY _hx_array_set_size_exact(ARRAY inArray, int inLen) { return inArray->__SetSizeExact(inLen); } template inline int _hx_array_memcmp(ARRAY1 inArray1, ARRAY2 inArray2) { return inArray1->memcmp(inArray2); } template inline typename ARRAY::Elem _hx_array_unsafe_set(ARRAY inArray, int inIndex, VALUE inValue) { return inArray->__unsafe_set(inIndex, inValue); } template inline typename ARRAY::Elem _hx_array_unsafe_get(ARRAY inArray, int inIndex) { return inArray->__unsafe_get(inIndex); } // Include again, for functions that required Array definition #ifdef HX_VARRAY_DEFINED #include "cpp/VirtualArray.h" #endif #if HXCPP_API_LEVEL >= 330 template cpp::VirtualArray Array_obj::map(Dynamic inFunc) { cpp::VirtualArray result = cpp::VirtualArray_obj::__new(length,0); for(int i=0;i__unsafe_set(i,inFunc(__unsafe_get(i))); return result; } #else template Dynamic Array_obj::map(Dynamic inFunc) { Array_obj *result = new Array_obj(length,0); for(int i=0;i__unsafe_set(i,inFunc(__unsafe_get(i))); return result; } #endif #endif