⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 node_iterator.h

📁 彩信浏览器
💻 H
字号:
/* * This file is part of Ambulant Player, www.ambulantplayer.org. * * Copyright (C) 2003-2007 Stichting CWI,  * Kruislaan 413, 1098 SJ Amsterdam, The Netherlands. * * Ambulant Player is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * Ambulant Player 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Ambulant Player; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA *//*  * @$Id: node_iterator.h,v 1.12 2007/02/12 14:14:38 jackjansen Exp $  */#ifndef AMBULANT_LIB_NODE_ITERATOR_H#define AMBULANT_LIB_NODE_ITERATOR_H#include "ambulant/config/config.h"// pair#include <utility>namespace ambulant {namespace lib {/// Node tree iterator.////// Traverses a constant XML tree.////// Root designates the container to be traversed and remains const./// Each node is visited twice: once in the 'down' direction and once in the 'up-next'.////// the first element is: (true, root) /// the last element is: (false, root) /// incrementing last element results to the universal 'end' element (0, *).////// (*it).first is true or false depending on the direction/// (*it).second is a pointer to the node.template <class Node>class const_tree_iterator  {  //////////////  public:	/// The type of the values returned by this iterator.	typedef std::pair<bool, const Node*> const_deref_type;	const_tree_iterator()	:	m_root(0), m_cur(0), m_move(&const_tree_iterator::down) {}			const_tree_iterator(const Node *p)	:	m_root(p), m_cur(p), m_move(&const_tree_iterator::down) {}	// pre-increment	const_tree_iterator& operator++() { if(m_cur)(this->*m_move)(); return *this;}		// post-increment	const_tree_iterator operator++(int) 		{ const_tree_iterator temp(*this); ++*this; return temp;}	// dereferencing this returns a pair of const_deref_type	const_deref_type operator*() { return const_deref_type((m_move == &const_tree_iterator::down), m_cur);}	// an instance of this object acts like a pointer to a const_deref_type	// it->m_cur is the node, it->m_move is true if 'down'    const_deref_type* operator->() {return (&**this); }	/// True if iterator is exhausted.	bool is_end() { return m_cur == 0;}	/// Returns the current node.	const Node *get_cur() const { return m_cur;}		/// Returns the root of this iterator. 	const Node *get_root() const { return m_root;}		/// Returns true if the two iterators move in the same direction.  	bool same_move(const const_tree_iterator& o) const   		{ return m_move == o.m_move;}  	///////////////  protected:	void down();	void next();	void up();	// container traversed by this iterator	const Node *m_root;		// iterator state	const Node *m_cur;	void (const_tree_iterator::*m_move)();};////////////////////////// tree_iterator/// Node tree iterator.////// Traverses an XML tree.////// Root designates the container to be traversed and remains const./// Each node is visited twice: once in the 'down' direction and once in the 'up-next'.////// the first element is: (true, root) /// the last element is: (false, root) /// incrementing last element results to the universal 'end' element (0, *).////// (*it).first is true or false depending on the direction/// (*it).second is a pointer to the node.template <class Node>class tree_iterator : public const_tree_iterator<Node> {  public:	/// The type of the values returned by this iterator.	typedef std::pair<bool, Node*> deref_type;	tree_iterator() : const_tree_iterator<Node>(){}	tree_iterator(Node *p) : const_tree_iterator<Node>(p){}	// pre-increment	tree_iterator& operator++() { if(this->m_cur)(this->*const_tree_iterator<Node>::m_move)(); return *this;}		// post-increment	tree_iterator operator++(int) 		{ tree_iterator temp(*this); ++*this; return temp;}	// dereferencing this returns a pair of deref_type	deref_type operator*() 		{ return deref_type( (this->m_move == &tree_iterator::down), const_cast<Node*>(this->m_cur));}	// an instance of this object acts like a pointer to a deref_type	// it->m_cur is the node, it->m_move is true if 'down'    deref_type* operator->() {return (&**this); }};////////////////////////////// const_tree_iterator inline implementationtemplate<class Node>inline void const_tree_iterator<Node>::down() {	const Node *p = m_cur->down();	if(!p) m_move = &const_tree_iterator::next;	else m_cur = p;}template<class Node>inline void const_tree_iterator<Node>::next() {	if(m_cur == m_root) { m_cur = 0; return;}		const Node* it = m_cur->next();	if(it) {		m_move = &const_tree_iterator::down;		m_cur = it;	} else {		m_move = &const_tree_iterator::up;		(this->*m_move)();	}}template<class Node>inline void const_tree_iterator<Node>::up() {	if(m_cur == m_root) { m_cur = 0; return;}	const Node* it = m_cur->up();	assert(it);	if(it) {		m_move = &const_tree_iterator::next;		m_cur = it;	}}} // namespace lib } // namespace ambulant/// Returns true if two iterators are in exactly the same state on the same tree.template <class Node>bool operator==(const ambulant::lib::const_tree_iterator<Node>& lhs, 	const ambulant::lib::const_tree_iterator<Node>& rhs) {		if((lhs.get_cur() == 0 && rhs.get_cur() != 0) || 			(lhs.get_cur() != 0 && rhs.get_cur() == 0)) return false;		if(lhs.get_cur() == 0 && rhs.get_cur() == 0) return true;		return lhs.get_root() == rhs.get_root() && 			lhs.get_cur() == rhs.get_cur() && 			lhs.same_move(rhs);	}template <class Node>bool operator!=(const ambulant::lib::const_tree_iterator<Node>& lhs, 	const ambulant::lib::const_tree_iterator<Node>& rhs)	{ return !(lhs == rhs);}	/// Returns true if two iterators are in exactly the same state on the same tree.template <class Node>bool operator==(const ambulant::lib::tree_iterator<Node>& lhs, 	const ambulant::lib::tree_iterator<Node>& rhs) {		if((lhs.get_cur() == 0 && rhs.get_cur() != 0) || 			(lhs.get_cur() != 0 && rhs.get_cur() == 0)) return false;		if(lhs.get_cur() == 0 && rhs.get_cur() == 0) return true;		return lhs.get_root() == rhs.get_root() && 			lhs.get_cur() == rhs.get_cur() && 			lhs.same_move(rhs);	}template <class Node>bool operator!=(const ambulant::lib::tree_iterator<Node>& lhs, 	const ambulant::lib::tree_iterator<Node>& rhs)	{ return !(lhs == rhs);}#endif // AMBULANT_LIB_TREE_NODE_ITERATOR_H

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -