Mem Continuous.h 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /******************************************************************************
  2. Use 'Memc' for continuous memory based dynamic array container.
  3. 'Memc' stores elements in continuous memory, for example:
  4. [ABCDE...]
  5. 'Memc' container reserves some extra memory for adding new elements.
  6. If creating a new element when there is no extra memory available,
  7. the container will reallocate the whole array into a new bigger one,
  8. thus changing the address of all elements.
  9. /******************************************************************************/
  10. T1(const_mem_addr TYPE) struct Memc : _Memc // Continuous Memory Based Container
  11. {
  12. // manage
  13. Memc& clear(); // remove all elements
  14. Memc& del (); // remove all elements and free helper memory
  15. // get / set
  16. Int elms ()C; // number of elements
  17. UInt elmSize ()C; // size of element
  18. UInt memUsage()C; // memory usage
  19. TYPE* data ( ) ; // get pointer to the start of the elements
  20. C TYPE* data ( )C; // get pointer to the start of the elements
  21. TYPE* addr (Int i) ; // get i-th element address, null is returned if index is out of range
  22. C TYPE* addr (Int i)C; // get i-th element address, null is returned if index is out of range
  23. TYPE* addrFirst ( ) ; // get first element address, null is returned if element doesn't exist
  24. C TYPE* addrFirst ( )C; // get first element address, null is returned if element doesn't exist
  25. TYPE* addrLast ( ) ; // get last element address, null is returned if element doesn't exist
  26. C TYPE* addrLast ( )C; // get last element address, null is returned if element doesn't exist
  27. TYPE& operator[](Int i) ; // get i-th element, accessing element out of range is an invalid operation and may cause undefined behavior
  28. C TYPE& operator[](Int i)C; // get i-th element, accessing element out of range is an invalid operation and may cause undefined behavior
  29. 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
  30. TYPE& first ( ) ; // get first element
  31. C TYPE& first ( )C; // get first element
  32. TYPE& last ( ) ; // get last element
  33. C TYPE& last ( )C; // get last element
  34. TYPE& New ( ) ; // create new element at the end , this method may change the memory address of all elements
  35. 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
  36. Int index (C TYPE *elm)C; // get index of element in container, -1 on fail , testing is done by comparing elements memory address only
  37. Bool contains(C TYPE *elm)C; // check if memory container actually contains element, testing is done by comparing elements memory address only
  38. // remove
  39. Memc& removeLast( ); // remove last element , this method does not change the memory address of any of the remaining elements
  40. Memc& 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
  41. Memc& removeNum ( Int i , Int n, Bool keep_order=false); // remove 'n' elements starting from i-th , if 'keep_order'=false then moves the last elements 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
  42. Memc& 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
  43. 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)
  44. 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)
  45. TYPE pop ( ); // get last element and remove it from the container
  46. Memc& setNum (Int num); // set number of elements to 'num' , this method may change the memory address of all elements
  47. Memc& setNumZero(Int num); // set number of elements to 'num', memory of new elements will be first zeroed before calling their constructor, this method may change the memory address of all elements
  48. Int addNum (Int num); // add 'num' elements, return index of first added element , this method may change the memory address of all elements
  49. // values
  50. 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
  51. T1(VALUE) Bool has (C VALUE &value )C {return find(value)>=0; } // check if 'value' is present in container
  52. T1(VALUE) Memc& add (C VALUE &value ) {New()=value; return T; } // add 'value' to container , this method may change the memory address of all elements
  53. 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 may change the memory address of all elements
  54. 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 all elements
  55. 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 all elements
  56. 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
  57. 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
  58. 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
  59. 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
  60. T1(VALUE) Memc& 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 all elements
  61. 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 all elements
  62. 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 all elements
  63. 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 all elements
  64. // order
  65. Memc& 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
  66. Memc& reverseOrder( ); // reverse order of elements, this method changes the memory address of all elements
  67. Memc& randomizeOrder( ); // randomize order of elements, this method may change the memory address of all elements
  68. Memc& rotateOrder(Int offset ); // rotate order of elements, changes the order of elements so "new_index=old_index+offset", 'offset'=offset of moving the original indexes into target indexes (-Inf..Inf)
  69. Memc& swapOrder(Int i , Int j ); // swap order of 'i' and 'j' elements
  70. Memc& moveElm (Int elm, Int new_index ); // move 'elm' element to new position located at 'new_index'
  71. // misc
  72. Memc& operator=(C Mems <TYPE > &src); // copy elements using assignment operator
  73. Memc& operator=(C Memc <TYPE > &src); // copy elements using assignment operator
  74. template<Int size> Memc& operator=(C Memt <TYPE, size> &src); // copy elements using assignment operator
  75. Memc& operator=(C Memb <TYPE > &src); // copy elements using assignment operator
  76. Memc& operator=(C Memx <TYPE > &src); // copy elements using assignment operator
  77. Memc& operator=(C Meml <TYPE > &src); // copy elements using assignment operator
  78. template<Int size> Memc& operator=(C MemPtr<TYPE, size> &src); // copy elements using assignment operator
  79. Memc& operator=( Memc <TYPE > &&src); // copy elements using assignment operator
  80. T1(EXTENDED) Memc& 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)
  81. T1(BASE) operator Memc<BASE>&() ; // casting to container of 'BASE' elements, 'TYPE' must be extended from BASE
  82. T1(BASE) operator C Memc<BASE>&()C; // casting to container of 'BASE' elements, 'TYPE' must be extended from BASE
  83. #if EE_PRIVATE
  84. void copyTo ( TYPE *dest)C {_Memc::copyTo (dest); } // copy raw memory of all elements to 'dest'
  85. Memc& copyFrom(C TYPE *src ) {_Memc::copyFrom(src ); return T;} // copy raw memory of all elements from 'src '
  86. #endif
  87. // io
  88. 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
  89. 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
  90. T1(USER) Bool save(File &f, C USER &user)C; // save elements with their own 'save' method and 'user' parameter, this method first saves number of current elements, and then for each element calls its 'save' method, false on fail
  91. T1(USER) Bool load(File &f, C USER &user) ; // load elements with their own 'load' method and 'user' parameter, this method first loads number of saved elements, and then for each element calls its 'load' method, false on fail
  92. T2(USER, USER1) Bool save(File &f, C USER &user, C USER1 &user1)C; // save elements with their own 'save' method and 'user, user1' parameter, this method first saves number of current elements, and then for each element calls its 'save' method, false on fail
  93. T2(USER, USER1) Bool load(File &f, C USER &user, C USER1 &user1) ; // load elements with their own 'load' method and 'user, user1' parameter, this method first loads number of saved elements, and then for each element calls its 'load' method, false on fail
  94. Bool saveRaw(File &f)C; // save raw memory of elements (number of elements + elements raw memory), false on fail
  95. Bool loadRaw(File &f) ; // load raw memory of elements (number of elements + elements raw memory), false on fail
  96. #if EE_PRIVATE
  97. Bool _saveRaw(File &f)C; // save raw memory of elements (number of elements + elements raw memory), false on fail, deprecated - do not use
  98. Bool _loadRaw(File &f) ; // load raw memory of elements (number of elements + elements raw memory), false on fail, deprecated - do not use
  99. 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, deprecated - do not use
  100. 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, deprecated - do not use
  101. #endif
  102. Memc( );
  103. Memc(C Memc &src);
  104. Memc( Memc &&src);
  105. };
  106. /******************************************************************************/
  107. T1(TYPE) struct MemcAbstract : _Memc // Continuous Memory Based Container which allows storage of abstract classes, 'replaceClass' should be called before creating new elements in it
  108. {
  109. // manage
  110. MemcAbstract& clear(); // remove all elements
  111. MemcAbstract& del (); // remove all elements and free helper memory
  112. // get / set
  113. Int elms ()C; // number of elements
  114. UInt elmSize ()C; // size of element
  115. UInt memUsage()C; // memory usage
  116. TYPE* data ( ) ; // get pointer to the start of the elements
  117. C TYPE* data ( )C; // get pointer to the start of the elements
  118. TYPE* addr (Int i) ; // get i-th element address, null is returned if index is out of range
  119. C TYPE* addr (Int i)C; // get i-th element address, null is returned if index is out of range
  120. TYPE& operator[](Int i) ; // get i-th element, accessing element out of range is an invalid operation and may cause undefined behavior
  121. C TYPE& operator[](Int i)C; // get i-th element, accessing element out of range is an invalid operation and may cause undefined behavior
  122. 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
  123. TYPE& first ( ) ; // get first element
  124. C TYPE& first ( )C; // get first element
  125. TYPE& last ( ) ; // get last element
  126. C TYPE& last ( )C; // get last element
  127. TYPE& New ( ) ; // create new element at the end , this method does not change the memory address of any of the elements
  128. 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
  129. Int index (C TYPE *elm)C; // get index of element in container, -1 on fail , testing is done by comparing elements memory address only
  130. Bool contains(C TYPE *elm)C; // check if memory container actually contains element, testing is done by comparing elements memory address only
  131. // remove
  132. MemcAbstract& removeLast( ); // remove last element , this method does not change the memory address of any of the remaining elements
  133. MemcAbstract& 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
  134. MemcAbstract& 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
  135. MemcAbstract& setNum (Int num); // set number of elements to 'num' , this method does not change the memory address of any of the elements
  136. MemcAbstract& 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
  137. 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
  138. T1(EXTENDED) MemcAbstract& 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)
  139. T1(BASE) operator Memc<BASE>&() ; // casting to container of 'BASE' elements, 'TYPE' must be extended from BASE
  140. T1(BASE) operator C Memc<BASE>&()C; // casting to container of 'BASE' elements, 'TYPE' must be extended from BASE
  141. MemcAbstract();
  142. };
  143. /******************************************************************************/
  144. inline Int Elms(C _Memc &memc) {return memc.elms();}
  145. /******************************************************************************/
  146. #if EE_PRIVATE
  147. T2(A, B) struct std__pair
  148. {
  149. A first;
  150. B second;
  151. std__pair() {}
  152. std__pair(C A &a, C B &b) : first(a), second(b) {}
  153. };
  154. T1(TYPE) STRUCT_PRIVATE(std__unique_ptr , Mems<TYPE>)
  155. //{
  156. TYPE& operator[](Int i) {return super::operator[](i);}
  157. C TYPE& operator[](Int i)C {return super::operator[](i);}
  158. Bool operator()( )C {return super::elms()!=0;}
  159. Bool operator! ( )C {return super::elms()==0;}
  160. Bool operator==(C TYPE *data)C {return super::data()==data;}
  161. Bool operator!=(C TYPE *data)C {return super::data()!=data;}
  162. void reset (Int elms) { super::setNum(elms);}
  163. TYPE* get ( ) {return super::data();}
  164. std__unique_ptr( ) {}
  165. std__unique_ptr(Int elms) {reset(elms);}
  166. };
  167. T1(TYPE) STRUCT_PRIVATE(std__vector , Memc<TYPE>)
  168. //{
  169. TYPE& operator[](Int i) {return super::operator[](i);}
  170. C TYPE& operator[](Int i)C {return super::operator[](i);}
  171. Bool empty()C {return !super::elms();}
  172. Int size ()C {return super::elms();}
  173. TYPE* begin() {return super::data();}
  174. TYPE* end () {return super::data()+super::elms();}
  175. C TYPE* cbegin()C {return super::data();}
  176. C TYPE* cend ()C {return super::data()+super::elms();}
  177. void clear( ) {super::clear();}
  178. void emplace_back(C TYPE &t) {super::add(t);}
  179. void push_back(C TYPE &t) {super::add(t);}
  180. void pop_back( ) {super::removeLast();}
  181. TYPE& back( ) {return super::last();}
  182. void resize (Int elms ) {super::setNumZero(elms);} // yes, zero is required !!
  183. void reserve(Int elms ) {super::reserve(elms);}
  184. std__vector() {}
  185. std__vector(Int elms ) {resize(elms);}
  186. std__vector(Int elms, C TYPE &def_val) {resize(elms); REPAO(T)=def_val;}
  187. };
  188. T1(TYPE) inline Int Elms(C std__vector<TYPE> &vector) {return vector.size();}
  189. #endif
  190. /******************************************************************************/