bbarray.h 4.0 KB

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