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