#ifndef BB_ARRAY_H #define BB_ARRAY_H #ifdef BB_THREADS #include "bbgc_mx.h" #else #include "bbgc.h" #endif template struct bbArray{ struct Rep : public bbGCNode{ int _sizes[D]; T _data[0]; Rep(){ memset( _sizes,0,sizeof(_sizes) ); } Rep( int sizes[] ){ bbGC::beginCtor( this ); memcpy( _sizes,sizes,D*sizeof(int) ); for( int i=0;i<_sizes[D-1];++i ) new( &_data[i] ) T(); } ~Rep(){ for( int i=0;i<_sizes[D-1];++i ) _data[i].~T(); } virtual const char *typeName()const{ return "bbArray::Rep"; } virtual void gcMark(){ for( int i=0;i<_sizes[D-1];++i ) bbGCMark( _data[i] ); } virtual void dbEmit(){ int n=_sizes[D-1];if( n>100 ) n=100; for( int i=0;i explicit bbArray( Args...args ){ int sizes[]{ args... }; for( int i=1;i explicit bbArray( std::initializer_list init,Args...args ){ int sizes[]{ args... }; for( int i=1;i_data[i++]=*it++; bbGC::endCtor( _rep ); } void retain()const{ bbGC::retain( _rep ); } void release()const{ bbGC::release( _rep ); } void discard(){ _rep=nullptr; } T *data(){ return _rep->_data; } const T *data()const{ return _rep->_data; } int length()const{ return _rep ? _rep->_sizes[D-1] : 0; } int size( int q )const{ bbDebugAssert( q>=0 && q_sizes[q]/_rep->_sizes[q-1] : _rep->_sizes[0]) : 0; } bbArray &operator=( const bbArray &t ){ bbGC::enqueue( t._rep ); _rep=t._rep; return *this; } T &operator[]( int index ){ bbDebugAssert( index>=0 && index=0 && index T &at( Args...args ){ const int indices[]{args...}; int index=indices[0]; bbDebugAssert( index>=0 && _rep,"Array index out of range" ); for( int i=1;i=0 && index<_rep->_sizes[i-1],"Array index out of range" ); index+=indices[i]*_rep->_sizes[i-1]; } bbDebugAssert( index 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{newlen}; for( int i=0;i resize( int newLength )const{ bbDebugAssert( newLength>=0,"Array Resize new length must not be negative" ); int ncopy=length(); if( ncopy>newLength ) ncopy=newLength; auto r=bbArray( newLength ); for( int i=0;i 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._rep==_rep && dstOffset>offset ){ for( int i=count-1;i>=0;--i ) dst.data()[dstOffset+i]=data()[offset+i]; }else{ for( int i=0;i bbString bbDBType( bbArray *p ){ return bbDBType()+"[]"; } template bbString bbDBValue( bbArray *p ){ char buf[64]; sprintf( buf,"@%p",*(void**)(&p->_rep) ); return bbString( buf )+"["+bbString( p->length() )+"]"; } template void bbGCMark( bbArray arr ){ bbGC::enqueue( arr._rep ); } #endif