~ubuntu-branches/debian/sid/boost1.49/sid

« back to all changes in this revision

Viewing changes to libs/range/test/test_driver/range_return_test_driver.hpp

  • Committer: Package Import Robot
  • Author(s): Steve M. Robbins
  • Date: 2012-02-26 00:31:44 UTC
  • Revision ID: package-import@ubuntu.com-20120226003144-eaytp12cbf6ubpms
Tags: upstream-1.49.0
ImportĀ upstreamĀ versionĀ 1.49.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//  Copyright Neil Groves 2009. Use, modification and
 
2
//  distribution is subject to the Boost Software License, Version
 
3
//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
 
4
//  http://www.boost.org/LICENSE_1_0.txt)
 
5
//
 
6
//
 
7
// For more information, see http://www.boost.org/libs/range/
 
8
//
 
9
#ifndef BOOST_RANGE_TEST_TEST_DRIVER_RANGE_RETURN_TEST_DRIVER_HPP_INCLUDED
 
10
#define BOOST_RANGE_TEST_TEST_DRIVER_RANGE_RETURN_TEST_DRIVER_HPP_INCLUDED
 
11
 
 
12
#include <boost/assert.hpp>
 
13
#include <boost/test/test_tools.hpp>
 
14
#include <boost/test/unit_test.hpp>
 
15
 
 
16
namespace boost
 
17
{
 
18
    namespace range_test
 
19
    {
 
20
        // check the results of an algorithm that returns
 
21
        // a range_return.
 
22
        //
 
23
        // This version is the general version. It should never be called.
 
24
        // All calls should invoke specialized implementations.
 
25
        template< range_return_value return_type >
 
26
        struct check_results
 
27
        {
 
28
            template< class Container, class Iterator >
 
29
            static void test(
 
30
                Container&          test,
 
31
                Container&          reference,
 
32
                Iterator            test_it,
 
33
                Iterator            reference_it
 
34
                )
 
35
            {
 
36
                BOOST_ASSERT( false );
 
37
            }
 
38
        };
 
39
 
 
40
        // check the results of an algorithm that returns
 
41
        // a 'found' iterator
 
42
        template< >
 
43
        struct check_results<return_found>
 
44
        {
 
45
            template< class Container, class Iterator >
 
46
            static void test(
 
47
                Container&          test,
 
48
                Container&          reference,
 
49
                Iterator            test_it,
 
50
                Iterator            reference_it
 
51
                )
 
52
            {
 
53
                BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
 
54
                    test.begin(), test.end() );
 
55
 
 
56
                BOOST_CHECK_EQUAL( std::distance(test.begin(), test_it),
 
57
                   std::distance(reference.begin(), reference_it) );
 
58
            }
 
59
        };
 
60
 
 
61
        // check the results of an algorithm that returns
 
62
        // a 'next(found)' iterator
 
63
        template< >
 
64
        struct check_results<return_next>
 
65
        {
 
66
            template< class Container, class Iterator >
 
67
            static void test(
 
68
                Container&          test,
 
69
                Container&          reference,
 
70
                Iterator            test_it,
 
71
                Iterator            reference_it
 
72
                )
 
73
            {
 
74
                BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
 
75
                    test.begin(), test.end() );
 
76
 
 
77
                if (reference_it == reference.end())
 
78
                {
 
79
                    BOOST_CHECK( test_it == test.end() );
 
80
                }
 
81
                else
 
82
                {
 
83
                    BOOST_CHECK_EQUAL(
 
84
                        std::distance(test.begin(), test_it),
 
85
                        std::distance(reference.begin(), reference_it) + 1);
 
86
                }
 
87
            }
 
88
        };
 
89
 
 
90
        // check the results of an algorithm that returns
 
91
        // a 'prior(found)' iterator
 
92
        template< >
 
93
        struct check_results<return_prior>
 
94
        {
 
95
            template< class Container, class Iterator >
 
96
            static void test(
 
97
                Container&          test,
 
98
                Container&          reference,
 
99
                Iterator            test_it,
 
100
                Iterator            reference_it
 
101
                )
 
102
            {
 
103
                BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
 
104
                    test.begin(), test.end() );
 
105
 
 
106
                if (reference_it == reference.begin())
 
107
                {
 
108
                    BOOST_CHECK( test_it == test.begin() );
 
109
                }
 
110
                else
 
111
                {
 
112
                    BOOST_CHECK_EQUAL(
 
113
                        std::distance(test.begin(), test_it) + 1,
 
114
                        std::distance(reference.begin(), reference_it));
 
115
                }
 
116
            }
 
117
        };
 
118
 
 
119
        // check the results of an algorithm that returns
 
120
        // a '[begin, found)' range
 
121
        template< >
 
122
        struct check_results<return_begin_found>
 
123
        {
 
124
            template< class Container, class Iterator >
 
125
            static void test(
 
126
                Container&                  test,
 
127
                Container&                  reference,
 
128
                iterator_range<Iterator>    test_rng,
 
129
                Iterator                    reference_it
 
130
                )
 
131
            {
 
132
                BOOST_CHECK_EQUAL_COLLECTIONS(
 
133
                    reference.begin(), reference.end(),
 
134
                    test.begin(), test.end()
 
135
                    );
 
136
 
 
137
                BOOST_CHECK( test_rng.begin() == test.begin() );
 
138
 
 
139
                BOOST_CHECK_EQUAL_COLLECTIONS(
 
140
                    reference.begin(), reference_it,
 
141
                    boost::begin(test_rng), boost::end(test_rng)
 
142
                    );
 
143
            }
 
144
        };
 
145
 
 
146
        // check the results of an algorithm that returns
 
147
        // a '[begin, next(found))' range
 
148
        template< >
 
149
        struct check_results<return_begin_next>
 
150
        {
 
151
            template< class Container, class Iterator >
 
152
            static void test(
 
153
                Container&                  test,
 
154
                Container&                  reference,
 
155
                iterator_range<Iterator>    test_rng,
 
156
                Iterator                    reference_it
 
157
                )
 
158
            {
 
159
                BOOST_CHECK_EQUAL_COLLECTIONS(
 
160
                    reference.begin(), reference.end(),
 
161
                    test.begin(), test.end()
 
162
                    );
 
163
 
 
164
                BOOST_CHECK( test_rng.begin() == test.begin() );
 
165
 
 
166
                if (reference_it == reference.end())
 
167
                {
 
168
                    BOOST_CHECK( test_rng.end() == test.end() );
 
169
                }
 
170
                else
 
171
                {
 
172
                    BOOST_CHECK_EQUAL_COLLECTIONS(
 
173
                        reference.begin(), boost::next(reference_it),
 
174
                        test_rng.begin(), test_rng.end());
 
175
                }
 
176
            }
 
177
        };
 
178
 
 
179
        // check the results of an algorithm that returns
 
180
        // a '[begin, prior(found))' range
 
181
        template< >
 
182
        struct check_results<return_begin_prior>
 
183
        {
 
184
            template< class Container, class Iterator >
 
185
            static void test(
 
186
                Container&                  test,
 
187
                Container&                  reference,
 
188
                iterator_range<Iterator>    test_rng,
 
189
                Iterator                    reference_it
 
190
                )
 
191
            {
 
192
                BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
 
193
                    test.begin(), test.end() );
 
194
 
 
195
                BOOST_CHECK( test_rng.begin() == test.begin() );
 
196
 
 
197
                if (reference_it == reference.begin())
 
198
                {
 
199
                    BOOST_CHECK( boost::end(test_rng) == test.begin() );
 
200
                }
 
201
                else
 
202
                {
 
203
                    BOOST_CHECK_EQUAL( std::distance(boost::begin(test_rng), boost::end(test_rng)) + 1,
 
204
                                       std::distance(reference.begin(), reference_it) );
 
205
                }
 
206
            }
 
207
        };
 
