bbarray.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. #ifndef BB_ARRAY_H
  2. #define BB_ARRAY_H
  3. #include "bbgc.h"
  4. #include "bbdebug.h"
  5. #include "bbobject.h"
  6. template<class T,int D> class bbArray : public bbGCNode{
  7. int _sizes[D];
  8. T _data[0];
  9. bbArray(){
  10. memset( _sizes,0,sizeof(_sizes) );
  11. }
  12. bbArray( int sizes[] ){
  13. bbGC::beginCtor( this );
  14. memcpy( _sizes,sizes,D*sizeof(int) );
  15. for( int i=0;i<_sizes[D-1];++i ) new( &_data[i] ) T();
  16. }
  17. ~bbArray(){
  18. for( int i=0;i<_sizes[D-1];++i ) _data[i].~T();
  19. }
  20. virtual void gcMark(){
  21. for( int i=0;i<_sizes[D-1];++i ) bbGCMark( _data[i] );
  22. }
  23. public:
  24. virtual const char *typeName()const{
  25. return "bbArray";
  26. }
  27. template<class...Args> static bbArray *create( Args...args ){
  28. int sizes[]{ args... };
  29. for( int i=1;i<D;++i ) sizes[i]*=sizes[i-1];
  30. if( !sizes[D-1] ) return nullptr;
  31. bbGCNode *p=bbGC::alloc( sizeof( bbArray )+sizes[D-1]*sizeof(T) );
  32. bbArray *r=new( p ) bbArray( sizes );
  33. bbGC::endCtor( r );
  34. return r;
  35. }
  36. template<class...Args> static bbArray *create( std::initializer_list<T> init,Args...args ){
  37. int sizes[]{ args... };
  38. for( int i=1;i<D;++i ) sizes[i]*=sizes[i-1];
  39. if( !sizes[D-1] ) return nullptr;
  40. bbGCNode *p=bbGC::alloc( sizeof( bbArray )+sizes[D-1]*sizeof(T) );
  41. bbArray *r=new( p ) bbArray( sizes );
  42. int i=0;
  43. for( auto it=init.begin();it!=init.end();++it ) r->_data[i++]=*it;
  44. bbGC::endCtor( r );
  45. return r;
  46. }
  47. T *data(){
  48. return _data;
  49. }
  50. const T *data()const{
  51. return _data;
  52. }
  53. int length()const{
  54. return this ? _sizes[D-1] : 0;
  55. }
  56. int size( int q )const{
  57. bbDebugAssert( q<D,"Array dimension out of range" );
  58. return this ? (q ? _sizes[q]/_sizes[q-1] : _sizes[0]) : 0;
  59. }
  60. bbArray<T,1> *slice( int from )const{
  61. return slice( from,length() );
  62. }
  63. bbArray<T,1> *slice( int from,int term )const{
  64. int length=this->length();
  65. if( from<0 ){
  66. from+=length;
  67. if( from<0 ) from=0;
  68. }else if( from>length ){
  69. from=length;
  70. }
  71. if( term<0 ){
  72. term+=length;
  73. if( term<from ) term=from;
  74. }else if( term<from ){
  75. term=from;
  76. }else if( term>length ){
  77. term=length;
  78. }
  79. int newlen=term-from;
  80. bbArray<T,1> *r=create( newlen );
  81. for( int i=0;i<newlen;++i ) r->data()[i]=data()[from+i];
  82. return r;
  83. }
  84. bbArray<T,1> *resize( int newLength )const{
  85. bbDebugAssert( newLength>=0,
  86. "Array Resize new length must not be negative" );
  87. if( newLength<=0 ) newLength=0;
  88. int n=this->length();
  89. if( n>newLength ) n=newLength;
  90. bbArray<T,1> *r=create( newLength );
  91. for( int i=0;i<n;++i ) r->data()[i]=data()[i];
  92. return r;
  93. }
  94. void copyTo( bbArray<T,1> *dst,int offset,int dstOffset,int count )const{
  95. bbDebugAssert( offset>=0 && dstOffset>=0 && count>=0 && offset+count<=length() && dstOffset+count<=dst->length(),
  96. "Array CopyTo parameters out of range" );
  97. if( dst==this && dstOffset>offset ){
  98. for( int i=count-1;i>=0;--i ) dst->data()[dstOffset+i]=data()[offset+i];
  99. }else{
  100. for( int i=0;i<count;++i ) dst->data()[dstOffset+i]=data()[offset+i];
  101. }
  102. }
  103. //fast 1D version
  104. T &at( int index ){
  105. bbDebugAssert( index>=0 && index<length(),
  106. "Array index out of range" );
  107. return data()[index];
  108. }
  109. //slower N-D version
  110. template<class...Args> T &at( Args...args ){
  111. const int indices[]{args...};
  112. int index=indices[0];
  113. bbDebugAssert( index>=0,"Array index out of range" );
  114. for( int i=1;i<D;++i ){
  115. bbDebugAssert( indices[i]>=0 && index<_sizes[i-1],"Array index out of range" );
  116. index+=indices[i]*_sizes[i-1];
  117. }
  118. bbDebugAssert( index<length(),"Array index out of range" );
  119. return data()[index];
  120. }
  121. T &get( int index ){
  122. if( index<0 || index>=length() ) puts( "Out of range" );
  123. return data()[index];
  124. }
  125. operator bool()const{
  126. return length();
  127. }
  128. void dbEmit(){
  129. int n=length();
  130. if( n>100 ) n=100;
  131. bbString t=bbDBType<T>();
  132. for( int i=0;i<n;++i ){
  133. bbString e=BB_T("[")+bbString( i )+"]:"+t+"="+bbDBValue( &at(i) );
  134. puts( e.c_str() );
  135. }
  136. }
  137. };
  138. template<class T,int N> bbString bbDBType( bbArray<T,N> **p ){
  139. return bbDBType<T>()+"[]";
  140. }
  141. template<class T,int N> bbString bbDBValue( bbArray<T,N> **p ){
  142. char buf[64];
  143. sprintf( buf,"@%p",*p );
  144. return buf;
  145. }
  146. #endif