xmlwrapp
xmlwrapp/nodes_view.h
Go to the documentation of this file.
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_