File: view_example.cpp

package info (click to toggle)
boost1.83 1.83.0-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 545,632 kB
  • sloc: cpp: 3,857,086; xml: 125,552; ansic: 34,414; python: 25,887; asm: 5,276; sh: 4,799; ada: 1,681; makefile: 1,629; perl: 1,212; pascal: 1,139; sql: 810; yacc: 478; ruby: 102; lisp: 24; csh: 6
file content (180 lines) | stat: -rw-r--r-- 4,433 bytes parent folder | download | duplicates (13)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
//
// Boost.Pointer Container
//
//  Copyright Thorsten Ottosen 2003-2005. Use, modification and
//  distribution is subject to the Boost Software License, Version
//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see http://www.boost.org/libs/ptr_container/
//

//
// This example is intended to show you how to
// use the 'view_clone_manager'. The idea
// is that we have a container of non-polymorphic
// objects and want to keep then sorted by different
// criteria at the same time. 
//

//
// We'll go for 'ptr_vector' here. Using a node-based 
// container would be a waste of space here.
// All container headers will also include
// the Clone Managers.
// 
#include <boost/ptr_container/ptr_vector.hpp>
#include <boost/ptr_container/indirect_fun.hpp>

#include <functional> // For 'binary_fnuction'
#include <cstdlib>    // For 'rand()'
#include <algorithm>  // For 'std::sort()'
#include <iostream>   // For 'std::cout'

using namespace std;

//
// This is our simple example data-structure. It can
// be ordered in three ways.
//
struct photon
{
    photon() : color( rand() ), 
               direction( rand() ),
               power( rand() )
    { }
    
    int color;
    int direction;
    int power;
};

//
// Our big container is a standard vector
//
typedef std::vector<photon>                                 vector_type;

//
// Now we define our view type by adding a second template argument.
// The 'view_clone_manager' will implements Cloning by taking address
// of objects.
//
// Notice the first template argument is 'photon' and not
// 'const photon' to allow the view container write access.
//
typedef boost::ptr_vector<photon,boost::view_clone_allocator> view_type;

//
// Our first sort criterium
//
struct sort_by_color
{
    typedef photon first_argument_type;
    typedef photon second_argument_type;
    typedef bool result_type;

    bool operator()( const photon& l, const photon& r ) const
    {
        return l.color < r.color;
    }
};

//
// Our second sort criterium
//
struct sort_by_direction
{
    typedef photon first_argument_type;
    typedef photon second_argument_type;
    typedef bool result_type;

    bool operator()( const photon& l, const photon& r ) const
    {
        return l.direction < r.direction;
    }
};


//
// Our third sort criterium
//
struct sort_by_power
{
    typedef photon first_argument_type;
    typedef photon second_argument_type;
    typedef bool result_type;

    bool operator()( const photon& l, const photon& r ) const
    {
        return l.power < r.power;
    }
};

//
// This function inserts "Clones" into the
// the view. 
//
// We need to pass the first argument
// as a non-const reference to be able to store
// 'T*' instead of 'const T*' objects. Alternatively,
// we might change the declaration of the 'view_type'
// to 
//     typedef boost::ptr_vector<const photon,boost::view_clone_manager> 
//               view_type;     ^^^^^^
//
void insert( vector_type& from, view_type& to )
{
        to.insert( to.end(), 
                   from.begin(),
                   from.end() );
}

int main()
{
    enum { sz = 10, count = 500 };

    //
    // First we create the main container and two views
    //
    std::vector<vector_type>  photons;
    view_type                 color_view;
    view_type                 direction_view;

    //
    // Then we fill the main container with some random data
    //
    for( int i = 0; i != sz; ++i )
    {
        photons.push_back( vector_type() ); 

        for( int j = 0; j != count; ++j )
            photons[i].push_back( photon() );
    }

    //
    // Then we create the two views.
    //
    for( int i = 0; i != sz; ++i )
    {
        insert( photons[i], color_view );
        insert( photons[i], direction_view );
    }

    //
    // First we sort the original photons, using one of
    // the view classes. This may sound trivial, but consider that
    // the objects are scatered all around 'sz' different vectors;
    // the view makes them act as one big vector.
    //
    std::sort( color_view.begin(), color_view.end(), sort_by_power() );
    
    //
    // And now we can sort the views themselves. Notice how
    // we switch to different iterators and different predicates:
    //
    color_view.sort( sort_by_color() );

    direction_view.sort( sort_by_direction() );

    return 0;
}