2 * Copyright 2001-2006 Internet2
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * @file XMLObjectChildrenList.h
20 * STL-compatible container wrapper
23 #if !defined(__xmltooling_list_h__)
24 #define __xmltooling_list_h__
26 #include <xmltooling/DOMCachingXMLObject.h>
27 #include <xmltooling/exceptions.h>
29 #define ListOf(type) xmltooling::XMLObjectChildrenList<type>
31 namespace xmltooling {
34 template <class _Tx, class _Ty=XMLObject> class XMLObjectChildrenList;
37 * STL iterator that mediates access to an iterator over typed XML children.
38 * @param _Ty a bidrectional sequence of the subtype to iterate over
41 class XMLObjectChildrenIterator
43 typename _Ty::iterator m_iter;
44 template <class _Tx, class _Tz> friend class XMLObjectChildrenList;
46 typedef typename _Ty::iterator::iterator_category iterator_category;
47 typedef typename _Ty::iterator::value_type value_type;
48 typedef typename _Ty::iterator::reference reference;
49 typedef typename _Ty::iterator::pointer pointer;
50 typedef typename _Ty::const_iterator::reference const_reference;
51 typedef typename _Ty::const_iterator::pointer const_pointer;
52 typedef typename _Ty::iterator::difference_type difference_type;
54 XMLObjectChildrenIterator() {
57 XMLObjectChildrenIterator(typename _Ty::iterator iter) {
61 const_reference operator*() const {
65 pointer operator->() const {
69 XMLObjectChildrenIterator& operator++() {
75 XMLObjectChildrenIterator& operator--() {
81 XMLObjectChildrenIterator operator++(int) {
83 XMLObjectChildrenIterator _Tmp = *this;
88 XMLObjectChildrenIterator operator--(int) {
90 XMLObjectChildrenIterator _Tmp = *this;
95 XMLObjectChildrenIterator& operator+=(difference_type _Off) {
96 // increment by integer
101 XMLObjectChildrenIterator operator+(difference_type _Off) const {
102 // return this + integer
103 XMLObjectChildrenIterator _Tmp = *this;
104 return (_Tmp += _Off);
107 XMLObjectChildrenIterator& operator-=(difference_type _Off) {
108 // decrement by integer
109 return (*this += -_Off);
112 XMLObjectChildrenIterator operator-(difference_type _Off) const {
113 // return this - integer
114 XMLObjectChildrenIterator _Tmp = *this;
115 return (_Tmp -= _Off);
118 difference_type operator-(const XMLObjectChildrenIterator& _Right) const {
119 // return difference of iterators
120 return m_iter - _Right.m_iter;
123 const_reference operator[](difference_type _Off) const {
125 return (*(*this + _Off));
128 bool operator==(const XMLObjectChildrenIterator &_Right) const {
129 // test for iterator equality
130 return (m_iter == _Right.m_iter);
133 bool operator!=(const XMLObjectChildrenIterator &_Right) const {
134 // test for iterator inequality
135 return (!(m_iter == _Right.m_iter));
140 * STL-compatible container that mediates access to underlying lists of typed XML children.
141 * @param _Tx the subtype to expose a container over
142 * @param _Ty the base type in the underlying list (defaults to XMLObject)
144 template <class _Tx, class _Ty>
145 class XMLObjectChildrenList
147 typedef typename std::vector<_Tx*> container;
148 typename XMLObjectChildrenList::container& m_vector;
149 typename std::list<_Ty*>& m_list;
150 typename std::list<_Ty*>::iterator m_fence;
154 typedef typename container::value_type value_type;
155 typedef typename container::reference reference;
156 typedef typename container::const_reference const_reference;
157 typedef typename container::difference_type difference_type;
158 typedef typename container::size_type size_type;
160 // We override the iterator types with our constrained wrapper.
161 typedef XMLObjectChildrenIterator<typename XMLObjectChildrenList::container> iterator;
162 typedef const XMLObjectChildrenIterator<typename XMLObjectChildrenList::container> const_iterator;
165 * Constructor to expose a typed collection of children backed by a list of a base type.
167 * @param parent parent object of the collection
168 * @param v underlying vector of iterators that reference the children
169 * @param backing backing list for children
170 * @param ins_fence a marker designating where new children of this type should be added
172 XMLObjectChildrenList(
174 typename XMLObjectChildrenList::container& v,
175 typename std::list<_Ty*>& backing,
176 typename std::list<_Ty*>::iterator ins_fence
177 ) : m_parent(parent), m_vector(v), m_list(backing), m_fence(ins_fence) {
180 size_type size() const {
181 // return length of sequence
182 return m_vector.size();
186 // test if sequence is empty
187 return m_vector.empty();
191 // return iterator for beginning of mutable sequence
192 return m_vector.begin();
196 // return iterator for end of mutable sequence
197 return m_vector.end();
200 const_iterator begin() const {
201 // return iterator for beginning of const sequence
202 return m_vector.begin();
205 const_iterator end() const {
206 // return iterator for end of const sequence
207 return m_vector.end();
210 const_reference at(size_type _Pos) const {
211 // subscript nonmutable sequence with checking
212 return m_vector.at(_Pos);
215 const_reference operator[](size_type _Pos) const {
216 // subscript nonmutable sequence
217 return m_vector[_Pos];
220 const_reference front() const {
221 // return first element of nonmutable sequence
225 const_reference back() const {
226 // return last element of nonmutable sequence
227 return *(m_vector.back());
230 void push_back(const_reference _Val) {
232 m_list.insert(m_fence,_Val);
233 m_vector.push_back(_Val);
236 iterator erase(iterator _Where) {
237 removeParent(*_Where);
238 removeChild(*_Where);
239 return m_vector.erase(_Where.m_iter);
242 iterator erase(iterator _First, iterator _Last) {
243 for (iterator i=_First; i!=_Last; i++) {
247 return m_vector.erase(_First,_Last);
251 void setParent(const_reference _Val) {
252 if (_Val->getParent())
253 throw XMLObjectException("Child object already has a parent.");
254 _Val->setParent(m_parent);
255 DOMCachingXMLObject* dc=dynamic_cast<DOMCachingXMLObject*>(_Val);
257 dc->releaseParentDOM(true);
261 void removeParent(const_reference _Val) {
262 if (_Val->getParent()!=m_parent)
263 throw XMLObjectException("Child object not owned by this parent.");
264 _Val->setParent(NULL);
265 DOMCachingXMLObject* dc=dynamic_cast<DOMCachingXMLObject*>(m_parent);
267 dc->releaseParentDOM(true);
271 void removeChild(const_reference _Val) {
272 for (typename std::list<_Ty*>::iterator i=m_list.begin(); i!=m_list.end(); i++) {
284 #endif /* __xmltooling_list_h__ */