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