#ifndef BB_ARRAY_H #define BB_ARRAY_H #include "bbgc.h" #include "bbdebug.h" #include "bbobject.h" template class bbArray : public bbGCNode{ int _sizes[D]; T _data[0]; bbArray(){ memset( _sizes,0,sizeof(_sizes) ); } bbArray( int sizes[] ){ bbGC::beginCtor( this ); memcpy( _sizes,sizes,D*sizeof(int) ); for( int i=0;i<_sizes[D-1];++i ) new( &_data[i] ) T(); } ~bbArray(){ for( int i=0;i<_sizes[D-1];++i ) _data[i].~T(); } virtual void gcMark(){ for( int i=0;i<_sizes[D-1];++i ) bbGCMark( _data[i] ); } public: virtual const char *typeName()const{ return "bbArray"; } template static bbArray *create( Args...args ){ int sizes[]{ args... }; for( int i=1;i static bbArray *create( std::initializer_list init,Args...args ){ int sizes[]{ args... }; for( int i=1;i_data[i++]=*it; bbGC::endCtor( r ); return r; } T *data(){ return _data; } const T *data()const{ return _data; } int length()const{ return this ? _sizes[D-1] : 0; } int size( int q )const{ bbDebugAssert( q *slice( int from )const{ return slice( from,length() ); } bbArray *slice( int from,int term )const{ int length=this->length(); if( from<0 ){ from+=length; if( from<0 ) from=0; }else if( from>length ){ from=length; } if( term<0 ){ term+=length; if( termlength ){ term=length; } int newlen=term-from; bbArray *r=create( newlen ); for( int i=0;idata()[i]=data()[from+i]; return r; } bbArray *resize( int newLength )const{ bbDebugAssert( newLength>=0, "Array Resize new length must not be negative" ); if( newLength<=0 ) newLength=0; int n=this->length(); if( n>newLength ) n=newLength; bbArray *r=create( newLength ); for( int i=0;idata()[i]=data()[i]; return r; } void copyTo( bbArray *dst,int offset,int dstOffset,int count )const{ bbDebugAssert( offset>=0 && dstOffset>=0 && count>=0 && offset+count<=length() && dstOffset+count<=dst->length(), "Array CopyTo parameters out of range" ); if( dst==this && dstOffset>offset ){ for( int i=count-1;i>=0;--i ) dst->data()[dstOffset+i]=data()[offset+i]; }else{ for( int i=0;idata()[dstOffset+i]=data()[offset+i]; } } //fast 1D version T &at( int index ){ bbDebugAssert( index>=0 && index T &at( Args...args ){ const int indices[]{args...}; int index=indices[0]; bbDebugAssert( index>=0,"Array index out of range" ); for( int i=1;i=0 && index<_sizes[i-1],"Array index out of range" ); index+=indices[i]*_sizes[i-1]; } bbDebugAssert( index=length() ) puts( "Out of range" ); return data()[index]; } operator bool()const{ return length(); } void dbEmit(){ int n=length(); if( n>100 ) n=100; bbString t=bbDBType(); for( int i=0;i bbString bbDBValue( bbArray **p ){ char buf[64]; sprintf( buf,"@%p",*p ); return buf; } #endif