1 /*=============================================================================
2 Copyright (c) 2001-2011 Joel de Guzman
3 Copyright (c) 2011 Eric Niebler
4
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 ==============================================================================*/
8 #include <sstream>
9 #include <boost/detail/lightweight_test.hpp>
10 #include <boost/fusion/algorithm/iteration/for_each.hpp>
11 #include <boost/fusion/algorithm/query/find_if.hpp>
12 #include <boost/fusion/container/vector/vector.hpp>
13 #include <boost/fusion/container/generation/make_vector.hpp>
14 #include <boost/fusion/view/iterator_range/iterator_range.hpp>
15 #include <boost/fusion/sequence/comparison/equal_to.hpp>
16 #include <boost/fusion/sequence/io/out.hpp>
17 #include <boost/fusion/sequence/intrinsic/size.hpp>
18 #include <boost/mpl/vector_c.hpp>
19 #include <boost/mpl/begin.hpp>
20 #include <boost/mpl/next.hpp>
21 #include <boost/static_assert.hpp>
22 #include "tree.hpp"
23
24 struct ostream_fun
25 {
ostream_funostream_fun26 ostream_fun(std::ostream &sout)
27 : sout_(sout)
28 {}
29 template<typename T>
operator ()ostream_fun30 void operator ()(T const &t) const
31 {
32 sout_ << t << ' ';
33 }
34 private:
35 std::ostream & sout_;
36 };
37
38 template<typename Tree>
39 void
process_tree(Tree const & tree)40 process_tree(Tree const &tree)
41 {
42 using namespace boost;
43 using namespace fusion;
44 using mpl::_;
45
46 typedef typename boost::fusion::result_of::find_if<Tree const, is_same<_,short> >::type short_iter;
47 typedef typename boost::fusion::result_of::find_if<Tree const, is_same<_,float> >::type float_iter;
48
49 typedef iterator_range<short_iter, float_iter> slice_t;
50 BOOST_STATIC_ASSERT(traits::is_segmented<slice_t>::value);
51
52 // find_if of a segmented data structure returns generic
53 // segmented iterators
54 short_iter si = find_if<is_same<_,short> >(tree);
55 float_iter fi = find_if<is_same<_,float> >(tree);
56
57 // If you put them in an iterator range, the range
58 // is automatically a segmented data structure.
59 slice_t slice(si, fi);
60
61 std::stringstream sout;
62 fusion::for_each(slice, ostream_fun(sout));
63 BOOST_TEST((sout.str() == "100 e f 0 B "));
64 }
65
66 int
main()67 main()
68 {
69 using namespace boost::fusion;
70
71 std::cout << tuple_open('[');
72 std::cout << tuple_close(']');
73 std::cout << tuple_delimiter(", ");
74
75 {
76 char const* s = "Ruby";
77 typedef vector<int, char, double, char const*> vector_type;
78 vector_type vec(1, 'x', 3.3, s);
79
80 {
81 typedef vector_iterator<vector_type, 1> i1t;
82 typedef vector_iterator<vector_type, 3> i3t;
83
84 i1t i1(vec);
85 i3t i3(vec);
86
87 typedef iterator_range<i1t, i3t> slice_t;
88 slice_t slice(i1, i3);
89 std::cout << slice << std::endl;
90 BOOST_TEST((slice == make_vector('x', 3.3)));
91 BOOST_STATIC_ASSERT(boost::fusion::result_of::size<slice_t>::value == 2);
92 }
93
94 {
95 typedef vector_iterator<vector_type, 0> i1t;
96 typedef vector_iterator<vector_type, 0> i3t;
97
98 i1t i1(vec);
99 i3t i3(vec);
100
101 typedef iterator_range<i1t, i3t> slice_t;
102 slice_t slice(i1, i3);
103 std::cout << slice << std::endl;
104 BOOST_TEST(slice == make_vector());
105 BOOST_STATIC_ASSERT(boost::fusion::result_of::size<slice_t>::value == 0);
106 }
107 }
108
109 {
110 typedef boost::mpl::vector_c<int, 2, 3, 4, 5, 6> mpl_vec;
111 typedef boost::mpl::begin<mpl_vec>::type it0;
112 typedef boost::mpl::next<it0>::type it1;
113 typedef boost::mpl::next<it1>::type it2;
114 typedef boost::mpl::next<it2>::type it3;
115
116 it1 f;
117 it3 l;
118
119 typedef iterator_range<it1, it3> slice_t;
120 slice_t slice(f, l);
121 std::cout << slice << std::endl;
122 BOOST_TEST((slice == make_vector(3, 4)));
123 BOOST_STATIC_ASSERT(boost::fusion::result_of::size<slice_t>::value == 2);
124 }
125
126 {
127 process_tree(
128 make_tree(
129 make_vector(double(0),'B')
130 , make_tree(
131 make_vector(1,2,long(3))
132 , make_tree(make_vector('a','b','c'))
133 , make_tree(make_vector(short('d'),'e','f'))
134 )
135 , make_tree(
136 make_vector(4,5,6)
137 , make_tree(make_vector(float(1),'h','i'))
138 , make_tree(make_vector('j','k','l'))
139 )
140 )
141 );
142 }
143
144 return boost::report_errors();
145 }
146
147