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