/************************************************************************
Xport: XHTML Parsing & Objective Reporting Toolkit
Copyright (C) 2007 Mitchel Haas
This file is part of Xport.
Xport is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Xport is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Xport. If not, see <http://www.gnu.org/licenses/>.
For complete documentation on this library and alternative
licensing options, visit http://www.xportpro.com
Email questions, comments or suggestions to mitchel.haas@xportpro.com
************************************************************************/
#pragma once
#include <list>
namespace Xport
{
template<typename T, typename U> class xhtml_markup;
template<typename T> class xhtml_stylesheet_item;
template<typename T, typename U, typename V, typename W> class xhtml_element;
template<typename T, typename U, typename V, typename W> class markup_iterator;
template<typename T, typename U, typename V, typename W> class descendant_markup_iterator;
template<typename T, typename U, typename V, typename W> class reverse_markup_iterator;
}
namespace XportPro
{
template<typename T, typename U> class xp_markup;
template<typename T> class xp_stylesheet_item;
}
/************************************************************************/
/* markup_iterator */
/************************************************************************/
template<typename node_type, typename CT, typename pointer_type, typename reference_type>
class Xport::markup_iterator
#if defined(_MSC_VER) && _MSC_VER < 1300
: public std::iterator<std::bidirectional_iterator_tag, node_type>
#else
: public std::iterator<std::bidirectional_iterator_tag, node_type, ptrdiff_t, pointer_type, reference_type>
#endif
{
public:
// constructors/destructor
markup_iterator() : pIt_parent(0) {}
// conversion constructor for const_iterator, copy constructor for iterator
markup_iterator(const markup_iterator<node_type, CT, node_type*, node_type&>& src) : it(src.it), pIt_parent(src.pIt_parent) {}
virtual ~markup_iterator() {}
private:
explicit markup_iterator(typename std::list<node_type*>::const_iterator _it, const node_type* _pParent) : it(_it), pIt_parent(_pParent) {}
// destructor and assignment operator will be compiler generated correctly
public:
// overloaded operators
reference_type operator*() const { return *(*it); }
pointer_type operator->() const { return *it; }
bool operator == (const markup_iterator<node_type, CT, const node_type*, const node_type&>& rhs) const { return pIt_parent == rhs.pIt_parent && it == rhs.it; }
bool operator != (const markup_iterator<node_type, CT, const node_type*, const node_type&>& rhs) const { return !(*this == rhs); }
#if !defined(_MSC_VER) || _MSC_VER >= 1300
bool operator == (const markup_iterator<node_type, CT, node_type*, node_type&>& rhs) const { return pIt_parent == rhs.pIt_parent && it == rhs.it; }
bool operator != (const markup_iterator<node_type, CT, node_type*, node_type&>& rhs) const { return !(*this == rhs); }
#endif
markup_iterator& operator ++() { ++it; return *this; }
markup_iterator operator ++(int) { markup_iterator old(*this); ++*this; return old; }
markup_iterator& operator --() { --it; return *this; }
markup_iterator operator --(int) { markup_iterator old(*this); --*this; return old; }
private:
// data
typename std::list<node_type*>::const_iterator it;
const node_type* pIt_parent;
// friends
#if defined(_MSC_VER) && _MSC_VER < 1300
friend class xhtml_markup<xhtml_strict, CT>;
friend class xhtml_markup<xhtml_frameset, CT>;
friend class xhtml_markup<xhtml_transitional, CT>;
friend class xhtml_element<xhtml_strict, CT, node_type, xhtml_stylesheet_item<CT> >;
friend class xhtml_element<xhtml_frameset, CT, node_type, xhtml_stylesheet_item<CT> >;
friend class xhtml_element<xhtml_transitional, CT, node_type, xhtml_stylesheet_item<CT> >;
friend class xhtml_element<xhtml_strict, CT, node_type, XportPro::xp_stylesheet_item<CT> >;
friend class xhtml_element<xhtml_frameset, CT, node_type, XportPro::xp_stylesheet_item<CT> >;
friend class xhtml_element<xhtml_transitional, CT, node_type, XportPro::xp_stylesheet_item<CT> >;
friend class descendant_markup_iterator<node_type, CT, pointer_type, reference_type>;
friend class reverse_markup_iterator<node_type, CT, pointer_type, reference_type>;
#else
template<typename T, typename U> friend class xhtml_markup;
template<typename T, typename U, typename V, typename W> friend class xhtml_element;
template<typename T, typename U, typename V, typename W> friend class descendant_markup_iterator;
template<typename T, typename U, typename V, typename W> friend class reverse_markup_iterator;
#endif
friend class markup_iterator<node_type, CT, const node_type*, const node_type&>; // needed for conversion constructor & equality operator
friend class markup_iterator<node_type, CT, node_type*, node_type&>; // needed for equality operator
friend class XportPro::xp_markup<xhtml_strict, CT>;
friend class XportPro::xp_markup<xhtml_transitional, CT>;
friend class XportPro::xp_markup<xhtml_frameset, CT>;
};