summaryrefslogtreecommitdiff
path: root/indra/llcommon/llassoclist.h
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon/llassoclist.h')
-rw-r--r--indra/llcommon/llassoclist.h278
1 files changed, 278 insertions, 0 deletions
diff --git a/indra/llcommon/llassoclist.h b/indra/llcommon/llassoclist.h
new file mode 100644
index 0000000000..d90a26dc8a
--- /dev/null
+++ b/indra/llcommon/llassoclist.h
@@ -0,0 +1,278 @@
+/**
+ * @file llassoclist.h
+ * @brief LLAssocList class header file
+ *
+ * Copyright (c) 2001-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#ifndef LL_LLASSOCLIST_H
+#define LL_LLASSOCLIST_H
+
+//------------------------------------------------------------------------
+// LLAssocList is an associative list container class.
+//
+// The implementation is a single linked list.
+// Both index and value objects are stored by value (not reference).
+// If pointer values are specified for index and/or value, this
+// container does NOT assume ownership of the referenced objects,
+// and does NOT delete() them on removal or destruction of the container.
+//
+// Note that operations are generally not optimized, and may of them
+// are O(n) complexity.
+//------------------------------------------------------------------------
+
+#include <iostream>
+
+template<class INDEX_TYPE, class VALUE_TYPE>
+class LLAssocList
+{
+private:
+ // internal list node type
+ class Node
+ {
+ public:
+ Node(const INDEX_TYPE &index, const VALUE_TYPE &value, Node *next)
+ {
+ mIndex = index;
+ mValue = value;
+ mNext = next;
+ }
+ ~Node() { }
+ INDEX_TYPE mIndex;
+ VALUE_TYPE mValue;
+ Node *mNext;
+ };
+
+ // head of the linked list
+ Node *mHead;
+
+public:
+ // Constructor
+ LLAssocList()
+ {
+ mHead = NULL;
+ }
+
+ // Destructor
+ ~LLAssocList()
+ {
+ removeAll();
+ }
+
+ // Returns TRUE if list is empty.
+ BOOL isEmpty()
+ {
+ return (mHead == NULL);
+ }
+
+ // Returns the number of items in the list.
+ U32 length()
+ {
+ U32 count = 0;
+ for ( Node *node = mHead;
+ node;
+ node = node->mNext )
+ {
+ count++;
+ }
+ return count;
+ }
+
+ // Removes item with the specified index.
+ BOOL remove( const INDEX_TYPE &index )
+ {
+ if (!mHead)
+ return FALSE;
+
+ if (mHead->mIndex == index)
+ {
+ Node *node = mHead;
+ mHead = mHead->mNext;
+ delete node;
+ return TRUE;
+ }
+
+ for ( Node *prev = mHead;
+ prev->mNext;
+ prev = prev->mNext )
+ {
+ if (prev->mNext->mIndex == index)
+ {
+ Node *node = prev->mNext;
+ prev->mNext = prev->mNext->mNext;
+ delete node;
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
+
+ // Removes all items from the list.
+ void removeAll()
+ {
+ while ( mHead )
+ {
+ Node *node = mHead;
+ mHead = mHead->mNext;
+ delete node;
+ }
+ }
+
+ // Adds a new item to the head of the list,
+ // removing any existing item with same index.
+ void addToHead( const INDEX_TYPE &index, const VALUE_TYPE &value )
+ {
+ remove(index);
+ Node *node = new Node(index, value, mHead);
+ mHead = node;
+ }
+
+ // Adds a new item to the end of the list,
+ // removing any existing item with the same index.
+ void addToTail( const INDEX_TYPE &index, const VALUE_TYPE &value )
+ {
+ remove(index);
+ Node *node = new Node(index, value, NULL);
+ if (!mHead)
+ {
+ mHead = node;
+ return;
+ }
+ for ( Node *prev=mHead;
+ prev;
+ prev=prev->mNext )
+ {
+ if (!prev->mNext)
+ {
+ prev->mNext=node;
+ return;
+ }
+ }
+ }
+
+ // Sets the value of a specified index.
+ // If index does not exist, a new value will be added only if
+ // 'addIfNotFound' is set to TRUE.
+ // Returns TRUE if successful.
+ BOOL setValue( const INDEX_TYPE &index, const VALUE_TYPE &value, BOOL addIfNotFound=FALSE )
+ {
+ VALUE_TYPE *valueP = getValue(index);
+ if (valueP)
+ {
+ *valueP = value;
+ return TRUE;
+ }
+ if (!addIfNotFound)
+ return FALSE;
+ addToTail(index, value);
+ return TRUE;
+ }
+
+ // Sets the ith value in the list.
+ // A new value will NOT be addded, if the ith value does not exist.
+ // Returns TRUE if successful.
+ BOOL setValueAt( U32 i, const VALUE_TYPE &value )
+ {
+ VALUE_TYPE *valueP = getValueAt(i);
+ if (valueP)
+ {
+ *valueP = value;
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ // Returns a pointer to the value for the specified index,
+ // or NULL if no item found.
+ VALUE_TYPE *getValue( const INDEX_TYPE &index )
+ {
+ for ( Node *node = mHead;
+ node;
+ node = node->mNext )
+ {
+ if (node->mIndex == index)
+ return &node->mValue;
+ }
+ return NULL;
+ }
+
+ // Returns a pointer to the ith value in the list, or
+ // NULL if i is not valid.
+ VALUE_TYPE *getValueAt( U32 i )
+ {
+ U32 count = 0;
+ for ( Node *node = mHead;
+ node;
+ node = node->mNext )
+ {
+ if (count == i)
+ return &node->mValue;
+ count++;
+ }
+ return NULL;
+ }
+
+ // Returns a pointer to the index for the specified index,
+ // or NULL if no item found.
+ INDEX_TYPE *getIndex( const INDEX_TYPE &index )
+ {
+ for ( Node *node = mHead;
+ node;
+ node = node->mNext )
+ {
+ if (node->mIndex == index)
+ return &node->mIndex;
+ }
+ return NULL;
+ }
+
+ // Returns a pointer to the ith index in the list, or
+ // NULL if i is not valid.
+ INDEX_TYPE *getIndexAt( U32 i )
+ {
+ U32 count = 0;
+ for ( Node *node = mHead;
+ node;
+ node = node->mNext )
+ {
+ if (count == i)
+ return &node->mIndex;
+ count++;
+ }
+ return NULL;
+ }
+
+ // Returns a pointer to the value for the specified index,
+ // or NULL if no item found.
+ VALUE_TYPE *operator[](const INDEX_TYPE &index)
+ {
+ return getValue(index);
+ }
+
+ // Returns a pointer to the ith value in the list, or
+ // NULL if i is not valid.
+ VALUE_TYPE *operator[](U32 i)
+ {
+ return getValueAt(i);
+ }
+
+ // Prints the list contents to the specified stream.
+ friend std::ostream &operator<<( std::ostream &os, LLAssocList &map )
+ {
+ os << "{";
+ for ( Node *node = map.mHead;
+ node;
+ node = node->mNext )
+ {
+ os << "<" << node->mIndex << ", " << node->mValue << ">";
+ if (node->mNext)
+ os << ", ";
+ }
+ os << "}";
+
+ return os;
+ }
+};
+
+#endif // LL_LLASSOCLIST_H