• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Boost.Pointer Container
3 //
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)
8 //
9 // For more information, see http://www.boost.org/libs/ptr_container/
10 //
11 
12 #include <boost/test/unit_test.hpp>
13 #include "test_data.hpp"
14 #include <boost/ptr_container/ptr_array.hpp>
15 #include <boost/ptr_container/detail/ptr_container_disable_deprecated.hpp>
16 #include <boost/utility.hpp>
17 #include <boost/array.hpp>
18 #include <algorithm>
19 #include <iostream>
20 #include <cstddef>
21 #include <string>
22 
23 using namespace std;
24 using namespace boost;
25 
26 template< class Node, size_t N >
27 class n_ary_tree : boost::noncopyable
28 {
29     typedef n_ary_tree<Node,N>       this_type;
30     typedef ptr_array<this_type,N>   tree_t;
31 
32     tree_t         tree;
33     Node           data;
34 
35 public:
n_ary_tree()36     n_ary_tree()                                 { }
n_ary_tree(const Node & r)37     n_ary_tree( const Node& r ) : data(r)        { }
38 
39 public: // modifers
set_data(const Node & r)40     void               set_data( const Node& r ) { data = r; }
41     template< size_t idx >
set_child(this_type * r)42     void               set_child( this_type* r ) { tree. BOOST_NESTED_TEMPLATE replace<idx>(r); }
43 
44 public: // accessors
45     void               print( std::ostream&, std::string indent = "  " );
46     template< size_t idx >
child()47     this_type&         child()                   { return tree. BOOST_NESTED_TEMPLATE at<idx>(); }
48     template< size_t idx >
child() const49     const this_type&   child() const             { return tree. BOOST_NESTED_TEMPLATE at<idx>(); }
50 
51 };
52 
53 
54 
55 template< class Node, size_t N >
print(std::ostream & out,std::string indent)56 void n_ary_tree<Node,N>::print( std::ostream& out, std::string indent )
57 {
58     out << indent << data << "\n";
59     indent += "  ";
60     for( size_t i = 0; i != N; ++i )
61         if( !tree.is_null(i) )
62             tree[i].print( out, indent  + "  " );
63 }
64 
65 
66 template< class C, class B, class T >
67 void test_array_interface();
68 
69 #if defined(BOOST_PTR_CONTAINER_DISABLE_DEPRECATED)
70 #pragma GCC diagnostic push
71 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
72 #endif
73 
test_array()74 void test_array()
75 {
76     typedef n_ary_tree<std::string,2> binary_tree;
77     binary_tree tree;
78     tree.set_data( "root" );
79     tree.set_child<0>( new binary_tree( "left subtree" ) );
80     tree.set_child<1>( new binary_tree( "right subtree" ) );
81     binary_tree& left = tree.child<0>();
82     left.set_child<0>( new binary_tree( "left left subtree" ) );
83     left.set_child<1>( new binary_tree( "left right subtree" ) );
84     binary_tree& right = tree.child<1>();
85     right.set_child<0>( new binary_tree( "right left subtree" ) );
86     right.set_child<1>( new binary_tree( "right right subtree" ) );
87 
88     tree.print( std::cout );
89 
90     test_array_interface<ptr_array<Base,10>,Base,Derived_class>();
91     test_array_interface<ptr_array<nullable<Base>,10>,Base,Derived_class>();
92     test_array_interface<ptr_array<Value,10>,Value,Value>();
93     test_array_interface<ptr_array<nullable<Value>,10>,Value,Value>();
94 
95     ptr_array<int,10> vec;
96     BOOST_CHECK_THROW( vec.at(10), bad_ptr_container_operation );
97     BOOST_CHECK_THROW( (vec.replace(10u, new int(0))), bad_ptr_container_operation );
98 #ifndef BOOST_NO_AUTO_PTR
99     BOOST_CHECK_THROW( (vec.replace(10u, std::auto_ptr<int>(new int(0)))), bad_ptr_container_operation );
100 #endif
101 #ifndef BOOST_NO_CXX11_SMART_PTR
102     BOOST_CHECK_THROW( (vec.replace(10u, std::unique_ptr<int>(new int(0)))), bad_ptr_container_operation );
103 #endif
104     BOOST_CHECK_THROW( (vec.replace(0u, 0)), bad_ptr_container_operation );
105 
106     ptr_array<Derived_class,2> derived;
107     derived.replace( 0, new Derived_class );
108     derived.replace( 1, new Derived_class );
109     ptr_array<Base,2> base( derived );
110 
111     BOOST_TEST_MESSAGE( "finished derived to base test" );
112 
113     base = derived;
114     ptr_array<Base,2> base2( base );
115     base2 = base;
116     base  = base;
117 }
118 
119 template< class C, class B, class T >
test_array_interface()120 void test_array_interface()
121 {
122     C c;
123     c.replace( 0, new T );
124     c.replace( 1, new B );
125     c.replace( 9, new T );
126 #ifndef BOOST_NO_AUTO_PTR
127     c.replace( 0, std::auto_ptr<T>( new T ) );
128 #endif
129 #ifndef BOOST_NO_CXX11_SMART_PTR
130     c.replace( 0, std::unique_ptr<T>( new T ) );
131 #endif
132     const C c2( c.clone() );
133 
134     BOOST_DEDUCED_TYPENAME C::iterator i                  = c.begin();
135     hide_warning(i);
136     BOOST_DEDUCED_TYPENAME C::const_iterator ci           = c2.begin();
137     hide_warning(ci);
138     BOOST_DEDUCED_TYPENAME C::iterator i2                 = c.end();
139     hide_warning(i2);
140     BOOST_DEDUCED_TYPENAME C::const_iterator ci2          = c2.begin();
141     hide_warning(ci2);
142     BOOST_DEDUCED_TYPENAME C::reverse_iterator ri         = c.rbegin();
143     hide_warning(ri);
144     BOOST_DEDUCED_TYPENAME C::const_reverse_iterator cri  = c2.rbegin();
145     hide_warning(cri);
146     BOOST_DEDUCED_TYPENAME C::reverse_iterator rv2        = c.rend();
147     hide_warning(rv2);
148     BOOST_DEDUCED_TYPENAME C::const_reverse_iterator cvr2 = c2.rend();
149     hide_warning(cvr2);
150 
151     BOOST_TEST_MESSAGE( "finished iterator test" );
152 
153     BOOST_CHECK_EQUAL( c.empty(), false );
154     BOOST_CHECK_EQUAL( c.size(), c.max_size() );
155 
156     BOOST_TEST_MESSAGE( "finished capacity test" );
157 
158     BOOST_CHECK_EQUAL( c.is_null(0), false );
159     BOOST_CHECK_EQUAL( c.is_null(1), false );
160     BOOST_CHECK_EQUAL( c.is_null(2), true );
161 
162     c.front();
163     c.back();
164     c2.front();
165     c2.back();
166     C c3;
167     c.swap( c3 );
168     C c4;
169     swap(c4,c3);
170     c3.swap(c4);
171 
172     BOOST_CHECK_EQUAL( c.is_null(0), true );
173     BOOST_CHECK_EQUAL( c3.is_null(0), false );
174 
175     c.replace( 5, new T );
176     BOOST_CHECK_EQUAL( c.is_null(5), false );
177     c = c3.release();
178     for( size_t i = 0; i < c3.size(); ++i )
179         BOOST_CHECK_EQUAL( c3.is_null(i), true );
180 
181     BOOST_TEST_MESSAGE( "finished element access test" );
182 }
183 
184 #if defined(BOOST_PTR_CONTAINER_DISABLE_DEPRECATED)
185 #pragma GCC diagnostic pop
186 #endif
187 
188 using boost::unit_test::test_suite;
189 
init_unit_test_suite(int argc,char * argv[])190 test_suite* init_unit_test_suite( int argc, char* argv[] )
191 {
192     test_suite* test = BOOST_TEST_SUITE( "Pointer Container Test Suite" );
193 
194     test->add( BOOST_TEST_CASE( &test_array ) );
195 
196     return test;
197 }
198