• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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