Update copyright.
[shibboleth/cpp-xmltooling.git] / xmltooling / util / XMLObjectChildrenList.h
index b528798..be3244e 100644 (file)
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file XMLObjectChildrenList.h\r
- * \r
- * STL-compatible container wrapper\r
- */\r
-\r
-#if !defined(__xmltooling_list_h__)\r
-#define __xmltooling_list_h__\r
-\r
-#include <xmltooling/DOMCachingXMLObject.h>\r
-#include <xmltooling/exceptions.h>\r
-\r
-#define ListOf(type) xmltooling::XMLObjectChildrenList<type>\r
-\r
-namespace xmltooling {\r
-\r
-    // Forward reference\r
-    template <class _Tx, class _Ty=XMLObject> class XMLObjectChildrenList;\r
-\r
-    /**\r
-     * STL iterator that mediates access to an iterator over typed XML children.\r
-     * @param _Ty   a bidrectional sequence of the subtype to iterate over\r
-     */\r
-    template <class _Ty>\r
-    class XMLObjectChildrenIterator\r
-    {\r
-        typename _Ty::iterator m_iter;\r
-        template <class _Tx, class _Ty> friend class XMLObjectChildrenList;\r
-    public:\r
-        typedef typename _Ty::iterator::iterator_category iterator_category;\r
-        typedef typename _Ty::iterator::value_type value_type;\r
-           typedef typename _Ty::iterator::reference reference;\r
-           typedef typename _Ty::iterator::pointer pointer;\r
-        typedef typename _Ty::const_iterator::reference const_reference;\r
-           typedef typename _Ty::const_iterator::pointer const_pointer;\r
-           typedef typename _Ty::iterator::difference_type difference_type;\r
-\r
-           XMLObjectChildrenIterator() {\r
-           }\r
-\r
-           XMLObjectChildrenIterator(typename _Ty::iterator& iter) {\r
-                   m_iter=iter;\r
-           }\r
-\r
-           const_reference operator*() const {\r
-                   return *m_iter;\r
-           }\r
-\r
-        pointer operator->() const {\r
-            return (&**this);\r
-           }\r
-\r
-           XMLObjectChildrenIterator& operator++() {\r
-                   // preincrement\r
-                   ++m_iter;\r
-                   return (*this);\r
-           }\r
-\r
-           XMLObjectChildrenIterator& operator--() {\r
-                   // predecrement\r
-                   --m_iter;\r
-                   return (*this);\r
-           }\r
-\r
-           XMLObjectChildrenIterator operator++(int) {\r
-                   // postincrement\r
-                   XMLObjectChildrenIterator _Tmp = *this;\r
-                   ++*this;\r
-                   return (_Tmp);\r
-           }\r
-\r
-           XMLObjectChildrenIterator operator--(int) {\r
-                   // postdecrement\r
-                   XMLObjectChildrenIterator _Tmp = *this;\r
-                   --*this;\r
-                   return (_Tmp);\r
-           }\r
-\r
-        XMLObjectChildrenIterator& operator+=(difference_type _Off) {\r
-            // increment by integer\r
-            m_iter += _Off;\r
-            return (*this);\r
-        }\r
-\r
-        XMLObjectChildrenIterator operator+(difference_type _Off) const {\r
-            // return this + integer\r
-            XMLObjectChildrenIterator _Tmp = *this;\r
-            return (_Tmp += _Off);\r
-        }\r
-\r
-        XMLObjectChildrenIterator& operator-=(difference_type _Off) {\r
-            // decrement by integer\r
-            return (*this += -_Off);\r
-        }\r
-\r
-        XMLObjectChildrenIterator operator-(difference_type _Off) const {\r
-            // return this - integer\r
-            XMLObjectChildrenIterator _Tmp = *this;\r
-            return (_Tmp -= _Off);\r
-        }\r
-\r
-        difference_type operator-(const XMLObjectChildrenIterator& _Right) const {\r
-            // return difference of iterators\r
-            return m_iter - _Right.m_iter);\r
-        }\r
-\r
-        const_reference operator[](difference_type _Off) const {\r
-            // subscript\r
-            return (*(*this + _Off));\r
-        }\r
-\r
-        bool operator==(const XMLObjectChildrenIterator &_Right) const {\r
-                   // test for iterator equality\r
-                   return (m_iter == _Right.m_iter);\r
-           }\r
-\r
-           bool operator!=(const XMLObjectChildrenIterator &_Right) const {\r
-                   // test for iterator inequality\r
-                   return (!(m_iter == _Right.m_iter));\r
-           }\r
-    };\r
-\r
-    /**\r
-     * STL-compatible container that mediates access to underlying lists of typed XML children.\r
-     * @param _Tx   the subtype to expose a container over\r
-     * @param _Ty   the base type in the underlying list (defaults to XMLObject)\r
-     */\r
-    template <class _Tx, class _Ty>\r
-    class XMLObjectChildrenList\r
-    {\r
-        typedef typename std::vector<_Tx*> container;\r
-        typename container& m_vector;\r
-        typename std::list<_Ty*>& m_list;\r
-        typename std::list<_Ty*>::iterator m_fence;\r
-        XMLObject* m_parent;\r
-\r
-       public:\r
-        typedef typename container::value_type value_type;\r
-        typedef typename container::reference reference;\r
-        typedef typename container::const_reference const_reference;\r
-        typedef typename container::difference_type difference_type;\r
-        typedef typename container::size_type size_type;\r
-\r
-        // We override the iterator types with our constrained wrapper.\r
-        typedef XMLObjectChildrenIterator<typename container> iterator;\r
-           typedef const XMLObjectChildrenIterator<typename container> const_iterator;\r
-\r
-        /**\r
-         * Constructor to expose a typed collection of children backed by a list of a base type.\r
-         *\r
-         * @param parent    parent object of the collection\r
-         * @param v         underlying vector of iterators that reference the children\r
-         * @param backing   backing list for children\r
-         * @param ins_fence a marker designating where new children of this type should be added\r
-         */\r
-           XMLObjectChildrenList(\r
-            XMLObject* parent,\r
-            typename container& v,\r
-            typename std::list<_Ty*>& backing,\r
-            typename std::list<_Ty*>::iterator ins_fence\r
-            ) : m_parent(parent), m_vector(v), m_list(backing), m_fence(ins_fence) {\r
-           }\r
-\r
-           size_type size() const {\r
-                   // return length of sequence\r
-                   return m_vector.size();\r
-           }\r
-\r
-           bool empty() const {\r
-                   // test if sequence is empty\r
-                   return m_vector.empty();\r
-           }\r
-\r
-           iterator begin() {\r
-                   // return iterator for beginning of mutable sequence\r
-                   return m_vector.begin();\r
-           }\r
-\r
-           iterator end() {\r
-                   // return iterator for end of mutable sequence\r
-                   return m_vector.end();\r
-           }\r
-\r
-           const_iterator begin() const {\r
-                   // return iterator for beginning of const sequence\r
-                   return m_vector.begin();\r
-           }\r
-\r
-           const_iterator end() const {\r
-                   // return iterator for end of const sequence\r
-                   return m_vector.end();\r
-           }\r
-\r
-        const_reference at(size_type _Pos) const {\r
-            // subscript nonmutable sequence with checking\r
-            return m_vector.at(_Pos);\r
-        }\r
-\r
-        const_reference operator[](size_type _Pos) const {\r
-            // subscript nonmutable sequence\r
-            return m_vector[_Pos];\r
-        }\r
-\r
-        const_reference front() const {\r
-            // return first element of nonmutable sequence\r
-            return (*begin());\r
-        }\r
-\r
-        const_reference back() const {\r
-            // return last element of nonmutable sequence\r
-            return *(m_vector.back());\r
-        }\r
-\r
-           void push_back(const_reference _Val) {\r
-               setParent(_Val);\r
-            m_list.insert(m_fence,_Val);\r
-            m_vector.push_back(_Val);\r
-           }\r
-\r
-        iterator erase(iterator _Where) {\r
-            removeParent(*_Where);\r
-            removeChild(*_Where);\r
-            return m_vector.erase(_Where.m_iter);\r
-        }\r
-\r
-        iterator erase(iterator _First, iterator _Last) {\r
-            for (iterator i=_First; i!=_Last; i++) {\r
-                removeParent(*i);\r
-                removeChild(*i);\r
-            }\r
-            return m_vector.erase(_First,_Last);\r
-        }\r
-\r
-    private:\r
-        void setParent(const_reference _Val) {\r
-            if (_Val->getParent())\r
-                throw XMLObjectException("Child object already has a parent.");\r
-            _Val->setParent(m_parent);\r
-            DOMCachingXMLObject* dc=dynamic_cast<DOMCachingXMLObject*>(_Val);\r
-            if (dc) {\r
-                dc->releaseParentDOM(true);\r
-            }\r
-        }\r
-\r
-        void removeParent(const_reference _Val) {\r
-            if (_Val->getParent()!=m_parent)\r
-                throw XMLObjectException("Child object not owned by this parent.");\r
-            _Val->setParent(NULL);\r
-            DOMCachingXMLObject* dc=dynamic_cast<DOMCachingXMLObject*>(m_parent);\r
-            if (dc) {\r
-                dc->releaseParentDOM(true);\r
-            }\r
-        }\r
-\r
-        void removeChild(const_reference _Val) {\r
-            for (typename std::list<_Ty*>::iterator i=m_list.begin(); i!=m_list.end(); i++) {\r
-                if ((*i)==_Val) {\r
-                    m_list.erase(i);\r
-                    delete _Val;\r
-                    return;\r
-                }\r
-            }\r
-        }\r
-    };\r
-\r
-};\r
-\r
-#endif /* __xmltooling_list_h__ */\r
+/*
+ *  Copyright 2001-2007 Internet2
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file XMLObjectChildrenList.h
+ * 
+ * STL-compatible container wrapper
+ */
+
+#ifndef __xmltooling_list_h__
+#define __xmltooling_list_h__
+
+#include <xmltooling/exceptions.h>
+
+/**
+ * Shorthand for an XMLObjectChildrenList wrapped around a vector
+ * 
+ * @param type  the type of object in the vector
+ */
+#define VectorOf(type) xmltooling::XMLObjectChildrenList< std::vector<type*> >
+
+/**
+ * Shorthand for an XMLObjectChildrenList wrapped around a list
+ * 
+ * @param type  the type of object in the list
+ */
+#define ListOf(type) xmltooling::XMLObjectChildrenList< std::list<type*> >
+
+/**
+ * Shorthand for an XMLObjectChildrenList wrapped around a deque
+ * 
+ * @param type  the type of object in the deque
+ */
+#define DequeOf(type) xmltooling::XMLObjectChildrenList< std::deque<type*> >
+
+/**
+ * Shorthand for an XMLObjectPairList wrapped around a vector
+ * 
+ * @param type1  the first type of object in the vector
+ * @param type2  the second type of object in the vector
+ */
+#define VectorOfPairs(type1,type2) xmltooling::XMLObjectPairList< std::vector< std::pair<type1*,type2*> > >
+
+/**
+ * Shorthand for an XMLObjectPairList wrapped around a list
+ * 
+ * @param type1  the first type of object in the vector
+ * @param type2  the second type of object in the vector
+ */
+#define ListOfPairs(type1,type2) xmltooling::XMLObjectPairList< std::list< std::pair<type1*,type2*> > >
+
+/**
+ * Shorthand for an XMLObjectPairList wrapped around a deque
+ * 
+ * @param type1  the first type of object in the vector
+ * @param type2  the second type of object in the vector
+ */
+#define DequeOfPairs(type1,type2) xmltooling::XMLObjectPairList< std::deque< std::pair<type1*,type2*> > >
+
+namespace xmltooling {
+
+    // Forward reference
+    template <class _Tx, class _Ty=XMLObject> class XMLObjectChildrenList;
+    template <class _Tx, class _Ty=XMLObject> class XMLObjectPairList;
+
+    /**
+     * STL iterator that mediates access to an iterator over typed XML children.
+     * @param _Ty   a bidrectional sequence of the subtype to iterate over
+     */
+    template <class _Ty>
+    class XMLObjectChildrenIterator
+    {
+        /// @cond OFF
+        typename _Ty::iterator m_iter;
+        template <class _Tx, class _Tz> friend class XMLObjectChildrenList;
+        template <class _Tx, class _Tz> friend class XMLObjectPairList;
+    public:
+        typedef typename _Ty::iterator::iterator_category iterator_category;
+        typedef typename _Ty::iterator::value_type value_type;
+        typedef typename _Ty::iterator::reference reference;
+        typedef typename _Ty::iterator::pointer pointer;
+        typedef typename _Ty::const_iterator::reference const_reference;
+        typedef typename _Ty::const_iterator::pointer const_pointer;
+        typedef typename _Ty::iterator::difference_type difference_type;
+
+        XMLObjectChildrenIterator() {
+        }
+
+        XMLObjectChildrenIterator(typename _Ty::iterator iter) {
+            m_iter=iter;
+        }
+
+        const_reference operator*() const {
+            return *m_iter;
+        }
+
+        const_reference operator->() const {
+            return *(m_iter.operator->());
+        }
+
+        XMLObjectChildrenIterator& operator++() {
+            // preincrement
+            ++m_iter;
+            return (*this);
+        }
+
+        XMLObjectChildrenIterator& operator--() {
+            // predecrement
+            --m_iter;
+            return (*this);
+        }
+
+        XMLObjectChildrenIterator operator++(int) {
+            // postincrement
+            XMLObjectChildrenIterator _Tmp = *this;
+            ++*this;
+            return (_Tmp);
+        }
+
+        XMLObjectChildrenIterator operator--(int) {
+            // postdecrement
+            XMLObjectChildrenIterator _Tmp = *this;
+            --*this;
+            return (_Tmp);
+        }
+
+        XMLObjectChildrenIterator& operator+=(difference_type _Off) {
+            // increment by integer
+            m_iter += _Off;
+            return (*this);
+        }
+
+        XMLObjectChildrenIterator operator+(difference_type _Off) const {
+            // return this + integer
+            return m_iter + _Off;
+        }
+
+        XMLObjectChildrenIterator& operator-=(difference_type _Off) {
+            // decrement by integer
+            return (*this += -_Off);
+        }
+
+        XMLObjectChildrenIterator operator-(difference_type _Off) const {
+            // return this - integer
+            XMLObjectChildrenIterator _Tmp = *this;
+            return (_Tmp -= _Off);
+        }
+
+        difference_type operator-(const XMLObjectChildrenIterator& _Right) const {
+            // return difference of iterators
+            return m_iter - _Right.m_iter;
+        }
+
+        const_reference operator[](difference_type _Off) const {
+            // subscript
+            return (*(*this + _Off));
+        }
+
+        bool operator==(const XMLObjectChildrenIterator &_Right) const {
+                   // test for iterator equality
+                   return (m_iter == _Right.m_iter);
+           }
+
+           bool operator!=(const XMLObjectChildrenIterator &_Right) const {
+                   // test for iterator inequality
+                   return (!(m_iter == _Right.m_iter));
+           }
+        /// @endcond
+    };
+
+    /**
+     * STL-compatible container that mediates access to underlying lists of typed XML children.
+     * @param _Tx   the subtype container to encapsulate
+     * @param _Ty   the base type in the underlying list (defaults to XMLObject)
+     */
+    template <class Container, class _Ty>
+    class XMLObjectChildrenList
+    {
+        Container& m_container;
+        typename std::list<_Ty*>* m_list;
+        typename std::list<_Ty*>::iterator m_fence;
+        XMLObject* m_parent;
+
+       public:
+        /// @cond OFF
+        typedef typename Container::value_type value_type;
+        typedef typename Container::reference reference;
+        typedef typename Container::const_reference const_reference;
+        typedef typename Container::difference_type difference_type;
+        typedef typename Container::size_type size_type;
+
+        // We override the iterator types with our constrained wrapper.
+        typedef XMLObjectChildrenIterator<Container> iterator;
+        typedef XMLObjectChildrenIterator<Container> const_iterator;
+        /// @endcond
+
+        /**
+         * Constructor to expose a typed collection of children backed by a list of a base type.
+         *
+         * @param parent    parent object of the collection
+         * @param sublist   underlying container to expose
+         * @param backing   pointer to backing list for children, if any
+         * @param ins_fence a marker designating where new children of this type should be added
+         */
+        XMLObjectChildrenList(
+            XMLObject* parent,
+            Container& sublist,
+            typename std::list<_Ty*>* backing,
+            typename std::list<_Ty*>::iterator ins_fence
+            ) : m_container(sublist), m_list(backing), m_fence(ins_fence), m_parent(parent) {
+        }
+
+        /// @cond OFF
+
+        size_type size() const {
+            // return length of sequence
+            return m_container.size();
+        }
+
+        bool empty() const {
+            // test if sequence is empty
+            return m_container.empty();
+        }
+
+        iterator begin() {
+            // return iterator for beginning of mutable sequence
+            return m_container.begin();
+        }
+
+        iterator end() {
+            // return iterator for end of mutable sequence
+            return m_container.end();
+        }
+
+        const_iterator begin() const {
+            // return iterator for beginning of const sequence
+            return m_container.begin();
+        }
+
+        const_iterator end() const {
+            // return iterator for end of const sequence
+            return m_container.end();
+        }
+
+        const_reference at(size_type _Pos) const {
+            // subscript nonmutable sequence with checking
+            return m_container.at(_Pos);
+        }
+
+        const_reference operator[](size_type _Pos) const {
+            // subscript nonmutable sequence
+            return m_container[_Pos];
+        }
+
+        const_reference front() const {
+            // return first element of nonmutable sequence
+            return m_container.front();
+        }
+
+        const_reference back() const {
+            // return last element of nonmutable sequence
+            return m_container.back();
+        }
+
+        void push_back(const_reference _Val) {
+            setParent(_Val);
+            if (m_list)
+                m_list->insert(m_fence,_Val);
+            m_container.push_back(_Val);
+        }
+
+        iterator erase(iterator _Where) {
+            removeParent(*_Where);
+            if (m_list)
+                removeChild(*_Where);
+            else
+                delete *_Where.m_iter;
+            return m_container.erase(_Where.m_iter);
+        }
+
+        iterator erase(iterator _First, iterator _Last) {
+            for (iterator i=_First; i!=_Last; i++) {
+                removeParent(*i);
+                if (m_list)
+                    removeChild(*i);
+                else
+                    delete *i.m_iter;
+            }
+            return m_container.erase(_First.m_iter,_Last.m_iter);
+        }
+
+        void clear() {
+            erase(begin(),end());
+        }
+
+    private:
+        void setParent(const_reference _Val) {
+            if (_Val->getParent())
+                throw XMLObjectException("Child object already has a parent.");
+            _Val->setParent(m_parent);
+            _Val->releaseParentDOM(true);
+        }
+
+        void removeParent(const_reference _Val) {
+            if (_Val->getParent()!=m_parent)
+                throw XMLObjectException("Child object not owned by this parent.");
+            _Val->setParent(NULL);
+            m_parent->releaseParentDOM(true);
+        }
+
+        void removeChild(const_reference _Val) {
+            for (typename std::list<_Ty*>::iterator i=m_list->begin(); i!=m_list->end(); i++) {
+                if ((*i)==_Val) {
+                    m_list->erase(i);
+                    delete _Val;
+                    return;
+                }
+            }
+        }
+        /// @endcond
+    };
+
+    /**
+     * STL-compatible container that mediates access to underlying lists of typed XML children
+     * that come in pairs.
+     * 
+     * @param _Tx   the subtype container to encapsulate
+     * @param _Ty   the base type in the underlying list (defaults to XMLObject)
+     */
+    template <class Container, class _Ty>
+    class XMLObjectPairList
+    {
+        Container& m_container;
+        typename std::list<_Ty*>* m_list;
+        typename std::list<_Ty*>::iterator m_fence;
+        XMLObject* m_parent;
+
+    public:
+        /// @cond OFF
+        typedef typename Container::value_type value_type;
+        typedef typename Container::reference reference;
+        typedef typename Container::const_reference const_reference;
+        typedef typename Container::difference_type difference_type;
+        typedef typename Container::size_type size_type;
+
+        // We override the iterator types with our constrained wrapper.
+        typedef XMLObjectChildrenIterator<Container> iterator;
+        typedef XMLObjectChildrenIterator<Container> const_iterator;
+        /// @endcond
+
+        /**
+         * Constructor to expose a typed collection of pairs backed by a list of a base type.
+         *
+         * @param parent    parent object of the collection
+         * @param sublist   underlying container to expose
+         * @param backing   pointer to backing list for children, if any
+         * @param ins_fence a marker designating where new children of this type should be added
+         */
+        XMLObjectPairList(
+            XMLObject* parent,
+            Container& sublist,
+            typename std::list<_Ty*>* backing,
+            typename std::list<_Ty*>::iterator ins_fence
+            ) : m_container(sublist), m_list(backing), m_fence(ins_fence), m_parent(parent) {
+        }
+
+        /// @cond OFF
+
+        size_type size() const {
+            // return length of sequence
+            return m_container.size();
+        }
+
+        bool empty() const {
+            // test if sequence is empty
+            return m_container.empty();
+        }
+
+        iterator begin() {
+            // return iterator for beginning of mutable sequence
+            return m_container.begin();
+        }
+
+        iterator end() {
+            // return iterator for end of mutable sequence
+            return m_container.end();
+        }
+
+        const_iterator begin() const {
+            // return iterator for beginning of const sequence
+            return m_container.begin();
+        }
+
+        const_iterator end() const {
+            // return iterator for end of const sequence
+            return m_container.end();
+        }
+
+        const_reference at(size_type _Pos) const {
+            // subscript nonmutable sequence with checking
+            return m_container.at(_Pos);
+        }
+
+        const_reference operator[](size_type _Pos) const {
+            // subscript nonmutable sequence
+            return m_container[_Pos];
+        }
+
+        const_reference front() const {
+            // return first element of nonmutable sequence
+            return m_container.front();
+        }
+
+        const_reference back() const {
+            // return last element of nonmutable sequence
+            return m_container.back();
+        }
+
+        void push_back(const_reference _Val) {
+            setParent(_Val);
+            if (m_list) {
+                m_list->insert(m_fence,_Val.first);
+                m_list->insert(m_fence,_Val.second);
+            }
+            m_container.push_back(_Val);
+        }
+
+        iterator erase(iterator _Where) {
+            removeParent(*_Where);
+            if (m_list)
+                removeChild(*_Where);
+            else {
+                delete _Where.m_iter->first;
+                delete _Where.m_iter->second;
+            }
+            return m_container.erase(_Where.m_iter);
+        }
+
+        iterator erase(iterator _First, iterator _Last) {
+            for (iterator i=_First; i!=_Last; i++) {
+                removeParent(*i);
+                if (m_list)
+                    removeChild(*i);
+                else {
+                    delete i.m_iter->first;
+                    delete i.m_iter->second;
+                }
+            }
+            return m_container.erase(_First,_Last);
+        }
+
+        void clear() {
+            erase(begin(),end());
+        }
+
+    private:
+        void setParent(const_reference _Val) {
+            if (_Val.first->getParent() || (_Val.second && _Val.second->getParent()))
+                throw XMLObjectException("One of the child objects already has a parent.");
+            _Val.first->setParent(m_parent);
+            if (_Val.second)
+                _Val.second->setParent(m_parent);
+            _Val.first->releaseParentDOM(true);
+        }
+
+        void removeParent(const_reference _Val) {
+            if (_Val.first->getParent()!=m_parent || (_Val.second && _Val.second->getParent()!=m_parent))
+                throw XMLObjectException("One of the child objects not owned by this parent.");
+            _Val.first->setParent(NULL);
+            if (_Val.second)
+                _Val.second->setParent(NULL);
+            m_parent->releaseParentDOM(true);
+        }
+
+        void removeChild(const_reference _Val) {
+            for (typename std::list<_Ty*>::iterator i=m_list->begin(); i!=m_list->end(); i++) {
+                if ((*i)==_Val.first) {
+                    typename std::list<_Ty*>::iterator j=i++;
+                    m_list->erase(j);
+                    m_list->erase(i);
+                    delete _Val.first;
+                    delete _Val.second;
+                    return;
+                }
+                i++;
+            }
+        }
+        /// @endcond
+    };
+
+};
+
+#endif /* __xmltooling_list_h__ */