view_example.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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. // This example is intended to show you how to
  13. // use the 'view_clone_manager'. The idea
  14. // is that we have a container of non-polymorphic
  15. // objects and want to keep then sorted by different
  16. // criteria at the same time.
  17. //
  18. //
  19. // We'll go for 'ptr_vector' here. Using a node-based
  20. // container would be a waste of space here.
  21. // All container headers will also include
  22. // the Clone Managers.
  23. //
  24. #include <boost/ptr_container/ptr_vector.hpp>
  25. #include <boost/ptr_container/indirect_fun.hpp>
  26. #include <functional> // For 'binary_fnuction'
  27. #include <cstdlib> // For 'rand()'
  28. #include <algorithm> // For 'std::sort()'
  29. #include <iostream> // For 'std::cout'
  30. using namespace std;
  31. //
  32. // This is our simple example data-structure. It can
  33. // be ordered in three ways.
  34. //
  35. struct photon
  36. {
  37. photon() : color( rand() ),
  38. direction( rand() ),
  39. power( rand() )
  40. { }
  41. int color;
  42. int direction;
  43. int power;
  44. };
  45. //
  46. // Our big container is a standard vector
  47. //
  48. typedef std::vector<photon> vector_type;
  49. //
  50. // Now we define our view type by adding a second template argument.
  51. // The 'view_clone_manager' will implements Cloning by taking address
  52. // of objects.
  53. //
  54. // Notice the first template argument is 'photon' and not
  55. // 'const photon' to allow the view container write access.
  56. //
  57. typedef boost::ptr_vector<photon,boost::view_clone_allocator> view_type;
  58. //
  59. // Our first sort criterium
  60. //
  61. struct sort_by_color
  62. {
  63. typedef photon first_argument_type;
  64. typedef photon second_argument_type;
  65. typedef bool result_type;
  66. bool operator()( const photon& l, const photon& r ) const
  67. {
  68. return l.color < r.color;
  69. }
  70. };
  71. //
  72. // Our second sort criterium
  73. //
  74. struct sort_by_direction
  75. {
  76. typedef photon first_argument_type;
  77. typedef photon second_argument_type;
  78. typedef bool result_type;
  79. bool operator()( const photon& l, const photon& r ) const
  80. {
  81. return l.direction < r.direction;
  82. }
  83. };
  84. //
  85. // Our third sort criterium
  86. //
  87. struct sort_by_power
  88. {
  89. typedef photon first_argument_type;
  90. typedef photon second_argument_type;
  91. typedef bool result_type;
  92. bool operator()( const photon& l, const photon& r ) const
  93. {
  94. return l.power < r.power;
  95. }
  96. };
  97. //
  98. // This function inserts "Clones" into the
  99. // the view.
  100. //
  101. // We need to pass the first argument
  102. // as a non-const reference to be able to store
  103. // 'T*' instead of 'const T*' objects. Alternatively,
  104. // we might change the declaration of the 'view_type'
  105. // to
  106. // typedef boost::ptr_vector<const photon,boost::view_clone_manager>
  107. // view_type; ^^^^^^
  108. //
  109. void insert( vector_type& from, view_type& to )
  110. {
  111. to.insert( to.end(),
  112. from.begin(),
  113. from.end() );
  114. }
  115. int main()
  116. {
  117. enum { sz = 10, count = 500 };
  118. //
  119. // First we create the main container and two views
  120. //
  121. std::vector<vector_type> photons;
  122. view_type color_view;
  123. view_type direction_view;
  124. //
  125. // Then we fill the main container with some random data
  126. //
  127. for( int i = 0; i != sz; ++i )
  128. {
  129. photons.push_back( vector_type() );
  130. for( int j = 0; j != count; ++j )
  131. photons[i].push_back( photon() );
  132. }
  133. //
  134. // Then we create the two views.
  135. //
  136. for( int i = 0; i != sz; ++i )
  137. {
  138. insert( photons[i], color_view );
  139. insert( photons[i], direction_view );
  140. }
  141. //
  142. // First we sort the original photons, using one of
  143. // the view classes. This may sound trivial, but consider that
  144. // the objects are scatered all around 'sz' different vectors;
  145. // the view makes them act as one big vector.
  146. //
  147. std::sort( color_view.begin(), color_view.end(), sort_by_power() );
  148. //
  149. // And now we can sort the views themselves. Notice how
  150. // we switch to different iterators and different predicates:
  151. //
  152. color_view.sort( sort_by_color() );
  153. direction_view.sort( sort_by_direction() );
  154. return 0;
  155. }