1 /***************************************************************************
2 * examples/stream/stream1.cpp
3 *
4 * This file contains the example snippets from the stream tutorial.
5 *
6 * Part of the STXXL. See http://stxxl.sourceforge.net
7 *
8 * Copyright (C) 2012-2013 Timo Bingmann <tb@panthema.net>
9 *
10 * Distributed under the Boost Software License, Version 1.0.
11 * (See accompanying file LICENSE_1_0.txt or copy at
12 * http://www.boost.org/LICENSE_1_0.txt)
13 **************************************************************************/
14
15 #include <stxxl/stream>
16 #include <stxxl/vector>
17 #include <stxxl/sorter>
18
19 #include <vector>
20 #include <climits>
21
22 struct counter_object
23 {
24 // This stream produces a sequence of integers.
25 typedef int value_type;
26
27 private:
28 // A class attribute to save the current value.
29 int m_current_value;
30
31 public:
32 // A constructor to set the initial value to 1.
counter_objectcounter_object33 counter_object()
34 : m_current_value(1)
35 { }
36
37 // The retrieve operator returning the current value.
operator *counter_object38 const value_type& operator * () const
39 {
40 return m_current_value;
41 }
42
43 // Increment operator advancing to the next integer.
operator ++counter_object44 counter_object& operator ++ ()
45 {
46 ++m_current_value;
47 return *this;
48 }
49
50 // Empty indicator, which in this case can check the current value.
emptycounter_object51 bool empty() const
52 {
53 return (m_current_value > 1000);
54 }
55 };
56
57 template <typename InputStream>
58 struct squaring_object
59 {
60 // This stream produces a sequence of integers.
61 typedef int value_type;
62
63 private:
64 // A reference to another stream of integers, which are our input.
65 InputStream& m_input_stream;
66
67 // A temporary value buffer to hold the current square in for retrieval.
68 value_type m_current_value;
69
70 public:
71 // A constructor taking another stream of integers as input.
squaring_objectsquaring_object72 squaring_object(InputStream& input_stream)
73 : m_input_stream(input_stream)
74 {
75 if (!m_input_stream.empty())
76 {
77 m_current_value = *m_input_stream;
78 m_current_value = m_current_value * m_current_value;
79 }
80 }
81
82 // The retrieve operator returning the square of the input stream.
operator *squaring_object83 const value_type& operator * () const
84 {
85 return m_current_value;
86 }
87
88 // Increment operator: handled by incrementing the input stream.
operator ++squaring_object89 squaring_object& operator ++ ()
90 {
91 ++m_input_stream;
92 if (!m_input_stream.empty())
93 {
94 m_current_value = *m_input_stream;
95 m_current_value = m_current_value * m_current_value;
96 }
97 return *this;
98 }
99
100 // Empty indicator: this stream is empty when the input stream is.
emptysquaring_object101 bool empty() const
102 {
103 return m_input_stream.empty();
104 }
105 };
106
107 // define comparator class: compare right-most decimal and then absolute value
108 struct CompareMod10
109 {
110 // comparison operator() returning true if (a < b)
operator ()CompareMod10111 inline bool operator () (int a, int b) const
112 {
113 if ((a % 10) == (b % 10))
114 return a < b;
115 else
116 return (a % 10) < (b % 10);
117 }
118
119 // smallest possible integer value
min_valueCompareMod10120 int min_value() const { return INT_MIN; }
121 // largest possible integer value
max_valueCompareMod10122 int max_value() const { return INT_MAX; }
123 };
124
main()125 int main()
126 {
127 {
128 counter_object counter;
129
130 while (!counter.empty())
131 {
132 std::cout << *counter << " ";
133 ++counter;
134 }
135 std::cout << std::endl;
136 }
137
138 {
139 for (counter_object cnt; !cnt.empty(); ++cnt)
140 {
141 std::cout << *cnt << " ";
142 }
143 std::cout << std::endl;
144 }
145
146 {
147 counter_object counter;
148 squaring_object<counter_object> squares(counter);
149
150 while (!squares.empty())
151 {
152 std::cout << *squares << " ";
153 ++squares;
154 }
155 std::cout << std::endl;
156 }
157
158 {
159 std::vector<int> intvector;
160 // (fill intvector)
161
162 // define stream class iterating over an integer vector
163 typedef stxxl::stream::iterator2stream<std::vector<int>::const_iterator> intstream_type;
164
165 // instantiate the stream object, iterate from begin to end of intvector.
166 intstream_type intstream(intvector.begin(), intvector.end());
167
168 // plug in squaring object after vector iterator stream.
169 squaring_object<intstream_type> squares(intstream);
170 }
171
172 {
173 stxxl::vector<int> intvector;
174 // (fill intvector)
175
176 // define stream class iterating over an integer vector
177 typedef stxxl::stream::vector_iterator2stream<stxxl::vector<int>::const_iterator> intstream_type;
178
179 // instantiate the stream object, iterate from begin to end of intvector.
180 intstream_type intstream(intvector.begin(), intvector.end());
181
182 // plug in squaring object after vector iterator stream.
183 squaring_object<intstream_type> squares(intstream);
184 }
185
186 {
187 // construct the squared counter stream
188 counter_object counter;
189 squaring_object<counter_object> squares(counter);
190
191 // allocate vector of 100 integers
192 std::vector<int> intvector(100);
193
194 // materialize 100 integers from stream and put into vector
195 stxxl::stream::materialize(squares, intvector.begin(), intvector.end());
196 }
197
198 {
199 // construct the squared counter stream
200 counter_object counter;
201 squaring_object<counter_object> squares(counter);
202
203 // allocate STXXL vector of 100 integers
204 stxxl::vector<int> intvector(100);
205
206 // materialize 100 integers from stream and put into STXXL vector
207 stxxl::stream::materialize(squares, intvector.begin(), intvector.end());
208 }
209
210 {
211 static const int ram_use = 10 * 1024 * 1024; // amount of memory to use in runs creation
212
213 counter_object counter; // the counter stream from first examples
214
215 // define a runs sorter for the counter stream which order by CompareMod10 object.
216 typedef stxxl::stream::runs_creator<counter_object, CompareMod10> rc_counter_type;
217
218 // instance of CompareMod10 comparator class
219 CompareMod10 comparemod10;
220
221 // instance of runs_creator which reads the counter stream.
222 rc_counter_type rc_counter(counter, comparemod10, ram_use);
223
224 // define a runs merger for the sorted runs from rc_counter.
225 typedef stxxl::stream::runs_merger<rc_counter_type::sorted_runs_type, CompareMod10> rm_counter_type;
226
227 // instance of runs_merger which merges sorted runs from rc_counter.
228 rm_counter_type rm_counter(rc_counter.result(), comparemod10, ram_use);
229
230 // read sorted stream: runs_merger also conforms to the stream interface.
231 while (!rm_counter.empty())
232 {
233 std::cout << *rm_counter << " ";
234 ++rm_counter;
235 }
236 std::cout << std::endl;
237 }
238
239 {
240 static const int ram_use = 10 * 1024 * 1024; // amount of memory to use in runs creation
241
242 // define a runs sorter which accepts imperative push()s and orders by CompareMod10 object.
243 typedef stxxl::stream::runs_creator<stxxl::stream::use_push<int>, CompareMod10> rc_counter_type;
244
245 // instance of CompareMod10 comparator class.
246 CompareMod10 comparemod10;
247
248 // instance of runs_creator which waits for input.
249 rc_counter_type rc_counter(comparemod10, ram_use);
250
251 // write sequence of integers into runs
252 for (int i = 1; i <= 1000; ++i)
253 rc_counter.push(i);
254
255 // define a runs merger for the sorted runs from rc_counter.
256 typedef stxxl::stream::runs_merger<rc_counter_type::sorted_runs_type, CompareMod10> rm_counter_type;
257
258 // instance of runs_merger which merges sorted runs from rc_counter.
259 rm_counter_type rm_counter(rc_counter.result(), comparemod10, ram_use);
260
261 // read sorted stream: runs_merger also conforms to the stream interface.
262 while (!rm_counter.empty())
263 {
264 std::cout << *rm_counter << " ";
265 ++rm_counter;
266 }
267 std::cout << std::endl;
268 }
269
270 {
271 static const int ram_use = 10 * 1024 * 1024; // amount of memory to use in runs creation
272
273 // define a runs sorter which accepts imperative push()s and orders by CompareMod10 object.
274 typedef stxxl::sorter<int, CompareMod10> sr_counter_type;
275
276 // instance of CompareMod10 comparator class.
277 CompareMod10 comparemod10;
278
279 // instance of sorter which waits for input.
280 sr_counter_type sr_counter(comparemod10, ram_use);
281
282 // write sequence of integers into sorter, which creates sorted runs
283 for (int i = 1; i <= 1000; ++i)
284 sr_counter.push(i);
285
286 // signal sorter that the input stream is finished and switch to output mode.
287 sr_counter.sort();
288
289 // read sorted stream: sorter also conforms to the stream interface.
290 while (!sr_counter.empty())
291 {
292 std::cout << *sr_counter << " ";
293 ++sr_counter;
294 }
295 std::cout << std::endl;
296 }
297 }
298