208
 
 
209
        // check the results of an algorithm that returns
 
210
        // a '[found, end)' range
 
211
        template< >
 
212
        struct check_results<return_found_end>
 
213
        {
 
214
            template< class Container, class Iterator >
 
215
            static void test(
 
216
                Container&                  test,
 
217
                Container&                  reference,
 
218
                iterator_range<Iterator>    test_rng,
 
219
                Iterator                    reference_it
 
220
                )
 
221
            {
 
222
                BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
 
223
                    test.begin(), test.end() );
 
224
 
 
225
                BOOST_CHECK_EQUAL(
 
226
                    std::distance(test.begin(), boost::begin(test_rng)),
 
227
                    std::distance(reference.begin(), reference_it));
 
228
 
 
229
                BOOST_CHECK( boost::end(test_rng) == test.end() );
 
230
            }
 
231
        };
 
232
 
 
233
        // check the results of an algorithm that returns
 
234
        // a '[next(found), end)' range
 
235
        template< >
 
236
        struct check_results<return_next_end>
 
237
        {
 
238
            template< class Container, class Iterator >
 
239
            static void test(
 
240
                Container&                  test,
 
241
                Container&                  reference,
 
242
                iterator_range<Iterator>    test_rng,
 
243
                Iterator                    reference_it
 
244
                )
 
245
            {
 
246
                BOOST_CHECK_EQUAL_COLLECTIONS(
 
247
                    reference.begin(), reference.end(),
 
248
                    test.begin(), test.end()
 
249
                    );
 
250
 
 
251
                BOOST_CHECK( test_rng.end() == test.end() );
 
252
 
 
253
                if (reference_it == reference.end())
 
254
                {
 
255
                    BOOST_CHECK( test_rng.begin() == test.end() );
 
256
                }
 
257
                else
 
258
                {
 
259
                    BOOST_CHECK_EQUAL_COLLECTIONS(
 
260
                        boost::next(reference_it), reference.end(),
 
261
                        test_rng.begin(), test_rng.end()
 
262
                        );
 
263
                }
 
264
            }
 
265
        };
 
266
 
 
267
        // check the results of an algorithm that returns
 
268
        // a 'prior(found), end)' range
 
269
        template< >
 
270
        struct check_results<return_prior_end>
 
271
        {
 
272
            template< class Container, class Iterator >
 
273
            static void test(
 
274
                Container&                  test,
 
275
                Container&                  reference,
 
276
                iterator_range<Iterator>    test_rng,
 
277
                Iterator                    reference_it
 
278
                )
 
279
            {
 
280
                BOOST_CHECK_EQUAL_COLLECTIONS(
 
281
                    reference.begin(), reference.end(),
 
282
                    test.begin(), test.end()
 
283
                    );
 
284
 
 
285
                BOOST_CHECK( test_rng.end() == test.end() );
 
286
 
 
287
                if (reference_it == reference.begin())
 
288
                {
 
289
                    BOOST_CHECK( test_rng.begin() == test.begin() );
 
290
                }
 
291
                else
 
292
                {
 
293
                    BOOST_CHECK_EQUAL_COLLECTIONS(
 
294
                        boost::prior(reference_it), reference.end(),
 
295
                        test_rng.begin(), test_rng.end()
 
296
                        );
 
297
                }
 
298
            }
 
299
        };
 
300
 
 
301
        // check the results of an algorithm that returns
 
302
        // a '[begin, end)' range
 
303
        template< >
 
304
        struct check_results<return_begin_end>
 
305
        {
 
306
            template< class Container, class Iterator >
 
307
            static void test(
 
308
                Container&                  test,
 
309
                Container&                  reference,
 
310
                iterator_range<Iterator>    test_rng,
 
311
                Iterator                    reference_it
 
312
                )
 
313
            {
 
314
                BOOST_CHECK_EQUAL_COLLECTIONS(
 
315
                    reference.begin(), reference.end(),
 
316
                    test.begin(), test.end()
 
317
                    );
 
318
 
 
319
                BOOST_CHECK( test_rng.begin() == test.begin() );
 
320
                BOOST_CHECK( test_rng.end() == test.end() );
 
321
            }
 
322
        };
 
