used boost::iterator_adaptor

pull/40/head
Matchman Green 2012-05-11 00:06:05 +08:00
parent 155f4dae77
commit 204e0db62e
5 changed files with 58 additions and 69 deletions

View File

@ -7,6 +7,7 @@ find_package(JSONC REQUIRED)
find_package(CURL REQUIRED)
find_package(EXPAT REQUIRED)
find_package(CppUnit)
find_package(Boost REQUIRED)
IF ( CPPUNIT_FOUND )
set( OPT_INCS ${CPPUNIT_INCLUDE_DIR} )

View File

@ -37,6 +37,11 @@ class Json ;
class OAuth2 ;
class Path ;
/*! \brief corresponds to an "entry" in the resource feed
This class is decodes an entry in the resource feed. It will stored the properties like
title, filename and ETag etc in member variables.
*/
class Entry
{
public :

View File

@ -85,14 +85,14 @@ public :
if ( map[child->m_type] != 0 )
{
ImplVec& vec = *map[child->m_type] ;
iterator p = std::lower_bound( vec.begin(), vec.end(), child, Comp() ) ;
std::pair<iterator,iterator> p =
std::equal_range( vec.begin(), vec.end(), child, Comp() ) ;
// cannot allow duplicate attribute nodes
if ( child->m_type == attr && p != vec.end() &&
(*p)->m_type == attr && (*p)->m_name == child->m_name )
if ( child->m_type == attr && p.first != p.second )
throw std::runtime_error( "duplicate attribute " + child->m_name ) ;
vec.insert( p, child ) ;
vec.insert( p.second, child ) ;
}
m_children.push_back( child ) ;
@ -107,12 +107,10 @@ public :
: Find( m_element, name ) ;
}
Impl* Find( ImplVec& map, const std::string& name )
std::pair<iterator,iterator> Children( const std::string& name )
{
Impl tmp( name , element ) ;
iterator i = std::lower_bound( map.begin(), map.end(), &tmp, Comp() ) ;
return i != map.end() && (*i)->m_name == name ? *i : 0 ;
return std::equal_range( m_element.begin(), m_element.end(), &tmp, Comp() ) ;
}
iterator Begin()
@ -172,6 +170,15 @@ public :
}
} ;
private :
Impl* Find( ImplVec& map, const std::string& name )
{
Impl tmp( name , element ) ;
iterator i = std::lower_bound( map.begin(), map.end(), &tmp, Comp() ) ;
return i != map.end() && (*i)->m_name == name ? *i : 0 ;
}
private :
std::size_t m_ref ;
@ -182,40 +189,13 @@ private :
ImplVec m_children ;
} ;
Node::iterator::iterator( )
Node::iterator::iterator( ImplVec::iterator i ) : iterator_adaptor(i)
{
}
Node::iterator::iterator( ImplVec::iterator it ) : m_it( it )
Node::iterator::reference Node::iterator::dereference() const
{
}
Node::iterator::value_type Node::iterator::operator*() const
{
return Node( (*m_it)->AddRef() ) ;
}
Node::iterator Node::iterator::operator++()
{
m_it++ ;
return *this ;
}
Node::iterator Node::iterator::operator++(int)
{
iterator tmp( *this ) ;
++tmp ;
return tmp ;
}
bool Node::iterator::operator==( const iterator& i ) const
{
return m_it == i.m_it ;
}
bool Node::iterator::operator!=( const iterator& i ) const
{
return m_it != i.m_it ;
return Node( (*base_reference())->AddRef() ) ;
}
Node::Node() : m_ptr( new Impl )
@ -415,5 +395,11 @@ Node::Range Node::Attr() const
return std::make_pair( iterator(is.first), iterator(is.second) ) ;
}
Node::Range Node::Children( const std::string& name ) const
{
std::pair<Impl::iterator, Impl::iterator> is = m_ptr->Children( name ) ;
return std::make_pair( iterator(is.first), iterator(is.second) ) ;
}
} } // end namespace

View File

@ -19,6 +19,8 @@
#pragma once
#include <boost/iterator_adaptors.hpp>
#include <iosfwd>
#include <string>
#include <vector>
@ -28,9 +30,13 @@ namespace gr { namespace xml {
class Node
{
private :
class Impl ;
typedef std::vector<Impl*> ImplVec ;
public :
class iterator ;
typedef std::pair<Node::iterator, Node::iterator> Range ;
typedef std::pair<iterator, iterator> Range ;
public :
Node() ;
@ -66,34 +72,7 @@ public :
iterator end() const ;
Range Attr() const ;
private :
class Impl ;
typedef std::vector<Impl*> ImplVec ;
public :
class iterator
{
public :
iterator() ;
explicit iterator( std::vector< gr::xml::Node::Impl* >::iterator it ) ;
typedef Node value_type ;
typedef std::forward_iterator_tag iterator_category ;
typedef std::ptrdiff_t difference_type;
typedef Node* pointer;
typedef Node& reference;
value_type operator*() const ;
iterator operator++() ;
iterator operator++(int) ;
bool operator==( const iterator& i ) const ;
bool operator!=( const iterator& i ) const ;
private :
ImplVec::iterator m_it ;
} ;
Range Children( const std::string& name ) const ;
private :
explicit Node( Impl *impl ) ;
@ -102,6 +81,23 @@ private :
Impl *m_ptr ;
} ;
class Node::iterator : public boost::iterator_adaptor<
Node::iterator,
Node::ImplVec::iterator,
Node,
boost::random_access_traversal_tag,
Node
>
{
public :
explicit iterator( ImplVec::iterator i ) ;
private :
friend class boost::iterator_core_access;
reference dereference() const ;
} ;
std::ostream& operator<<( std::ostream& os, const Node& node ) ;
} } // end of namespace

View File

@ -55,7 +55,7 @@ void NodeTest::TestTree( )
void NodeTest::TestParseFile( )
{
Node n = TreeBuilder::Parse( "<entry><link href=\"q\"><href>abc</href></link></entry>" ) ;
Node n = TreeBuilder::Parse( "<entry><link href=\"q\"><href>abc</href></link><link></link></entry>" ) ;
CPPUNIT_ASSERT_EQUAL( std::string("entry"), n["entry"].Name() ) ;
CPPUNIT_ASSERT_EQUAL( std::string("link"), n["entry"]["link"].Name() ) ;
CPPUNIT_ASSERT_EQUAL( std::string("q"), n["entry"]["link"]["@href"].Value() ) ;
@ -70,7 +70,8 @@ void NodeTest::TestParseFile( )
++i ;
}
std::cout << n << std::endl ;
Node::Range r = n["entry"].Children("link") ;
// CPPUNIT_ASSERT_EQUAL( 2, r.second - r.first ) ;
}
} // end of namespace grut