/************************************************************************
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>
#include "markup_iterator.h"
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
namespace Xport
{
template<typename T, typename U> class xhtml_markup;
template<typename T, typename U, typename V, typename W> class descendant_markup_iterator;
}
namespace XportPro
{
template<typename T, typename U> class xp_markup;
}
/************************************************************************/
/* descendant_markup_iterator */
/************************************************************************/
template<typename node_type, typename CT, typename pointer_type, typename reference_type>
class Xport::descendant_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
descendant_markup_iterator() : pTop_node(0), at_top(false) {}
// conversion constructor for const_descendant_iterator. copy constructor for descendant_iterator
descendant_markup_iterator(const descendant_markup_iterator<node_type, CT, node_type*, node_type&>& src) : it(src.it), pTop_node(src.pTop_node), at_top(src.at_top) {}
virtual ~descendant_markup_iterator() {}
private:
descendant_markup_iterator(pointer_type pCalled_node, bool beg) : it(beg ? pCalled_node->begin() : pCalled_node->end()), pTop_node(pCalled_node), at_top(beg) {}
// destructor and assignment operator will be compiler generated correctly
public:
// overloaded operators
descendant_markup_iterator& operator ++();
descendant_markup_iterator operator ++(int) { descendant_markup_iterator old(*this); ++*this; return old; }
descendant_markup_iterator& operator --();
descendant_markup_iterator operator --(int) { descendant_markup_iterator old(*this); --*this; return old; }
// public interface
reference_type operator*() const { return at_top ? *pTop_node : it.operator *(); }
pointer_type operator->() const { return at_top ? pTop_node : it.operator ->(); }
bool operator == (const descendant_markup_iterator<node_type, CT, const node_type*, const node_type&>& rhs) const { return it == rhs.it && at_top == rhs.at_top; }
bool operator != (const descendant_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 descendant_markup_iterator<node_type, CT, node_type*, node_type&>& rhs) const { return it == rhs.it && at_top == rhs.at_top; }
bool operator != (const descendant_markup_iterator<node_type, CT, node_type*, node_type&>& rhs) const { return !(*this == rhs); }
#endif
// data
private:
markup_iterator<node_type, CT, pointer_type, reference_type> it;
std::stack<markup_iterator<node_type, CT, pointer_type, reference_type> > node_stack;
pointer_type pTop_node;
typename std::list<node_type*>::const_reverse_iterator rit;
bool at_top;
// 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>;
#else
template<typename T, typename U> friend class xhtml_markup;
#endif
friend class descendant_markup_iterator<node_type, CT, const node_type*, const node_type&>; // needed for conversion constructor & equality operator
friend class descendant_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>;
};
#include "descendant_markup_iterator.inl"