diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 6aa14e8d6..e35d5b5dd 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -82,6 +82,7 @@ set(llui_SOURCE_FILES
set(llui_HEADER_FILES
CMakeLists.txt
+ ailist.h
llalertdialog.h
llbutton.h
llcallbackmap.h
diff --git a/indra/llui/ailist.h b/indra/llui/ailist.h
new file mode 100644
index 000000000..821f679cb
--- /dev/null
+++ b/indra/llui/ailist.h
@@ -0,0 +1,191 @@
+/**
+ * @file ailist.h
+ * @brief A linked list with iterators that advance when their element is deleted.
+ *
+ * Copyright (c) 2013, Aleric Inglewood.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution.
+ *
+ * CHANGELOG
+ * and additional copyright holders.
+ *
+ * 05/02/2013
+ * Initial version, written by Aleric Inglewood @ SL
+ */
+
+#ifndef AILIST_H
+#define AILIST_H
+
+#include
+
+template
+class AIConstListIterator;
+
+template
+class AIListIterator {
+ private:
+ typedef AIListIterator _Self;
+ typedef std::list _Container;
+ typedef typename _Container::iterator _Iterator;
+
+ _Container* mContainer;
+ _Iterator mIterator;
+
+ public:
+ typedef typename _Iterator::difference_type difference_type;
+ typedef typename _Iterator::iterator_category iterator_category;
+ typedef typename _Iterator::value_type value_type;
+ typedef typename _Iterator::pointer pointer;
+ typedef typename _Iterator::reference reference;
+
+ AIListIterator(void) : mContainer(NULL) { }
+ AIListIterator(_Container* __c, _Iterator const& __i) : mContainer(__c), mIterator(__i) { }
+
+ _Self& operator=(_Self const& __x) { mContainer = __x.mContainer; mIterator = __x.mIterator; return *this; }
+
+ reference operator*() const { return *mIterator; }
+ pointer operator->() const { return mIterator.operator->(); }
+ _Self& operator++() { ++mIterator; return *this; }
+ _Self operator++(int) { _Self tmp = *this; ++mIterator; return tmp; }
+ _Self& operator--() { --mIterator; return *this; }
+ _Self operator--(int) { _Self tmp = *this; --mIterator; return tmp; }
+
+ bool operator==(_Self const& __x) const { return mIterator == __x.mIterator; }
+ bool operator!=(_Self const& __x) const { return mIterator != __x.mIterator; }
+
+ template friend class AIConstListIterator;
+ template friend bool operator==(AIListIterator const& __x, AIConstListIterator const& __y);
+ template friend bool operator!=(AIListIterator const& __x, AIConstListIterator const& __y);
+};
+
+template
+class AIConstListIterator {
+ private:
+ typedef AIConstListIterator _Self;
+ typedef std::list _Container;
+ typedef typename _Container::const_iterator _ConstIterator;
+ typedef AIListIterator iterator;
+
+ _Container const* mContainer;
+ _ConstIterator mConstIterator;
+
+ public:
+ typedef typename _ConstIterator::difference_type difference_type;
+ typedef typename _ConstIterator::iterator_category iterator_category;
+ typedef typename _ConstIterator::value_type value_type;
+ typedef typename _ConstIterator::pointer pointer;
+ typedef typename _ConstIterator::reference reference;
+
+ AIConstListIterator(void) : mContainer(NULL) { }
+ AIConstListIterator(_Container const* __c, _ConstIterator const& __i) : mContainer(__c), mConstIterator(__i) { }
+ AIConstListIterator(iterator const& __x) : mContainer(__x.mContainer), mConstIterator(__x.mIterator) { }
+
+ _Self& operator=(_Self const& __x) { mContainer = __x.mContainer; mConstIterator = __x.mConstIterator; return *this; }
+ _Self& operator=(iterator const& __x) { mContainer = __x.mContainer; mConstIterator = __x.mIterator; return *this; }
+
+ reference operator*() const { return *mConstIterator; }
+ pointer operator->() const { return mConstIterator.operator->(); }
+ _Self& operator++() { ++mConstIterator; return *this; }
+ _Self operator++(int) { _Self tmp = *this; ++mConstIterator; return tmp; }
+ _Self& operator--() { --mConstIterator; return *this; }
+ _Self operator--(int) { _Self tmp = *this; --mConstIterator; return tmp; }
+
+ bool operator==(_Self const& __x) const { return mConstIterator == __x.mConstIterator; }
+ bool operator!=(_Self const& __x) const { return mConstIterator != __x.mConstIterator; }
+
+ template friend bool operator==(AIListIterator const& __x, AIConstListIterator const& __y);
+ template friend bool operator!=(AIListIterator const& __x, AIConstListIterator const& __y);
+};
+
+template
+inline bool operator==(AIListIterator const& __x, AIConstListIterator const& __y)
+{
+ return __x.mIterator == __y.mConstIterator;
+}
+
+template
+inline bool operator!=(AIListIterator const& __x, AIConstListIterator const& __y)
+{
+ return __x.mIterator != __y.mConstIterator;
+}
+
+template
+class AIList {
+ private:
+ std::list mContainer;
+
+ public:
+ typedef T value_type;
+ typedef T* pointer;
+ typedef T const* const_pointer;
+ typedef T& reference;
+ typedef T const& const_reference;
+ typedef AIListIterator iterator;
+ typedef AIConstListIterator const_iterator;
+ typedef std::reverse_iterator reverse_iterator;
+ typedef std::reverse_iterator const_reverse_iterator;
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+
+ AIList(void) { }
+ //AIList(std::list const& __list) : mContainer(__list) { }
+
+ explicit AIList(size_type __n, value_type const& __value = value_type()) : mContainer(__n, __value) { }
+ AIList(AIList const& __list) : mContainer(__list.mContainer) { }
+
+ template
+ AIList(_InputIterator __first, _InputIterator __last) : mContainer(__first, __last) { }
+
+ AIList& operator=(AIList const& __list) { mContainer = __list.mContainer; return *this; }
+
+ iterator begin() { return iterator(&mContainer, mContainer.begin()); }
+ const_iterator begin() const { return const_iterator(&mContainer, mContainer.begin()); }
+ iterator end() { return iterator(&mContainer, mContainer.end()); }
+ const_iterator end() const { return const_iterator(&mContainer, mContainer.end()); }
+ reverse_iterator rbegin() { return reverse_iterator(end()); }
+ const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
+ reverse_iterator rend() { return reverse_iterator(begin()); }
+ const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
+
+ bool empty() const { return mContainer.empty(); }
+ size_type size() const { return mContainer.size(); }
+ size_type max_size() const { return mContainer.max_size(); }
+
+ reference front() { return mContainer.front(); }
+ const_reference front() const { return mContainer.front(); }
+ reference back() { return mContainer.back(); }
+ const_reference back() const { return mContainer.back(); }
+
+ void push_front(value_type const& __x) { mContainer.push_front(__x); }
+ void pop_front() { mContainer.pop_front(); }
+ void push_back(value_type const& __x) { mContainer.push_back(__x); }
+ void pop_back() { mContainer.pop_back(); }
+ iterator insert(iterator __position, value_type const& __x) { return iterator(&mContainer, mContainer.insert(__position, __x)); }
+ iterator erase(iterator __position) { return iterator(&mContainer, mContainer.erase(__position)); }
+ void clear() { mContainer.clear(); }
+ void remove(value_type const& __value) { mContainer.remove(__value); }
+
+ // Use this with care. No iterators should be left pointing at elements after the code returns.
+ std::list const& get_std_list(void) const { return mContainer; }
+
+ void sort() { mContainer.sort(); }
+ template
+ void sort(_StrictWeakOrdering pred) { mContainer.sort(pred); }
+};
+
+#endif
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index fbd132a8a..2ec5ce58c 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -57,6 +57,7 @@
#include "llinitparam.h"
#include "llfocusmgr.h"
#include
+#include "ailist.h"
const U32 FOLLOWS_NONE = 0x00;
const U32 FOLLOWS_LEFT = 0x01;
@@ -231,7 +232,7 @@ public:
SNAP_BOTTOM
};
- typedef std::list child_list_t;
+ typedef AIList child_list_t;
typedef child_list_t::iterator child_list_iter_t;
typedef child_list_t::const_iterator child_list_const_iter_t;
typedef child_list_t::reverse_iterator child_list_reverse_iter_t;
diff --git a/indra/llui/llviewquery.cpp b/indra/llui/llviewquery.cpp
index 2c1b9c2cd..7faf53726 100644
--- a/indra/llui/llviewquery.cpp
+++ b/indra/llui/llviewquery.cpp
@@ -76,7 +76,7 @@ viewList_t LLViewQuery::run(LLView* view) const
viewList_t result;
// prefilter gets immediate children of view
- filterResult_t pre = runFilters(view, *view->getChildList(), mPreFilters);
+ filterResult_t pre = runFilters(view, view->getChildList()->get_std_list(), mPreFilters);
if(!pre.first && !pre.second)
{
// not including ourselves or the children
@@ -113,7 +113,7 @@ viewList_t LLViewQuery::run(LLView* view) const
void LLViewQuery::filterChildren(LLView * view, viewList_t & filtered_children) const
{
- viewList_t views(*(view->getChildList()));
+ viewList_t views(view->getChildList()->get_std_list());
if (mSorterp)
{
(*mSorterp)(view, views); // sort the children per the sorter