xmlwrapp
nodes_view.h
Go to the documentation of this file.
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 
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 
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  */
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 
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.
179  iterator begin() { return iterator(data_begin_, advance_func_); }
180 
181  /// Get an iterator that points to the beginning of this view's nodes.
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.
185  iterator end() { return iterator(); }
186 
187  /// Get an iterator that points one past the last child for this view.
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?
194  bool empty() const { return !data_begin_; }
195 
196 private:
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 
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.
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.
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?
247  bool empty() const { return !data_begin_; }
248 
249 private:
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_