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