PageRenderTime 43ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llcommon/llassoclist.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 296 lines | 201 code | 26 blank | 69 comment | 29 complexity | d22df65b52080d57c1c4ad8db6862981 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llassoclist.h
  3. * @brief LLAssocList class header file
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #ifndef LL_LLASSOCLIST_H
  27. #define LL_LLASSOCLIST_H
  28. //------------------------------------------------------------------------
  29. // LLAssocList is an associative list container class.
  30. //
  31. // The implementation is a single linked list.
  32. // Both index and value objects are stored by value (not reference).
  33. // If pointer values are specified for index and/or value, this
  34. // container does NOT assume ownership of the referenced objects,
  35. // and does NOT delete() them on removal or destruction of the container.
  36. //
  37. // Note that operations are generally not optimized, and may of them
  38. // are O(n) complexity.
  39. //------------------------------------------------------------------------
  40. #include <iostream>
  41. template<class INDEX_TYPE, class VALUE_TYPE>
  42. class LLAssocList
  43. {
  44. private:
  45. // internal list node type
  46. class Node
  47. {
  48. public:
  49. Node(const INDEX_TYPE &index, const VALUE_TYPE &value, Node *next)
  50. {
  51. mIndex = index;
  52. mValue = value;
  53. mNext = next;
  54. }
  55. ~Node() { }
  56. INDEX_TYPE mIndex;
  57. VALUE_TYPE mValue;
  58. Node *mNext;
  59. };
  60. // head of the linked list
  61. Node *mHead;
  62. public:
  63. // Constructor
  64. LLAssocList()
  65. {
  66. mHead = NULL;
  67. }
  68. // Destructor
  69. ~LLAssocList()
  70. {
  71. removeAll();
  72. }
  73. // Returns TRUE if list is empty.
  74. BOOL isEmpty()
  75. {
  76. return (mHead == NULL);
  77. }
  78. // Returns the number of items in the list.
  79. U32 length()
  80. {
  81. U32 count = 0;
  82. for ( Node *node = mHead;
  83. node;
  84. node = node->mNext )
  85. {
  86. count++;
  87. }
  88. return count;
  89. }
  90. // Removes item with the specified index.
  91. BOOL remove( const INDEX_TYPE &index )
  92. {
  93. if (!mHead)
  94. return FALSE;
  95. if (mHead->mIndex == index)
  96. {
  97. Node *node = mHead;
  98. mHead = mHead->mNext;
  99. delete node;
  100. return TRUE;
  101. }
  102. for ( Node *prev = mHead;
  103. prev->mNext;
  104. prev = prev->mNext )
  105. {
  106. if (prev->mNext->mIndex == index)
  107. {
  108. Node *node = prev->mNext;
  109. prev->mNext = prev->mNext->mNext;
  110. delete node;
  111. return TRUE;
  112. }
  113. }
  114. return FALSE;
  115. }
  116. // Removes all items from the list.
  117. void removeAll()
  118. {
  119. while ( mHead )
  120. {
  121. Node *node = mHead;
  122. mHead = mHead->mNext;
  123. delete node;
  124. }
  125. }
  126. // Adds a new item to the head of the list,
  127. // removing any existing item with same index.
  128. void addToHead( const INDEX_TYPE &index, const VALUE_TYPE &value )
  129. {
  130. remove(index);
  131. Node *node = new Node(index, value, mHead);
  132. mHead = node;
  133. }
  134. // Adds a new item to the end of the list,
  135. // removing any existing item with the same index.
  136. void addToTail( const INDEX_TYPE &index, const VALUE_TYPE &value )
  137. {
  138. remove(index);
  139. Node *node = new Node(index, value, NULL);
  140. if (!mHead)
  141. {
  142. mHead = node;
  143. return;
  144. }
  145. for ( Node *prev=mHead;
  146. prev;
  147. prev=prev->mNext )
  148. {
  149. if (!prev->mNext)
  150. {
  151. prev->mNext=node;
  152. return;
  153. }
  154. }
  155. }
  156. // Sets the value of a specified index.
  157. // If index does not exist, a new value will be added only if
  158. // 'addIfNotFound' is set to TRUE.
  159. // Returns TRUE if successful.
  160. BOOL setValue( const INDEX_TYPE &index, const VALUE_TYPE &value, BOOL addIfNotFound=FALSE )
  161. {
  162. VALUE_TYPE *valueP = getValue(index);
  163. if (valueP)
  164. {
  165. *valueP = value;
  166. return TRUE;
  167. }
  168. if (!addIfNotFound)
  169. return FALSE;
  170. addToTail(index, value);
  171. return TRUE;
  172. }
  173. // Sets the ith value in the list.
  174. // A new value will NOT be addded, if the ith value does not exist.
  175. // Returns TRUE if successful.
  176. BOOL setValueAt( U32 i, const VALUE_TYPE &value )
  177. {
  178. VALUE_TYPE *valueP = getValueAt(i);
  179. if (valueP)
  180. {
  181. *valueP = value;
  182. return TRUE;
  183. }
  184. return FALSE;
  185. }
  186. // Returns a pointer to the value for the specified index,
  187. // or NULL if no item found.
  188. VALUE_TYPE *getValue( const INDEX_TYPE &index )
  189. {
  190. for ( Node *node = mHead;
  191. node;
  192. node = node->mNext )
  193. {
  194. if (node->mIndex == index)
  195. return &node->mValue;
  196. }
  197. return NULL;
  198. }
  199. // Returns a pointer to the ith value in the list, or
  200. // NULL if i is not valid.
  201. VALUE_TYPE *getValueAt( U32 i )
  202. {
  203. U32 count = 0;
  204. for ( Node *node = mHead;
  205. node;
  206. node = node->mNext )
  207. {
  208. if (count == i)
  209. return &node->mValue;
  210. count++;
  211. }
  212. return NULL;
  213. }
  214. // Returns a pointer to the index for the specified index,
  215. // or NULL if no item found.
  216. INDEX_TYPE *getIndex( const INDEX_TYPE &index )
  217. {
  218. for ( Node *node = mHead;
  219. node;
  220. node = node->mNext )
  221. {
  222. if (node->mIndex == index)
  223. return &node->mIndex;
  224. }
  225. return NULL;
  226. }
  227. // Returns a pointer to the ith index in the list, or
  228. // NULL if i is not valid.
  229. INDEX_TYPE *getIndexAt( U32 i )
  230. {
  231. U32 count = 0;
  232. for ( Node *node = mHead;
  233. node;
  234. node = node->mNext )
  235. {
  236. if (count == i)
  237. return &node->mIndex;
  238. count++;
  239. }
  240. return NULL;
  241. }
  242. // Returns a pointer to the value for the specified index,
  243. // or NULL if no item found.
  244. VALUE_TYPE *operator[](const INDEX_TYPE &index)
  245. {
  246. return getValue(index);
  247. }
  248. // Returns a pointer to the ith value in the list, or
  249. // NULL if i is not valid.
  250. VALUE_TYPE *operator[](U32 i)
  251. {
  252. return getValueAt(i);
  253. }
  254. // Prints the list contents to the specified stream.
  255. friend std::ostream &operator<<( std::ostream &os, LLAssocList &map )
  256. {
  257. os << "{";
  258. for ( Node *node = map.mHead;
  259. node;
  260. node = node->mNext )
  261. {
  262. os << "<" << node->mIndex << ", " << node->mValue << ">";
  263. if (node->mNext)
  264. os << ", ";
  265. }
  266. os << "}";
  267. return os;
  268. }
  269. };
  270. #endif // LL_LLASSOCLIST_H