1//Copyright (c) 2006-2015 Emil Dotchevski and Reverge Studios, Inc.
2
3//Distributed under the Boost Software License, Version 1.0. (See accompanying
4//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6#include <boost/config.hpp>
7
8#if defined( BOOST_NO_EXCEPTIONS )
9# error This program requires exception handling.
10#endif
11
12#include <boost/exception/get_error_info.hpp>
13#include <boost/exception/info_tuple.hpp>
14#include <boost/exception_ptr.hpp>
15#include <boost/detail/lightweight_test.hpp>
16#include <boost/detail/workaround.hpp>
17
18struct throws_on_copy;
19struct non_printable { };
20
21struct
22user_data
23 {
24 int & count;
25
26 explicit
27 user_data( int & count ):
28 count(count)
29 {
30 ++count;
31 }
32
33 user_data( user_data const & x ):
34 count(x.count)
35 {
36 ++count;
37 }
38
39 ~user_data()
40 {
41 --count;
42 }
43 };
44
45typedef boost::error_info<struct tag_test_1,int> test_1;
46typedef boost::error_info<struct tag_test_2,unsigned int> test_2;
47typedef boost::error_info<struct tag_test_3,float> test_3;
48typedef boost::error_info<struct tag_test_4,throws_on_copy> test_4;
49typedef boost::error_info<struct tag_test_5,std::string> test_5;
50typedef boost::error_info<struct tag_test_6,non_printable> test_6;
51typedef boost::error_info<struct tag_user_data,user_data> test_7;
52
53struct
54test_exception:
55 boost::exception
56 {
57 };
58
59struct
60throws_on_copy
61 {
62 throws_on_copy()
63 {
64 }
65
66 throws_on_copy( throws_on_copy const & )
67 {
68 throw test_exception();
69 }
70 };
71
72void
73basic_test()
74 {
75 try
76 {
77 test_exception x;
78 add_info(e: add_info(e: add_info(e: x,i: test_1(1)),i: test_2(2u)),i: test_3(3.14159f));
79 throw x;
80 }
81 catch(
82 test_exception & x )
83 {
84 ++*boost::get_error_info<test_1>(some_exception&: x);
85 ++*boost::get_error_info<test_2>(some_exception&: x);
86 ++*boost::get_error_info<test_3>(some_exception&: x);
87 BOOST_TEST(*boost::get_error_info<test_1>(x)==2);
88 BOOST_TEST(*boost::get_error_info<test_2>(x)==3u);
89 BOOST_TEST(*boost::get_error_info<test_3>(x)==4.14159f);
90 BOOST_TEST(!boost::get_error_info<test_4>(x));
91 }
92 try
93 {
94 test_exception x;
95 add_info(e: add_info(e: add_info(e: x,i: test_1(1)),i: test_2(2u)),i: test_3(3.14159f));
96 throw x;
97 }
98 catch(
99 test_exception const & x )
100 {
101 BOOST_TEST(*boost::get_error_info<test_1>(x)==1);
102 BOOST_TEST(*boost::get_error_info<test_2>(x)==2u);
103 BOOST_TEST(*boost::get_error_info<test_3>(x)==3.14159f);
104 BOOST_TEST(!boost::get_error_info<test_4>(x));
105 }
106 }
107
108void
109exception_safety_test()
110 {
111 test_exception x;
112 try
113 {
114 add_info(e: x,i: test_4(throws_on_copy()));
115 BOOST_TEST(false);
116 }
117 catch(
118 test_exception & )
119 {
120 BOOST_TEST(!boost::get_error_info<test_4>(x));
121 }
122 }
123
124void
125throw_empty()
126 {
127 throw test_exception();
128 }
129
130void
131throw_test_1( char const * value )
132 {
133 throw add_info(e: test_exception(),i: test_5(std::string(value)));
134 }
135
136void
137throw_test_2()
138 {
139 throw add_info(e: test_exception(),i: test_6(non_printable()));
140 }
141
142void
143throw_catch_add_file_name( char const * name )
144 {
145 try
146 {
147 throw_empty();
148 BOOST_TEST(false);
149 }
150 catch(
151 boost::exception & x )
152 {
153 add_info(e: x,i: test_5(std::string(name)));
154 throw;
155 }
156 }
157
158void
159test_empty()
160 {
161 try
162 {
163 throw_empty();
164 BOOST_TEST(false);
165 }
166 catch(
167 boost::exception & x )
168 {
169#ifndef BOOST_NO_RTTI
170 BOOST_TEST( dynamic_cast<test_exception *>(&x) );
171#endif
172 BOOST_TEST( !boost::get_error_info<test_1>(x) );
173 }
174 catch(
175 ... )
176 {
177 BOOST_TEST(false);
178 }
179
180 try
181 {
182 throw_empty();
183 BOOST_TEST(false);
184 }
185 catch(
186 test_exception & x )
187 {
188#ifndef BOOST_NO_RTTI
189 BOOST_TEST( dynamic_cast<boost::exception const *>(&x)!=0 );
190#endif
191 }
192 catch(
193 ... )
194 {
195 BOOST_TEST(false);
196 }
197 }
198
199void
200test_basic_throw_catch()
201 {
202 try
203 {
204 throw_test_1(value: "test");
205 BOOST_ASSERT(false);
206 }
207 catch(
208 boost::exception & x )
209 {
210 BOOST_TEST(*boost::get_error_info<test_5>(x)==std::string("test"));
211 }
212 catch(
213 ... )
214 {
215 BOOST_TEST(false);
216 }
217
218 try
219 {
220 throw_test_2();
221 BOOST_ASSERT(false);
222 }
223 catch(
224 boost::exception & x )
225 {
226 BOOST_TEST(boost::get_error_info<test_6>(x));
227 }
228 catch(
229 ... )
230 {
231 BOOST_TEST(false);
232 }
233 }
234
235void
236test_catch_add_info()
237 {
238 try
239 {
240 throw_catch_add_file_name(name: "test");
241 BOOST_TEST(false);
242 }
243 catch(
244 boost::exception & x )
245 {
246 BOOST_TEST(*boost::get_error_info<test_5>(x)==std::string("test"));
247 }
248 catch(
249 ... )
250 {
251 BOOST_TEST(false);
252 }
253 }
254
255void
256test_add_tuple()
257 {
258 typedef boost::tuple<> tuple_test_;
259 typedef boost::tuple<test_1> tuple_test_1;
260 typedef boost::tuple<test_1,test_2> tuple_test_12;
261 typedef boost::tuple<test_1,test_2,test_3> tuple_test_123;
262 typedef boost::tuple<test_1,test_2,test_3,test_5> tuple_test_1235;
263 try
264 {
265 throw add_info(e: test_exception(),i: tuple_test_());
266 }
267 catch(
268 test_exception & )
269 {
270 }
271 catch(
272 ... )
273 {
274 BOOST_TEST(false);
275 }
276 try
277 {
278 throw add_info(e: test_exception(),i: tuple_test_1(42));
279 }
280 catch(
281 test_exception & x )
282 {
283 BOOST_TEST( *boost::get_error_info<test_1>(x)==42 );
284 }
285 catch(
286 ... )
287 {
288 BOOST_TEST(false);
289 }
290 try
291 {
292 throw add_info(e: test_exception(),i: tuple_test_12(42,42u));
293 }
294 catch(
295 test_exception & x )
296 {
297 BOOST_TEST( *boost::get_error_info<test_1>(x)==42 );
298 BOOST_TEST( *boost::get_error_info<test_2>(x)==42u );
299 }
300 catch(
301 ... )
302 {
303 BOOST_TEST(false);
304 }
305 try
306 {
307 throw add_info(e: test_exception(),i: tuple_test_123(42,42u,42.0f));
308 }
309 catch(
310 test_exception & x )
311 {
312 BOOST_TEST( *boost::get_error_info<test_1>(x)==42 );
313 BOOST_TEST( *boost::get_error_info<test_2>(x)==42u );
314 BOOST_TEST( *boost::get_error_info<test_3>(x)==42.0f );
315 }
316 catch(
317 ... )
318 {
319 BOOST_TEST(false);
320 }
321 try
322 {
323 throw add_info(e: test_exception(),i: tuple_test_1235(42,42u,42.0f,std::string("42")));
324 }
325 catch(
326 test_exception & x )
327 {
328 BOOST_TEST( *boost::get_error_info<test_1>(x)==42 );
329 BOOST_TEST( *boost::get_error_info<test_2>(x)==42u );
330 BOOST_TEST( *boost::get_error_info<test_3>(x)==42.0f );
331 BOOST_TEST( *boost::get_error_info<test_5>(x)=="42" );
332 }
333 catch(
334 ... )
335 {
336 BOOST_TEST(false);
337 }
338 }
339
340void
341test_lifetime1()
342 {
343 int count=0;
344 try
345 {
346 throw add_info(e: test_exception(),i: test_7(user_data(count)));
347 }
348 catch(
349 boost::exception & x )
350 {
351 BOOST_TEST(count==1);
352 BOOST_TEST( boost::get_error_info<test_7>(x) );
353 }
354 catch(
355 ... )
356 {
357 BOOST_TEST(false);
358 }
359 BOOST_TEST(!count);
360 }
361
362void
363test_lifetime2()
364 {
365 int count=0;
366 {
367 boost::exception_ptr ep;
368 test_exception e; add_info(e,i: test_7(user_data(count)));
369 ep=boost::copy_exception(e);
370 BOOST_TEST(count>0);
371 }
372 BOOST_TEST(!count);
373 }
374
375bool
376is_const( int const * )
377 {
378 return true;
379 }
380
381bool
382is_const( int * )
383 {
384 return false;
385 }
386
387void
388test_const()
389 {
390 test_exception e;
391 boost::exception const & c(e);
392 boost::exception & m(e);
393 BOOST_TEST(is_const(boost::get_error_info<test_1>(c)));
394 BOOST_TEST(!is_const(boost::get_error_info<test_1>(m)));
395 }
396
397int
398main()
399 {
400 basic_test();
401 exception_safety_test();
402 test_empty();
403 test_basic_throw_catch();
404 test_catch_add_info();
405 test_add_tuple();
406 test_lifetime1();
407 test_lifetime2();
408 test_const();
409 return boost::report_errors();
410 }
411

source code of boost/libs/exception/test/error_info_test.hpp