declare var table ; declare var len ; declare var ret ; declare var __len__ ; declare var __get_call_undefined__ ; declare var __set_call_undefined__ ; declare var rawget ; declare var rawset ; module JS { export class ArrayHelper { @ __len__ public static getLength ( _this ) { throw 0 ; } public static pushOne < T > ( _this , obj ) { const vals = ( < any > _this ) . _values ; if ( vals ) { table . insert ( vals , obj ) ; return ; } if ( ! _this [ 0 ] ) { _this [ 0 ] = obj ; return ; } table . insert ( _this , obj ) ; } } export class ArrayNullElement { public static __isNull = true ; public static __tostring ( ) { return 'null' ; } } export class ArrayUndefinedElement { public static __isUndefined = true ; public static __tostring ( ) { return 'undefined' ; } } export class Array < T > { [ k ] : T ; private _values : T [ ] = < T [ ] > { } ; public constructor ( size ? ) { const zeroVal = rawget ( this , 0 ) ; if ( zeroVal !== null || rawget ( this , 1 ) !== null ) { if ( zeroVal !== null ) { delete this [ 0 ] ; } const _len = ArrayHelper . getLength ( this ) ; if ( zeroVal !== null ) { table . insert ( this . _values , zeroVal ) ; } for ( let i = 1 ; i <= _len ; i ++ ) { table . insert ( this . _values , rawget ( this , i ) ) ; } for ( let i = _len ; i > 0 ; i -- ) { table . remove ( this , i ) ; delete this [ i ] ; } rawset ( this , 'length' , null ) ; } this . __tostring = function ( ) : string { return this . join ( ) ; } ; this . __ipairs = Array . __ipairsFunc ; this . __pairs = Array . __pairsFunc ; this . __index = function ( _this , indx ) : any { if ( typeof ( indx ) === 'number' ) { const v = rawget ( _this . _values , indx + 1 ) ; const isObject = typeof ( v ) === 'object' ; return isObject && ( < any > v ) . __isNull ? null : isObject && ( < any > v ) . __isUndefined ? undefined : v === null ? undefined : v ; } return __get_call_undefined__ ( _this , indx ) ; } ; this . __newindex = function ( _this , indx , val ) : void { if ( typeof ( indx ) === 'number' ) { rawset ( _this . _values , indx + 1 , val ) ; return ; } __set_call_undefined__ ( _this , indx , val ) ; } ; if ( size ) { this . length = size ; } } public push ( ... objs ) { let any = false ; for ( const obj of objs ) { any = true ; table . insert ( this . _values , obj !== null ? obj : ArrayNullElement ) ; } if ( ! any ) { table . insert ( this . _values , ArrayNullElement ) ; } } public pop ( ) { const l = this . _values . length ; if ( l === 0 ) { throw new Error ( 'Out of items' ) ; } const v = table . remove ( this . _values ) ; return typeof ( v ) === 'object' && ( < any > v ) . isNull ? null : v === null ? undefined : v ; } public get length ( ) : number { return ArrayHelper . getLength ( this . _values ) ; } public set length ( newSize ) { const _len = ArrayHelper . getLength ( this . _values ) ; if ( _len === newSize ) { return ; } if ( newSize < _len ) { for ( let i = _len ; i >= newSize ; i -- ) { table . remove ( this . _values , i ) ; } } else { for ( let i = _len + 1 ; i <= newSize ; i ++ ) { table . insert ( this . _values , i , ArrayUndefinedElement ) ; } } } public indexOf ( val ) { const vals = this . _values ; const length_ = ArrayHelper . getLength ( vals ) ; for ( let i = 1 ; i <= length_ ; i ++ ) { if ( rawget ( vals , i ) == val ) { return i - 1 ; } } return - 1 ; } public join ( ) { return table . concat ( this . _values ) ; } public sort ( ) { table . sort ( this . _values ) ; } public shift ( ) { const v = table . remove ( this . _values , 1 ) ; return typeof ( v ) === 'object' && ( < any > v ) . isNull ? null : v == null ? undefined : v ; } public unshift ( ... objs ) { const vals = this . _values ; for ( const obj of objs ) { table . insert ( vals , obj ) ; } } public concat ( other ) { const retArr = new Array < T > ( ) ; const _vals = this . _values ; const _len = ArrayHelper . getLength ( _vals ) ; for ( let i = 1 ; i <= _len ; i ++ ) { table . insert ( retArr . _values , _vals [ i ] ) ; } for ( const obj of other ) { table . insert ( retArr . _values , obj ) ; } return retArr ; } public remove ( obj ) { const idx = this . indexOf ( obj ) ; if ( idx !== - 1 ) { table . remove ( this . _values , idx + 1 ) ; } } public map ( func , thisValue ? ) { const retArr = new Array < T > ( ) ; let index = 0 ; const _vals = this . _values ; const _len = ArrayHelper . getLength ( _vals ) ; for ( let i = 1 ; i <= _len ; i ++ ) { const obj = func ( _vals [ i ] , index ++ , this ) ; ArrayHelper . pushOne ( retArr , obj ) ; } return retArr ; } public filter ( func , thisValue ? ) { const retArr = new Array < T > ( ) ; let index = 0 ; const _vals = this . _values ; const _len = ArrayHelper . getLength ( _vals ) ; for ( let i = 1 ; i <= _len ; i ++ ) { const val = _vals [ i ] ; const iftrue = func ( val , index ++ , this ) ; if ( iftrue ) { ArrayHelper . pushOne ( ret , val ) ; } } return retArr ; } public forEach ( func , thisValue ? ) { let index = 0 ; const _vals = this . _values ; const _len = ArrayHelper . getLength ( _vals ) ; for ( let i = 1 ; i <= _len ; i ++ ) { const val = _vals [ i ] ; func ( val , index ++ , this ) ; } } public every ( func , thisValue ? ) { let index = 0 ; let result = true ; for ( const val of this . _values ) { result &= func ( val , index ++ , this ) ; } return result ; } public splice ( index , howmany ? , ... items ) { const count = howmany || 1 ; const retArr = new Array < T > ( ) ; for ( let i = index + count ; i > index ; i -- ) { ArrayHelper . pushOne ( retArr , rawget ( this . _values , i ) ) ; table . remove ( this . _values , i ) ; } if ( items ) { const length_ = ArrayHelper . getLength ( items ) ; for ( let i = 0 ; i < length_ ; i ++ ) { const ind = i + index + 1 ; table . insert ( this . _values , ind , items [ i ] ) ; } } return retArr ; } public slice ( begin ? , _end ? ) { const retArr = new Array < T > ( ) ; const from = begin || 0 ; if ( from < 0 ) { throw new Error ( `Index out of bounds: ${ from }` ) ; } let to = _end || this . length ; if ( to > this . length ) { to = this . length ; } for ( let i = from ; i < to ; i ++ ) { table . insert ( retArr . _values , rawget ( this . _values , i + 1 ) ) ; } return retArr ; } } }