jarray.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #ifndef JARRAY_HPP
  14. #define JARRAY_HPP
  15. #include "platform.h"
  16. #include "jiface.hpp"
  17. typedef size32_t aindex_t;
  18. #define NotFound (aindex_t)-1
  19. /************************************************************************
  20. * Copy Lists *
  21. ************************************************************************/
  22. extern "C"
  23. {
  24. typedef int (* StdCompare)(const void *_e1, const void *_e2);
  25. }
  26. /*
  27. * Start of definition:
  28. */
  29. class jlib_decl Allocator
  30. {
  31. public:
  32. void kill();
  33. inline bool isItem(aindex_t pos = 0) const { return pos < used; } /* Is there an item at pos */
  34. inline aindex_t length() const { return used; } /* Return number of items */
  35. inline aindex_t ordinality() const { return used; } /* Return number of items */
  36. inline bool empty() const { return (used==0); }
  37. protected:
  38. void * _doBAdd(void *, size32_t size, StdCompare compare, bool & isNew);
  39. void * _doBSearch(const void *, size32_t size, StdCompare compare) const;
  40. void _doSort(size32_t size, StdCompare compare);
  41. void _ensure(aindex_t, size32_t);
  42. inline void _init() { max=0; _head=0; used=0; } // inline because it is called a lot
  43. void _reallocate(aindex_t newlen, size32_t iSize);
  44. void _doRotateR(aindex_t pos1, aindex_t pos2, size32_t iSize, aindex_t num);
  45. void _doRotateL(aindex_t pos1, aindex_t pos2, size32_t iSize, aindex_t num);
  46. void _space(size32_t iSize);
  47. void _doSwap(aindex_t pos1, aindex_t pos2, size32_t iSize);
  48. void _doTransfer(aindex_t to, aindex_t from, size32_t iSize);
  49. void doSwapWith(Allocator & other);
  50. protected:
  51. void * _head;
  52. aindex_t used;
  53. aindex_t max;
  54. };
  55. template <unsigned SIZE> class AllocatorOf : public Allocator
  56. {
  57. public:
  58. inline void ensure(aindex_t num) { _ensure(num, SIZE); }
  59. inline void rotateR(aindex_t pos1, aindex_t pos2) { _doRotateR(pos1, pos2, SIZE, 1); }
  60. inline void rotateL(aindex_t pos1, aindex_t pos2) { _doRotateL(pos1, pos2, SIZE, 1); }
  61. inline void rotateRN(aindex_t pos1, aindex_t pos2, aindex_t num) { _doRotateR(pos1, pos2, SIZE, num); }
  62. inline void rotateLN(aindex_t pos1, aindex_t pos2, aindex_t num) { _doRotateL(pos1, pos2, SIZE, num); }
  63. inline void swap(aindex_t pos1, aindex_t pos2) { _doSwap(pos1, pos2, SIZE); }
  64. inline void transfer(aindex_t to, aindex_t from) { _doTransfer(to, from, SIZE); }
  65. protected:
  66. inline void _space(void) { Allocator::_space(SIZE); }
  67. inline void _move(aindex_t pos1, aindex_t pos2, aindex_t num) { memmove((char *)_head + pos1 * SIZE, (char *)_head + pos2 * SIZE, num * SIZE); }
  68. };
  69. /* inheritance structure:
  70. BaseArrayOf inherits from AllocatorOf
  71. CopyArrayOf (non-owning ref array) inherits from BaseArrayOf
  72. OwningArrayOf inherits from BaseArrayOf
  73. ArrayOf (owning ref array) inherits from OwningArrayOf
  74. PtrArrayOf (owning ptr array) inherits from OwningArrayOf
  75. the difference between the latter two is that they call different functions to convert MEMBER to PARAM (Array__Member2Param vs Array__Member2ParamPtr)
  76. this is necessary because of the use of global functions, to allow two arrays with the
  77. same MEMBER but different PARAMs (otherwise these functions would have the same prototype, because their arguments only involve MEMBER and not PARAM)
  78. */
  79. template <class MEMBER, class PARAM>
  80. class BaseArrayOf : public AllocatorOf<sizeof(MEMBER)>
  81. {
  82. typedef AllocatorOf<sizeof(MEMBER)> PARENT;
  83. typedef BaseArrayOf<MEMBER,PARAM> SELF;
  84. protected:
  85. typedef int (*CompareFunc)(MEMBER *, MEMBER *);
  86. public:
  87. inline bool contains(PARAM search) const { return find(search) != NotFound; }
  88. void add(PARAM, aindex_t pos); /* Adds at pos */
  89. void append(PARAM); /* Adds to end of array */
  90. bool appendUniq(PARAM); /* Adds to end of array if not already in array - returns true if added*/
  91. aindex_t bAdd(MEMBER & newItem, CompareFunc, bool & isNew);
  92. aindex_t bSearch(const MEMBER & key, CompareFunc) const;
  93. aindex_t find(PARAM) const;
  94. MEMBER *getArray(aindex_t = 0) const;
  95. void sort(CompareFunc);
  96. void swap(aindex_t pos1, aindex_t pos2);
  97. void swapWith(SELF & other) { this->doSwapWith(other); }
  98. };
  99. template <class MEMBER, class PARAM>
  100. class CopyArrayOf : public BaseArrayOf<MEMBER, PARAM>
  101. {
  102. typedef BaseArrayOf<MEMBER, PARAM> PARENT;
  103. typedef CopyArrayOf<MEMBER, PARAM> SELF;
  104. public:
  105. CopyArrayOf() { SELF::_init(); }
  106. ~CopyArrayOf();
  107. void clear();
  108. inline PARAM item(aindex_t pos) const;
  109. PARAM tos(void) const;
  110. PARAM tos(aindex_t) const;
  111. PARAM pop(void);
  112. void popn(aindex_t);
  113. void popAll(void);
  114. void remove(aindex_t pos); /* Remove (delete) item at pos */
  115. void removen(aindex_t pos, aindex_t num); /* Remove (delete) item at pos */
  116. void replace(PARAM, aindex_t pos); /* Replace an item at pos */
  117. void trunc(aindex_t);
  118. bool zap(PARAM);
  119. };
  120. template <class MEMBER, class PARAM>
  121. class OwningArrayOf : public BaseArrayOf<MEMBER, PARAM>
  122. {
  123. typedef BaseArrayOf<MEMBER, PARAM> PARENT;
  124. typedef OwningArrayOf<MEMBER,PARAM> SELF;
  125. public:
  126. OwningArrayOf() { SELF::_init(); }
  127. ~OwningArrayOf();
  128. void clear(bool nodel = false); /* Remove all items, don't free array */
  129. void kill(bool nodel = false); /* Remove all items */
  130. void pop(bool nodel = false);
  131. void popn(aindex_t,bool nodel = false);
  132. void popAll(bool nodel = false);
  133. void replace(PARAM, aindex_t pos, bool nodel = false); /* Replace an item at pos */
  134. void remove(aindex_t pos, bool nodel = false); /* Remove (delete) item at pos */
  135. void removen(aindex_t pos, aindex_t num, bool nodel = false); /* Remove N items (delete) item at pos */
  136. void trunc(aindex_t pos, bool nodel = false);
  137. bool zap(PARAM, bool nodel = false);
  138. };
  139. template <class MEMBER, class PARAM>
  140. class ArrayOf : public OwningArrayOf<MEMBER, PARAM>
  141. {
  142. typedef OwningArrayOf<MEMBER, PARAM> PARENT;
  143. typedef ArrayOf<MEMBER,PARAM> SELF;
  144. public:
  145. inline PARAM item(aindex_t pos) const;
  146. PARAM popGet();
  147. PARAM tos(void) const;
  148. PARAM tos(aindex_t) const;
  149. };
  150. template <class MEMBER, class PARAM>
  151. class PtrArrayOf : public OwningArrayOf<MEMBER, PARAM>
  152. {
  153. typedef OwningArrayOf<MEMBER, PARAM> PARENT;
  154. typedef PtrArrayOf<MEMBER,PARAM> SELF;
  155. public:
  156. inline PARAM item(aindex_t pos) const { assertex(SELF::isItem(pos)); return Array__Member2ParamPtr(((MEMBER *)AllocatorOf<sizeof(MEMBER)>::_head)[pos]);}
  157. PARAM popGet();
  158. PARAM tos(void) const;
  159. PARAM tos(aindex_t) const;
  160. };
  161. template <class ARRAY, class PARAM> class ArrayIteratorOf
  162. {
  163. public:
  164. ArrayIteratorOf(ARRAY & _array) : array(_array) { cur = 0; }
  165. inline bool first(void) { cur = 0; return isValid(); }
  166. inline bool isValid(void) { return array.isItem(cur); }
  167. inline PARAM query() { assertex(isValid()); return array.item(cur); }
  168. inline bool hasNext(void) { return array.isItem(cur+1); }
  169. inline bool hasPrev(void) { return array.isItem(cur-1); }
  170. inline bool last(void) { cur = array.ordinality()-1; return isValid(); }
  171. inline bool next(void) { ++cur; return isValid(); }
  172. inline bool prev(void) { --cur; return isValid(); }
  173. inline bool select(aindex_t seek) { cur = seek; return isValid(); }
  174. private:
  175. ARRAY & array;
  176. aindex_t cur;
  177. };
  178. #define ForEachItem(x) aindex_t numItems##x = ordinality(); \
  179. aindex_t x = 0; \
  180. for (; x< numItems##x; ++x)
  181. #define ForEachItemRev(x) aindex_t x = ordinality(); \
  182. for (;x--;)
  183. #define ForEachItemIn(x,y) aindex_t numItems##x = (y).ordinality(); \
  184. aindex_t x = 0; \
  185. for (; x< numItems##x; ++x)
  186. #define ForEachItemInRev(x,y) aindex_t x = (y).ordinality(); \
  187. for (;x--;)
  188. #define CloneArray(TGT, SRC) \
  189. { ForEachItemIn(idx##__LINE__, SRC) \
  190. (TGT).append((SRC).item(idx##__LINE__)); }
  191. #define MAKEArrayOf(member, param, array) class array : public ArrayOf<member, param> {};
  192. #define MAKECopyArrayOf(member, param, array) class array : public CopyArrayOf<member, param> {};
  193. #define MAKEPtrArrayOf(member, param, array) class array : public PtrArrayOf<member, param> {};
  194. #define MAKEValueArray(simple, array) \
  195. inline simple Array__Member2Param(simple &src) { return src; } \
  196. inline void Array__Assign(simple & dest, simple const & src){ dest = src; } \
  197. inline bool Array__Equal(simple const & m, simple const p) { return m==p; } \
  198. MAKECopyArrayOf(simple, simple, array)
  199. #define MAKEPointerArray(simple, array) \
  200. inline simple & Array__Member2Param(simple *&src) { return *src; } \
  201. inline void Array__Assign(simple * & dest, simple & src) { dest = &src; } \
  202. inline bool Array__Equal(simple * const & m, simple const & p) { return m==&p; } \
  203. MAKECopyArrayOf(simple *, simple &, array)
  204. /* Documentation on the macros:
  205. MAKEValueArray(simple-type, array-name)
  206. Declare an array of a built in, or simple type. It takes care of defining
  207. all the inline functions required. e.g. MAKEValueArray(unsigned, unsignedArray)
  208. MAKE[Copy]ArrayOf(member, param, array-name)
  209. Declares an array class of members, where param is used as the parameter
  210. that is passed into and returned from the access functions. Including Copy
  211. in the name means that no action is taken when the items are destroyed.
  212. */
  213. #endif