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