1 /*=============================================================================
2     Copyright (c) 2001-2011 Joel de Guzman
3     Copyright (c) 2007 Dan Marsden
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 <boost/detail/lightweight_test.hpp>
9 #include <boost/fusion/container/vector/vector.hpp>
10 #include <boost/fusion/adapted/mpl.hpp>
11 #include <boost/fusion/sequence/io/out.hpp>
12 #include <boost/fusion/container/generation/make_vector.hpp>
13 #include <boost/fusion/sequence/comparison/equal_to.hpp>
14 #include <boost/fusion/algorithm/transformation/transform.hpp>
15 #include <boost/type_traits/is_class.hpp>
16 #include <boost/type_traits/is_same.hpp>
17 #include <boost/mpl/range_c.hpp>
18 #include <boost/type_traits/is_reference.hpp>
19 
20 struct square
21 {
22     template<typename Sig>
23     struct result;
24 
25     template <typename T>
26     struct result<square(T)>
27     {
28         typedef int type;
29     };
30 
31     template <typename T>
operator ()square32     int operator()(T x) const
33     {
34         return x * x;
35     }
36 };
37 
38 struct add
39 {
40     template<typename Sig>
41     struct result;
42 
43     template <typename A, typename B>
44     struct result<add(A, B)>
45     {
46         typedef int type;
47     };
48 
49     template <typename A, typename B>
operator ()add50     int operator()(A a, B b) const
51     {
52         return a + b;
53     }
54 };
55 
56 struct unary_lvalue_transform
57 {
58     template<typename Sig>
59     struct result;
60 
61     template<typename T>
62     struct result<unary_lvalue_transform(T&)>
63     {
64         typedef T* type;
65     };
66 
67     template<typename T>
operator ()unary_lvalue_transform68     T* operator()(T& t) const
69     {
70         return &t;
71     }
72 };
73 
twice(int v)74 int twice(int v)
75 {
76     return v*2;
77 }
78 
79 struct binary_lvalue_transform
80 {
81     template<typename Sig>
82     struct result;
83 
84     template<typename T0, typename T1>
85     struct result<binary_lvalue_transform(T0&,T1&)>
86     {
87         typedef T0* type;
88     };
89 
90     template<typename T0, typename T1>
91     T0* operator()(T0& t0, T1&) const
92     {
93         return &t0;
94     }
95 };
96 
97 int
main()98 main()
99 {
100     using namespace boost::fusion;
101     using boost::mpl::range_c;
102 
103     std::cout << tuple_open('[');
104     std::cout << tuple_close(']');
105     std::cout << tuple_delimiter(", ");
106 
107 /// Testing the transform
108 
109     {
110         typedef range_c<int, 5, 9> sequence_type;
111         sequence_type sequence;
112         std::cout << boost::fusion::transform(sequence, square()) << std::endl;
113         BOOST_TEST((boost::fusion::transform(sequence, square()) == make_vector(25, 36, 49, 64)));
114     }
115 
116     {
117         typedef range_c<int, 5, 9> mpl_list1;
118         std::cout << boost::fusion::transform(mpl_list1(), square()) << std::endl;
119         BOOST_TEST((boost::fusion::transform(mpl_list1(), square()) == make_vector(25, 36, 49, 64)));
120     }
121 
122     {
123         vector<int, int, int> tup(1, 2, 3);
124         std::cout << boost::fusion::transform(tup, square()) << std::endl;
125         BOOST_TEST((boost::fusion::transform(tup, square()) == make_vector(1, 4, 9)));
126     }
127 
128     {
129         vector<int, int, int> tup1(1, 2, 3);
130         vector<int, int, int> tup2(4, 5, 6);
131         std::cout << boost::fusion::transform(tup1, tup2, add()) << std::endl;
132         BOOST_TEST((boost::fusion::transform(tup1, tup2, add()) == make_vector(5, 7, 9)));
133     }
134 
135     {
136         // Unary transform that requires lvalues, just check compilation
137         vector<int, int, int> tup1(1, 2, 3);
138         BOOST_TEST(at_c<0>(boost::fusion::transform(tup1, unary_lvalue_transform())) == &at_c<0>(tup1));
139         BOOST_TEST(*begin(boost::fusion::transform(tup1, unary_lvalue_transform())) == &at_c<0>(tup1));
140     }
141 
142     {
143         vector<int, int, int> tup1(1, 2, 3);
144         vector<int, int, int> tup2(4, 5, 6);
145         BOOST_TEST(at_c<0>(boost::fusion::transform(tup1, tup2, binary_lvalue_transform())) == &at_c<0>(tup1));
146         BOOST_TEST(*begin(boost::fusion::transform(tup1, tup2, binary_lvalue_transform())) == &at_c<0>(tup1));
147     }
148 
149     {
150         vector<int, int, int> tup1(1, 2, 3);
151         BOOST_TEST(boost::fusion::transform(tup1, twice) == make_vector(2,4,6));
152     }
153 
154 
155     return boost::report_errors();
156 }
157 
158