test_data.hpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  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. #include <boost/static_assert.hpp>
  12. #include <boost/type_traits.hpp>
  13. #include <boost/config.hpp>
  14. #include <boost/test/unit_test.hpp>
  15. #include <boost/lexical_cast.hpp>
  16. #include <boost/functional/hash.hpp>
  17. #include <algorithm>
  18. #include <iostream>
  19. #include <string>
  20. #include <utility>
  21. #include <cstdlib>
  22. using namespace std;
  23. using namespace boost;
  24. //////////////////////////////////////////////////////////////////////////////
  25. // Test class 1: a class hierarchy
  26. //////////////////////////////////////////////////////////////////////////////
  27. namespace test
  28. {
  29. class Base
  30. {
  31. protected:
  32. Base( const Base& r ) : data1(r.data1), data2(r.data2),
  33. data3(r.data3), data(r.data)
  34. {
  35. #ifdef PTR_CONTAINER_DEBUG
  36. objects++;
  37. std::cout <<"+ " << objects << "\n";
  38. #endif
  39. }
  40. Base& operator=( const Base& );
  41. public: // for test reasons only
  42. int data1, data2, data3;
  43. string data;
  44. public:
  45. Base() : data1(1), data2(2), data3(rand()%256),
  46. data(lexical_cast<string>(rand()))
  47. {
  48. #ifdef PTR_CONTAINER_DEBUG
  49. objects++;
  50. std::cout <<"+ " << objects << "\n";
  51. #endif
  52. }
  53. virtual ~Base()
  54. {
  55. #ifdef PTR_CONTAINER_DEBUG
  56. objects--;
  57. std::cout <<"- " << objects << "\n";
  58. if( objects < 0 )
  59. terminate();
  60. #endif
  61. }
  62. void print( ostream& out ) const { do_print( out); }
  63. Base* clone() const { return do_clone(); }
  64. void foo() { do_foo(); }
  65. virtual bool less_than( const Base& b ) const
  66. {
  67. return data3 < b.data3;
  68. }
  69. virtual bool equal( const Base& b ) const
  70. {
  71. return data1 == b.data1 &&
  72. data2 == b.data2 &&
  73. data3 == b.data3 &&
  74. data == b.data;
  75. }
  76. #ifdef PTR_CONTAINER_DEBUG
  77. static int objects;
  78. #endif
  79. private:
  80. virtual void do_print( ostream& /*out*/ ) const { };
  81. virtual Base* do_clone() const { return new Base( *this ); };
  82. virtual void do_foo() { };
  83. };
  84. #ifdef PTR_CONTAINER_DEBUG
  85. int Base::objects = 0;
  86. #endif
  87. ostream& operator<<( ostream& out, const Base& b )
  88. {
  89. b.print( out );
  90. return out;
  91. }
  92. //
  93. // We rely on argument dependent lookup
  94. // for this to be found
  95. //
  96. inline Base* new_clone( const Base& b )
  97. {
  98. return b.clone();
  99. }
  100. inline bool operator<( const Base& l, const Base& r )
  101. {
  102. return l.less_than( r );
  103. }
  104. inline bool operator>( const Base& l, const Base& r )
  105. {
  106. return r < l;
  107. }
  108. inline bool operator==( const Base& l, const Base& r )
  109. {
  110. return l.equal( r );
  111. }
  112. inline bool operator!=( const Base& l, const Base& r )
  113. {
  114. return !l.equal( r );
  115. }
  116. inline std::size_t hash_value( const Base& b )
  117. {
  118. std::size_t seed = 0;
  119. boost::hash_combine( seed, b.data );
  120. boost::hash_combine( seed, b.data1 );
  121. boost::hash_combine( seed, b.data2 );
  122. boost::hash_combine( seed, b.data3 );
  123. return seed;
  124. }
  125. class Derived_class : public Base
  126. {
  127. protected:
  128. Derived_class( const Derived_class& r ) : Base( r ), i_(r.i_)
  129. { }
  130. public: // for test reasons only
  131. int i_;
  132. private:
  133. virtual void do_print( ostream& out ) const
  134. {
  135. out << i_;
  136. }
  137. virtual Base* do_clone() const
  138. {
  139. return new Derived_class( *this );
  140. }
  141. virtual void do_foo()
  142. {
  143. ++i_;
  144. }
  145. public:
  146. Derived_class() : i_( rand() )
  147. { }
  148. virtual bool less_than( const Base& b ) const
  149. {
  150. const Derived_class& d = dynamic_cast<const Derived_class&>( b );
  151. return i_ < d.i_;
  152. }
  153. };
  154. inline std::size_t hash_value( const Derived_class& b )
  155. {
  156. std::size_t seed = hash_value( static_cast<const Base&>( b ) );
  157. boost::hash_combine( seed, b.i_ );
  158. return seed;
  159. }
  160. }
  161. using test::Base;
  162. using test::Derived_class;
  163. //////////////////////////////////////////////////////////////////////////////
  164. // Test class 2: a value class
  165. //////////////////////////////////////////////////////////////////////////////
  166. class Value
  167. {
  168. public: // for test reasons only
  169. string s_;
  170. public:
  171. Value() : s_( boost::lexical_cast<string>( rand() ) )
  172. {}
  173. ~Value() { /** debug code here */ }
  174. string name() const
  175. {
  176. return s_;
  177. }
  178. };
  179. inline bool operator<( const Value& l, const Value& r )
  180. {
  181. return l.name() < r.name();
  182. }
  183. inline bool operator>( const Value& l, const Value& r )
  184. {
  185. return l.name() > r.name();
  186. }
  187. inline bool operator==( const Value& l, const Value& r )
  188. {
  189. return l.name() == r.name();
  190. }
  191. inline bool operator!=( const Value& l, const Value& r )
  192. {
  193. return l.name() != r.name();
  194. }
  195. inline ostream& operator<<( ostream& out, const Value& v )
  196. {
  197. return out << v.name() << " ";
  198. }
  199. inline std::size_t hash_value( const Value& v )
  200. {
  201. return boost::hash_value( v.s_ );
  202. }
  203. //
  204. // used to hide "unused variable" warnings
  205. //
  206. template< class T >
  207. inline void hide_warning( T& /*r*/ )
  208. { }
  209. //
  210. // used to customize tests for circular_buffer
  211. //
  212. template< class Cont >
  213. struct set_capacity
  214. {
  215. void operator()( Cont& ) const
  216. { }
  217. };
  218. //
  219. // transfer() test
  220. //
  221. template< class Cont1, class Cont2 >
  222. void transfer_test( Cont1& from, Cont2& to )
  223. {
  224. BOOST_TEST_MESSAGE( "starting container transfer test" );
  225. BOOST_CHECK( !from.empty() );
  226. to. BOOST_NESTED_TEMPLATE transfer<Cont1>( from );
  227. BOOST_CHECK( !to.empty() );
  228. BOOST_TEST_MESSAGE( "finishing container transfer test" );
  229. }
  230. //
  231. // test of copy operations
  232. //
  233. template< class BaseContainer, class DerivedContainer, class Derived >
  234. void container_assignment_test()
  235. {
  236. BOOST_TEST_MESSAGE( "starting container assignment test" );
  237. DerivedContainer derived;
  238. set_capacity<DerivedContainer>()( derived );
  239. derived.insert( derived.begin(), new Derived );
  240. derived.insert( derived.begin(), new Derived );
  241. BaseContainer base( derived );
  242. BOOST_CHECK_EQUAL( derived.size(), base.size() );
  243. base.clear();
  244. base = derived;
  245. BOOST_CHECK_EQUAL( derived.size(), base.size() );
  246. BaseContainer base2( base );
  247. BOOST_CHECK_EQUAL( base2.size(), base.size() );
  248. base2 = base;
  249. BOOST_CHECK_EQUAL( base2.size(), base.size() );
  250. base = base;
  251. BOOST_TEST_MESSAGE( "finished container assignment test" );
  252. }