1 //Copyright (c) 2006-2009 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/diagnostic_information.hpp>
13 #include <boost/exception/info.hpp>
14 #include <boost/detail/lightweight_test.hpp>
15 #include <boost/detail/workaround.hpp>
16 
17 #if BOOST_WORKAROUND(BOOST_CODEGEARC, BOOST_TESTED_AT(0x610))
18 struct test_tag1 {};
19 struct test_tag2 {};
20 #endif
21 
22 typedef boost::error_info<struct test_tag1,int> tagged_int1;
23 typedef boost::error_info<struct test_tag2,int> tagged_int2;
24 
25 std::string
to_string(tagged_int2 const & x)26 to_string( tagged_int2 const & x )
27     {
28     return '[' +boost::error_info_name(x) + "] = " + (x.value()==42 ? "fourty-two" : "bad value");
29     }
30 
31 struct
32 error1:
33     std::exception,
34     boost::exception
35     {
36     char const *
whaterror137     what() const BOOST_NOEXCEPT_OR_NOTHROW
38         {
39         return "error1";
40         }
41     };
42 
43 struct
44 error2:
45     boost::exception
46     {
47     };
48 
49 struct
50 error3:
51     std::exception
52     {
53     char const *
whaterror354     what() const BOOST_NOEXCEPT_OR_NOTHROW
55         {
56         return "error3";
57         }
58     };
59 
60 struct
61 error4:
62     std::exception,
63     boost::exception
64     {
65     char const *
whaterror466     what() const BOOST_NOEXCEPT_OR_NOTHROW
67         {
68         return diagnostic_information_what(*this);
69         }
70     };
71 
72 void
test1(std::string const & di1,std::string const & di2)73 test1( std::string const & di1, std::string const & di2 )
74     {
75     BOOST_TEST( di1!=di2 );
76 #ifndef BOOST_NO_RTTI
77     BOOST_TEST(di1.find("type:")!=std::string::npos);
78     BOOST_TEST(di1.find("error1")!=std::string::npos);
79 #endif
80     BOOST_TEST(di1.find("test_tag1")!=std::string::npos);
81     BOOST_TEST(di1.find("test_tag2")!=std::string::npos);
82     BOOST_TEST(di1.find("fourty-two")!=std::string::npos);
83 #ifndef BOOST_NO_RTTI
84     BOOST_TEST(di2.find("type:")!=std::string::npos);
85     BOOST_TEST(di2.find("error1")!=std::string::npos);
86 #endif
87     BOOST_TEST(di2.find("test_tag1")!=std::string::npos);
88     BOOST_TEST(di2.find("test_tag2")!=std::string::npos);
89     BOOST_TEST(di2.find("bad value")!=std::string::npos);
90     }
91 
92 void
test2(std::string const & di1,std::string const & di2)93 test2( std::string const & di1, std::string const & di2 )
94     {
95     BOOST_TEST( di1!=di2 );
96     BOOST_TEST(di1.find("test_tag1")!=std::string::npos);
97     BOOST_TEST(di1.find("test_tag2")!=std::string::npos);
98     BOOST_TEST(di1.find("fourty-two")!=std::string::npos);
99     BOOST_TEST(di2.find("test_tag1")!=std::string::npos);
100     BOOST_TEST(di2.find("test_tag2")!=std::string::npos);
101     BOOST_TEST(di2.find("bad value")!=std::string::npos);
102     }
103 
104 void
test3(std::string const & di)105 test3( std::string const & di )
106     {
107 #ifndef BOOST_NO_RTTI
108     BOOST_TEST(di.find("type:")!=std::string::npos);
109 #endif
110     BOOST_TEST(di.find("error3")!=std::string::npos);
111     }
112 
113 void
test4(std::string const & di1,std::string const & di2)114 test4( std::string const & di1, std::string const & di2 )
115     {
116     BOOST_TEST( di1!=di2 );
117 #ifndef BOOST_NO_RTTI
118     BOOST_TEST(di1.find("type:")!=std::string::npos);
119 #endif
120     BOOST_TEST(di1.find("test_tag1")!=std::string::npos);
121     BOOST_TEST(di1.find("test_tag2")!=std::string::npos);
122     BOOST_TEST(di1.find("fourty-two")!=std::string::npos);
123 #ifndef BOOST_NO_RTTI
124     BOOST_TEST(di2.find("type:")!=std::string::npos);
125 #endif
126     BOOST_TEST(di2.find("test_tag1")!=std::string::npos);
127     BOOST_TEST(di2.find("test_tag2")!=std::string::npos);
128     BOOST_TEST(di2.find("bad value")!=std::string::npos);
129     }
130 
131 int
main()132 main()
133     {
134     using namespace boost;
135     try
136         {
137         error1 x; x << tagged_int1(42) << tagged_int2(42);
138         BOOST_TEST(x.what()==std::string("error1"));
139         throw x;
140         }
141     catch(
142     error1 & x )
143         {
144         std::string di1=boost::diagnostic_information(x);
145         x << tagged_int1(2) << tagged_int2(2);
146         std::string di2 = diagnostic_information(x);
147         test1(di1,di2);
148         }
149     try
150         {
151         error1 x; x << tagged_int1(42) << tagged_int2(42);
152         BOOST_TEST(x.what()==std::string("error1"));
153         throw x;
154         }
155     catch(
156     error1 & x )
157         {
158         std::string di1=boost::current_exception_diagnostic_information();
159         x << tagged_int1(2) << tagged_int2(2);
160         std::string di2 = current_exception_diagnostic_information();
161         test1(di1,di2);
162         }
163     try
164         {
165         error2 x;
166         x << tagged_int1(42) << tagged_int2(42);
167         throw x;
168         }
169     catch(
170     error2 & x )
171         {
172         std::string di1 = diagnostic_information(x);
173         x << tagged_int1(2) << tagged_int2(2);
174         std::string di2 = diagnostic_information(x);
175         test2(di1,di2);
176         }
177     try
178         {
179         error2 x;
180         x << tagged_int1(42) << tagged_int2(42);
181         throw x;
182         }
183     catch(
184     error2 & x )
185         {
186         std::string di1 = current_exception_diagnostic_information();
187         BOOST_TEST(di1==boost::diagnostic_information_what(x));
188         x << tagged_int1(2) << tagged_int2(2);
189         std::string di2 = current_exception_diagnostic_information();
190         BOOST_TEST(di2==boost::diagnostic_information_what(x));
191         test2(di1,di2);
192         }
193     try
194         {
195         error3 x;
196         std::string di=diagnostic_information(x);
197         test3(di);
198         throw x;
199         }
200     catch(
201     ... )
202         {
203         std::string di=current_exception_diagnostic_information();
204         test3(di);
205         }
206     try
207         {
208         throw error4();
209         }
210     catch(
211     error4 & x )
212         {
213         std::string di1=boost::diagnostic_information(x);
214         std::string wh1=x.what();
215         BOOST_TEST(wh1==di1);
216         }
217     try
218         {
219         error4 x; x << tagged_int1(42) << tagged_int2(42);
220         throw x;
221         }
222     catch(
223     error4 & x )
224         {
225         std::string di1=boost::diagnostic_information(x);
226         std::string wh1=x.what();
227         BOOST_TEST(wh1==di1);
228         x << tagged_int1(2) << tagged_int2(2);
229         std::string di2 = diagnostic_information(x);
230         std::string wh2=x.what();
231         BOOST_TEST(wh2==di2);
232         test4(di1,di2);
233         }
234     try
235         {
236         error4 x; x << tagged_int1(42) << tagged_int2(42);
237         throw x;
238         }
239     catch(
240     error4 & x )
241         {
242         std::string di1=boost::current_exception_diagnostic_information();
243         std::string wh1=x.what();
244         BOOST_TEST(wh1==di1);
245         x << tagged_int1(2) << tagged_int2(2);
246         std::string di2 = current_exception_diagnostic_information();
247         std::string wh2=x.what();
248         BOOST_TEST(wh2==di2);
249         test4(di1,di2);
250         }
251     return boost::report_errors();
252     }
253