Mem List.h 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /******************************************************************************
  2. Use 'Meml' for list based dynamic array container.
  3. 'Meml' preserves elements memory address in every operation.
  4. 'Meml' stores elements independently, for example:
  5. null <- A <-> B <-> C -> null
  6. /******************************************************************************/
  7. // Meml iterate macros
  8. #define MFREP( meml) for(MemlNode *i=(meml).first(); i; i=i->next()) // forward repeat
  9. #define MFREPD(i, meml) for(MemlNode *i=(meml).first(); i; i=i->next()) // forward repeat with definition
  10. #define MREP( meml) for(MemlNode *i=(meml).last (); i; i=i->prev()) // repeat
  11. #define MREPD( i, meml) for(MemlNode *i=(meml).last (); i; i=i->prev()) // repeat with definition
  12. // safe Meml iterate macros, use when 'i' may be deleted
  13. #define SMFREP( meml) for(MemlNode *i=(meml).first(), *_next_=(i ? i->next() : null); i; i=_next_, _next_=(_next_ ? _next_->next() : null)) // forward repeat
  14. #define SMFREPD(i, meml) for(MemlNode *i=(meml).first(), *_next_=(i ? i->next() : null); i; i=_next_, _next_=(_next_ ? _next_->next() : null)) // forward repeat with definition
  15. #define SMREP( meml) for(MemlNode *i=(meml).last (), *_prev_=(i ? i->prev() : null); i; i=_prev_, _prev_=(_prev_ ? _prev_->prev() : null)) // repeat
  16. #define SMREPD( i, meml) for(MemlNode *i=(meml).last (), *_prev_=(i ? i->prev() : null); i; i=_prev_, _prev_=(_prev_ ? _prev_->prev() : null)) // repeat with definition
  17. /******************************************************************************/
  18. struct MemlNode // Memory List Node, single node of Memory List
  19. {
  20. Ptr data() {return ((Byte*)this)+SIZE(T);} // get pointer to elements data
  21. MemlNode* prev() {return _prev ;} // get previous element
  22. MemlNode* next() {return _next ;} // get next element
  23. #if !EE_PRIVATE
  24. private:
  25. #endif
  26. MemlNode *_prev, *_next;
  27. //TYPE _data;
  28. MemlNode() {}
  29. NO_COPY_CONSTRUCTOR(MemlNode);
  30. };
  31. /******************************************************************************/
  32. T1(TYPE) struct Meml : _Meml // List Based Container
  33. {
  34. // manage
  35. Meml& del (); // remove all elements
  36. Meml& clear(); // remove all elements
  37. // get / set
  38. Int elms ()C; // get number of elements
  39. UInt elmSize ()C; // get size of element
  40. UInt memUsage()C; // get memory usage
  41. TYPE* addr (Int i ) ; // get i-th MemlNode data address, null is returned if index is out of range
  42. C TYPE* addr (Int i )C; // get i-th MemlNode data address, null is returned if index is out of range
  43. TYPE& operator[](Int i ) ; // get i-th MemlNode data, accessing element out of range is an invalid operation and may cause undefined behavior
  44. C TYPE& operator[](Int i )C; // get i-th MemlNode data, accessing element out of range is an invalid operation and may cause undefined behavior
  45. TYPE& operator()(Int i ) ; // get i-th MemlNode data, 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
  46. TYPE& operator[](MemlNode *node) ; // get MemlNode data, accessing element out of range is an invalid operation and may cause undefined behavior
  47. C TYPE& operator[](MemlNode *node)C; // get MemlNode data, accessing element out of range is an invalid operation and may cause undefined behavior
  48. TYPE& New ( ) ; // create new element at the end , this method does not change the memory address of any of the elements
  49. TYPE& NewAt (Int i ) ; // create new element at i-th index, all old element valid indexes starting from i-th position will be moved to the right, this method does not change the memory address of any of the elements
  50. MemlNode* add ( ); // add element at the end of the list, this method does not change the memory address of any of the elements
  51. MemlNode* addBefore(MemlNode *node); // add element before 'node' , this method does not change the memory address of any of the elements
  52. MemlNode* addAfter (MemlNode *node); // add element after 'node' , this method does not change the memory address of any of the elements
  53. MemlNode* first()C; // get first element
  54. MemlNode* last ()C; // get last element
  55. MemlNode* loopPrev(MemlNode *node)C {return node ? (node->prev() ? node->prev() : last ()) : null;} // get looped previous element, loopPrev(first())==last ()
  56. MemlNode* loopNext(MemlNode *node)C {return node ? (node->next() ? node->next() : first()) : null;} // get looped next element, loopNext(last ())==first()
  57. Int index (C TYPE *elm)C; // get index of element in container, -1 on fail , testing is done by comparing elements memory address only
  58. Bool contains(C TYPE *elm)C; // check if memory container actually contains element, testing is done by comparing elements memory address only
  59. // remove
  60. Meml& removeFirst( Bool keep_order=false); // remove first element , this method does not change the memory address of any of the remaining elements, 'keep_order'=this parameter is ignored for 'Meml' because it always keeps order (it is kept here only for compatibility with other memory containers)
  61. Meml& removeLast ( ); // remove last element , this method does not change the memory address of any of the remaining elements
  62. Meml& remove (MemlNode *node, Bool keep_order=false); // remove element , this method does not change the memory address of any of the remaining elements, 'keep_order'=this parameter is ignored for 'Meml' because it always keeps order (it is kept here only for compatibility with other memory containers)
  63. Meml& removeData (C TYPE *elm , Bool keep_order=false); // remove element by giving its memory address, this method does not change the memory address of any of the remaining elements, 'keep_order'=this parameter is ignored for 'Meml' because it always keeps order (it is kept here only for compatibility with other memory containers)
  64. Meml& removeIndex(Int i , Bool keep_order=false); // remove i-th element , this method does not change the memory address of any of the remaining elements, 'keep_order'=this parameter is ignored for 'Meml' because it always keeps order (it is kept here only for compatibility with other memory containers)
  65. Meml& setNum (Int num); // set number of elements to 'num', this method does not change the memory address of any of the elements
  66. Meml& 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
  67. // values
  68. 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
  69. // order
  70. Meml& sort(Int compare(C TYPE &a, C TYPE &b)); // sort elements with custom comparing function, method does not change the memory address of any of the elements
  71. Meml& reverseOrder( ); // reverse order of elements (reversing modifies only indexes), this method does not change the memory address of any of the elements
  72. Meml& swapOrder(Int i, Int j ); // swap order of 'i' and 'j' elements (swapping modifies only indexes), this method does not change the memory address of any of the elements
  73. // misc
  74. Meml& operator=(C Mems <TYPE > &src); // copy elements using assignment operator
  75. Meml& operator=(C Memc <TYPE > &src); // copy elements using assignment operator
  76. template<Int size> Meml& operator=(C Memt <TYPE, size> &src); // copy elements using assignment operator
  77. Meml& operator=(C Memb <TYPE > &src); // copy elements using assignment operator
  78. Meml& operator=(C Memx <TYPE > &src); // copy elements using assignment operator
  79. Meml& operator=(C Meml <TYPE > &src); // copy elements using assignment operator
  80. template<Int size> Meml& operator=(C MemPtr<TYPE, size> &src); // copy elements using assignment operator
  81. Meml& operator=( Meml <TYPE > &&src); // copy elements using assignment operator
  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. Meml();
  86. Meml(C Meml &src);
  87. Meml( Meml &&src);
  88. };
  89. /******************************************************************************/
  90. inline Int Elms(C _Meml &meml) {return meml.elms();}
  91. /******************************************************************************/