]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | //----------------------------------------------------------------------------- |
2 | // boost-libs variant/libs/test/jobs.h header 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 | #ifndef _JOBSH_INC_ | |
14 | #define _JOBSH_INC_ | |
15 | ||
16 | #include <algorithm> | |
17 | #include <iostream> | |
18 | #include <sstream> | |
19 | #include <string> | |
20 | #include <typeinfo> | |
21 | #include <vector> | |
22 | ||
23 | #include "boost/variant/variant_fwd.hpp" | |
24 | #include "boost/variant/get.hpp" | |
25 | #include "boost/variant/apply_visitor.hpp" | |
26 | #include "boost/variant/static_visitor.hpp" | |
27 | ||
28 | #include "boost/type_index.hpp" | |
29 | #include "boost/detail/workaround.hpp" | |
30 | #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551)) | |
31 | # pragma warn -lvc | |
32 | #endif | |
33 | ||
34 | struct to_text : boost::static_visitor<std::string> | |
35 | { | |
36 | private: // NO_FUNCTION_TEMPLATE_ORDERING workaround | |
37 | ||
38 | template < BOOST_VARIANT_ENUM_PARAMS(typename U) > | |
39 | std::string to_text_impl( | |
40 | const boost::variant< BOOST_VARIANT_ENUM_PARAMS(U) >& operand, long | |
41 | ) const | |
42 | { | |
43 | std::ostringstream ost; | |
44 | ost << "[V] " << boost::apply_visitor(to_text(), operand); | |
45 | ||
46 | return ost.str(); | |
47 | } | |
48 | ||
49 | template <typename Value> | |
50 | std::string to_text_impl(const Value& operand, int) const | |
51 | { | |
52 | std::ostringstream ost; | |
53 | ost << "[V] " << operand; | |
54 | ||
55 | return ost.str(); | |
56 | } | |
57 | ||
58 | public: | |
59 | ||
60 | template <typename T> | |
61 | std::string operator()(const T& operand) const | |
62 | { | |
63 | return to_text_impl(operand, 1L); | |
64 | } | |
65 | ||
66 | }; | |
67 | ||
68 | struct total_sizeof : boost::static_visitor<int> | |
69 | { | |
70 | total_sizeof() : total_(0) { } | |
71 | ||
72 | template<class Value> | |
73 | int operator()(const Value&) const | |
74 | { | |
75 | total_ += sizeof(Value); | |
76 | return total_; | |
77 | } | |
78 | ||
79 | int result() const | |
80 | { | |
81 | return total_; | |
82 | } | |
83 | ||
84 | mutable int total_; | |
85 | ||
86 | }; // total_sizeof | |
87 | ||
88 | ||
89 | ||
90 | //Function object: sum_int | |
91 | //Description: Compute total sum of a series of numbers, (when called successively) | |
92 | //Use sizeof(T) if applied with a non-integral type | |
93 | struct sum_int : boost::static_visitor<int> | |
94 | { | |
95 | ||
96 | sum_int() : total_(0) { } | |
97 | ||
98 | ||
99 | template<int n> | |
100 | struct int_to_type | |
101 | { | |
102 | BOOST_STATIC_CONSTANT(int, value = n); | |
103 | }; | |
104 | ||
105 | //Integral type - add numerical value | |
106 | template<typename T> | |
107 | void add(T t, int_to_type<true> ) const | |
108 | { | |
109 | total_ += t; | |
110 | } | |
111 | ||
112 | //Other types - add sizeof<T> | |
113 | template<typename T> | |
114 | void add(T& , int_to_type<false> ) const | |
115 | { | |
116 | total_ += sizeof(T); | |
117 | } | |
118 | ||
119 | template<typename T> | |
120 | int operator()(const T& t) const | |
121 | { | |
122 | //Int_to_type is used to select the correct add() overload | |
123 | add(t, int_to_type<boost::is_integral<T>::value>()); | |
124 | return total_; | |
125 | } | |
126 | ||
127 | int result() const | |
128 | { | |
129 | return total_; | |
130 | } | |
131 | ||
132 | private: | |
133 | mutable int total_; | |
134 | ||
135 | }; //sum_int | |
136 | ||
137 | ||
138 | ||
139 | ||
140 | ||
141 | ||
142 | //Function object: sum_double | |
143 | //Description: Compute total sum of a series of numbers, (when called successively) | |
144 | //Accpetable input types: float, double (Other types are silently ignored) | |
145 | struct sum_double : boost::static_visitor<double> | |
146 | { | |
147 | ||
148 | sum_double() : total_(0) { } | |
149 | ||
150 | void operator()(float value) const | |
151 | { | |
152 | total_ += value; | |
153 | } | |
154 | ||
155 | void operator()(double value) const | |
156 | { | |
157 | total_ += value; | |
158 | } | |
159 | ||
160 | template<typename T> | |
161 | void operator()(const T&) const | |
162 | { | |
163 | //Do nothing | |
164 | } | |
165 | ||
166 | double result() const | |
167 | { | |
168 | return total_; | |
169 | } | |
170 | ||
171 | private: | |
172 | mutable double total_; | |
173 | ||
174 | }; //sum_double | |
175 | ||
176 | ||
177 | ||
178 | struct int_printer : boost::static_visitor<std::string> | |
179 | { | |
180 | ||
181 | int_printer(std::string prefix_s = "") : prefix_s_(prefix_s) { } | |
182 | int_printer(const int_printer& other) : prefix_s_(other.prefix_s_) | |
183 | { | |
184 | ost_ << other.str(); | |
185 | } | |
186 | ||
187 | std::string operator()(int x) const | |
188 | { | |
189 | ost_ << prefix_s_ << x; | |
190 | return str(); | |
191 | } | |
192 | ||
193 | std::string operator()(const std::vector<int>& x) const | |
194 | { | |
195 | ost_ << prefix_s_; | |
196 | ||
197 | //Use another Int_printer object for printing a list of all integers | |
198 | int_printer job(","); | |
199 | ost_ << std::for_each(x.begin(), x.end(), job).str(); | |
200 | ||
201 | return str(); | |
202 | } | |
203 | ||
204 | std::string str() const | |
205 | { | |
206 | return ost_.str(); | |
207 | } | |
208 | ||
209 | private: | |
210 | std::string prefix_s_; | |
211 | mutable std::ostringstream ost_; | |
212 | }; //int_printer | |
213 | ||
214 | ||
215 | struct int_adder : boost::static_visitor<> | |
216 | { | |
217 | ||
218 | int_adder(int rhs) : rhs_(rhs) { } | |
219 | ||
220 | result_type operator()(int& lhs) const | |
221 | { | |
222 | lhs += rhs_; | |
223 | } | |
224 | ||
225 | template<typename T> | |
226 | result_type operator()(const T& ) const | |
227 | { | |
228 | //Do nothing | |
229 | } | |
230 | ||
231 | int rhs_; | |
232 | }; //int_adder | |
233 | ||
234 | ||
235 | ||
236 | template<typename T> | |
237 | struct spec | |
238 | { | |
239 | typedef T result; | |
240 | }; | |
241 | ||
242 | template<typename VariantType, typename S> | |
243 | inline void verify(VariantType& var, spec<S>, std::string str = "") | |
244 | { | |
245 | const VariantType& cvar = var; | |
246 | ||
92f5a8d4 TL |
247 | BOOST_TEST(boost::apply_visitor(total_sizeof(), cvar) == sizeof(S)); |
248 | BOOST_TEST(cvar.type() == boost::typeindex::type_id<S>()); | |
7c673cae FG |
249 | |
250 | // | |
251 | // Check get<>() | |
252 | // | |
92f5a8d4 TL |
253 | BOOST_TEST(boost::get<S>(&var)); |
254 | BOOST_TEST(boost::get<S>(&cvar)); | |
7c673cae FG |
255 | |
256 | const S* ptr1 = 0; | |
257 | const S* ptr2 = 0; | |
258 | try | |
259 | { | |
260 | S& r = boost::get<S>(var); | |
261 | ptr1 = &r; | |
262 | } | |
263 | catch(const boost::bad_get& ) | |
264 | { | |
265 | BOOST_ERROR( "get<S> failed unexpectedly" ); | |
266 | } | |
267 | ||
268 | try | |
269 | { | |
270 | const S& cr = boost::get<S>(cvar); | |
271 | ptr2 = &cr; | |
272 | } | |
273 | catch(const boost::bad_get& ) | |
274 | { | |
275 | BOOST_ERROR( "get<S> const failed unexpectedly" ); | |
276 | } | |
277 | ||
92f5a8d4 | 278 | BOOST_TEST(ptr1 != 0 && ptr2 == ptr1); |
7c673cae FG |
279 | |
280 | // | |
281 | // Check string content | |
282 | // | |
283 | if(str.length() > 0) | |
284 | { | |
285 | std::string temp = boost::apply_visitor(to_text(), cvar); | |
286 | std::cout << "temp = " << temp << ", str = " << str << std::endl; | |
92f5a8d4 | 287 | BOOST_TEST(temp == str); |
7c673cae FG |
288 | } |
289 | } | |
290 | ||
291 | ||
292 | template<typename VariantType, typename S> | |
293 | inline void verify_not(VariantType& var, spec<S>) | |
294 | { | |
295 | const VariantType& cvar = var; | |
296 | ||
92f5a8d4 | 297 | BOOST_TEST(cvar.type() != boost::typeindex::type_id<S>()); |
7c673cae FG |
298 | |
299 | // | |
300 | // Check get<>() | |
301 | // | |
92f5a8d4 TL |
302 | BOOST_TEST(!boost::get<S>(&var)); |
303 | BOOST_TEST(!boost::get<S>(&cvar)); | |
7c673cae FG |
304 | |
305 | const S* ptr1 = 0; | |
306 | const S* ptr2 = 0; | |
307 | try | |
308 | { | |
309 | S& r = boost::get<S>(var); // should throw | |
310 | BOOST_ERROR( "get<S> passed unexpectedly" ); | |
311 | ||
312 | ptr1 = &r; | |
313 | } | |
314 | catch(const boost::bad_get& ) | |
315 | { | |
316 | // do nothing except pass-through | |
317 | } | |
318 | ||
319 | try | |
320 | { | |
321 | const S& cr = boost::get<S>(var); // should throw | |
322 | BOOST_ERROR( "get<S> const passed unexpectedly" ); | |
323 | ||
324 | ptr2 = &cr; | |
325 | } | |
326 | catch(const boost::bad_get& ) | |
327 | { | |
328 | // do nothing except pass-through | |
329 | } | |
330 | ||
92f5a8d4 | 331 | BOOST_TEST(ptr1 == 0 && ptr2 == 0); |
7c673cae FG |
332 | } |
333 | ||
334 | ||
335 | #endif //_JOBSH_INC_ |