323
 
 
324
        // A test driver to exercise a test through all of the range_return
 
325
        // combinations.
 
326
        //
 
327
        // The test driver also contains the code required to check the
 
328
        // return value correctness.
 
329
        //
 
330
        // The TestPolicy needs to implement two functions:
 
331
        //
 
332
        // - perform the boost range version of the algorithm that returns
 
333
        //   a range_return<Container,return_type>::type
 
334
        // template<range_return_value return_type, class Container>
 
335
        // BOOST_DEDUCED_TYPENAME range_return<Container,return_type>::type
 
336
        // test(Container& cont);
 
337
        //
 
338
        // - perform the reference std version of the algorithm that
 
339
        //   returns the standard iterator result
 
340
        // template<class Container>
 
341
        // BOOST_DEDUCED_TYPENAME range_iterator<Container>::type
 
342
        // reference(Container& cont);
 
343
        class range_return_test_driver
 
344
        {
 
345
        public:
 
346
            template< class Container,
 
347
                      class TestPolicy >
 
348
            void operator()(Container& cont, TestPolicy policy)
 
349
            {
 
350
                test_range_iter               (cont, policy);
 
351
                test_range<return_found,Container,TestPolicy>      ()(cont, policy);
 
352
                test_range<return_next,Container,TestPolicy>       ()(cont, policy);
 
353
                test_range<return_prior,Container,TestPolicy>      ()(cont, policy);
 
354
                test_range<return_begin_found,Container,TestPolicy>()(cont, policy);
 
355
                test_range<return_begin_next,Container,TestPolicy> ()(cont, policy);
 
356
                test_range<return_begin_prior,Container,TestPolicy>()(cont, policy);
 
357
                test_range<return_found_end,Container,TestPolicy>  ()(cont, policy);
 
358
                test_range<return_next_end,Container,TestPolicy>   ()(cont, policy);
 
359
                test_range<return_prior_end,Container,TestPolicy>  ()(cont, policy);
 
360
                test_range<return_begin_end,Container,TestPolicy>  ()(cont, policy);
 
361
            }
 
362
 
 
363
        private:
 
364
            template< class Container, class TestPolicy >
 
365
            void test_range_iter(
 
366
                Container&          cont,
 
367
                TestPolicy          policy
 
368
                )
 
369
            {
 
370
                typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::type iterator_t;
 
371
 
 
372
                Container reference(cont);
 
373
                Container test(cont);
 
374
 
 
375
                iterator_t range_result = policy.test_iter(test);
 
376
                iterator_t reference_it = policy.reference(reference);
 
377
 
 
378
                check_results<return_found>::test(test, reference,
 
379
                                                  range_result, reference_it);
 
380
            }
 
381
 
 
382
            template< range_return_value result_type, class Container, class TestPolicy >
 
383
            struct test_range
 
384
            {
 
385
                void operator()(Container& cont, TestPolicy policy)
 
386
                {
 
387
                    typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::type iterator_t;
 
388
                    typedef BOOST_DEDUCED_TYPENAME range_return<Container, result_type>::type range_return_t;
 
389
                    typedef BOOST_DEDUCED_TYPENAME TestPolicy::template test_range<result_type> test_range_t;
 
390
 
 
391
                    Container reference(cont);
 
392
                    Container test_cont(cont);
 
393
 
 
394
                    test_range_t test_range_fn;
 
395
                    range_return_t range_result = test_range_fn(policy, test_cont);
 
396
                    iterator_t reference_it = policy.reference(reference);
 
397
 
 
398
                    check_results<result_type>::test(test_cont, reference,
 
399
                                                     range_result, reference_it);
 
400
                }
 
401
            };
 
402
        };
 
403
    }
 
404
}
 
405
 
 
406
#endif // include guard