xmlwrapp
|
00001 /* 00002 * Copyright (C) 2009 Vaclav Slavik <vslavik@gmail.com> 00003 * All Rights Reserved 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 00009 * 1. Redistributions of source code must retain the above copyright 00010 * notice, this list of conditions and the following disclaimer. 00011 * 2. Redistributions in binary form must reproduce the above copyright 00012 * notice, this list of conditions and the following disclaimer in 00013 * the documentation and/or other materials provided with the 00014 * distribution. 00015 * 3. Neither the name of the Author nor the names of its contributors 00016 * may be used to endorse or promote products derived from this software 00017 * without specific prior written permission. 00018 * 00019 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' 00020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 00021 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00022 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 00023 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00024 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00025 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 00026 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 00027 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00028 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 00029 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00030 * SUCH DAMAGE. 00031 */ 00032 00033 /** 00034 @file 00035 00036 This file contains the definition of the xml::nodes_view and 00037 xml::const_nodes_view classes. 00038 */ 00039 00040 #ifndef _xmlwrapp_nodes_view_h_ 00041 #define _xmlwrapp_nodes_view_h_ 00042 00043 // xmlwrapp includes 00044 #include "xmlwrapp/init.h" 00045 00046 // standard includes 00047 #include <iterator> 00048 00049 namespace xml 00050 { 00051 00052 class node; 00053 class const_nodes_view; 00054 00055 namespace impl 00056 { 00057 00058 struct nipimpl; 00059 class iter_advance_functor; 00060 00061 } // namespace impl 00062 00063 /** 00064 This class implements a view of XML nodes. A @em view is a container-like 00065 class that only allows access to a subset of xml::node's child nodes. The 00066 exact content depends on how the view was obtained; typical uses are 00067 e.g. a view of all element children or all elements with a given name. 00068 00069 The nodes_view class implements the same container interface that 00070 xml::node does: it has begin() and end() methods. 00071 00072 @since 0.6.0 00073 00074 @see xml::node::elements(), xml::node::elements(const char *) 00075 */ 00076 class nodes_view 00077 { 00078 public: 00079 nodes_view() : data_begin_(0), advance_func_(0) {} 00080 nodes_view(const nodes_view& other); 00081 ~nodes_view(); 00082 00083 nodes_view& operator=(const nodes_view& other); 00084 00085 class const_iterator; 00086 00087 /** 00088 The iterator provides a way to access nodes in the view 00089 similar to a standard C++ container. 00090 00091 @see xml::node::iterator 00092 */ 00093 class iterator 00094 { 00095 public: 00096 typedef node value_type; 00097 typedef int difference_type; 00098 typedef value_type* pointer; 00099 typedef value_type& reference; 00100 typedef std::forward_iterator_tag iterator_category; 00101 00102 iterator() : pimpl_(0), advance_func_(0) {} 00103 iterator(const iterator& other); 00104 iterator& operator=(const iterator& other); 00105 ~iterator(); 00106 00107 reference operator*() const; 00108 pointer operator->() const; 00109 00110 iterator& operator++(); 00111 iterator operator++(int); 00112 00113 bool operator==(const iterator& other) const 00114 { return get_raw_node() == other.get_raw_node(); } 00115 bool operator!=(const iterator& other) const 00116 { return !(*this == other); } 00117 00118 private: 00119 explicit iterator(void *data, impl::iter_advance_functor *advance_func); 00120 void* get_raw_node() const; 00121 void swap(iterator& other); 00122 00123 impl::nipimpl *pimpl_; 00124 // function for advancing the iterator (note that it is "owned" by the 00125 // parent view object, so we don't have to care about its reference 00126 // count here) 00127 impl::iter_advance_functor *advance_func_; 00128 00129 friend class nodes_view; 00130 friend class const_iterator; 00131 }; 00132 00133 /** 00134 The const_iterator provides a way to access nodes in the view 00135 similar to a standard C++ container. The nodes that are pointed to by 00136 the iterator cannot be changed. 00137 00138 @see xml::node::const_iterator 00139 */ 00140 class const_iterator 00141 { 00142 public: 00143 typedef const node value_type; 00144 typedef int difference_type; 00145 typedef value_type* pointer; 00146 typedef value_type& reference; 00147 typedef std::forward_iterator_tag iterator_category; 00148 00149 const_iterator() : pimpl_(0), advance_func_(0) {} 00150 const_iterator(const const_iterator& other); 00151 const_iterator(const iterator& other); 00152 const_iterator& operator=(const const_iterator& other); 00153 const_iterator& operator=(const iterator& other); 00154 ~const_iterator(); 00155 00156 reference operator*() const; 00157 pointer operator->() const; 00158 00159 const_iterator& operator++(); 00160 const_iterator operator++(int); 00161 00162 bool operator==(const const_iterator& other) const 00163 { return get_raw_node() == other.get_raw_node(); } 00164 bool operator!=(const const_iterator& other) const 00165 { return !(*this == other); } 00166 00167 private: 00168 explicit const_iterator(void *data, impl::iter_advance_functor *advance_func); 00169 void* get_raw_node() const; 00170 void swap(const_iterator& other); 00171 00172 impl::nipimpl *pimpl_; 00173 // function for advancing the iterator (note that it is "owned" by the 00174 // parent view object, so we don't have to care about its reference 00175 // count here) 00176 impl::iter_advance_functor *advance_func_; 00177 00178 friend class const_nodes_view; 00179 friend class nodes_view; 00180 }; 00181 00182 /** 00183 Get an iterator that points to the beginning of this node's 00184 children. 00185 00186 @return An iterator that points to the beginning of the children. 00187 */ 00188 iterator begin() { return iterator(data_begin_, advance_func_); } 00189 00190 /** 00191 Get an iterator that points to the beginning of this node's 00192 children. 00193 00194 @return An iterator that points to the beginning of the children. 00195 */ 00196 const_iterator begin() const { return const_iterator(data_begin_, advance_func_); } 00197 00198 /** 00199 Get an iterator that points one past the last child for this node. 00200 00201 @return A "one past the end" iterator. 00202 */ 00203 iterator end() { return iterator(); } 00204 00205 /** 00206 Get an iterator that points one past the last child for this node. 00207 00208 @return A "one past the end" iterator. 00209 */ 00210 const_iterator end() const { return const_iterator(); } 00211 00212 /// Is the view empty? 00213 bool empty() const { return !data_begin_; } 00214 00215 private: 00216 explicit nodes_view(void *data_begin, impl::iter_advance_functor *advance_func) 00217 : data_begin_(data_begin), advance_func_(advance_func) {} 00218 00219 // begin iterator 00220 void *data_begin_; 00221 // function for advancing the iterator (owned by the view object) 00222 impl::iter_advance_functor *advance_func_; 00223 00224 friend class node; 00225 friend class const_nodes_view; 00226 }; 00227 00228 00229 /** 00230 This class implements a @em read-only view of XML nodes. The only 00231 difference from xml::nodes_view is that it doesn't allow modifications of 00232 the nodes, it is otherwise identical. 00233 00234 @see nodes_view 00235 00236 @since 0.6.0 00237 */ 00238 class const_nodes_view 00239 { 00240 public: 00241 const_nodes_view() : data_begin_(0), advance_func_(0) {} 00242 const_nodes_view(const const_nodes_view& other); 00243 const_nodes_view(const nodes_view& other); 00244 ~const_nodes_view(); 00245 00246 const_nodes_view& operator=(const const_nodes_view& other); 00247 const_nodes_view& operator=(const nodes_view& other); 00248 00249 typedef nodes_view::const_iterator iterator; 00250 typedef nodes_view::const_iterator const_iterator; 00251 00252 /** 00253 Get an iterator that points to the beginning of this node's 00254 children. 00255 00256 @return An iterator that points to the beginning of the children. 00257 */ 00258 const_iterator begin() const 00259 { return const_iterator(data_begin_, advance_func_); } 00260 00261 /** 00262 Get an iterator that points one past the last child for this node. 00263 00264 @return A "one past the end" iterator. 00265 */ 00266 const_iterator end() const { return const_iterator(); } 00267 00268 /// Is the view empty? 00269 bool empty() const { return !data_begin_; } 00270 00271 private: 00272 explicit const_nodes_view(void *data_begin, impl::iter_advance_functor *advance_func) 00273 : data_begin_(data_begin), advance_func_(advance_func) {} 00274 00275 // begin iterator 00276 void *data_begin_; 00277 // function for advancing the iterator (owned by the view object) 00278 impl::iter_advance_functor *advance_func_; 00279 00280 friend class node; 00281 }; 00282 00283 } // end xml namespace 00284 00285 #endif // _xmlwrapp_nodes_view_h_