Imported Upstream version 1.57.0
[platform/upstream/boost.git] / libs / range / test / adaptor_test / type_erased_example.cpp
1 // Boost.Range library
2 //
3 //  Copyright Neil Groves 2010. Use, modification and
4 //  distribution is subject to the Boost Software License, Version
5 //  1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 //  http://www.boost.org/LICENSE_1_0.txt)
7 //
8 //
9 // For more information, see http://www.boost.org/libs/range/
10 //
11 //[type_erased_example
12 #include <boost/range/adaptor/type_erased.hpp>
13 #include <boost/range/algorithm/copy.hpp>
14 #include <boost/assign.hpp>
15 #include <boost/foreach.hpp>
16 #include <iterator>
17 #include <iostream>
18 #include <list>
19 #include <vector>
20 //<-
21 #include <boost/test/test_tools.hpp>
22 #include <boost/test/unit_test.hpp>
23
24 namespace
25 {
26     namespace boost_range_test
27     {
28         namespace type_erased_example
29         {
30 //->            
31
32 // The client interface from an OO perspective merely requires a sequence
33 // of integers that can be forward traversed
34 typedef boost::any_range<
35     int
36   , boost::forward_traversal_tag
37   , int
38   , std::ptrdiff_t
39 > integer_range;
40
41 namespace server
42 {
43     void display_integers(const integer_range& rng)
44     {
45         boost::copy(rng,
46                     std::ostream_iterator<int>(std::cout, ","));
47
48         std::cout << std::endl;
49     }
50 }
51
52 namespace client
53 {
54     void run()
55     {
56         using namespace boost::assign;
57         using namespace boost::adaptors;
58
59         // Under most conditions one would simply use an appropriate
60         // any_range as a function parameter. The type_erased adaptor
61         // is often superfluous. However because the type_erased
62         // adaptor is applied to a range, we can use default template
63         // arguments that are generated in conjunction with the
64         // range type to which we are applying the adaptor.
65
66         std::vector<int> input;
67         input += 1,2,3,4,5;
68
69         // Note that this call is to a non-template function
70         server::display_integers(input);
71
72         std::list<int> input2;
73         input2 += 6,7,8,9,10;
74
75         // Note that this call is to the same non-tempate function
76         server::display_integers(input2);
77
78         input2.clear();
79         input2 += 11,12,13,14,15;
80
81         // Calling using the adaptor looks like this:
82         // Notice that here I have a type_erased that would be a
83         // bidirectional_traversal_tag, but this is convertible
84         // to the forward_traversal_tag equivalent hence this
85         // works.
86         server::display_integers(input2 | type_erased<>());
87
88         // However we may simply wish to define an adaptor that
89         // takes a range and makes it into an appropriate
90         // forward_traversal any_range...
91         typedef boost::adaptors::type_erased<
92             boost::use_default
93           , boost::forward_traversal_tag
94         > type_erased_forward;
95
96         // This adaptor can turn other containers with different
97         // value_types and reference_types into the appropriate
98         // any_range.
99
100         server::display_integers(input2 | type_erased_forward());
101     }
102 }
103
104 //=int main(int argc, const char* argv[])
105 //={
106 //=    client::run();
107 //=    return 0;
108 //=}
109 //]
110
111         } // namespace type_erased_example
112     } // namespace boost_range_test
113 } // anonymous namespace
114
115 boost::unit_test::test_suite*
116 init_unit_test_suite(int argc, char* argv[])
117 {
118     boost::unit_test::test_suite* test
119         = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.type_erased_example" );
120
121     test->add( BOOST_TEST_CASE( &boost_range_test::type_erased_example::client::run) );
122
123     return test;
124 }