]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | { | |
42 | 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 | // | |
11fdf7f2 | 70 | struct sort_by_color |
7c673cae | 71 | { |
11fdf7f2 TL |
72 | typedef photon first_argument_type; |
73 | typedef photon second_argument_type; | |
74 | typedef bool result_type; | |
75 | ||
7c673cae FG |
76 | 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 | // | |
11fdf7f2 | 85 | struct sort_by_direction |
7c673cae | 86 | { |
11fdf7f2 TL |
87 | typedef photon first_argument_type; |
88 | typedef photon second_argument_type; | |
89 | typedef bool result_type; | |
90 | ||
7c673cae FG |
91 | 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 | // | |
11fdf7f2 | 101 | struct sort_by_power |
7c673cae | 102 | { |
11fdf7f2 TL |
103 | typedef photon first_argument_type; |
104 | typedef photon second_argument_type; | |
105 | typedef bool result_type; | |
106 | ||
7c673cae FG |
107 | 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 | // | |
125 | void insert( vector_type& from, view_type& to ) | |
126 | { | |
127 | to.insert( to.end(), | |
128 | from.begin(), | |
129 | from.end() ); | |
130 | } | |
131 | ||
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 | } |