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 #ifndef __xmltooling_list_h__
24 #define __xmltooling_list_h__
26 #include <xmltooling/exceptions.h>
29 * Shorthand for an XMLObjectChildrenList wrapped around a vector
31 * @param type the type of object in the vector
33 #define VectorOf(type) xmltooling::XMLObjectChildrenList< std::vector<type*> >
36 * Shorthand for an XMLObjectChildrenList wrapped around a list
38 * @param type the type of object in the list
40 #define ListOf(type) xmltooling::XMLObjectChildrenList< std::list<type*> >
43 * Shorthand for an XMLObjectChildrenList wrapped around a deque
45 * @param type the type of object in the deque
47 #define DequeOf(type) xmltooling::XMLObjectChildrenList< std::deque<type*> >
49 namespace xmltooling {
52 template <class _Tx, class _Ty=XMLObject> class XMLObjectChildrenList;
55 * STL iterator that mediates access to an iterator over typed XML children.
56 * @param _Ty a bidrectional sequence of the subtype to iterate over
59 class XMLObjectChildrenIterator
62 typename _Ty::iterator m_iter;
63 template <class _Tx, class _Tz> friend class XMLObjectChildrenList;
65 typedef typename _Ty::iterator::iterator_category iterator_category;
66 typedef typename _Ty::iterator::value_type value_type;
67 typedef typename _Ty::iterator::reference reference;
68 typedef typename _Ty::iterator::pointer pointer;
69 typedef typename _Ty::const_iterator::reference const_reference;
70 typedef typename _Ty::const_iterator::pointer const_pointer;
71 typedef typename _Ty::iterator::difference_type difference_type;
73 XMLObjectChildrenIterator() {
76 XMLObjectChildrenIterator(typename _Ty::iterator iter) {
80 const_reference operator*() const {
84 const_reference operator->() const {
85 return *(m_iter.operator->());
88 XMLObjectChildrenIterator& operator++() {
94 XMLObjectChildrenIterator& operator--() {
100 XMLObjectChildrenIterator operator++(int) {
102 XMLObjectChildrenIterator _Tmp = *this;
107 XMLObjectChildrenIterator operator--(int) {
109 XMLObjectChildrenIterator _Tmp = *this;
114 XMLObjectChildrenIterator& operator+=(difference_type _Off) {
115 // increment by integer
120 XMLObjectChildrenIterator operator+(difference_type _Off) const {
121 // return this + integer
122 return m_iter + _Off;
125 XMLObjectChildrenIterator& operator-=(difference_type _Off) {
126 // decrement by integer
127 return (*this += -_Off);
130 XMLObjectChildrenIterator operator-(difference_type _Off) const {
131 // return this - integer
132 XMLObjectChildrenIterator _Tmp = *this;
133 return (_Tmp -= _Off);
136 difference_type operator-(const XMLObjectChildrenIterator& _Right) const {
137 // return difference of iterators
138 return m_iter - _Right.m_iter;
141 const_reference operator[](difference_type _Off) const {
143 return (*(*this + _Off));
146 bool operator==(const XMLObjectChildrenIterator &_Right) const {
147 // test for iterator equality
148 return (m_iter == _Right.m_iter);
151 bool operator!=(const XMLObjectChildrenIterator &_Right) const {
152 // test for iterator inequality
153 return (!(m_iter == _Right.m_iter));
159 * STL-compatible container that mediates access to underlying lists of typed XML children.
160 * @param _Tx the subtype container to encapsulate
161 * @param _Ty the base type in the underlying list (defaults to XMLObject)
163 template <class Container, class _Ty>
164 class XMLObjectChildrenList
166 Container& m_container;
167 typename std::list<_Ty*>* m_list;
168 typename std::list<_Ty*>::iterator m_fence;
173 typedef typename Container::value_type value_type;
174 typedef typename Container::reference reference;
175 typedef typename Container::const_reference const_reference;
176 typedef typename Container::difference_type difference_type;
177 typedef typename Container::size_type size_type;
179 // We override the iterator types with our constrained wrapper.
180 typedef XMLObjectChildrenIterator<Container> iterator;
181 typedef XMLObjectChildrenIterator<Container> const_iterator;
185 * Constructor to expose a typed collection of children backed by a list of a base type.
187 * @param parent parent object of the collection
188 * @param sublist underlying container to expose
189 * @param backing pointer to backing list for children, if any
190 * @param ins_fence a marker designating where new children of this type should be added
192 XMLObjectChildrenList(
195 typename std::list<_Ty*>* backing,
196 typename std::list<_Ty*>::iterator ins_fence
197 ) : m_container(sublist), m_list(backing), m_fence(ins_fence), m_parent(parent) {
202 size_type size() const {
203 // return length of sequence
204 return m_container.size();
208 // test if sequence is empty
209 return m_container.empty();
213 // return iterator for beginning of mutable sequence
214 return m_container.begin();
218 // return iterator for end of mutable sequence
219 return m_container.end();
222 const_iterator begin() const {
223 // return iterator for beginning of const sequence
224 return m_container.begin();
227 const_iterator end() const {
228 // return iterator for end of const sequence
229 return m_container.end();
232 const_reference at(size_type _Pos) const {
233 // subscript nonmutable sequence with checking
234 return m_container.at(_Pos);
237 const_reference operator[](size_type _Pos) const {
238 // subscript nonmutable sequence
239 return m_container[_Pos];
242 const_reference front() const {
243 // return first element of nonmutable sequence
244 return m_container.front();
247 const_reference back() const {
248 // return last element of nonmutable sequence
249 return m_container.back();
252 void push_back(const_reference _Val) {
255 m_list->insert(m_fence,_Val);
256 m_container.push_back(_Val);
259 iterator erase(iterator _Where) {
260 removeParent(*_Where);
262 removeChild(*_Where);
264 delete *_Where.m_iter;
265 return m_container.erase(_Where.m_iter);
268 iterator erase(iterator _First, iterator _Last) {
269 for (iterator i=_First; i!=_Last; i++) {
276 return m_container.erase(_First,_Last);
280 erase(begin(),end());
284 void setParent(const_reference _Val) {
285 if (_Val->getParent())
286 throw XMLObjectException("Child object already has a parent.");
287 _Val->setParent(m_parent);
288 _Val->releaseParentDOM(true);
291 void removeParent(const_reference _Val) {
292 if (_Val->getParent()!=m_parent)
293 throw XMLObjectException("Child object not owned by this parent.");
294 _Val->setParent(NULL);
295 m_parent->releaseParentDOM(true);
298 void removeChild(const_reference _Val) {
299 for (typename std::list<_Ty*>::iterator i=m_list->begin(); i!=m_list->end(); i++) {
312 #endif /* __xmltooling_list_h__ */