2 // Boost.Pointer Container
4 // Copyright Thorsten Ottosen 2003-2005. Use, modification and
5 // distribution is subject to the Boost Software License, Version
6 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
9 // For more information, see http://www.boost.org/libs/ptr_container/
12 #include "test_data.hpp"
13 #include <boost/ptr_container/ptr_vector.hpp>
14 #include <boost/utility.hpp>
15 #include <boost/lexical_cast.hpp>
22 using namespace boost
;
28 typedef ptr_vector
<node
> nodes_t
;
33 { nodes
.swap( r
.nodes
); }
36 typedef nodes_t::iterator iterator
;
37 typedef nodes_t::const_iterator const_iterator
;
40 void add_child( node
* n
);
41 void remove( iterator n
);
42 void write_tree( ostream
& os
) const;
44 node
& child( size_t idx
);
45 const node
& child( size_t idx
) const;
46 iterator
child_begin();
47 const_iterator
child_begin() const;
49 const_iterator
child_end() const;
50 iterator
find( const string
& match
);
55 class node
: noncopyable
57 virtual size_t do_node_size() const = 0;
58 virtual string
do_description() const = 0;
59 virtual void do_write_value( ostream
& os
) const = 0;
63 size_t node_size() const { return do_node_size(); }
64 string
description() const { return do_description(); }
65 void write_value( ostream
& os
) const { do_write_value( os
); }
70 class inner_node
: public node
, public tree
74 virtual size_t do_node_size() const
79 virtual string
do_description() const
81 return lexical_cast
<string
>( name
);
84 virtual void do_write_value( ostream
& os
) const
86 os
<< " inner node: " << name
;
89 void swap( inner_node
& r
)
96 inner_node() : name("inner node")
99 inner_node( const string
& r
) : name(r
)
102 inner_node
* release()
104 inner_node
* ptr( new inner_node
);
113 class leaf
: public node
117 virtual size_t do_node_size() const
122 virtual string
do_description() const
124 return lexical_cast
<string
>( data
);
127 virtual void do_write_value( ostream
& os
) const
129 os
<< " leaf: " << data
;
136 leaf( const T
& r
) : data(r
)
139 void set_data( const T
& r
)
143 /////////////////////////////////////////////////////////////////////////
144 // tree implementation
145 /////////////////////////////////////////////////////////////////////////
147 inline void tree::add_child( node
* n
)
149 nodes
.push_back( n
);
152 inline void tree::remove( iterator n
)
154 BOOST_ASSERT( n
!= nodes
.end() );
158 void tree::write_tree( ostream
& os
) const
160 for( const_iterator i
= nodes
.begin(),
164 i
->write_value( os
);
165 if( const inner_node
* p
= dynamic_cast<const inner_node
*>( &*i
) )
170 size_t tree::size() const
174 for( const_iterator i
= nodes
.begin(),
178 res
+= i
->node_size();
184 inline node
& tree::child( size_t idx
)
189 inline const node
& tree::child( size_t idx
) const
194 inline tree::iterator
tree::child_begin()
196 return nodes
.begin();
199 inline tree::const_iterator
tree::child_begin() const
201 return nodes
.begin();
204 inline tree::iterator
tree::child_end()
209 inline tree::const_iterator
tree::child_end() const
214 tree::iterator
tree::find( const string
& match
)
216 for( iterator i
= nodes
.begin(),
220 if( i
->description() == match
)
223 if( inner_node
* p
= dynamic_cast<inner_node
*>( &*i
) )
225 iterator j
= p
->find( match
);
226 if( j
!= p
->child_end() )
235 /////////////////////////////////////////////////////////////////////////
237 /////////////////////////////////////////////////////////////////////////
242 BOOST_CHECK_EQUAL( root
.size(), 1u );
243 inner_node
node1( "node 1" );
244 node1
.add_child( new leaf
<string
>( "leaf 1" ) );
245 node1
.add_child( new leaf
<int>( 42 ) );
246 inner_node
node2( "node 2" );
247 node2
.add_child( new leaf
<float>( 42.0f
) );
248 node2
.add_child( new leaf
<string
>( "leaf 4" ) );
250 root
.add_child( node1
.release() );
251 BOOST_CHECK_EQUAL( root
.size(), 4u );
252 root
.add_child( node2
.release() );
253 root
.add_child( new inner_node( "node 3" ) );
254 BOOST_CHECK_EQUAL( root
.size(), 8u );
255 root
.add_child( new leaf
<string
>( "leaf 5" ) );
256 BOOST_CHECK_EQUAL( root
.size(), 9u );
258 root
.write_tree( cout
);
259 tree::iterator a_leaf
= root
.find( "42" );
260 BOOST_CHECK_EQUAL( a_leaf
->description(), "42" );
261 leaf
<int>& the_leaf
= dynamic_cast< leaf
<int>& >( *a_leaf
);
262 the_leaf
.set_data( 2*42 );
263 BOOST_CHECK_EQUAL( a_leaf
->description(), "84" );
267 #include <boost/test/unit_test.hpp>
268 using boost::unit_test::test_suite
;
270 test_suite
* init_unit_test_suite( int argc
, char* argv
[] )
272 test_suite
* test
= BOOST_TEST_SUITE( "Pointer Container Test Suite" );
274 test
->add( BOOST_TEST_CASE( &test_tree
) );