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