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
24namespace
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
34typedef boost::any_range<
35 int
36 , boost::forward_traversal_tag
37 , int
38 , std::ptrdiff_t
39> integer_range;
40
41namespace server
42{
43 void display_integers(const integer_range& rng)
44 {
45 boost::copy(rng,
46 out: std::ostream_iterator<int>(std::cout, ","));
47
48 std::cout << std::endl;
49 }
50}
51
52namespace 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(rng: 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(rng: 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(rng: 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(rng: 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
115boost::unit_test::test_suite*
116init_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}
125

source code of boost/libs/range/test/adaptor_test/type_erased_example.cpp