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 VectorOf(type) xmltooling::XMLObjectChildrenList< std::vector<type*> >
30 #define ListOf(type) xmltooling::XMLObjectChildrenList< std::list<type*> >
31 #define DequeOf(type) xmltooling::XMLObjectChildrenList< std::deque<type*> >
33 namespace xmltooling {
36 template <class _Tx, class _Ty=XMLObject> class XMLObjectChildrenList;
39 * STL iterator that mediates access to an iterator over typed XML children.
40 * @param _Ty a bidrectional sequence of the subtype to iterate over
43 class XMLObjectChildrenIterator
45 typename _Ty::iterator m_iter;
46 template <class _Tx, class _Tz> friend class XMLObjectChildrenList;
48 typedef typename _Ty::iterator::iterator_category iterator_category;
49 typedef typename _Ty::iterator::value_type value_type;
50 typedef typename _Ty::iterator::reference reference;
51 typedef typename _Ty::iterator::pointer pointer;
52 typedef typename _Ty::const_iterator::reference const_reference;
53 typedef typename _Ty::const_iterator::pointer const_pointer;
54 typedef typename _Ty::iterator::difference_type difference_type;
56 XMLObjectChildrenIterator() {
59 XMLObjectChildrenIterator(typename _Ty::iterator iter) {
63 const_reference operator*() const {
67 const_reference operator->() const {
68 return *(m_iter.operator->());
71 XMLObjectChildrenIterator& operator++() {
77 XMLObjectChildrenIterator& operator--() {
83 XMLObjectChildrenIterator operator++(int) {
85 XMLObjectChildrenIterator _Tmp = *this;
90 XMLObjectChildrenIterator operator--(int) {
92 XMLObjectChildrenIterator _Tmp = *this;
97 XMLObjectChildrenIterator& operator+=(difference_type _Off) {
98 // increment by integer
103 XMLObjectChildrenIterator operator+(difference_type _Off) const {
104 // return this + integer
105 XMLObjectChildrenIterator _Tmp = *this;
106 return (_Tmp += _Off);
109 XMLObjectChildrenIterator& operator-=(difference_type _Off) {
110 // decrement by integer
111 return (*this += -_Off);
114 XMLObjectChildrenIterator operator-(difference_type _Off) const {
115 // return this - integer
116 XMLObjectChildrenIterator _Tmp = *this;
117 return (_Tmp -= _Off);
120 difference_type operator-(const XMLObjectChildrenIterator& _Right) const {
121 // return difference of iterators
122 return m_iter - _Right.m_iter;
125 const_reference operator[](difference_type _Off) const {
127 return (*(*this + _Off));
130 bool operator==(const XMLObjectChildrenIterator &_Right) const {
131 // test for iterator equality
132 return (m_iter == _Right.m_iter);
135 bool operator!=(const XMLObjectChildrenIterator &_Right) const {
136 // test for iterator inequality
137 return (!(m_iter == _Right.m_iter));
142 * STL-compatible container that mediates access to underlying lists of typed XML children.
143 * @param _Tx the subtype container to encapsulate
144 * @param _Ty the base type in the underlying list (defaults to XMLObject)
146 template <class Container, class _Ty>
147 class XMLObjectChildrenList
149 typename Container& m_container;
150 typename std::list<_Ty*>* m_list;
151 typename std::list<_Ty*>::iterator m_fence;
155 typedef typename Container::value_type value_type;
156 typedef typename Container::reference reference;
157 typedef typename Container::const_reference const_reference;
158 typedef typename Container::difference_type difference_type;
159 typedef typename Container::size_type size_type;
161 // We override the iterator types with our constrained wrapper.
162 typedef XMLObjectChildrenIterator<Container> iterator;
163 typedef const XMLObjectChildrenIterator<Container> const_iterator;
166 * Constructor to expose a typed collection of children backed by a list of a base type.
168 * @param parent parent object of the collection
169 * @param sublist underlying container to expose
170 * @param backing pointer to backing list for children, if any
171 * @param ins_fence a marker designating where new children of this type should be added
173 XMLObjectChildrenList(
176 typename std::list<_Ty*>* backing,
177 typename std::list<_Ty*>::iterator ins_fence
178 ) : m_parent(parent), m_container(sublist), m_list(backing), m_fence(ins_fence) {
181 size_type size() const {
182 // return length of sequence
183 return m_container.size();
187 // test if sequence is empty
188 return m_container.empty();
192 // return iterator for beginning of mutable sequence
193 return m_container.begin();
197 // return iterator for end of mutable sequence
198 return m_container.end();
201 const_iterator begin() const {
202 // return iterator for beginning of const sequence
203 return m_container.begin();
206 const_iterator end() const {
207 // return iterator for end of const sequence
208 return m_container.end();
211 const_reference at(size_type _Pos) const {
212 // subscript nonmutable sequence with checking
213 return m_container.at(_Pos);
216 const_reference operator[](size_type _Pos) const {
217 // subscript nonmutable sequence
218 return m_container[_Pos];
221 const_reference front() const {
222 // return first element of nonmutable sequence
223 return m_container.front();
226 const_reference back() const {
227 // return last element of nonmutable sequence
228 return m_container.back();
231 void push_back(const_reference _Val) {
234 m_list->insert(m_fence,_Val);
235 m_container.push_back(_Val);
238 iterator erase(iterator _Where) {
239 removeParent(*_Where);
241 removeChild(*_Where);
242 return m_container.erase(_Where.m_iter);
245 iterator erase(iterator _First, iterator _Last) {
246 for (iterator i=_First; i!=_Last; i++) {
251 return m_container.erase(_First,_Last);
255 erase(begin(),end());
259 void setParent(const_reference _Val) {
260 if (_Val->getParent())
261 throw XMLObjectException("Child object already has a parent.");
262 _Val->setParent(m_parent);
263 DOMCachingXMLObject* dc=dynamic_cast<DOMCachingXMLObject*>(_Val);
265 dc->releaseParentDOM(true);
269 void removeParent(const_reference _Val) {
270 if (_Val->getParent()!=m_parent)
271 throw XMLObjectException("Child object not owned by this parent.");
272 _Val->setParent(NULL);
273 DOMCachingXMLObject* dc=dynamic_cast<DOMCachingXMLObject*>(m_parent);
275 dc->releaseParentDOM(true);
279 void removeChild(const_reference _Val) {
280 for (typename std::list<_Ty*>::iterator i=m_list->begin(); i!=m_list->end(); i++) {
292 #endif /* __xmltooling_list_h__ */