Mem Block.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /******************************************************************************
  2. Use 'Memb' for block based dynamic array container.
  3. 'Memb' stores elements in blocks, for example:
  4. block 0: [ABCD]
  5. block 1: [EFGH]
  6. block 2: [IJ..]
  7. ..
  8. Creating new elements in 'Memb' container does not change the memory address of its elements.
  9. Only new blocks are allocated when needed.
  10. Removing existing elements however, will move others into different position in the block,
  11. thus changing their memory address.
  12. /******************************************************************************/
  13. T1(const_mem_addr TYPE) struct Memb : _Memb // Block Based Container
  14. {
  15. // manage
  16. Memb& clear(); // remove all elements
  17. Memb& del (); // remove all elements and free helper memory
  18. // get / set
  19. Int elms ()C; // number of elements
  20. UInt elmSize ()C; // size of element
  21. UInt blockElms ()C; // number of elements per block
  22. UInt memUsage()C; // memory usage
  23. TYPE* addr (Int i) ; // get i-th element address, null is returned if index is out of range
  24. C TYPE* addr (Int i)C; // get i-th element address, null is returned if index is out of range
  25. TYPE& operator[](Int i) ; // get i-th element, accessing element out of range is an invalid operation and may cause undefined behavior
  26. C TYPE& operator[](Int i)C; // get i-th element, accessing element out of range is an invalid operation and may cause undefined behavior
  27. TYPE& operator()(Int i) ; // get i-th element, accessing element out of range will cause creation of all elements before it, memory of those elements will be first zeroed before calling their constructor
  28. TYPE& first ( ) ; // get first element
  29. C TYPE& first ( )C; // get first element
  30. TYPE& last ( ) ; // get last element
  31. C TYPE& last ( )C; // get last element
  32. TYPE& New ( ) ; // create new element at the end , this method does not change the memory address of any of the elements
  33. TYPE& NewAt (Int i) ; // create new element at i-th position, all old elements starting from i-th position will be moved to the right, this method may change the memory address of all elements
  34. Int index (C TYPE *elm)C; // get index of element in container, -1 on fail , testing is done by comparing elements memory address only
  35. Bool contains(C TYPE *elm)C; // check if memory container actually contains element, testing is done by comparing elements memory address only
  36. // remove
  37. Memb& removeLast( ); // remove last element , this method does not change the memory address of any of the remaining elements
  38. Memb& remove ( Int i , Bool keep_order=false); // remove i-th element , if 'keep_order'=false then moves the last element to i-th, if 'keep_order'=true then moves all elements after i-th to the left (keeping order), this method may change the memory address of some elements
  39. Memb& removeData(C TYPE *elm, Bool keep_order=false); // remove element by giving its memory address, if 'keep_order'=false then moves the last element to i-th, if 'keep_order'=true then moves all elements after i-th to the left (keeping order), this method may change the memory address of some elements
  40. TYPE popFirst( Bool keep_order=true); // get first element and remove it from the container, if 'keep_order'=true then moves all elements after i-th to the left (keeping order)
  41. TYPE pop (Int i, Bool keep_order=true); // get i-th element and remove it from the container, if 'keep_order'=true then moves all elements after i-th to the left (keeping order)
  42. TYPE pop ( ); // get last element and remove it from the container
  43. Memb& setNum (Int num); // set number of elements to 'num' , this method does not change the memory address of any of the elements
  44. Memb& setNumZero(Int num); // set number of elements to 'num', memory of new elements will be first zeroed before calling their constructor, this method does not change the memory address of any of the elements
  45. Int addNum (Int num); // add 'num' elements, return index of first added element , this method does not change the memory address of any of the elements
  46. // values
  47. T1(VALUE) Int find (C VALUE &value )C {REPA(T)if(T[i]==value)return i; return -1; } // check if 'value' is present in container and return its index, -1 if not found
  48. T1(VALUE) Bool has (C VALUE &value )C {return find(value)>=0; } // check if 'value' is present in container
  49. T1(VALUE) Memb& add (C VALUE &value ) {New()=value; return T; } // add 'value' to container , this method does not change the memory address of any of the elements
  50. T1(VALUE) Bool include(C VALUE &value ) {if(!has(value)){add(value); return true;} return false; } // include 'value' if it's not already present in container, returns true if value wasn't present and has been added , this method does not change the memory address of any of the elements
  51. T1(VALUE) Bool exclude(C VALUE &value, Bool keep_order=false) {Int i=find(value); if(i>=0){remove(i, keep_order); return true ;} return false;} // exclude 'value' if present in container , returns true if value was present and has been removed, this method may change the memory address of some elements
  52. T1(VALUE) Bool toggle (C VALUE &value, Bool keep_order=false) {Int i=find(value); if(i>=0){remove(i, keep_order); return false;} add(value); return true ;} // toggle 'value' presence in container , returns true if value is now present in container , this method may change the memory address of some elements
  53. T1(VALUE) Bool binarySearch (C VALUE &value, Int &index, Int compare(C TYPE &a, C VALUE &b)=Compare)C; // search sorted container for presence of 'value' and return if it was found in the container, 'index'=if the function returned true then this index points to the location where the 'value' is located in the container, if the function returned false then it means that 'value' was not found in the container however the 'index' points to the place where it should be added in the container while preserving sorted data, 'index' will always be in range (0..elms) inclusive
  54. T1(VALUE) Bool binaryHas (C VALUE &value, Int compare(C TYPE &a, C VALUE &b)=Compare)C {Int i; return binarySearch(value, i, compare); } // check if 'value' (using binary search) is present in container
  55. T1(VALUE) TYPE* binaryFind (C VALUE &value, Int compare(C TYPE &a, C VALUE &b)=Compare) {Int i; return binarySearch(value, i, compare) ? &T[i] : null; } // check if 'value' (using binary search) is present in container and return it, null on fail
  56. T1(VALUE) C TYPE* binaryFind (C VALUE &value, Int compare(C TYPE &a, C VALUE &b)=Compare)C {return ConstCast(T).binaryFind(value, compare); } // check if 'value' (using binary search) is present in container and return it, null on fail
  57. T1(VALUE) Memb& binaryAdd (C VALUE &value, Int compare(C TYPE &a, C VALUE &b)=Compare) {Int i; binarySearch(value, i, compare); NewAt (i)=value; return T;} // add 'value' (using binary search) , this method may change the memory address of some elements
  58. T1(VALUE) Bool binaryInclude(C VALUE &value, Int compare(C TYPE &a, C VALUE &b)=Compare) {Int i; if( !binarySearch(value, i, compare)){NewAt (i)=value; return true;} return false;} // include 'value' (using binary search) if it's not already present in container, returns true if value wasn't present and has been added , this method may change the memory address of some elements
  59. T1(VALUE) Bool binaryExclude(C VALUE &value, Int compare(C TYPE &a, C VALUE &b)=Compare) {Int i; if( binarySearch(value, i, compare)){remove(i, true); return true;} return false;} // exclude 'value' (using binary search) if present in container , returns true if value was present and has been removed, this method may change the memory address of some elements
  60. T1(VALUE) Bool binaryToggle (C VALUE &value, Int compare(C TYPE &a, C VALUE &b)=Compare) {Int i; if( !binarySearch(value, i, compare)){NewAt (i)=value; return true;} remove(i, true); return false;} // toggle 'value' (using binary search) presence in container , returns true if value is now present in container , this method may change the memory address of some elements
  61. // order
  62. Memb& sort(Int compare(C TYPE &a, C TYPE &b)); // sort elements with custom comparing function, this method may change the memory address of all elements
  63. Memb& reverseOrder( ); // swap order of elements, this method may change the memory address of all elements
  64. Memb& swapOrder(Int i , Int j ); // swap order of 'i' and 'j' valid elements
  65. Memb& moveElm(Int elm, Int new_index ); // move 'elm' element to new position located at 'new_index'
  66. // misc
  67. Memb& operator=(C Mems <TYPE > &src); // copy elements using assignment operator
  68. Memb& operator=(C Memc <TYPE > &src); // copy elements using assignment operator
  69. template<Int size> Memb& operator=(C Memt <TYPE, size> &src); // copy elements using assignment operator
  70. Memb& operator=(C Memb <TYPE > &src); // copy elements using assignment operator
  71. Memb& operator=(C Memx <TYPE > &src); // copy elements using assignment operator
  72. Memb& operator=(C Meml <TYPE > &src); // copy elements using assignment operator
  73. template<Int size> Memb& operator=(C MemPtr<TYPE, size> &src); // copy elements using assignment operator
  74. Memb& operator=( Memb <TYPE > &&src); // copy elements using assignment operator
  75. T1(EXTENDED) Memb& replaceClass(); // replace the type of class stored in the container, all elements are automatically removed before changing the type of the class, the new type must be extended from the base 'TYPE' (if you're receiving a compilation error pointing to this method this means that the new class isn't extended from the base class)
  76. T1(BASE) operator Memb<BASE>&() ; // casting to container of 'BASE' elements, 'TYPE' must be extended from BASE
  77. T1(BASE) operator C Memb<BASE>&()C; // casting to container of 'BASE' elements, 'TYPE' must be extended from BASE
  78. #if EE_PRIVATE
  79. void copyTo ( TYPE *dest)C {_Memb::copyTo (dest); } // copy raw memory of all elements to 'dest'
  80. Memb& copyFrom(C TYPE *src ) {_Memb::copyFrom(src ); return T;} // copy raw memory of all elements from 'src '
  81. #endif
  82. // io
  83. Bool save(File &f); Bool save(File &f)C; // save elements with their own 'save' method, this method first saves number of current elements, and then for each element calls its 'save' method, false on fail
  84. Bool load(File &f); // load elements with their own 'load' method, this method first loads number of saved elements, and then for each element calls its 'load' method, false on fail
  85. Bool saveRaw(File &f)C; // save raw memory of elements (number of elements + elements raw memory), false on fail
  86. Bool loadRaw(File &f) ; // load raw memory of elements (number of elements + elements raw memory), false on fail
  87. explicit Memb(Int block_elms=32); // 'block_elms'=number of elements per block
  88. Memb(C Memb &src );
  89. Memb( Memb &&src );
  90. };
  91. /******************************************************************************/
  92. T1(TYPE) struct MembAbstract : _Memb // Block Based Container which allows storage of abstract classes, 'replaceClass' should be called before creating new elements in it
  93. {
  94. // manage
  95. MembAbstract& clear(); // remove all elements
  96. MembAbstract& del (); // remove all elements and free helper memory
  97. // get / set
  98. Int elms ()C; // number of elements
  99. UInt elmSize()C; // size of element
  100. UInt blockElms()C; // number of elements per block
  101. TYPE* addr (Int i) ; // get i-th element address, null is returned if index is out of range
  102. C TYPE* addr (Int i)C; // get i-th element address, null is returned if index is out of range
  103. TYPE& operator[](Int i) ; // get i-th element, accessing element out of range is an invalid operation and may cause undefined behavior
  104. C TYPE& operator[](Int i)C; // get i-th element, accessing element out of range is an invalid operation and may cause undefined behavior
  105. TYPE& operator()(Int i) ; // get i-th element, accessing element out of range will cause creation of all elements before it, memory of those elements will be first zeroed before calling their constructor
  106. TYPE& first ( ) ; // get first element
  107. C TYPE& first ( )C; // get first element
  108. TYPE& last ( ) ; // get last element
  109. C TYPE& last ( )C; // get last element
  110. TYPE& New ( ) ; // create new element at the end , this method does not change the memory address of any of the elements
  111. TYPE& NewAt (Int i) ; // create new element at i-th position, all old elements starting from i-th position will be moved to the right, this method may change the memory address of all elements
  112. Int index (C TYPE *elm)C; // get index of element in container, -1 on fail , testing is done by comparing elements memory address only
  113. Bool contains(C TYPE *elm)C; // check if memory container actually contains element, testing is done by comparing elements memory address only
  114. // remove
  115. MembAbstract& removeLast( ); // remove last element , this method does not change the memory address of any of the remaining elements
  116. MembAbstract& remove ( Int i , Bool keep_order=false); // remove i-th element , if 'keep_order'=false then moves the last element to i-th, if 'keep_order'=true then moves all elements after i-th to the left (keeping order), this method may change the memory address of some elements
  117. MembAbstract& removeData(C TYPE *elm, Bool keep_order=false); // remove element by giving its memory address, if 'keep_order'=false then moves the last element to i-th, if 'keep_order'=true then moves all elements after i-th to the left (keeping order), this method may change the memory address of some elements
  118. MembAbstract& setNum (Int num); // set number of elements to 'num' , this method does not change the memory address of any of the elements
  119. MembAbstract& setNumZero(Int num); // set number of elements to 'num', memory of new elements will be first zeroed before calling their constructor, this method does not change the memory address of any of the elements
  120. Int addNum (Int num); // add 'num' elements, return index of first added element , this method does not change the memory address of any of the elements
  121. T1(EXTENDED) MembAbstract& replaceClass(); // replace the type of class stored in the container, all elements are automatically removed before changing the type of the class, the new type must be extended from the base 'TYPE' (if you're receiving a compilation error pointing to this method this means that the new class isn't extended from the base class)
  122. T1(BASE) operator Memb<BASE>&() ; // casting to container of 'BASE' elements, 'TYPE' must be extended from BASE
  123. T1(BASE) operator C Memb<BASE>&()C; // casting to container of 'BASE' elements, 'TYPE' must be extended from BASE
  124. explicit MembAbstract(Int block_elms=32); // 'block_elms'=number of elements per block
  125. };
  126. /******************************************************************************/
  127. T1(TYPE) struct MembConst : Memb<TYPE> // Block Based Container which allows modifying elements even when being 'const'
  128. {
  129. TYPE* addr (Int i)C; // get i-th element address, null is returned if index is out of range
  130. TYPE& operator[](Int i)C; // get i-th element, accessing element out of range is an invalid operation and may cause undefined behavior
  131. TYPE& first ( )C; // get first element
  132. TYPE& last ( )C; // get last element
  133. T1(BASE) operator MembConst<BASE>&() ; // casting to container of 'BASE' elements, 'TYPE' must be extended from BASE
  134. T1(BASE) operator C MembConst<BASE>&()C; // casting to container of 'BASE' elements, 'TYPE' must be extended from BASE
  135. explicit MembConst(Int block_elms=32) : Memb<TYPE>(block_elms) {} // 'block_elms'=number of elements per block
  136. };
  137. /******************************************************************************/
  138. inline Int Elms(C _Memb &memb) {return memb.elms();}
  139. /******************************************************************************/