85cad3898dfe0fba3b9a023f16d20fa0448cdfad
[platform/upstream/boost.git] / libs / variant / test / recursive_variant_test.cpp
1 //-----------------------------------------------------------------------------
2 // boost-libs variant/test/recursive_variant_test.cpp source file
3 // See http://www.boost.org for updates, documentation, and revision history.
4 //-----------------------------------------------------------------------------
5 //
6 // Copyright (c) 2003
7 // Eric Friedman, Itay Maman
8 //
9 // Distributed under the Boost Software License, Version 1.0. (See
10 // accompanying file LICENSE_1_0.txt or copy at
11 // http://www.boost.org/LICENSE_1_0.txt)
12
13 #include "boost/test/minimal.hpp"
14 #include "boost/variant.hpp"
15 #include "boost/mpl/vector.hpp"
16 #include "boost/mpl/copy.hpp"
17
18 #include <iostream>
19 #include <sstream>
20 #include <vector>
21 #include <map>
22
23 struct vector_printer
24     : boost::static_visitor<std::string>
25 {
26     template <typename T>
27     std::string operator()(const std::vector<T>& vec) const
28     {
29         std::ostringstream ost;
30
31         ost << "( ";
32
33         typename std::vector<T>::const_iterator it = vec.begin();
34         for (; it != vec.end(); ++it)
35             ost << boost::apply_visitor( vector_printer(), *it );
36
37         ost << ") ";
38
39         return ost.str();
40     }
41
42     template <typename T>
43     std::string operator()(const T& operand) const
44     {
45         std::ostringstream ost;
46         ost << operand << ' ';
47         return ost.str();
48     }
49 };
50
51 void test_recursive_variant()
52 {
53     typedef boost::make_recursive_variant<
54           int
55         , std::vector<boost::recursive_variant_>
56         >::type var1_t;
57
58     std::vector<var1_t> vec1;
59     vec1.push_back(3);
60     vec1.push_back(5);
61     vec1.push_back(vec1);
62     vec1.push_back(7);
63
64     var1_t var1(vec1);
65     std::string result1( boost::apply_visitor( vector_printer(), var1 ) );
66
67     std::cout << "result1: " << result1 << '\n';
68     BOOST_CHECK(result1 == "( 3 5 ( 3 5 ) 7 ) ");
69
70     typedef boost::make_recursive_variant<
71           boost::variant<int, double>
72         , std::vector<boost::recursive_variant_>
73         >::type var2_t;
74
75     std::vector<var2_t> vec2;
76     vec2.push_back(boost::variant<int, double>(3));
77     vec2.push_back(boost::variant<int, double>(3.5));
78     vec2.push_back(vec2);
79     vec2.push_back(boost::variant<int, double>(7));
80
81     var2_t var2(vec2);
82     std::string result2( boost::apply_visitor( vector_printer(), var2 ) );
83
84     std::cout << "result2: " << result2 << '\n';
85     BOOST_CHECK(result2 == "( 3 3.5 ( 3 3.5 ) 7 ) ");
86     
87     typedef boost::make_recursive_variant<
88           int
89         , std::vector<
90               boost::variant<
91                     double
92                   , std::vector<boost::recursive_variant_>
93                   >
94               >
95         >::type var3_t;
96
97     typedef boost::variant<double, std::vector<var3_t> > var4_t;
98
99     std::vector<var3_t> vec3;
100     vec3.push_back(3);
101     vec3.push_back(5);
102     std::vector<var4_t> vec4;
103     vec4.push_back(3.5);
104     vec4.push_back(vec3);
105     vec3.push_back(vec4);
106     vec3.push_back(7);
107
108     var4_t var4(vec3);
109     std::string result3( boost::apply_visitor( vector_printer(), var4 ) );
110
111     std::cout << "result2: " << result3 << '\n';
112     BOOST_CHECK(result3 == "( 3 5 ( 3.5 ( 3 5 ) ) 7 ) ");
113
114     typedef boost::make_recursive_variant<
115           double,
116           std::vector<var1_t>
117         >::type var5_t;
118
119     std::vector<var5_t> vec5;
120     vec5.push_back(3.5);
121     vec5.push_back(vec1);
122     vec5.push_back(17.25);
123
124     std::string result5( vector_printer()(vec5) );
125
126     std::cout << "result5: " << result5 << '\n';
127     BOOST_CHECK(result5 == "( 3.5 ( 3 5 ( 3 5 ) 7 ) 17.25 ) ");
128
129     typedef boost::make_recursive_variant<
130           int,
131           std::map<int, boost::recursive_variant_>
132         >::type var6_t;
133     var6_t var6;
134 }
135
136 void test_recursive_variant_over()
137 {
138     typedef boost::make_recursive_variant_over<
139           boost::mpl::vector<
140               int
141             , std::vector<boost::recursive_variant_>
142           >
143         >::type var1_t;
144
145     std::vector<var1_t> vec1;
146     vec1.push_back(3);
147     vec1.push_back(5);
148     vec1.push_back(vec1);
149     vec1.push_back(7);
150
151     var1_t var1(vec1);
152     std::string result1( boost::apply_visitor( vector_printer(), var1 ) );
153
154     std::cout << "result1: " << result1 << '\n';
155     BOOST_CHECK(result1 == "( 3 5 ( 3 5 ) 7 ) ");
156
157     typedef boost::make_recursive_variant_over<
158           boost::mpl::vector<
159               boost::make_variant_over<boost::mpl::vector<int, double> >::type
160             , std::vector<boost::recursive_variant_>
161             >
162         >::type var2_t;
163
164     std::vector<var2_t> vec2;
165     vec2.push_back(boost::variant<int, double>(3));
166     vec2.push_back(boost::variant<int, double>(3.5));
167     vec2.push_back(vec2);
168     vec2.push_back(boost::variant<int, double>(7));
169
170     var2_t var2(vec2);
171     std::string result2( boost::apply_visitor( vector_printer(), var2 ) );
172
173     std::cout << "result2: " << result2 << '\n';
174     BOOST_CHECK(result2 == "( 3 3.5 ( 3 3.5 ) 7 ) ");
175     
176     typedef boost::make_recursive_variant_over<
177           boost::mpl::vector<
178               int
179             , std::vector<
180                   boost::make_variant_over<
181                       boost::mpl::vector<
182                           double
183                         , std::vector<boost::recursive_variant_>
184                         >
185                     >::type
186                 >
187             >
188         >::type var3_t;
189
190     typedef boost::make_variant_over<
191           boost::mpl::copy<
192               boost::mpl::vector<
193                   double
194                 , std::vector<var3_t>
195                 >
196             >::type
197         >::type var4_t;
198
199     std::vector<var3_t> vec3;
200     vec3.push_back(3);
201     vec3.push_back(5);
202     std::vector<var4_t> vec4;
203     vec4.push_back(3.5);
204     vec4.push_back(vec3);
205     vec3.push_back(vec4);
206     vec3.push_back(7);
207
208     var4_t var3(vec3);
209     std::string result3( boost::apply_visitor( vector_printer(), var3 ) );
210
211     std::cout << "result2: " << result3 << '\n';
212     BOOST_CHECK(result3 == "( 3 5 ( 3.5 ( 3 5 ) ) 7 ) ");
213     
214     typedef boost::make_recursive_variant_over<
215           boost::mpl::vector<
216               double
217             , std::vector<var1_t>
218             >
219         >::type var5_t;
220
221     std::vector<var5_t> vec5;
222     vec5.push_back(3.5);
223     vec5.push_back(vec1);
224     vec5.push_back(17.25);
225
226     std::string result5( vector_printer()(vec5) );
227
228     std::cout << "result5: " << result5 << '\n';
229     BOOST_CHECK(result5 == "( 3.5 ( 3 5 ( 3 5 ) 7 ) 17.25 ) ");
230 }
231
232 int test_main(int , char* [])
233 {
234     test_recursive_variant();
235     test_recursive_variant_over();
236
237     return boost::exit_success;
238 }