Mem Pointer.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /******************************************************************************
  2. Use 'MemPtr' to operate on any kind of memory container.
  3. 'MemPtr' is a pointer to one of all supported memory container types:
  4. 'Mems', 'Memc', 'Memt', 'Memb', 'Memx', 'Meml' or regular continuous memory.
  5. 'MemPtr' allows to write one function which can operate on all memory container types.
  6. For example, instead of writing multiple functions which accept different containers:
  7. Int Sum(C Memc<Int> &values) {Int sum=0; REPA(values)sum+=values[i]; return sum;}
  8. Int Sum(C Memb<Int> &values) {Int sum=0; REPA(values)sum+=values[i]; return sum;}
  9. ..
  10. You can write just one function:
  11. Int Sum(C MemPtr<Int> &values) {Int sum=0; REPA(values)sum+=values[i]; return sum;}
  12. This function will accept all memory container types, so you can do the following:
  13. Memc<Int> memc_values; Sum(memc_values);
  14. Memb<Int> memb_values; Sum(memb_values);
  15. ..
  16. /******************************************************************************/
  17. template<typename TYPE, Int Memt_size> struct MemPtr // Memory Container Pointer, 'Memt_size'=size of the 'Memt' helper stack memory
  18. {
  19. // manage
  20. MemPtr& clear(); // remove all elements
  21. MemPtr& del (); // remove all elements and free helper memory
  22. // get / set
  23. Int elms ()C; // number of elements
  24. UInt elmSize ()C; // size of element
  25. UInt memUsage()C; // memory usage
  26. TYPE* data ( ) ; // get pointer to the start of the elements
  27. C TYPE* data ( )C; // get pointer to the start of the elements
  28. TYPE* addr (Int i) ; // get i-th element address, null is returned if index is out of range
  29. C TYPE* addr (Int i)C; // get i-th element address, null is returned if index is out of range
  30. TYPE& operator[](Int i) ; // get i-th element, accessing element out of range is an invalid operation and may cause undefined behavior
  31. C TYPE& operator[](Int i)C; // get i-th element, accessing element out of range is an invalid operation and may cause undefined behavior
  32. 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
  33. TYPE& first ( ) ; // get first element
  34. C TYPE& first ( )C; // get first element
  35. TYPE& last ( ) ; // get last element
  36. C TYPE& last ( )C; // get last element
  37. TYPE& New ( ) ; // create new element at the end , this method changes the memory address of all elements
  38. 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 changes the memory address of all elements
  39. Int index (C TYPE *elm)C; // get index of element in container, -1 on fail , testing is done by comparing elements memory address only
  40. Bool contains(C TYPE *elm)C; // check if memory container actually contains element, testing is done by comparing elements memory address only
  41. operator Bool()C; // if points to something (not null)
  42. Bool resizable()C; // if supports adding/removing elements
  43. Bool continuous()C; // if elements are stored in continuous memory
  44. // remove
  45. MemPtr& removeLast( ); // remove last element , this method does not change the memory address of any of the remaining elements
  46. MemPtr& 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
  47. MemPtr& 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
  48. MemPtr& setNum (Int num); // set number of elements to 'num' , this method changes the memory address of all elements
  49. MemPtr& setNumZero(Int num); // set number of elements to 'num', memory of new elements will be first zeroed before calling their constructor, this method changes the memory address of all elements
  50. Int addNum (Int num); // add 'num' elements, return index of first added element , this method changes the memory address of all elements
  51. // values
  52. 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
  53. T1(VALUE) Bool has (C VALUE &value )C {return find(value)>=0; } // check if 'value' is present in container
  54. T1(VALUE) MemPtr& add (C VALUE &value ) {New()=value; return T; } // add 'value' to container , this method changes the memory address of all elements
  55. 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 changes the memory address of all elements
  56. 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 changes the memory address of all elements
  57. 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 changes the memory address of all elements
  58. 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
  59. 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
  60. 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
  61. 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
  62. T1(VALUE) MemPtr& 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 changes the memory address of all elements
  63. 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 changes the memory address of all elements
  64. 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 changes the memory address of all elements
  65. 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 changes the memory address of all elements
  66. // order
  67. MemPtr& sort(Int compare(C TYPE &a, C TYPE &b)); // sort elements with custom comparing function
  68. MemPtr& reverseOrder( ); // reverse order of elements
  69. MemPtr& swapOrder(Int i, Int j ); // swap order of 'i' and 'j' valid elements
  70. // misc
  71. MemPtr& operator=(C TYPE &src ); // copy elements using assignment operator
  72. template<Int src_elms> MemPtr& operator=(C TYPE (&src)[src_elms]); // copy elements using assignment operator
  73. MemPtr& operator=(C Mems <TYPE > &src ); // copy elements using assignment operator
  74. MemPtr& operator=(C Memc <TYPE > &src ); // copy elements using assignment operator
  75. template<Int src_size> MemPtr& operator=(C Memt <TYPE, src_size> &src ); // copy elements using assignment operator
  76. MemPtr& operator=(C Memb <TYPE > &src ); // copy elements using assignment operator
  77. MemPtr& operator=(C Memx <TYPE > &src ); // copy elements using assignment operator
  78. MemPtr& operator=(C Meml <TYPE > &src ); // copy elements using assignment operator
  79. MemPtr& operator=(C MemPtr<TYPE, Memt_size> &src ); // copy elements using assignment operator (this must be specified even though method below should do the same, because without it compiler will try to use the built-in 'operator=' which will just do raw memory copy)
  80. template<Int src_size> MemPtr& operator=(C MemPtr<TYPE, src_size> &src ); // copy elements using assignment operator (this will allow copying from 'MemPtr' with other sizes)
  81. #if EE_PRIVATE
  82. void copyTo ( TYPE *dest)C; // copy raw memory of all elements to 'dest'
  83. MemPtr& copyFrom(C TYPE *src ) ; // copy raw memory of all elements from 'src '
  84. #endif
  85. // io
  86. 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
  87. 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
  88. Bool saveRaw(File &f)C; // save raw memory of elements (number of elements + elements raw memory), false on fail
  89. Bool loadRaw(File &f) ; // load raw memory of elements (number of elements + elements raw memory), false on fail
  90. // initialize 'MemPtr' to point to source
  91. MemPtr& point( null_t=null );
  92. MemPtr& point( TYPE &src );
  93. MemPtr& point( TYPE *src, Int src_elms );
  94. template<Int src_elms> MemPtr& point( TYPE (&src) [src_elms]);
  95. MemPtr& point(Mems <TYPE > &src );
  96. MemPtr& point(Memc <TYPE > &src );
  97. MemPtr& point(Memt <TYPE, Memt_size> &src );
  98. MemPtr& point(Memb <TYPE > &src );
  99. MemPtr& point(Memx <TYPE > &src );
  100. MemPtr& point(Meml <TYPE > &src );
  101. MemPtr& point(MemPtr<TYPE, Memt_size> &src );
  102. MemPtr( null_t=null ) {point(null );}
  103. MemPtr( TYPE &src ) {point(src );}
  104. template<Int src_elms> MemPtr( TYPE (&src) [src_elms]) {point(src );}
  105. MemPtr( TYPE *src, Int src_elms ) {point(src, src_elms);}
  106. MemPtr( Mems <TYPE > &src ) {point(src );}
  107. MemPtr( Memc <TYPE > &src ) {point(src );}
  108. //T1(EXTENDED) MemPtr( Memc <EXTENDED > &src ) {point(src );} introduces compilation problems
  109. MemPtr( Memt <TYPE, Memt_size> &src ) {point(src );}
  110. MemPtr( Memb <TYPE > &src ) {point(src );}
  111. //T1(EXTENDED) MemPtr( Memb <EXTENDED > &src ) {point(src );} introduces compilation problems
  112. MemPtr( Memx <TYPE > &src ) {point(src );}
  113. //T1(EXTENDED) MemPtr( Memx <EXTENDED > &src ) {point(src );} introduces compilation problems
  114. MemPtr( Meml <TYPE > &src ) {point(src );}
  115. #if WINDOWS // this compiles only on Windows, on other platforms it fails to compile. The following only prevents from pointing to const pointers (normal constructor is not needed, because in it all we want is to copy all members)
  116. MemPtr( MemPtr<TYPE, Memt_size> &src ) {point(src );}
  117. MemPtr(C MemPtr<TYPE, Memt_size> &src )=delete;
  118. #endif
  119. enum MODE
  120. {
  121. PTR ,
  122. MEMS,
  123. MEMC,
  124. MEMT,
  125. MEMB,
  126. MEMX,
  127. MEML,
  128. };
  129. MODE mode()C {return _mode;} // get type of container from which 'MemPtr' was created
  130. Mems<TYPE >* mems() {return (_mode==MEMS) ? _mems : null;}
  131. Memc<TYPE >* memc() {return (_mode==MEMC) ? _memc : null;}
  132. Memt<TYPE, Memt_size>* memt() {return (_mode==MEMT) ? _memt : null;}
  133. Memb<TYPE >* memb() {return (_mode==MEMB) ? _memb : null;}
  134. Memx<TYPE >* memx() {return (_mode==MEMX) ? _memx : null;}
  135. Meml<TYPE >* meml() {return (_mode==MEML) ? _meml : null;}
  136. private:
  137. union
  138. {
  139. TYPE *_ptr ;
  140. Mems<TYPE > *_mems;
  141. Memc<TYPE > *_memc;
  142. Memt<TYPE, Memt_size> *_memt;
  143. Memb<TYPE > *_memb;
  144. Memx<TYPE > *_memx;
  145. Meml<TYPE > *_meml;
  146. };
  147. MODE _mode;
  148. Int _elms;
  149. MemPtr& operator=(null_t)=delete;
  150. friend struct Mems<TYPE>;
  151. friend struct Memc<TYPE>;
  152. friend struct Memt<TYPE, Memt_size>;
  153. friend struct Memb<TYPE>;
  154. friend struct Memx<TYPE>;
  155. friend struct Meml<TYPE>;
  156. };
  157. /******************************************************************************/
  158. template<const_mem_addr typename TYPE, Int Memt_elms> struct MemPtrN : MemPtr<TYPE, SIZE(TYPE)*Memt_elms> // Memory Container Pointer, 'Memt_elms'=number of elements of the 'Memt'
  159. {
  160. // copy elements using assignment operator
  161. MemPtrN& operator=(C TYPE &src ); // copy elements using assignment operator
  162. template<Int src_elms> MemPtrN& operator=(C TYPE (&src)[src_elms]); // copy elements using assignment operator
  163. MemPtrN& operator=(C Mems <TYPE > &src ); // copy elements using assignment operator
  164. MemPtrN& operator=(C Memc <TYPE > &src ); // copy elements using assignment operator
  165. template<Int src_size> MemPtrN& operator=(C Memt <TYPE, src_size> &src ); // copy elements using assignment operator
  166. MemPtrN& operator=(C Memb <TYPE > &src ); // copy elements using assignment operator
  167. MemPtrN& operator=(C Memx <TYPE > &src ); // copy elements using assignment operator
  168. MemPtrN& operator=(C Meml <TYPE > &src ); // copy elements using assignment operator
  169. template<Int src_size> MemPtrN& operator=(C MemPtr <TYPE, src_size> &src ); // copy elements using assignment operator (this will allow copying from 'MemPtr' with other sizes)
  170. MemPtrN& operator=(C MemPtrN<TYPE, Memt_elms> &src ); // copy elements using assignment operator (this must be specified even though method above should do the same, because without it compiler will try to use the built-in 'operator=' which will just do raw memory copy)
  171. // initialize 'MemPtrN' to point to source
  172. MemPtrN( null_t=null ) {}
  173. MemPtrN( TYPE &src ) : MemPtr<TYPE, SIZE(TYPE)*Memt_elms>(src ) {}
  174. template<Int src_elms> MemPtrN( TYPE (&src) [src_elms]) : MemPtr<TYPE, SIZE(TYPE)*Memt_elms>(src ) {}
  175. MemPtrN( TYPE *src, Int src_elms ) : MemPtr<TYPE, SIZE(TYPE)*Memt_elms>(src, src_elms) {}
  176. MemPtrN(Mems <TYPE > &src ) : MemPtr<TYPE, SIZE(TYPE)*Memt_elms>(src ) {}
  177. MemPtrN(Memc <TYPE > &src ) : MemPtr<TYPE, SIZE(TYPE)*Memt_elms>(src ) {}
  178. MemPtrN(Memt <TYPE, SIZE(TYPE)*Memt_elms> &src ) : MemPtr<TYPE, SIZE(TYPE)*Memt_elms>(src ) {}
  179. MemPtrN(Memb <TYPE > &src ) : MemPtr<TYPE, SIZE(TYPE)*Memt_elms>(src ) {}
  180. MemPtrN(Memx <TYPE > &src ) : MemPtr<TYPE, SIZE(TYPE)*Memt_elms>(src ) {}
  181. MemPtrN(Meml <TYPE > &src ) : MemPtr<TYPE, SIZE(TYPE)*Memt_elms>(src ) {}
  182. MemPtrN(MemPtr<TYPE, SIZE(TYPE)*Memt_elms> &src ) : MemPtr<TYPE, SIZE(TYPE)*Memt_elms>(src ) {}
  183. MemPtrN& operator=(null_t)=delete;
  184. };
  185. /******************************************************************************/
  186. template<typename TYPE, Int size> inline Int Elms(C MemPtr<TYPE, size> &memp) {return memp.elms();}
  187. /******************************************************************************/