DS_Multilist.h 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650
  1. /*
  2. * Copyright (c) 2014, Oculus VR, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. *
  9. */
  10. /// \file DS_Multilist.h
  11. /// \internal
  12. /// \brief ADT that can represent an unordered list, ordered list, stack, or queue with a common interface
  13. ///
  14. #ifndef __MULTILIST_H
  15. #define __MULTILIST_H
  16. #include "RakAssert.h"
  17. #include <string.h> // memmove
  18. #include "Export.h"
  19. #include "RakMemoryOverride.h"
  20. #include "NativeTypes.h"
  21. #ifdef _MSC_VER
  22. #pragma warning( push )
  23. #pragma warning( disable : 4127 ) // warning C4127: conditional expression is constant
  24. #pragma warning( disable : 4512 ) // warning C4512: assignment operator could not be generated
  25. #endif
  26. /// What algorithm to use to store the data for the Multilist
  27. enum MultilistType
  28. {
  29. /// Removing from the middle of the list will swap the end of the list rather than shift the elements. Push and Pop operate on the tail.
  30. ML_UNORDERED_LIST,
  31. /// A normal list, with the list order preserved. Push and Pop operate on the tail.
  32. ML_STACK,
  33. /// A queue. Push and Pop operate on the head
  34. ML_QUEUE,
  35. /// A list that is always kept in order. Elements must be unique, and compare against each other consistently using <, ==, and >
  36. ML_ORDERED_LIST,
  37. /// A list whose type can change at runtime
  38. ML_VARIABLE_DURING_RUNTIME
  39. };
  40. /// The namespace DataStructures was only added to avoid compiler errors for commonly named data structures
  41. /// As these data structures are stand-alone, you can use them outside of RakNet for your own projects if you wish.
  42. namespace DataStructures
  43. {
  44. /// Can be used with Multilist::ForEach
  45. /// Assuming the Multilist holds pointers, will delete those pointers
  46. template <class templateType>
  47. void DeletePtr_RakNet(templateType &ptr, const char *file, unsigned int line ) {RakNet::OP_DELETE(ptr, file, line);}
  48. /// Can be used with Multilist::ForEach
  49. /// Assuming the Multilist holds pointers, will delete those pointers
  50. template <class templateType>
  51. void DeletePtr(templateType &ptr) {delete ptr;}
  52. /// The following is invalid.
  53. /// bool operator<( const MyClass *myClass, const int &inputKey ) {return myClass->value < inputKey;}
  54. /// At least one type has to be a reference to a class
  55. /// MLKeyRef is a helper class to turn a native type into a class, so you can compare that native type against a pointer to a different class
  56. /// Used for he Multilist, when _DataType != _KeyType
  57. template < class templateType >
  58. class MLKeyRef
  59. {
  60. public:
  61. MLKeyRef(const templateType& input) : val(input) {}
  62. const templateType &Get(void) const {return val;}
  63. bool operator<( const templateType &right ) {return val < right;}
  64. bool operator>( const templateType &right ) {return val > right;}
  65. bool operator==( const templateType &right ) {return val == right;}
  66. protected:
  67. const templateType &val;
  68. };
  69. /// For the Multilist, when _DataType != _KeyType, you must define the comparison operators between the key and the data
  70. /// This is non-trivial due to the need to use MLKeyRef in case the type held is a pointer to a structure or class and the key type is not a class
  71. /// For convenience, this macro will implement the comparison operators under the following conditions
  72. /// 1. _DataType is a pointer to a class or structure
  73. /// 2. The key is a member variable of _DataType
  74. #define DEFINE_MULTILIST_PTR_TO_MEMBER_COMPARISONS( _CLASS_NAME_, _KEY_TYPE_, _MEMBER_VARIABLE_NAME_ ) \
  75. bool operator<( const DataStructures::MLKeyRef<_KEY_TYPE_> &inputKey, const _CLASS_NAME_ *cls ) {return inputKey.Get() < cls->_MEMBER_VARIABLE_NAME_;} \
  76. bool operator>( const DataStructures::MLKeyRef<_KEY_TYPE_> &inputKey, const _CLASS_NAME_ *cls ) {return inputKey.Get() > cls->_MEMBER_VARIABLE_NAME_;} \
  77. bool operator==( const DataStructures::MLKeyRef<_KEY_TYPE_> &inputKey, const _CLASS_NAME_ *cls ) {return inputKey.Get() == cls->_MEMBER_VARIABLE_NAME_;}
  78. typedef uint32_t DefaultIndexType;
  79. /// \brief The multilist, representing an abstract data type that generally holds lists.
  80. /// \param[in] _MultilistType What type of list this is, \sa MultilistType
  81. /// \param[in] _DataType What type of data this list holds.
  82. /// \param[in] _KeyType If a function takes a key to sort on, what type of key this is. The comparison operator between _DataType and _KeyType must be defined
  83. /// \param[in] _IndexType What variable type to use for indices
  84. template <const MultilistType _MultilistType, class _DataType, class _KeyType=_DataType, class _IndexType=DefaultIndexType>
  85. class RAK_DLL_EXPORT Multilist
  86. {
  87. public:
  88. Multilist();
  89. ~Multilist();
  90. Multilist( const Multilist& source );
  91. Multilist& operator= ( const Multilist& source );
  92. _DataType& operator[] ( const _IndexType position ) const;
  93. /// Unordered list, stack is LIFO
  94. /// QUEUE is FIFO
  95. /// Ordered list is inserted in order
  96. void Push(const _DataType &d, const char *file=__FILE__, unsigned int line=__LINE__ );
  97. void Push(const _DataType &d, const _KeyType &key, const char *file=__FILE__, unsigned int line=__LINE__ );
  98. /// \brief Gets or removes and gets an element from the list, according to the same rules as Push().
  99. /// Ordered list is LIFO for the purposes of Pop and Peek.
  100. _DataType &Pop(const char *file=__FILE__, unsigned int line=__LINE__);
  101. _DataType &Peek(void) const;
  102. /// \brief Same as Push(), except FIFO and LIFO are reversed.
  103. /// Ordered list still inserts in order.
  104. void PushOpposite(const _DataType &d, const char *file=__FILE__, unsigned int line=__LINE__ );
  105. void PushOpposite(const _DataType &d, const _KeyType &key, const char *file=__FILE__, unsigned int line=__LINE__ );
  106. /// \brief Same as Pop() and Peek(), except FIFO and LIFO are reversed.
  107. _DataType &PopOpposite(const char *file=__FILE__, unsigned int line=__LINE__);
  108. _DataType &PeekOpposite(void) const;
  109. /// \brief Stack,Queue: Inserts at index indicated, elements are shifted.
  110. /// Ordered list: Inserts, position is ignored
  111. void InsertAtIndex(const _DataType &d, _IndexType index, const char *file=__FILE__, unsigned int line=__LINE__);
  112. /// \brief Unordered list, removes at index indicated, swaps last element with that element.
  113. /// Otherwise, array is shifted left to overwrite removed element
  114. /// \details Index[0] returns the same as Pop() for a queue.
  115. /// Same as PopOpposite() for the list and ordered list
  116. void RemoveAtIndex(_IndexType position, const char *file=__FILE__, unsigned int line=__LINE__);
  117. /// \brief Find the index of \a key, and remove at that index.
  118. bool RemoveAtKey(_KeyType key, bool assertIfDoesNotExist, const char *file=__FILE__, unsigned int line=__LINE__);
  119. /// \brief Finds the index of \a key. Return -1 if the key is not found.
  120. _IndexType GetIndexOf(_KeyType key) const;
  121. /// \brief Returns where in the list we should insert the item, to preserve list order.
  122. /// Returns -1 if the item is already in the list
  123. _IndexType GetInsertionIndex(_KeyType key) const;
  124. /// \brief Finds the index of \a key. Return 0 if the key is not found. Useful if _DataType is always non-zero pointers.
  125. _DataType GetPtr(_KeyType key) const;
  126. /// \brief Iterate over the list, calling the function pointer on each element.
  127. void ForEach(void (*func)(_DataType &item, const char *file, unsigned int line), const char *file, unsigned int line);
  128. void ForEach(void (*func)(_DataType &item));
  129. /// \brief Returns if the list is empty.
  130. bool IsEmpty(void) const;
  131. /// \brief Returns the number of elements used in the list.
  132. _IndexType GetSize(void) const;
  133. /// \brief Empties the list. The list is not deallocated if it is small,
  134. /// unless \a deallocateSmallBlocks is true
  135. void Clear( bool deallocateSmallBlocks=true, const char *file=__FILE__, unsigned int line=__LINE__ );
  136. /// \brief Empties the list, first calling RakNet::OP_Delete on all items.
  137. /// \details The list is not deallocated if it is small, unless \a deallocateSmallBlocks is true
  138. void ClearPointers( bool deallocateSmallBlocks=true, const char *file=__FILE__, unsigned int line=__LINE__ );
  139. /// \brief Empty one item from the list, first calling RakNet::OP_Delete on that item.
  140. void ClearPointer( _KeyType key, const char *file=__FILE__, unsigned int line=__LINE__ );
  141. /// \brief Reverses the elements in the list, and flips the sort order
  142. /// returned by GetSortOrder() if IsSorted() returns true at the time the function is called
  143. void ReverseList(void);
  144. /// \brief Reallocates the list to a larger size.
  145. /// If \a size is smaller than the value returned by GetSize(), the call does nothing.
  146. void Reallocate(_IndexType size, const char *file=__FILE__, unsigned int line=__LINE__);
  147. /// \brief Sorts the list unless it is an ordered list, in which it does nothing as the list is assumed to already be sorted.
  148. /// \details However, if \a force is true, it will also resort the ordered list, useful if the comparison operator between _KeyType and _DataType would now return different results
  149. /// Once the list is sorted, further operations to lookup by key will be log2(n) until the list is modified
  150. void Sort(bool force);
  151. /// \brief Sets the list to be remembered as sorted.
  152. /// \details Optimization if the source is sorted already
  153. void TagSorted(void);
  154. /// \brief Defaults to ascending.
  155. /// \details Used by Sort(), and by ML_ORDERED_LIST
  156. void SetSortOrder(bool ascending);
  157. /// \brief Returns true if ascending.
  158. bool GetSortOrder(void) const;
  159. /// \brief Returns true if the list is currently believed to be in a sorted state.
  160. /// \details Doesn't actually check for sortedness, just if Sort()
  161. /// was recently called, or MultilistType is ML_ORDERED_LIST
  162. bool IsSorted(void) const;
  163. /// Returns what type of list this is
  164. MultilistType GetMultilistType(void) const;
  165. /// \brief Changes what type of list this is.
  166. /// \pre Template must be defined with ML_VARIABLE_DURING_RUNTIME for this to do anything
  167. /// \param[in] mlType Any value of the enum MultilistType, except ML_VARIABLE_DURING_RUNTIME
  168. void SetMultilistType(MultilistType newType);
  169. /// \brief Returns the intersection of two lists.
  170. /// Intersection is items common to both lists.
  171. static void FindIntersection(
  172. Multilist& source1,
  173. Multilist& source2,
  174. Multilist& intersection,
  175. Multilist& uniqueToSource1,
  176. Multilist& uniqueToSource2);
  177. protected:
  178. void ReallocateIfNeeded(const char *file, unsigned int line);
  179. void DeallocateIfNeeded(const char *file, unsigned int line);
  180. void ReallocToSize(_IndexType newAllocationSize, const char *file, unsigned int line);
  181. void ReverseListInternal(void);
  182. void InsertInOrderedList(const _DataType &d, const _KeyType &key);
  183. _IndexType GetIndexFromKeyInSortedList(const _KeyType &key, bool *objectExists) const;
  184. void InsertShiftArrayRight(const _DataType &d, _IndexType index);
  185. void DeleteShiftArrayLeft(_IndexType index);
  186. void QSortAscending(_IndexType left, _IndexType right);
  187. void QSortDescending(_IndexType left, _IndexType right);
  188. void CopySource( const Multilist& source );
  189. /// An array of user values
  190. _DataType* data;
  191. /// Number of elements in the list
  192. _IndexType dataSize;
  193. /// Size of \a array
  194. _IndexType allocationSize;
  195. /// Array index for the head of the queue
  196. _IndexType queueHead;
  197. /// Array index for the tail of the queue
  198. _IndexType queueTail;
  199. /// How many bytes the user chose to preallocate
  200. /// Won't automatically deallocate below this
  201. _IndexType preallocationSize;
  202. enum
  203. {
  204. ML_UNSORTED,
  205. ML_SORTED_ASCENDING,
  206. ML_SORTED_DESCENDING
  207. } sortState;
  208. bool ascendingSort;
  209. // In case we are using the variable type multilist
  210. MultilistType variableMultilistType;
  211. };
  212. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  213. Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::Multilist()
  214. {
  215. data=0;
  216. dataSize=0;
  217. allocationSize=0;
  218. ascendingSort=true;
  219. sortState=ML_UNSORTED;
  220. queueHead=0;
  221. queueTail=0;
  222. preallocationSize=0;
  223. if (_MultilistType==ML_ORDERED_LIST)
  224. sortState=ML_SORTED_ASCENDING;
  225. else
  226. sortState=ML_UNSORTED;
  227. if (_MultilistType==ML_VARIABLE_DURING_RUNTIME)
  228. variableMultilistType=ML_UNORDERED_LIST;
  229. }
  230. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  231. Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::~Multilist()
  232. {
  233. if (data!=0)
  234. RakNet::OP_DELETE_ARRAY(data, _FILE_AND_LINE_);
  235. }
  236. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  237. Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::Multilist( const Multilist& source )
  238. {
  239. CopySource(source);
  240. }
  241. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  242. Multilist<_MultilistType, _DataType, _KeyType, _IndexType>& Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::operator= ( const Multilist& source )
  243. {
  244. Clear(true);
  245. CopySource(source);
  246. return *this;
  247. }
  248. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  249. void Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::CopySource( const Multilist& source )
  250. {
  251. dataSize=source.GetSize();
  252. ascendingSort=source.ascendingSort;
  253. sortState=source.sortState;
  254. queueHead=0;
  255. queueTail=dataSize;
  256. preallocationSize=source.preallocationSize;
  257. variableMultilistType=source.variableMultilistType;
  258. if (source.data==0)
  259. {
  260. data=0;
  261. allocationSize=0;
  262. }
  263. else
  264. {
  265. allocationSize=dataSize;
  266. data = RakNet::OP_NEW_ARRAY<_DataType>(dataSize,_FILE_AND_LINE_);
  267. _IndexType i;
  268. for (i=0; i < dataSize; i++)
  269. data[i]=source[i];
  270. }
  271. }
  272. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  273. _DataType& Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::operator[] ( const _IndexType position ) const
  274. {
  275. RakAssert(position<GetSize());
  276. if (GetMultilistType()==ML_QUEUE)
  277. {
  278. if ( queueHead + position >= allocationSize )
  279. return data[ queueHead + position - allocationSize ];
  280. else
  281. return data[ queueHead + position ];
  282. }
  283. return data[position];
  284. }
  285. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  286. void Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::Push(const _DataType &d, const char *file, unsigned int line )
  287. {
  288. Push(d,d,file,line);
  289. }
  290. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  291. void Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::Push(const _DataType &d, const _KeyType &key, const char *file, unsigned int line )
  292. {
  293. ReallocateIfNeeded(file,line);
  294. if (GetMultilistType()==ML_UNORDERED_LIST || GetMultilistType()==ML_STACK)
  295. {
  296. data[dataSize]=d;
  297. dataSize++;
  298. }
  299. else if (GetMultilistType()==ML_QUEUE)
  300. {
  301. data[queueTail++] = d;
  302. if ( queueTail == allocationSize )
  303. queueTail = 0;
  304. dataSize++;
  305. }
  306. else
  307. {
  308. RakAssert(GetMultilistType()==ML_ORDERED_LIST);
  309. InsertInOrderedList(d,key);
  310. }
  311. if (GetMultilistType()==ML_UNORDERED_LIST || GetMultilistType()==ML_STACK || GetMultilistType()==ML_QUEUE)
  312. {
  313. // Break sort if no longer sorted
  314. if (sortState!=ML_UNSORTED && dataSize>1)
  315. {
  316. if (ascendingSort)
  317. {
  318. if ( MLKeyRef<_KeyType>(key) < operator[](dataSize-2) )
  319. sortState=ML_UNSORTED;
  320. }
  321. else
  322. {
  323. if ( MLKeyRef<_KeyType>(key) > operator[](dataSize-2) )
  324. sortState=ML_UNSORTED;
  325. }
  326. sortState=ML_UNSORTED;
  327. }
  328. }
  329. }
  330. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  331. _DataType &Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::Pop(const char *file, unsigned int line)
  332. {
  333. RakAssert(IsEmpty()==false);
  334. DeallocateIfNeeded(file,line);
  335. if (GetMultilistType()==ML_UNORDERED_LIST || GetMultilistType()==ML_STACK || GetMultilistType()==ML_ORDERED_LIST)
  336. {
  337. dataSize--;
  338. return data[dataSize];
  339. }
  340. else
  341. {
  342. RakAssert(GetMultilistType()==ML_QUEUE);
  343. if ( ++queueHead == allocationSize )
  344. queueHead = 0;
  345. if ( queueHead == 0 )
  346. return data[ allocationSize -1 ];
  347. dataSize--;
  348. return data[ queueHead -1 ];
  349. }
  350. }
  351. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  352. _DataType &Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::Peek(void) const
  353. {
  354. RakAssert(IsEmpty()==false);
  355. if (GetMultilistType()==ML_UNORDERED_LIST || GetMultilistType()==ML_STACK || GetMultilistType()==ML_ORDERED_LIST)
  356. {
  357. return data[dataSize-1];
  358. }
  359. else
  360. {
  361. RakAssert(GetMultilistType()==ML_QUEUE);
  362. return data[ queueHead ];
  363. }
  364. }
  365. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  366. void Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::PushOpposite(const _DataType &d, const char *file, unsigned int line )
  367. {
  368. PushOpposite(d,d,file,line);
  369. }
  370. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  371. void Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::PushOpposite(const _DataType &d, const _KeyType &key, const char *file, unsigned int line )
  372. {
  373. ReallocateIfNeeded(file,line);
  374. // Unordered list Push at back
  375. if (GetMultilistType()==ML_UNORDERED_LIST)
  376. {
  377. data[dataSize]=d;
  378. dataSize++;
  379. }
  380. else if (GetMultilistType()==ML_STACK)
  381. {
  382. // Stack push at front of the list, instead of back as normal
  383. InsertAtIndex(d,0,file,line);
  384. }
  385. else if (GetMultilistType()==ML_QUEUE)
  386. {
  387. // Queue push at front of the list, instead of back as normal
  388. InsertAtIndex(d,0,file,line);
  389. }
  390. else
  391. {
  392. RakAssert(GetMultilistType()==ML_ORDERED_LIST);
  393. InsertInOrderedList(d,key);
  394. }
  395. if (GetMultilistType()==ML_UNORDERED_LIST || GetMultilistType()==ML_STACK || GetMultilistType()==ML_QUEUE)
  396. {
  397. // Break sort if no longer sorted
  398. if (sortState!=ML_UNSORTED && dataSize>1)
  399. {
  400. if (ascendingSort)
  401. {
  402. if ( MLKeyRef<_KeyType>(key) > operator[](1) )
  403. sortState=ML_UNSORTED;
  404. }
  405. else
  406. {
  407. if ( MLKeyRef<_KeyType>(key) < operator[](1) )
  408. sortState=ML_UNSORTED;
  409. }
  410. }
  411. }
  412. }
  413. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  414. _DataType &Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::PopOpposite(const char *file, unsigned int line)
  415. {
  416. RakAssert(IsEmpty()==false);
  417. if (GetMultilistType()==ML_UNORDERED_LIST || GetMultilistType()==ML_STACK || GetMultilistType()==ML_ORDERED_LIST)
  418. {
  419. // Copy leftmost to end
  420. ReallocateIfNeeded(file,line);
  421. data[dataSize]=data[0];
  422. DeleteShiftArrayLeft(0);
  423. --dataSize;
  424. // Assuming still leaves at least one element past the end of the list allocated
  425. DeallocateIfNeeded(file,line);
  426. // Return end
  427. return data[dataSize+1];
  428. }
  429. else
  430. {
  431. RakAssert(GetMultilistType()==ML_QUEUE);
  432. // Deallocate first, since we are returning off the existing list
  433. DeallocateIfNeeded(file,line);
  434. dataSize--;
  435. if (queueTail==0)
  436. queueTail=allocationSize-1;
  437. else
  438. --queueTail;
  439. return data[queueTail];
  440. }
  441. }
  442. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  443. _DataType &Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::PeekOpposite(void) const
  444. {
  445. RakAssert(IsEmpty()==false);
  446. if (GetMultilistType()==ML_UNORDERED_LIST || GetMultilistType()==ML_STACK || GetMultilistType()==ML_ORDERED_LIST)
  447. {
  448. return data[0];
  449. }
  450. else
  451. {
  452. RakAssert(GetMultilistType()==ML_QUEUE);
  453. _IndexType priorIndex;
  454. if (queueTail==0)
  455. priorIndex=allocationSize-1;
  456. else
  457. priorIndex=queueTail-1;
  458. return data[priorIndex];
  459. }
  460. }
  461. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  462. void Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::InsertAtIndex(const _DataType &d, _IndexType index, const char *file, unsigned int line)
  463. {
  464. ReallocateIfNeeded(file,line);
  465. if (GetMultilistType()==ML_UNORDERED_LIST || GetMultilistType()==ML_STACK || GetMultilistType()==ML_ORDERED_LIST)
  466. {
  467. if (index>=dataSize)
  468. {
  469. // insert at end
  470. data[dataSize]=d;
  471. dataSize++;
  472. }
  473. else
  474. {
  475. // insert at index
  476. InsertShiftArrayRight(d,index);
  477. }
  478. }
  479. else
  480. {
  481. data[queueTail++] = d;
  482. if ( queueTail == allocationSize )
  483. queueTail = 0;
  484. ++dataSize;
  485. if (dataSize==1)
  486. return;
  487. _IndexType writeIndex, readIndex, trueWriteIndex, trueReadIndex;
  488. writeIndex=dataSize-1;
  489. readIndex=writeIndex-1;
  490. while (readIndex >= index)
  491. {
  492. if ( queueHead + writeIndex >= allocationSize )
  493. trueWriteIndex = queueHead + writeIndex - allocationSize;
  494. else
  495. trueWriteIndex = queueHead + writeIndex;
  496. if ( queueHead + readIndex >= allocationSize )
  497. trueReadIndex = queueHead + readIndex - allocationSize;
  498. else
  499. trueReadIndex = queueHead + readIndex;
  500. data[trueWriteIndex]=data[trueReadIndex];
  501. if (readIndex==0)
  502. break;
  503. writeIndex--;
  504. readIndex--;
  505. }
  506. if ( queueHead + index >= allocationSize )
  507. trueWriteIndex = queueHead + index - allocationSize;
  508. else
  509. trueWriteIndex = queueHead + index;
  510. data[trueWriteIndex]=d;
  511. }
  512. if (_MultilistType!=ML_ORDERED_LIST)
  513. sortState=ML_UNSORTED;
  514. }
  515. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  516. void Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::RemoveAtIndex(_IndexType position, const char *file, unsigned int line)
  517. {
  518. RakAssert(position < dataSize);
  519. RakAssert(IsEmpty()==false);
  520. if (GetMultilistType()==ML_UNORDERED_LIST)
  521. {
  522. // Copy tail to current
  523. data[position]=data[dataSize-1];
  524. }
  525. else if (GetMultilistType()==ML_STACK || GetMultilistType()==ML_ORDERED_LIST)
  526. {
  527. DeleteShiftArrayLeft(position);
  528. }
  529. else
  530. {
  531. RakAssert(GetMultilistType()==ML_QUEUE);
  532. _IndexType index, next;
  533. if ( queueHead + position >= allocationSize )
  534. index = queueHead + position - allocationSize;
  535. else
  536. index = queueHead + position;
  537. next = index + 1;
  538. if ( next == allocationSize )
  539. next = 0;
  540. while ( next != queueTail )
  541. {
  542. // Overwrite the previous element
  543. data[ index ] = data[ next ];
  544. index = next;
  545. //next = (next + 1) % allocationSize;
  546. if ( ++next == allocationSize )
  547. next = 0;
  548. }
  549. // Move the queueTail back
  550. if ( queueTail == 0 )
  551. queueTail = allocationSize - 1;
  552. else
  553. --queueTail;
  554. }
  555. dataSize--;
  556. DeallocateIfNeeded(file,line);
  557. }
  558. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  559. bool Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::RemoveAtKey(_KeyType key, bool assertIfDoesNotExist, const char *file, unsigned int line)
  560. {
  561. _IndexType index = GetIndexOf(key);
  562. if (index==(_IndexType)-1)
  563. {
  564. RakAssert(assertIfDoesNotExist==false && "RemoveAtKey element not found");
  565. return false;
  566. }
  567. RemoveAtIndex(index,file,line);
  568. return true;
  569. }
  570. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  571. _IndexType Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::GetIndexOf(_KeyType key) const
  572. {
  573. _IndexType i;
  574. if (IsSorted())
  575. {
  576. bool objectExists;
  577. i=GetIndexFromKeyInSortedList(key, &objectExists);
  578. if (objectExists)
  579. return i;
  580. return (_IndexType)-1;
  581. }
  582. else if (GetMultilistType()==ML_UNORDERED_LIST || GetMultilistType()==ML_STACK)
  583. {
  584. for (i=0; i < dataSize; i++)
  585. {
  586. if (MLKeyRef<_KeyType>(key)==data[i])
  587. return i;
  588. }
  589. return (_IndexType)-1;
  590. }
  591. else
  592. {
  593. RakAssert( GetMultilistType()==ML_QUEUE );
  594. for (i=0; i < dataSize; i++)
  595. {
  596. if (MLKeyRef<_KeyType>(key)==operator[](i))
  597. return i;
  598. }
  599. return (_IndexType)-1;
  600. }
  601. }
  602. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  603. _IndexType Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::GetInsertionIndex(_KeyType key) const
  604. {
  605. _IndexType i;
  606. if (IsSorted())
  607. {
  608. bool objectExists;
  609. i=GetIndexFromKeyInSortedList(key, &objectExists);
  610. if (objectExists)
  611. return (_IndexType)-1;
  612. return i;
  613. }
  614. else if (GetMultilistType()==ML_UNORDERED_LIST || GetMultilistType()==ML_STACK)
  615. {
  616. for (i=0; i < dataSize; i++)
  617. {
  618. if (MLKeyRef<_KeyType>(key)==data[i])
  619. return (_IndexType)-1;
  620. }
  621. return dataSize;
  622. }
  623. else
  624. {
  625. RakAssert( GetMultilistType()==ML_QUEUE );
  626. for (i=0; i < dataSize; i++)
  627. {
  628. if (MLKeyRef<_KeyType>(key)==operator[](i))
  629. return (_IndexType)-1;
  630. }
  631. return dataSize;
  632. }
  633. }
  634. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  635. _DataType Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::GetPtr(_KeyType key) const
  636. {
  637. _IndexType i = GetIndexOf(key);
  638. if (i==(_IndexType)-1)
  639. return 0;
  640. return data[i];
  641. }
  642. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  643. void Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::ForEach(void (*func)(_DataType &item, const char *file, unsigned int line), const char *file, unsigned int line)
  644. {
  645. _IndexType i;
  646. for (i=0; i < dataSize; i++)
  647. func(operator[](i), file, line);
  648. }
  649. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  650. void Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::ForEach(void (*func)(_DataType &item))
  651. {
  652. _IndexType i;
  653. for (i=0; i < dataSize; i++)
  654. func(operator[](i));
  655. }
  656. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  657. bool Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::IsEmpty(void) const
  658. {
  659. return dataSize==0;
  660. }
  661. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  662. _IndexType Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::GetSize(void) const
  663. {
  664. return dataSize;
  665. }
  666. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  667. void Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::Clear( bool deallocateSmallBlocks, const char *file, unsigned int line )
  668. {
  669. dataSize=0;
  670. if (GetMultilistType()==ML_ORDERED_LIST)
  671. if (ascendingSort)
  672. sortState=ML_SORTED_ASCENDING;
  673. else
  674. sortState=ML_SORTED_DESCENDING;
  675. else
  676. sortState=ML_UNSORTED;
  677. queueHead=0;
  678. queueTail=0;
  679. if (deallocateSmallBlocks && allocationSize < 128 && data)
  680. {
  681. RakNet::OP_DELETE_ARRAY(data,file,line);
  682. data=0;
  683. allocationSize=0;
  684. }
  685. }
  686. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  687. void Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::ClearPointers( bool deallocateSmallBlocks, const char *file, unsigned int line )
  688. {
  689. _IndexType i;
  690. for (i=0; i < dataSize; i++)
  691. RakNet::OP_DELETE(operator[](i), file, line);
  692. Clear(deallocateSmallBlocks, file, line);
  693. }
  694. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  695. void Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::ClearPointer( _KeyType key, const char *file, unsigned int line )
  696. {
  697. _IndexType i;
  698. i = GetIndexOf(key);
  699. if (i!=-1)
  700. {
  701. RakNet::OP_DELETE(operator[](i), file, line);
  702. RemoveAtIndex(i);
  703. }
  704. }
  705. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  706. void Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::ReverseList(void)
  707. {
  708. if (IsSorted())
  709. ascendingSort=!ascendingSort;
  710. ReverseListInternal();
  711. }
  712. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  713. void Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::Reallocate(_IndexType size, const char *file, unsigned int line)
  714. {
  715. _IndexType newAllocationSize;
  716. if (size < dataSize)
  717. newAllocationSize=dataSize;
  718. else
  719. newAllocationSize=size;
  720. preallocationSize=size;
  721. ReallocToSize(newAllocationSize,file,line);
  722. }
  723. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  724. void Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::Sort(bool force)
  725. {
  726. if (IsSorted() && force==false)
  727. return;
  728. if (dataSize>1)
  729. {
  730. if (ascendingSort)
  731. QSortAscending(0,dataSize-1);
  732. else
  733. QSortDescending(0,dataSize-1);
  734. }
  735. TagSorted();
  736. }
  737. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  738. void Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::TagSorted(void)
  739. {
  740. if (ascendingSort)
  741. sortState=ML_SORTED_ASCENDING;
  742. else
  743. sortState=ML_SORTED_DESCENDING;
  744. }
  745. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  746. void Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::QSortAscending(_IndexType leftEdge, _IndexType rightEdge)
  747. {
  748. _DataType temp;
  749. _IndexType left=leftEdge;
  750. _IndexType right=rightEdge;
  751. _IndexType pivotIndex=left++;
  752. while (left<right)
  753. {
  754. if (data[left] <= data[pivotIndex])
  755. {
  756. ++left;
  757. }
  758. else
  759. {
  760. temp=data[left];
  761. data[left]=data[right];
  762. data[right]=temp;
  763. --right;
  764. }
  765. }
  766. temp=data[pivotIndex];
  767. // Move pivot to center
  768. if (data[left] > data[pivotIndex])
  769. {
  770. --left;
  771. data[pivotIndex]=data[left];
  772. data[left]=temp;
  773. }
  774. else
  775. {
  776. data[pivotIndex]=data[left];
  777. data[left]=temp;
  778. --left;
  779. }
  780. if (left!=leftEdge)
  781. QSortAscending(leftEdge, left);
  782. if (right!=rightEdge)
  783. QSortAscending(right, rightEdge);
  784. }
  785. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  786. void Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::QSortDescending(_IndexType leftEdge, _IndexType rightEdge)
  787. {
  788. _DataType temp;
  789. _IndexType left=leftEdge;
  790. _IndexType right=rightEdge;
  791. _IndexType pivotIndex=left++;
  792. while (left<right)
  793. {
  794. if (data[left] >= data[pivotIndex])
  795. {
  796. ++left;
  797. }
  798. else
  799. {
  800. temp=data[left];
  801. data[left]=data[right];
  802. data[right]=temp;
  803. --right;
  804. }
  805. }
  806. temp=data[pivotIndex];
  807. // Move pivot to center
  808. if (data[left] < data[pivotIndex])
  809. {
  810. --left;
  811. data[pivotIndex]=data[left];
  812. data[left]=temp;
  813. }
  814. else
  815. {
  816. data[pivotIndex]=data[left];
  817. data[left]=temp;
  818. --left;
  819. }
  820. if (left!=leftEdge)
  821. QSortDescending(leftEdge, left);
  822. if (right!=rightEdge)
  823. QSortDescending(right, rightEdge);
  824. }
  825. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  826. void Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::SetSortOrder(bool ascending)
  827. {
  828. if (ascendingSort!=ascending && IsSorted())
  829. {
  830. ascendingSort=ascending;
  831. // List is sorted, and the sort order has changed. So reverse the list
  832. ReverseListInternal();
  833. }
  834. else
  835. ascendingSort=ascending;
  836. }
  837. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  838. bool Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::GetSortOrder(void) const
  839. {
  840. return ascendingSort;
  841. }
  842. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  843. bool Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::IsSorted(void) const
  844. {
  845. return GetMultilistType()==ML_ORDERED_LIST || sortState!=ML_UNSORTED;
  846. }
  847. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  848. MultilistType Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::GetMultilistType(void) const
  849. {
  850. if (_MultilistType==ML_VARIABLE_DURING_RUNTIME)
  851. return variableMultilistType;
  852. return _MultilistType;
  853. }
  854. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  855. void Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::SetMultilistType(MultilistType newType)
  856. {
  857. RakAssert(_MultilistType==ML_VARIABLE_DURING_RUNTIME);
  858. switch (variableMultilistType)
  859. {
  860. case ML_UNORDERED_LIST:
  861. switch (newType)
  862. {
  863. case ML_UNORDERED_LIST:
  864. // No change
  865. break;
  866. case ML_STACK:
  867. // Same data format
  868. break;
  869. case ML_QUEUE:
  870. queueHead=0;
  871. queueTail=dataSize;
  872. break;
  873. case ML_ORDERED_LIST:
  874. Sort(false);
  875. break;
  876. }
  877. break;
  878. case ML_STACK:
  879. switch (newType)
  880. {
  881. case ML_UNORDERED_LIST:
  882. // Same data format
  883. break;
  884. case ML_STACK:
  885. // No change
  886. break;
  887. case ML_QUEUE:
  888. queueHead=0;
  889. queueTail=dataSize;
  890. break;
  891. case ML_ORDERED_LIST:
  892. Sort(false);
  893. break;
  894. }
  895. break;
  896. case ML_QUEUE:
  897. switch (newType)
  898. {
  899. case ML_UNORDERED_LIST:
  900. case ML_STACK:
  901. case ML_ORDERED_LIST:
  902. if (queueTail < queueHead)
  903. {
  904. // Realign data if wrapped
  905. ReallocToSize(dataSize, _FILE_AND_LINE_);
  906. }
  907. else
  908. {
  909. // Else can just copy starting at head
  910. _IndexType i;
  911. for (i=0; i < dataSize; i++)
  912. data[i]=operator[](i);
  913. }
  914. if (newType==ML_ORDERED_LIST)
  915. Sort(false);
  916. break;
  917. case ML_QUEUE:
  918. // No change
  919. break;
  920. }
  921. break;
  922. case ML_ORDERED_LIST:
  923. switch (newType)
  924. {
  925. case ML_UNORDERED_LIST:
  926. case ML_STACK:
  927. case ML_QUEUE:
  928. // Same data format
  929. // Tag as sorted
  930. if (ascendingSort)
  931. sortState=ML_SORTED_ASCENDING;
  932. else
  933. sortState=ML_SORTED_DESCENDING;
  934. if (newType==ML_QUEUE)
  935. {
  936. queueHead=0;
  937. queueTail=dataSize;
  938. }
  939. break;
  940. case ML_ORDERED_LIST:
  941. // No change
  942. break;
  943. }
  944. break;
  945. }
  946. variableMultilistType=newType;
  947. }
  948. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  949. void Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::FindIntersection(
  950. Multilist& source1,
  951. Multilist& source2,
  952. Multilist& intersection,
  953. Multilist& uniqueToSource1,
  954. Multilist& uniqueToSource2)
  955. {
  956. _IndexType index1=0, index2=0;
  957. source1.SetSortOrder(true);
  958. source2.SetSortOrder(true);
  959. source1.Sort(false);
  960. source2.Sort(false);
  961. intersection.Clear(true,_FILE_AND_LINE_);
  962. uniqueToSource1.Clear(true,_FILE_AND_LINE_);
  963. uniqueToSource2.Clear(true,_FILE_AND_LINE_);
  964. while (index1 < source1.GetSize() && index2 < source2.GetSize())
  965. {
  966. if (source1[index1]<source2[index2])
  967. {
  968. uniqueToSource1.Push(source1[index1],_FILE_AND_LINE_);
  969. index1++;
  970. }
  971. else if (source1[index1]==source2[index2])
  972. {
  973. intersection.Push(source1[index1],_FILE_AND_LINE_);
  974. index1++;
  975. index2++;
  976. }
  977. else
  978. {
  979. uniqueToSource2.Push(source2[index2],_FILE_AND_LINE_);
  980. index2++;
  981. }
  982. }
  983. while (index1 < source1.GetSize())
  984. {
  985. uniqueToSource1.Push(source1[index1],_FILE_AND_LINE_);
  986. index1++;
  987. }
  988. while (index2 < source2.GetSize())
  989. {
  990. uniqueToSource2.Push(source2[index2],_FILE_AND_LINE_);
  991. index2++;
  992. }
  993. }
  994. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  995. void Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::ReallocateIfNeeded(const char *file, unsigned int line)
  996. {
  997. if (dataSize<allocationSize)
  998. return;
  999. _IndexType newAllocationSize;
  1000. if (allocationSize<16)
  1001. newAllocationSize=32;
  1002. else if (allocationSize>65536)
  1003. newAllocationSize=allocationSize+65536;
  1004. else
  1005. {
  1006. newAllocationSize=allocationSize<<1; // * 2
  1007. // Protect against underflow
  1008. if (newAllocationSize < allocationSize)
  1009. newAllocationSize=allocationSize+65536;
  1010. }
  1011. ReallocToSize(newAllocationSize,file,line);
  1012. }
  1013. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  1014. void Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::DeallocateIfNeeded(const char *file, unsigned int line)
  1015. {
  1016. if (allocationSize<512)
  1017. return;
  1018. if (dataSize >= allocationSize/3 )
  1019. return;
  1020. if (dataSize <= preallocationSize )
  1021. return;
  1022. _IndexType newAllocationSize = dataSize<<1; // * 2
  1023. ReallocToSize(newAllocationSize,file,line);
  1024. }
  1025. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  1026. void Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::ReallocToSize(_IndexType newAllocationSize, const char *file, unsigned int line)
  1027. {
  1028. _DataType* newData = RakNet::OP_NEW_ARRAY<_DataType>(newAllocationSize,file,line);
  1029. _IndexType i;
  1030. for (i=0; i < dataSize; i++)
  1031. newData[i]=operator[](i);
  1032. if (dataSize>0)
  1033. {
  1034. RakNet::OP_DELETE_ARRAY(data,file,line);
  1035. if (GetMultilistType()==ML_QUEUE)
  1036. {
  1037. queueHead=0;
  1038. queueTail=dataSize;
  1039. }
  1040. }
  1041. data=newData;
  1042. allocationSize=newAllocationSize;
  1043. }
  1044. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  1045. void Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::ReverseListInternal(void)
  1046. {
  1047. _DataType temp;
  1048. _IndexType i;
  1049. for (i=0; i < dataSize/2; i++)
  1050. {
  1051. temp=operator[](i);
  1052. operator[](i)=operator[](dataSize-1-i);
  1053. operator[](dataSize-1-i)=temp;
  1054. }
  1055. }
  1056. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  1057. void Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::InsertInOrderedList(const _DataType &d, const _KeyType &key)
  1058. {
  1059. RakAssert(GetMultilistType()==ML_ORDERED_LIST);
  1060. bool objectExists;
  1061. _IndexType index;
  1062. index = GetIndexFromKeyInSortedList(key, &objectExists);
  1063. // if (objectExists)
  1064. // {
  1065. // Ordered list only allows unique insertions
  1066. // RakAssert("Duplicate insertion into ordered list" && false);
  1067. // return;
  1068. // }
  1069. if (index>=dataSize)
  1070. {
  1071. // insert at end
  1072. data[dataSize]=d;
  1073. dataSize++;
  1074. }
  1075. else
  1076. {
  1077. // insert at index
  1078. InsertShiftArrayRight(d,index);
  1079. }
  1080. }
  1081. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  1082. _IndexType Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::GetIndexFromKeyInSortedList(const _KeyType &key, bool *objectExists) const
  1083. {
  1084. RakAssert(IsSorted());
  1085. _IndexType index, upperBound, lowerBound;
  1086. if (dataSize==0)
  1087. {
  1088. *objectExists=false;
  1089. return 0;
  1090. }
  1091. upperBound=dataSize-1;
  1092. lowerBound=0;
  1093. index = dataSize/2;
  1094. #ifdef _MSC_VER
  1095. #pragma warning( disable : 4127 ) // warning C4127: conditional expression is constant
  1096. #endif
  1097. while (1)
  1098. {
  1099. if (MLKeyRef<_KeyType>(key) > operator[](index) )
  1100. {
  1101. if (ascendingSort)
  1102. lowerBound=index+1;
  1103. else
  1104. upperBound=index-1;
  1105. }
  1106. else if (MLKeyRef<_KeyType>(key) < operator[](index) )
  1107. {
  1108. if (ascendingSort)
  1109. upperBound=index-1;
  1110. else
  1111. lowerBound=index+1;
  1112. }
  1113. else
  1114. {
  1115. // ==
  1116. *objectExists=true;
  1117. return index;
  1118. }
  1119. index=lowerBound+(upperBound-lowerBound)/2;
  1120. if (lowerBound>upperBound || upperBound==(_IndexType)-1)
  1121. {
  1122. *objectExists=false;
  1123. return lowerBound; // No match
  1124. }
  1125. }
  1126. }
  1127. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  1128. void Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::InsertShiftArrayRight(const _DataType &d, _IndexType index)
  1129. {
  1130. RakAssert(_MultilistType!=ML_QUEUE);
  1131. // Move the elements in the list to make room
  1132. _IndexType i;
  1133. for ( i = dataSize; i != index; i-- )
  1134. data[ i ] = data[ i - 1 ];
  1135. // Insert the new item at the correct spot
  1136. data[ index ] = d;
  1137. ++dataSize;
  1138. }
  1139. template <const MultilistType _MultilistType, class _DataType, class _KeyType, class _IndexType>
  1140. void Multilist<_MultilistType, _DataType, _KeyType, _IndexType>::DeleteShiftArrayLeft( _IndexType index )
  1141. {
  1142. RakAssert(index < dataSize);
  1143. RakAssert(_MultilistType!=ML_QUEUE);
  1144. _IndexType i;
  1145. for ( i = index; i < dataSize-1; i++ )
  1146. data[i]=data[i+1];
  1147. }
  1148. };
  1149. /*
  1150. struct KeyAndValue
  1151. {
  1152. int key;
  1153. short value;
  1154. };
  1155. DEFINE_MULTILIST_PTR_TO_MEMBER_COMPARISONS(KeyAndValue,int,key)
  1156. void MultilistUnitTest(void)
  1157. {
  1158. DataStructures::DefaultIndexType oldSize;
  1159. DataStructures::Multilist<ML_UNORDERED_LIST, int> ml1;
  1160. ml1.Reallocate(64);
  1161. RakAssert(ml1.IsEmpty());
  1162. ml1.Push(53);
  1163. RakAssert(ml1.Peek()==53);
  1164. RakAssert(ml1.IsEmpty()==false);
  1165. RakAssert(ml1.Pop()==53);
  1166. RakAssert(ml1.IsEmpty()==true);
  1167. for (int i=0; i < 512; i++)
  1168. ml1.Push(i);
  1169. RakAssert(ml1.GetIndexOf(200)==200);
  1170. RakAssert(ml1.PeekOpposite()==0);
  1171. RakAssert(ml1.PopOpposite()==0);
  1172. RakAssert(ml1.PeekOpposite()==1);
  1173. RakAssert(ml1.Peek()==511);
  1174. ml1.ReverseList();
  1175. for (int i=0; i < 511; i++)
  1176. RakAssert(ml1[i]==511-i);
  1177. RakAssert(ml1.PeekOpposite()==511);
  1178. RakAssert(ml1.Peek()==1);
  1179. oldSize = ml1.GetSize();
  1180. ml1.RemoveAtIndex(0);
  1181. RakAssert(ml1.GetSize()==oldSize-1);
  1182. RakAssert(ml1.PeekOpposite()==1);
  1183. ml1.Clear(_FILE_AND_LINE_);
  1184. RakAssert(ml1.IsEmpty()==true);
  1185. ml1.Sort(true);
  1186. ml1.Clear(_FILE_AND_LINE_);
  1187. ml1.Push(100);
  1188. ml1.Sort(true);
  1189. ml1.Clear(_FILE_AND_LINE_);
  1190. ml1.Push(50);
  1191. ml1.Push(100);
  1192. ml1.Sort(true);
  1193. ml1.Clear(_FILE_AND_LINE_);
  1194. ml1.Push(100);
  1195. ml1.Push(50);
  1196. ml1.Sort(true);
  1197. ml1.Clear(_FILE_AND_LINE_);
  1198. ml1.Push(100);
  1199. ml1.Push(50);
  1200. ml1.Push(150);
  1201. ml1.Push(25);
  1202. ml1.Push(175);
  1203. ml1.Sort(true);
  1204. RakAssert(ml1[0]==25);
  1205. RakAssert(ml1[1]==50);
  1206. RakAssert(ml1[2]==100);
  1207. RakAssert(ml1[3]==150);
  1208. RakAssert(ml1[4]==175);
  1209. RakAssert(ml1.GetIndexOf(25)==0);
  1210. RakAssert(ml1.GetIndexOf(50)==1);
  1211. RakAssert(ml1.GetIndexOf(100)==2);
  1212. RakAssert(ml1.GetIndexOf(150)==3);
  1213. RakAssert(ml1.GetIndexOf(175)==4);
  1214. ml1.Clear(_FILE_AND_LINE_);
  1215. ml1.Push(1);
  1216. ml1.Push(2);
  1217. ml1.Push(3);
  1218. ml1.Push(4);
  1219. ml1.Push(5);
  1220. ml1.Sort(true);
  1221. RakAssert(ml1[0]==1);
  1222. RakAssert(ml1[1]==2);
  1223. RakAssert(ml1[2]==3);
  1224. RakAssert(ml1[3]==4);
  1225. RakAssert(ml1[4]==5);
  1226. RakAssert(ml1.GetIndexOf(1)==0);
  1227. RakAssert(ml1.GetIndexOf(2)==1);
  1228. RakAssert(ml1.GetIndexOf(3)==2);
  1229. RakAssert(ml1.GetIndexOf(4)==3);
  1230. RakAssert(ml1.GetIndexOf(5)==4);
  1231. ml1.Clear(_FILE_AND_LINE_);
  1232. ml1.Push(5);
  1233. ml1.Push(4);
  1234. ml1.Push(3);
  1235. ml1.Push(2);
  1236. ml1.Push(1);
  1237. ml1.Sort(true);
  1238. RakAssert(ml1[0]==1);
  1239. RakAssert(ml1[1]==2);
  1240. RakAssert(ml1[2]==3);
  1241. RakAssert(ml1[3]==4);
  1242. RakAssert(ml1[4]==5);
  1243. RakAssert(ml1.GetIndexOf(1)==0);
  1244. RakAssert(ml1.GetIndexOf(2)==1);
  1245. RakAssert(ml1.GetIndexOf(3)==2);
  1246. RakAssert(ml1.GetIndexOf(4)==3);
  1247. RakAssert(ml1.GetIndexOf(5)==4);
  1248. ml1.Sort(true);
  1249. RakAssert(ml1[0]==1);
  1250. RakAssert(ml1[1]==2);
  1251. RakAssert(ml1[2]==3);
  1252. RakAssert(ml1[3]==4);
  1253. RakAssert(ml1[4]==5);
  1254. RakAssert(ml1.GetIndexOf(1)==0);
  1255. RakAssert(ml1.GetIndexOf(2)==1);
  1256. RakAssert(ml1.GetIndexOf(3)==2);
  1257. RakAssert(ml1.GetIndexOf(4)==3);
  1258. RakAssert(ml1.GetIndexOf(5)==4);
  1259. ml1.Clear(_FILE_AND_LINE_);
  1260. DataStructures::Multilist<ML_STACK, int> ml2;
  1261. ml2.Reallocate(64);
  1262. RakAssert(ml2.IsEmpty());
  1263. ml2.Push(53);
  1264. RakAssert(ml2.Peek()==53);
  1265. RakAssert(ml2.IsEmpty()==false);
  1266. RakAssert(ml2.Pop()==53);
  1267. RakAssert(ml2.IsEmpty()==true);
  1268. for (int i=0; i < 512; i++)
  1269. ml2.Push(i);
  1270. RakAssert(ml2.GetIndexOf(200)==200);
  1271. RakAssert(ml2.PeekOpposite()==0);
  1272. RakAssert(ml2.PopOpposite()==0);
  1273. RakAssert(ml2.PeekOpposite()==1);
  1274. RakAssert(ml2.Peek()==511);
  1275. ml2.ReverseList();
  1276. for (int i=0; i < 511; i++)
  1277. RakAssert(ml2[i]==511-i);
  1278. RakAssert(ml2.PeekOpposite()==511);
  1279. RakAssert(ml2.Peek()==1);
  1280. oldSize = ml2.GetSize();
  1281. ml2.RemoveAtIndex(0);
  1282. RakAssert(ml2.GetSize()==oldSize-1);
  1283. RakAssert(ml2.Peek()==1);
  1284. RakAssert(ml2.PeekOpposite()==510);
  1285. ml2.Clear(_FILE_AND_LINE_);
  1286. RakAssert(ml2.IsEmpty()==true);
  1287. DataStructures::Multilist<ML_QUEUE, int> ml3;
  1288. RakAssert(ml3.IsEmpty());
  1289. ml3.Push(53);
  1290. RakAssert(ml3.Peek()==53);
  1291. RakAssert(ml3.IsEmpty()==false);
  1292. RakAssert(ml3.Pop()==53);
  1293. RakAssert(ml3.IsEmpty()==true);
  1294. for (int i=0; i < 512; i++)
  1295. ml3.Push(i);
  1296. RakAssert(ml3.GetIndexOf(200)==200);
  1297. RakAssert(ml3.PeekOpposite()==511);
  1298. RakAssert(ml3.PopOpposite()==511);
  1299. RakAssert(ml3.PeekOpposite()==510);
  1300. RakAssert(ml3.Peek()==0);
  1301. ml3.ReverseList();
  1302. for (int i=0; i < 511; i++)
  1303. RakAssert(ml3[i]==511-1-i);
  1304. RakAssert(ml3.PeekOpposite()==0);
  1305. RakAssert(ml3.Peek()==510);
  1306. oldSize = ml3.GetSize();
  1307. ml3.RemoveAtIndex(0);
  1308. RakAssert(ml3.GetSize()==oldSize-1);
  1309. RakAssert(ml3.Peek()==509);
  1310. RakAssert(ml3.PeekOpposite()==0);
  1311. ml3.Clear(_FILE_AND_LINE_);
  1312. RakAssert(ml3.IsEmpty()==true);
  1313. ml3.PushOpposite(100);
  1314. ml3.PushOpposite(50);
  1315. ml3.PushOpposite(150);
  1316. ml3.PushOpposite(25);
  1317. ml3.PushOpposite(175);
  1318. ml3.Sort(true);
  1319. RakAssert(ml3[0]==25);
  1320. RakAssert(ml3[1]==50);
  1321. RakAssert(ml3[2]==100);
  1322. RakAssert(ml3[3]==150);
  1323. RakAssert(ml3[4]==175);
  1324. RakAssert(ml3.GetIndexOf(25)==0);
  1325. RakAssert(ml3.GetIndexOf(50)==1);
  1326. RakAssert(ml3.GetIndexOf(100)==2);
  1327. RakAssert(ml3.GetIndexOf(150)==3);
  1328. RakAssert(ml3.GetIndexOf(175)==4);
  1329. ml3.Clear(_FILE_AND_LINE_);
  1330. ml3.PushOpposite(1);
  1331. ml3.PushOpposite(2);
  1332. ml3.PushOpposite(3);
  1333. ml3.PushOpposite(4);
  1334. ml3.PushOpposite(5);
  1335. ml3.Sort(true);
  1336. RakAssert(ml3[0]==1);
  1337. RakAssert(ml3[1]==2);
  1338. RakAssert(ml3[2]==3);
  1339. RakAssert(ml3[3]==4);
  1340. RakAssert(ml3[4]==5);
  1341. RakAssert(ml3.GetIndexOf(1)==0);
  1342. RakAssert(ml3.GetIndexOf(2)==1);
  1343. RakAssert(ml3.GetIndexOf(3)==2);
  1344. RakAssert(ml3.GetIndexOf(4)==3);
  1345. RakAssert(ml3.GetIndexOf(5)==4);
  1346. ml3.Clear(_FILE_AND_LINE_);
  1347. ml3.PushOpposite(5);
  1348. ml3.PushOpposite(4);
  1349. ml3.PushOpposite(3);
  1350. ml3.PushOpposite(2);
  1351. ml3.PushOpposite(1);
  1352. ml3.Sort(true);
  1353. RakAssert(ml3[0]==1);
  1354. RakAssert(ml3[1]==2);
  1355. RakAssert(ml3[2]==3);
  1356. RakAssert(ml3[3]==4);
  1357. RakAssert(ml3[4]==5);
  1358. RakAssert(ml3.GetIndexOf(1)==0);
  1359. RakAssert(ml3.GetIndexOf(2)==1);
  1360. RakAssert(ml3.GetIndexOf(3)==2);
  1361. RakAssert(ml3.GetIndexOf(4)==3);
  1362. RakAssert(ml3.GetIndexOf(5)==4);
  1363. ml3.Sort(true);
  1364. RakAssert(ml3[0]==1);
  1365. RakAssert(ml3[1]==2);
  1366. RakAssert(ml3[2]==3);
  1367. RakAssert(ml3[3]==4);
  1368. RakAssert(ml3[4]==5);
  1369. RakAssert(ml3.GetIndexOf(1)==0);
  1370. RakAssert(ml3.GetIndexOf(2)==1);
  1371. RakAssert(ml3.GetIndexOf(3)==2);
  1372. RakAssert(ml3.GetIndexOf(4)==3);
  1373. RakAssert(ml3.GetIndexOf(5)==4);
  1374. ml3.SetSortOrder(false);
  1375. ml3.Sort(false);
  1376. RakAssert(ml3[0]==5);
  1377. RakAssert(ml3[1]==4);
  1378. RakAssert(ml3[2]==3);
  1379. RakAssert(ml3[3]==2);
  1380. RakAssert(ml3[4]==1);
  1381. RakAssert(ml3.GetIndexOf(1)==4);
  1382. RakAssert(ml3.GetIndexOf(2)==3);
  1383. RakAssert(ml3.GetIndexOf(3)==2);
  1384. RakAssert(ml3.GetIndexOf(4)==1);
  1385. RakAssert(ml3.GetIndexOf(5)==0);
  1386. ml3.Clear(_FILE_AND_LINE_);
  1387. DataStructures::Multilist<ML_ORDERED_LIST, int> ml4;
  1388. ml4.Reallocate(64);
  1389. RakAssert(ml4.IsEmpty());
  1390. ml4.Push(53);
  1391. RakAssert(ml4.Peek()==53);
  1392. RakAssert(ml4.IsEmpty()==false);
  1393. RakAssert(ml4.Pop()==53);
  1394. RakAssert(ml4.IsEmpty()==true);
  1395. for (int i=0; i < 512; i++)
  1396. ml4.Push(i);
  1397. RakAssert(ml4.GetIndexOf(200)==200);
  1398. RakAssert(ml4.PeekOpposite()==0);
  1399. RakAssert(ml4.PopOpposite()==0);
  1400. RakAssert(ml4.PeekOpposite()==1);
  1401. RakAssert(ml4.Peek()==511);
  1402. ml4.ReverseList();
  1403. for (int i=0; i < 511; i++)
  1404. RakAssert(ml4[i]==511-i);
  1405. RakAssert(ml4.PeekOpposite()==511);
  1406. RakAssert(ml4.Peek()==1);
  1407. oldSize = ml4.GetSize();
  1408. ml4.RemoveAtIndex(0);
  1409. RakAssert(ml4.GetSize()==oldSize-1);
  1410. RakAssert(ml4.Peek()==1);
  1411. RakAssert(ml4.PeekOpposite()==510);
  1412. ml4.Clear(_FILE_AND_LINE_);
  1413. RakAssert(ml4.IsEmpty()==true);
  1414. DataStructures::Multilist<ML_ORDERED_LIST, KeyAndValue*, int> ml5;
  1415. for (int i=0; i < 16; i++)
  1416. {
  1417. KeyAndValue *kav = new KeyAndValue;
  1418. kav->key=i;
  1419. kav->value=i+100;
  1420. ml5.Push(kav,kav->key);
  1421. }
  1422. RakAssert(ml5.GetIndexOf(0)==0);
  1423. RakAssert(ml5.GetIndexOf(5)==5);
  1424. RakAssert(ml5.GetIndexOf(15)==15);
  1425. RakAssert(ml5.GetIndexOf(16)==-1);
  1426. ml5.RemoveAtKey(0,true);
  1427. RakAssert(ml5.GetIndexOf(1)==0);
  1428. KeyAndValue *iPtr = ml5.GetPtr(5);
  1429. RakAssert(iPtr);
  1430. RakAssert(iPtr->value=105);
  1431. iPtr = ml5.GetPtr(1234);
  1432. RakAssert(iPtr==0);
  1433. ml5.ForEach(DataStructures::DeletePtr<KeyAndValue*>);
  1434. DataStructures::Multilist<ML_VARIABLE_DURING_RUNTIME, int> ml6;
  1435. ml6.Push(2);
  1436. ml6.Push(1);
  1437. ml6.Push(6);
  1438. ml6.Push(3);
  1439. RakAssert(ml6.Peek()==3);
  1440. ml6.SetMultilistType(ML_STACK);
  1441. RakAssert(ml6.Peek()==3);
  1442. ml6.SetMultilistType(ML_QUEUE);
  1443. RakAssert(ml6.Peek()==2);
  1444. ml6.SetMultilistType(ML_ORDERED_LIST);
  1445. RakAssert(ml6.Peek()=6);
  1446. ml6.SetMultilistType(ML_STACK);
  1447. RakAssert(ml6.Peek()==6);
  1448. ml6.SetMultilistType(ML_QUEUE);
  1449. RakAssert(ml6.Peek()==1);
  1450. }
  1451. #ifdef _MSC_VER
  1452. #pragma warning( pop )
  1453. #endif
  1454. */
  1455. #endif
粤ICP备19079148号