1 /* 2 * Copyright (C) 2009 Vaclav Slavik <vslavik@gmail.com> 3 * All Rights Reserved 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in 13 * the documentation and/or other materials provided with the 14 * distribution. 15 * 3. Neither the name of the Author nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 23 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 27 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 29 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 /** 34 @file 35 36 This file contains the definition of the xml::nodes_view and 37 xml::const_nodes_view classes. 38 */ 39 40 #ifndef _xmlwrapp_nodes_view_h_ 41 #define _xmlwrapp_nodes_view_h_ 42 43 // xmlwrapp includes 44 #include "xmlwrapp/init.h" 45 #include "xmlwrapp/export.h" 46 47 // standard includes 48 #include <iterator> 49 50 namespace xml 51 { 52 53 class node; 54 class const_nodes_view; 55 56 namespace impl 57 { 58 59 struct nipimpl; 60 class iter_advance_functor; 61 62 } // namespace impl 63 64 /** 65 This class implements a view of XML nodes. A @em view is a container-like 66 class that only allows access to a subset of xml::node's child nodes. The 67 exact content depends on how the view was obtained; typical uses are 68 e.g. a view of all element children or all elements with a given name. 69 70 The nodes_view class implements the same container interface that 71 xml::node does: it has begin() and end() methods. 72 73 @since 0.6.0 74 75 @see xml::node::elements(), xml::node::elements(const char *) 76 */ 77 class XMLWRAPP_API nodes_view 78 { 79 public: 80 /// Size type. 81 typedef std::size_t size_type; 82 nodes_view()83 nodes_view() : data_begin_(0), advance_func_(0) {} 84 nodes_view(const nodes_view& other); 85 ~nodes_view(); 86 87 nodes_view& operator=(const nodes_view& other); 88 89 class const_iterator; 90 91 /** 92 The iterator provides a way to access nodes in the view 93 similar to a standard C++ container. 94 95 @see xml::node::iterator 96 */ 97 class iterator 98 { 99 public: 100 typedef node value_type; 101 typedef int difference_type; 102 typedef value_type* pointer; 103 typedef value_type& reference; 104 typedef std::forward_iterator_tag iterator_category; 105 iterator()106 iterator() : pimpl_(0), advance_func_(0) {} 107 iterator(const iterator& other); 108 iterator& operator=(const iterator& other); 109 ~iterator(); 110 111 reference operator*() const; 112 pointer operator->() const; 113 114 iterator& operator++(); 115 iterator operator++(int); 116 117 private: 118 explicit iterator(void *data, impl::iter_advance_functor *advance_func); 119 void* get_raw_node() const; 120 void swap(iterator& other); 121 122 impl::nipimpl *pimpl_; 123 // function for advancing the iterator (note that it is "owned" by the 124 // parent view object, so we don't have to care about its reference 125 // count here) 126 impl::iter_advance_functor *advance_func_; 127 128 friend class nodes_view; 129 friend class const_iterator; 130 friend bool XMLWRAPP_API operator==(const iterator& lhs, const iterator& rhs); 131 }; 132 133 /** 134 The const_iterator provides a way to access nodes in the view 135 similar to a standard C++ container. The nodes that are pointed to by 136 the iterator cannot be changed. 137 138 @see xml::node::const_iterator 139 */ 140 class const_iterator 141 { 142 public: 143 typedef const node value_type; 144 typedef int difference_type; 145 typedef value_type* pointer; 146 typedef value_type& reference; 147 typedef std::forward_iterator_tag iterator_category; 148 const_iterator()149 const_iterator() : pimpl_(0), advance_func_(0) {} 150 const_iterator(const const_iterator& other); 151 const_iterator(const iterator& other); 152 const_iterator& operator=(const const_iterator& other); 153 const_iterator& operator=(const iterator& other); 154 ~const_iterator(); 155 156 reference operator*() const; 157 pointer operator->() const; 158 159 const_iterator& operator++(); 160 const_iterator operator++(int); 161 162 private: 163 explicit const_iterator(void *data, impl::iter_advance_functor *advance_func); 164 void* get_raw_node() const; 165 void swap(const_iterator& other); 166 167 impl::nipimpl *pimpl_; 168 // function for advancing the iterator (note that it is "owned" by the 169 // parent view object, so we don't have to care about its reference 170 // count here) 171 impl::iter_advance_functor *advance_func_; 172 173 friend class const_nodes_view; 174 friend class nodes_view; 175 friend bool XMLWRAPP_API operator==(const const_iterator& lhs, const const_iterator& rhs); 176 }; 177 178 /// Get an iterator that points to the beginning of this view's nodes. begin()179 iterator begin() { return iterator(data_begin_, advance_func_); } 180 181 /// Get an iterator that points to the beginning of this view's nodes. begin()182 const_iterator begin() const { return const_iterator(data_begin_, advance_func_); } 183 184 /// Get an iterator that points one past the last child for this view. end()185 iterator end() { return iterator(); } 186 187 /// Get an iterator that points one past the last child for this view. end()188 const_iterator end() const { return const_iterator(); } 189 190 /// Returns the number of nodes in this view. 191 size_type size() const; 192 193 /// Is the view empty? empty()194 bool empty() const { return !data_begin_; } 195 196 private: nodes_view(void * data_begin,impl::iter_advance_functor * advance_func)197 explicit nodes_view(void *data_begin, impl::iter_advance_functor *advance_func) 198 : data_begin_(data_begin), advance_func_(advance_func) {} 199 200 // begin iterator 201 void *data_begin_; 202 // function for advancing the iterator (owned by the view object) 203 impl::iter_advance_functor *advance_func_; 204 205 friend class node; 206 friend class const_nodes_view; 207 }; 208 209 210 /** 211 This class implements a @em read-only view of XML nodes. The only 212 difference from xml::nodes_view is that it doesn't allow modifications of 213 the nodes, it is otherwise identical. 214 215 @see nodes_view 216 217 @since 0.6.0 218 */ 219 class XMLWRAPP_API const_nodes_view 220 { 221 public: 222 /// Size type. 223 typedef std::size_t size_type; 224 const_nodes_view()225 const_nodes_view() : data_begin_(0), advance_func_(0) {} 226 const_nodes_view(const const_nodes_view& other); 227 const_nodes_view(const nodes_view& other); 228 ~const_nodes_view(); 229 230 const_nodes_view& operator=(const const_nodes_view& other); 231 const_nodes_view& operator=(const nodes_view& other); 232 233 typedef nodes_view::const_iterator iterator; 234 typedef nodes_view::const_iterator const_iterator; 235 236 /// Get an iterator that points to the beginning of this view's nodes. begin()237 const_iterator begin() const 238 { return const_iterator(data_begin_, advance_func_); } 239 240 /// Get an iterator that points one past the last child for this view. end()241 const_iterator end() const { return const_iterator(); } 242 243 /// Returns the number of nodes in this view. 244 size_type size() const; 245 246 /// Is the view empty? empty()247 bool empty() const { return !data_begin_; } 248 249 private: const_nodes_view(void * data_begin,impl::iter_advance_functor * advance_func)250 explicit const_nodes_view(void *data_begin, impl::iter_advance_functor *advance_func) 251 : data_begin_(data_begin), advance_func_(advance_func) {} 252 253 // begin iterator 254 void *data_begin_; 255 // function for advancing the iterator (owned by the view object) 256 impl::iter_advance_functor *advance_func_; 257 258 friend class node; 259 }; 260 261 // Comparison operators for xml::[const_]nodes_view iterators 262 263 inline bool XMLWRAPP_API operator==(const nodes_view::iterator& lhs, 264 const nodes_view::iterator& rhs) 265 { return lhs.get_raw_node() == rhs.get_raw_node(); } 266 inline bool XMLWRAPP_API operator!=(const nodes_view::iterator& lhs, 267 const nodes_view::iterator& rhs) 268 { return !(lhs == rhs); } 269 270 inline bool XMLWRAPP_API operator==(const nodes_view::const_iterator& lhs, 271 const nodes_view::const_iterator& rhs) 272 { return lhs.get_raw_node() == rhs.get_raw_node(); } 273 inline bool XMLWRAPP_API operator!=(const nodes_view::const_iterator& lhs, 274 const nodes_view::const_iterator& rhs) 275 { return !(lhs == rhs); } 276 277 } // end xml namespace 278 279 #endif // _xmlwrapp_nodes_view_h_ 280