PageRenderTime 48ms CodeModel.GetById 32ms app.highlight 13ms 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
  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
 27#ifndef LL_LLASSOCLIST_H
 28#define LL_LLASSOCLIST_H
 29
 30//------------------------------------------------------------------------
 31// LLAssocList is an associative list container class.
 32//
 33// The implementation is a single linked list.
 34// Both index and value objects are stored by value (not reference).
 35// If pointer values are specified for index and/or value, this
 36// container does NOT assume ownership of the referenced objects,
 37// and does NOT delete() them on removal or destruction of the container.
 38//
 39// Note that operations are generally not optimized, and may of them
 40// are O(n) complexity.
 41//------------------------------------------------------------------------
 42
 43#include <iostream>
 44
 45template<class INDEX_TYPE, class VALUE_TYPE>
 46class LLAssocList
 47{
 48private:
 49	// internal list node type
 50	class Node
 51	{
 52	public:
 53		Node(const INDEX_TYPE &index, const VALUE_TYPE &value, Node *next)
 54		{
 55			mIndex = index;
 56			mValue = value;
 57			mNext = next;
 58		}
 59		~Node() { }
 60		INDEX_TYPE	mIndex;
 61		VALUE_TYPE	mValue;
 62		Node		*mNext;
 63	};
 64
 65	// head of the linked list
 66	Node *mHead;
 67
 68public:
 69	// Constructor
 70	LLAssocList()
 71	{
 72		mHead = NULL;
 73	}
 74
 75	// Destructor
 76	~LLAssocList()
 77	{
 78		removeAll();
 79	}
 80
 81	// Returns TRUE if list is empty.
 82	BOOL isEmpty()
 83	{
 84		return (mHead == NULL);
 85	}
 86
 87	// Returns the number of items in the list.
 88	U32 length()
 89	{
 90		U32 count = 0;
 91		for (	Node *node = mHead;
 92				node;
 93				node = node->mNext )
 94		{
 95			count++;
 96		}
 97		return count;
 98	}
 99
100	// Removes item with the specified index.
101	BOOL remove( const INDEX_TYPE &index )
102	{
103		if (!mHead)
104			return FALSE;
105
106		if (mHead->mIndex == index)
107		{
108			Node *node = mHead;
109			mHead = mHead->mNext;
110			delete node;
111			return TRUE;
112		}
113
114		for (	Node *prev = mHead;
115				prev->mNext;
116				prev = prev->mNext )
117		{
118			if (prev->mNext->mIndex == index)
119			{
120				Node *node = prev->mNext;
121				prev->mNext = prev->mNext->mNext;
122				delete node;
123				return TRUE;
124			}
125		}
126		return FALSE;
127	}
128
129	// Removes all items from the list.
130	void removeAll()
131	{
132		while ( mHead )
133		{
134			Node *node = mHead;
135			mHead = mHead->mNext;
136			delete node;
137		}
138	}
139
140	// Adds a new item to the head of the list,
141	// removing any existing item with same index.
142	void addToHead( const INDEX_TYPE &index, const VALUE_TYPE &value )
143	{
144		remove(index);
145		Node *node = new Node(index, value, mHead);
146		mHead = node;
147	}
148
149	// Adds a new item to the end of the list,
150	// removing any existing item with the same index.
151	void addToTail( const INDEX_TYPE &index, const VALUE_TYPE &value )
152	{
153		remove(index);
154		Node *node = new Node(index, value, NULL);
155		if (!mHead)
156		{
157			mHead = node;
158			return;
159		}
160		for (	Node *prev=mHead;
161				prev;
162				prev=prev->mNext )
163		{
164			if (!prev->mNext)
165			{
166				prev->mNext=node;
167				return;
168			}
169		}
170	}
171
172	// Sets the value of a specified index.
173	// If index does not exist, a new value will be added only if
174	// 'addIfNotFound' is set to TRUE.
175	// Returns TRUE if successful.
176	BOOL setValue( const INDEX_TYPE &index, const VALUE_TYPE &value, BOOL addIfNotFound=FALSE )
177	{
178		VALUE_TYPE *valueP = getValue(index);
179		if (valueP)
180		{
181			*valueP = value;
182			return TRUE;
183		}
184		if (!addIfNotFound)
185			return FALSE;
186		addToTail(index, value);
187		return TRUE;
188	}
189
190	// Sets the ith value in the list.
191	// A new value will NOT be addded, if the ith value does not exist.
192	// Returns TRUE if successful.
193	BOOL setValueAt( U32 i, const VALUE_TYPE &value )
194	{
195		VALUE_TYPE *valueP = getValueAt(i);
196		if (valueP)
197		{
198			*valueP = value;
199			return TRUE;
200		}
201		return FALSE;
202	}
203
204	// Returns a pointer to the value for the specified index,
205	// or NULL if no item found.
206	VALUE_TYPE *getValue( const INDEX_TYPE &index )
207	{
208		for (	Node *node = mHead;
209				node;
210				node = node->mNext )
211		{
212			if (node->mIndex == index)
213				return &node->mValue;
214		}
215		return NULL;
216	}
217
218	// Returns a pointer to the ith value in the list, or
219	// NULL if i is not valid.
220	VALUE_TYPE *getValueAt( U32 i )
221	{
222		U32 count = 0;
223		for (	Node *node = mHead;
224				node;
225				node = node->mNext )
226		{
227			if (count == i)
228				return &node->mValue;
229			count++;
230		}
231		return NULL;
232	}
233
234	// Returns a pointer to the index for the specified index,
235	// or NULL if no item found.
236	INDEX_TYPE *getIndex( const INDEX_TYPE &index )
237	{
238		for (	Node *node = mHead;
239				node;
240				node = node->mNext )
241		{
242			if (node->mIndex == index)
243				return &node->mIndex;
244		}
245		return NULL;
246	}
247
248	// Returns a pointer to the ith index in the list, or
249	// NULL if i is not valid.
250	INDEX_TYPE *getIndexAt( U32 i )
251	{
252		U32 count = 0;
253		for (	Node *node = mHead;
254				node;
255				node = node->mNext )
256		{
257			if (count == i)
258				return &node->mIndex;
259			count++;
260		}
261		return NULL;
262	}
263
264	// Returns a pointer to the value for the specified index,
265	// or NULL if no item found.
266	VALUE_TYPE *operator[](const INDEX_TYPE &index)
267	{
268		return getValue(index);
269	}
270
271	// Returns a pointer to the ith value in the list, or
272	// NULL if i is not valid.
273	VALUE_TYPE *operator[](U32 i)
274	{
275		return getValueAt(i);
276	}
277
278	// Prints the list contents to the specified stream.
279	friend std::ostream &operator<<( std::ostream &os, LLAssocList &map )
280	{
281		os << "{";
282		for (	Node *node = map.mHead;
283				node;
284				node = node->mNext )
285		{
286			os << "<" << node->mIndex << ", " << node->mValue << ">";
287			if (node->mNext)
288				os << ", ";
289		}
290		os << "}";
291
292		return os;
293	}
294};
295
296#endif // LL_LLASSOCLIST_H