Fixes for VS 2008
[dyninst.git] / external / boost / exception / exception.hpp
1 //Copyright (c) 2006-2008 Emil Dotchevski and Reverge Studios, Inc.\r
2 \r
3 //Distributed under the Boost Software License, Version 1.0. (See accompanying\r
4 //file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\r
5 \r
6 #ifndef UUID_274DA366004E11DCB1DDFE2E56D89593\r
7 #define UUID_274DA366004E11DCB1DDFE2E56D89593\r
8 \r
9 namespace\r
10 boost\r
11     {\r
12     namespace\r
13     exception_detail\r
14         {\r
15         template <class T>\r
16         class\r
17         refcount_ptr\r
18             {\r
19             public:\r
20 \r
21             refcount_ptr():\r
22                 px_(0)\r
23                 {\r
24                 }\r
25 \r
26             ~refcount_ptr()\r
27                 {\r
28                 release();\r
29                 }\r
30 \r
31             refcount_ptr( refcount_ptr const & x ):\r
32                 px_(x.px_)\r
33                 {\r
34                 add_ref();\r
35                 }\r
36 \r
37             refcount_ptr &\r
38             operator=( refcount_ptr const & x )\r
39                 {\r
40                 adopt(x.px_);\r
41                 return *this;\r
42                 }\r
43 \r
44             void\r
45             adopt( T * px )\r
46                 {\r
47                 release();\r
48                 px_=px;\r
49                 add_ref();\r
50                 }\r
51 \r
52             T *\r
53             get() const\r
54                 {\r
55                 return px_;\r
56                 }\r
57 \r
58             private:\r
59 \r
60             T * px_;\r
61 \r
62             void\r
63             add_ref()\r
64                 {\r
65                 if( px_ )\r
66                     px_->add_ref();\r
67                 }\r
68 \r
69             void\r
70             release()\r
71                 {\r
72                 if( px_ )\r
73                     px_->release();\r
74                 }\r
75             };\r
76         }\r
77 \r
78     ////////////////////////////////////////////////////////////////////////\r
79 \r
80     template <class Tag,class T>\r
81     class error_info;\r
82 \r
83     typedef error_info<struct tag_throw_function,char const *> throw_function;\r
84     typedef error_info<struct tag_throw_file,char const *> throw_file;\r
85     typedef error_info<struct tag_throw_line,int> throw_line;\r
86 \r
87     template <>\r
88     class\r
89     error_info<tag_throw_function,char const *>\r
90         {\r
91         public:\r
92         typedef char const * value_type;\r
93         value_type v_;\r
94         explicit\r
95         error_info( value_type v ):\r
96             v_(v)\r
97             {\r
98             }\r
99         };\r
100 \r
101     template <>\r
102     class\r
103     error_info<tag_throw_file,char const *>\r
104         {\r
105         public:\r
106         typedef char const * value_type;\r
107         value_type v_;\r
108         explicit\r
109         error_info( value_type v ):\r
110             v_(v)\r
111             {\r
112             }\r
113         };\r
114 \r
115     template <>\r
116     class\r
117     error_info<tag_throw_line,int>\r
118         {\r
119         public:\r
120         typedef int value_type;\r
121         value_type v_;\r
122         explicit\r
123         error_info( value_type v ):\r
124             v_(v)\r
125             {\r
126             }\r
127         };\r
128 \r
129     template <class E,class Tag,class T>\r
130     E const & operator<<( E const &, error_info<Tag,T> const & );\r
131 \r
132     class exception;\r
133 \r
134     template <class>\r
135     class shared_ptr;\r
136 \r
137     namespace\r
138     exception_detail\r
139         {\r
140         class error_info_base;\r
141         struct type_info_;\r
142 \r
143         struct\r
144         error_info_container\r
145             {\r
146             virtual char const * diagnostic_information() const = 0;\r
147             virtual shared_ptr<error_info_base const> get( type_info_ const & ) const = 0;\r
148             virtual void set( shared_ptr<error_info_base const> const &, type_info_ const & ) = 0;\r
149             virtual void add_ref() const = 0;\r
150             virtual void release() const = 0;\r
151 \r
152             protected:\r
153 \r
154             virtual\r
155             ~error_info_container() throw()\r
156                 {\r
157                 }\r
158             };\r
159 \r
160         template <class>\r
161         struct get_info;\r
162 \r
163         template <>\r
164         struct get_info<throw_function>;\r
165 \r
166         template <>\r
167         struct get_info<throw_file>;\r
168 \r
169         template <>\r
170         struct get_info<throw_line>;\r
171 \r
172         char const * get_diagnostic_information( exception const & );\r
173         }\r
174 \r
175     class\r
176     exception\r
177         {\r
178         protected:\r
179 \r
180         exception():\r
181             throw_function_(0),\r
182             throw_file_(0),\r
183             throw_line_(-1)\r
184             {\r
185             }\r
186 \r
187 #ifdef __HP_aCC\r
188         //On HP aCC, this protected copy constructor prevents throwing boost::exception.\r
189         //On all other platforms, the same effect is achieved by the pure virtual destructor.\r
190         exception( exception const & x ) throw():\r
191             data_(x.data_),\r
192             throw_function_(x.throw_function_),\r
193             throw_file_(x.throw_file_),\r
194             throw_line_(x.throw_line_)\r
195             {\r
196             }\r
197 #endif\r
198 \r
199         virtual ~exception() throw()\r
200 #ifndef __HP_aCC\r
201             = 0 //Workaround for HP aCC, =0 incorrectly leads to link errors.\r
202 #endif\r
203             ;\r
204 \r
205         private:\r
206 \r
207         template <class E>\r
208         friend\r
209         E const &\r
210         operator<<( E const & x, throw_function const & y )\r
211             {\r
212             x.throw_function_=y.v_;\r
213             return x;\r
214             }\r
215 \r
216         template <class E>\r
217         friend\r
218         E const &\r
219         operator<<( E const & x, throw_file const & y )\r
220             {\r
221             x.throw_file_=y.v_;\r
222             return x;\r
223             }\r
224 \r
225         template <class E>\r
226         friend\r
227         E const &\r
228         operator<<( E const & x, throw_line const & y )\r
229             {\r
230             x.throw_line_=y.v_;\r
231             return x;\r
232             }\r
233 \r
234         friend char const * exception_detail::get_diagnostic_information( exception const & );\r
235 \r
236         template <class E,class Tag,class T>\r
237         friend E const & operator<<( E const &, error_info<Tag,T> const & );\r
238 \r
239         template <class>\r
240         friend struct exception_detail::get_info;\r
241         friend struct exception_detail::get_info<throw_function>;\r
242         friend struct exception_detail::get_info<throw_file>;\r
243         friend struct exception_detail::get_info<throw_line>;\r
244 \r
245         mutable exception_detail::refcount_ptr<exception_detail::error_info_container> data_;\r
246         mutable char const * throw_function_;\r
247         mutable char const * throw_file_;\r
248         mutable int throw_line_;\r
249         };\r
250 \r
251     inline\r
252     exception::\r
253     ~exception() throw()\r
254         {\r
255         }\r
256 \r
257     ////////////////////////////////////////////////////////////////////////\r
258 \r
259     namespace\r
260     exception_detail\r
261         {\r
262         template <class T>\r
263         struct\r
264         error_info_injector:\r
265             public T,\r
266             public exception\r
267             {\r
268             explicit\r
269             error_info_injector( T const & x ):\r
270                 T(x)\r
271                 {\r
272                 }\r
273 \r
274             ~error_info_injector() throw()\r
275                 {\r
276                 }\r
277             };\r
278 \r
279         struct large_size { char c[256]; };\r
280         large_size dispatch( exception * );\r
281 \r
282         struct small_size { };\r
283         small_size dispatch( void * );\r
284 \r
285         template <class,int>\r
286         struct enable_error_info_helper;\r
287 \r
288         template <class T>\r
289         struct\r
290         enable_error_info_helper<T,sizeof(large_size)>\r
291             {\r
292             typedef T type;\r
293             };\r
294 \r
295         template <class T>\r
296         struct\r
297         enable_error_info_helper<T,sizeof(small_size)>\r
298             {\r
299             typedef error_info_injector<T> type;\r
300             };\r
301 \r
302         template <class T>\r
303         struct\r
304         enable_error_info_return_type\r
305             {\r
306             typedef typename enable_error_info_helper<T,sizeof(dispatch((T*)0))>::type type;\r
307             };\r
308         }\r
309 \r
310     template <class T>\r
311     inline\r
312     typename\r
313     exception_detail::enable_error_info_return_type<T>::type\r
314     enable_error_info( T const & x )\r
315         {\r
316         typedef typename exception_detail::enable_error_info_return_type<T>::type rt;\r
317         return rt(x);\r
318         }\r
319 \r
320     ////////////////////////////////////////////////////////////////////////\r
321 \r
322     namespace\r
323     exception_detail\r
324         {\r
325         class\r
326         clone_base\r
327             {\r
328             public:\r
329 \r
330             virtual clone_base const * clone() const = 0;\r
331             virtual void rethrow() const = 0;\r
332 \r
333             virtual\r
334             ~clone_base() throw()\r
335                 {\r
336                 }\r
337             };\r
338 \r
339         inline\r
340         void\r
341         copy_boost_exception( exception * a, exception const * b )\r
342             {\r
343             *a = *b;\r
344             }\r
345 \r
346         inline\r
347         void\r
348         copy_boost_exception( void *, void const * )\r
349             {\r
350             }\r
351 \r
352         template <class T>\r
353         class\r
354         clone_impl:\r
355             public T,\r
356             public clone_base\r
357             {\r
358             public:\r
359 \r
360             explicit\r
361             clone_impl( T const & x ):\r
362                 T(x)\r
363                 {\r
364                 copy_boost_exception(this,&x);\r
365                 }\r
366 \r
367             ~clone_impl() throw()\r
368                 {\r
369                 }\r
370 \r
371             private:\r
372 \r
373             clone_base const *\r
374             clone() const\r
375                 {\r
376                 return new clone_impl(*this);\r
377                 }\r
378 \r
379             void\r
380             rethrow() const\r
381                 {\r
382                 throw*this;\r
383                 }\r
384             };\r
385         }\r
386 \r
387     template <class T>\r
388     inline\r
389     exception_detail::clone_impl<T>\r
390     enable_current_exception( T const & x )\r
391         {\r
392         return exception_detail::clone_impl<T>(x);\r
393         }\r
394     }\r
395 \r
396 #endif\r