]> git.lyx.org Git - lyx.git/blob - 3rdparty/boost/boost/exception/exception.hpp
Amend 770362da97d28
[lyx.git] / 3rdparty / boost / boost / exception / exception.hpp
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 #ifndef BOOST_EXCEPTION_274DA366004E11DCB1DDFE2E56D89593
7 #define BOOST_EXCEPTION_274DA366004E11DCB1DDFE2E56D89593
8
9 #include <boost/assert/source_location.hpp>
10 #include <boost/config.hpp>
11 #include <exception>
12
13 #ifdef BOOST_EXCEPTION_MINI_BOOST
14 #include  <memory>
15 namespace boost { namespace exception_detail { using std::shared_ptr; } }
16 #else
17 namespace boost { template <class T> class shared_ptr; }
18 namespace boost { namespace exception_detail { using boost::shared_ptr; } }
19 #endif
20
21 #if !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
22 #if __GNUC__*100+__GNUC_MINOR__>301
23 #pragma GCC system_header
24 #endif
25 #ifdef __clang__
26 #pragma clang system_header
27 #endif
28 #ifdef _MSC_VER
29 #pragma warning(push,1)
30 #pragma warning(disable: 4265)
31 #endif
32 #endif
33
34 namespace
35 boost
36     {
37     namespace
38     exception_detail
39         {
40         template <class T>
41         class
42         refcount_ptr
43             {
44             public:
45
46             refcount_ptr():
47                 px_(0)
48                 {
49                 }
50
51             ~refcount_ptr()
52                 {
53                 release();
54                 }
55
56             refcount_ptr( refcount_ptr const & x ):
57                 px_(x.px_)
58                 {
59                 add_ref();
60                 }
61
62             refcount_ptr &
63             operator=( refcount_ptr const & x )
64                 {
65                 adopt(x.px_);
66                 return *this;
67                 }
68
69             void
70             adopt( T * px )
71                 {
72                 release();
73                 px_=px;
74                 add_ref();
75                 }
76
77             T *
78             get() const
79                 {
80                 return px_;
81                 }
82
83             private:
84
85             T * px_;
86
87             void
88             add_ref()
89                 {
90                 if( px_ )
91                     px_->add_ref();
92                 }
93
94             void
95             release()
96                 {
97                 if( px_ && px_->release() )
98                     px_=0;
99                 }
100             };
101         }
102
103     ////////////////////////////////////////////////////////////////////////
104
105     template <class Tag,class T>
106     class error_info;
107
108     typedef error_info<struct throw_function_,char const *> throw_function;
109     typedef error_info<struct throw_file_,char const *> throw_file;
110     typedef error_info<struct throw_line_,int> throw_line;
111     typedef error_info<struct throw_column_,int> throw_column;
112
113     template <>
114     class
115     error_info<throw_function_,char const *>
116         {
117         public:
118         typedef char const * value_type;
119         value_type v_;
120         explicit
121         error_info( value_type v ):
122             v_(v)
123             {
124             }
125         };
126
127     template <>
128     class
129     error_info<throw_file_,char const *>
130         {
131         public:
132         typedef char const * value_type;
133         value_type v_;
134         explicit
135         error_info( value_type v ):
136             v_(v)
137             {
138             }
139         };
140
141     template <>
142     class
143     error_info<throw_line_,int>
144         {
145         public:
146         typedef int value_type;
147         value_type v_;
148         explicit
149         error_info( value_type v ):
150             v_(v)
151             {
152             }
153         };
154
155     template <>
156     class
157     error_info<throw_column_,int>
158         {
159         public:
160         typedef int value_type;
161         value_type v_;
162         explicit
163         error_info( value_type v ):
164             v_(v)
165             {
166             }
167         };
168
169     class
170     BOOST_SYMBOL_VISIBLE
171     exception;
172
173     namespace
174     exception_detail
175         {
176         class error_info_base;
177         struct type_info_;
178
179         struct
180         error_info_container
181             {
182             virtual char const * diagnostic_information( char const * ) const = 0;
183             virtual shared_ptr<error_info_base> get( type_info_ const & ) const = 0;
184             virtual void set( shared_ptr<error_info_base> const &, type_info_ const & ) = 0;
185             virtual void add_ref() const = 0;
186             virtual bool release() const = 0;
187             virtual refcount_ptr<exception_detail::error_info_container> clone() const = 0;
188
189             protected:
190
191             ~error_info_container() BOOST_NOEXCEPT_OR_NOTHROW
192                 {
193                 }
194             };
195
196         template <class>
197         struct get_info;
198
199         template <>
200         struct get_info<throw_function>;
201
202         template <>
203         struct get_info<throw_file>;
204
205         template <>
206         struct get_info<throw_line>;
207
208         template <>
209         struct get_info<throw_column>;
210
211         template <class>
212         struct set_info_rv;
213
214         template <>
215         struct set_info_rv<throw_function>;
216
217         template <>
218         struct set_info_rv<throw_file>;
219
220         template <>
221         struct set_info_rv<throw_line>;
222
223         template <>
224         struct set_info_rv<throw_column>;
225
226         char const * get_diagnostic_information( exception const &, char const * );
227
228         void copy_boost_exception( exception *, exception const * );
229
230         template <class E,class Tag,class T>
231         E const & set_info( E const &, error_info<Tag,T> const & );
232
233         template <class E>
234         E const & set_info( E const &, throw_function const & );
235
236         template <class E>
237         E const & set_info( E const &, throw_file const & );
238
239         template <class E>
240         E const & set_info( E const &, throw_line const & );
241
242         template <class E>
243         E const & set_info( E const &, throw_column const & );
244
245         boost::source_location get_exception_throw_location( exception const & );
246         }
247
248     class
249     BOOST_SYMBOL_VISIBLE
250     exception
251         {
252         //<N3757>
253         public:
254         template <class Tag> void set( typename Tag::type const & );
255         template <class Tag> typename Tag::type const * get() const;
256         //</N3757>
257
258         protected:
259
260         exception():
261             throw_function_(0),
262             throw_file_(0),
263             throw_line_(-1),
264             throw_column_(-1)
265             {
266             }
267
268 #ifdef __HP_aCC
269         //On HP aCC, this protected copy constructor prevents throwing boost::exception.
270         //On all other platforms, the same effect is achieved by the pure virtual destructor.
271         exception( exception const & x ) BOOST_NOEXCEPT_OR_NOTHROW:
272             data_(x.data_),
273             throw_function_(x.throw_function_),
274             throw_file_(x.throw_file_),
275             throw_line_(x.throw_line_),
276             throw_column_(x.throw_column_)
277             {
278             }
279 #endif
280
281         virtual ~exception() BOOST_NOEXCEPT_OR_NOTHROW
282 #ifndef __HP_aCC
283             = 0 //Workaround for HP aCC, =0 incorrectly leads to link errors.
284 #endif
285             ;
286
287 #if (defined(__MWERKS__) && __MWERKS__<=0x3207) || (defined(_MSC_VER) && _MSC_VER<=1310)
288         public:
289 #else
290         private:
291
292         template <class E>
293         friend E const & exception_detail::set_info( E const &, throw_function const & );
294
295         template <class E>
296         friend E const & exception_detail::set_info( E const &, throw_file const & );
297
298         template <class E>
299         friend E const & exception_detail::set_info( E const &, throw_line const & );
300
301         template <class E>
302         friend E const & exception_detail::set_info( E const &, throw_column const & );
303
304         template <class E,class Tag,class T>
305         friend E const & exception_detail::set_info( E const &, error_info<Tag,T> const & );
306
307         friend char const * exception_detail::get_diagnostic_information( exception const &, char const * );
308
309         friend boost::source_location exception_detail::get_exception_throw_location( exception const & );
310
311         template <class>
312         friend struct exception_detail::get_info;
313         friend struct exception_detail::get_info<throw_function>;
314         friend struct exception_detail::get_info<throw_file>;
315         friend struct exception_detail::get_info<throw_line>;
316         friend struct exception_detail::get_info<throw_column>;
317         template <class>
318         friend struct exception_detail::set_info_rv;
319         friend struct exception_detail::set_info_rv<throw_function>;
320         friend struct exception_detail::set_info_rv<throw_file>;
321         friend struct exception_detail::set_info_rv<throw_line>;
322         friend struct exception_detail::set_info_rv<throw_column>;
323         friend void exception_detail::copy_boost_exception( exception *, exception const * );
324 #endif
325         mutable exception_detail::refcount_ptr<exception_detail::error_info_container> data_;
326         mutable char const * throw_function_;
327         mutable char const * throw_file_;
328         mutable int throw_line_;
329         mutable int throw_column_;
330         };
331
332     inline
333     exception::
334     ~exception() BOOST_NOEXCEPT_OR_NOTHROW
335         {
336         }
337
338     namespace
339     exception_detail
340         {
341         template <class E>
342         E const &
343         set_info( E const & x, throw_function const & y )
344             {
345             x.throw_function_=y.v_;
346             return x;
347             }
348
349         template <class E>
350         E const &
351         set_info( E const & x, throw_file const & y )
352             {
353             x.throw_file_=y.v_;
354             return x;
355             }
356
357         template <class E>
358         E const &
359         set_info( E const & x, throw_line const & y )
360             {
361             x.throw_line_=y.v_;
362             return x;
363             }
364
365         template <class E>
366         E const &
367         set_info( E const & x, throw_column const & y )
368             {
369             x.throw_column_=y.v_;
370             return x;
371             }
372
373 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
374
375         template <>
376         struct
377         set_info_rv<throw_column>
378             {
379             template <class E>
380             static
381             E const &
382             set( E const & x, throw_column && y )
383                 {
384                 x.throw_column_=y.v_;
385                 return x;
386                 }
387             };
388
389 #endif
390
391         inline boost::source_location get_exception_throw_location( exception const & x )
392             {
393             return boost::source_location(
394                 x.throw_file_? x.throw_file_: "",
395                 x.throw_line_ >= 0? x.throw_line_: 0,
396                 x.throw_function_? x.throw_function_: "",
397                 x.throw_column_ >= 0? x.throw_column_: 0
398                 );
399             }
400         }
401
402     ////////////////////////////////////////////////////////////////////////
403
404     namespace
405     exception_detail
406         {
407         template <class T>
408         struct
409         BOOST_SYMBOL_VISIBLE
410         error_info_injector:
411             public T,
412             public exception
413             {
414             explicit
415             error_info_injector( T const & x ):
416                 T(x)
417                 {
418                 }
419
420             ~error_info_injector() BOOST_NOEXCEPT_OR_NOTHROW
421                 {
422                 }
423             };
424
425         struct large_size { char c[256]; };
426         large_size dispatch_boost_exception( exception const * );
427
428         struct small_size { };
429         small_size dispatch_boost_exception( void const * );
430
431         template <class,int>
432         struct enable_error_info_helper;
433
434         template <class T>
435         struct
436         enable_error_info_helper<T,sizeof(large_size)>
437             {
438             typedef T type;
439             };
440
441         template <class T>
442         struct
443         enable_error_info_helper<T,sizeof(small_size)>
444             {
445             typedef error_info_injector<T> type;
446             };
447
448         template <class T>
449         struct
450         enable_error_info_return_type
451             {
452             typedef typename enable_error_info_helper<T,sizeof(exception_detail::dispatch_boost_exception(static_cast<T *>(0)))>::type type;
453             };
454         }
455
456     template <class T>
457     inline
458     typename
459     exception_detail::enable_error_info_return_type<T>::type
460     enable_error_info( T const & x )
461         {
462         typedef typename exception_detail::enable_error_info_return_type<T>::type rt;
463         return rt(x);
464         }
465
466     ////////////////////////////////////////////////////////////////////////
467 #if defined(BOOST_NO_EXCEPTIONS)
468     BOOST_NORETURN void throw_exception(std::exception const & e); // user defined
469 #endif
470
471     namespace
472     exception_detail
473         {
474         class
475         BOOST_SYMBOL_VISIBLE
476         clone_base
477             {
478             public:
479
480             virtual clone_base const * clone() const = 0;
481             virtual void rethrow() const = 0;
482
483             virtual
484             ~clone_base() BOOST_NOEXCEPT_OR_NOTHROW
485                 {
486                 }
487             };
488
489         inline
490         void
491         copy_boost_exception( exception * a, exception const * b )
492             {
493             refcount_ptr<error_info_container> data;
494             if( error_info_container * d=b->data_.get() )
495                 data = d->clone();
496             a->throw_file_ = b->throw_file_;
497             a->throw_line_ = b->throw_line_;
498             a->throw_function_ = b->throw_function_;
499             a->throw_column_ = b->throw_column_;
500             a->data_ = data;
501             }
502
503         inline
504         void
505         copy_boost_exception( void *, void const * )
506             {
507             }
508
509         template <class T>
510         class
511         BOOST_SYMBOL_VISIBLE
512         clone_impl:
513             public T,
514             public virtual clone_base
515             {
516             struct clone_tag { };
517             clone_impl( clone_impl const & x, clone_tag ):
518                 T(x)
519                 {
520                 copy_boost_exception(this,&x);
521                 }
522
523             public:
524
525             explicit
526             clone_impl( T const & x ):
527                 T(x)
528                 {
529                 copy_boost_exception(this,&x);
530                 }
531
532             ~clone_impl() BOOST_NOEXCEPT_OR_NOTHROW
533                 {
534                 }
535
536             private:
537
538             clone_base const *
539             clone() const
540                 {
541                 return new clone_impl(*this,clone_tag());
542                 }
543
544             void
545             rethrow() const
546                 {
547 #if defined(BOOST_NO_EXCEPTIONS)
548                 boost::throw_exception(*this);
549 #else
550                 throw*this;
551 #endif
552                 }
553             };
554         }
555
556     template <class T>
557     inline
558     exception_detail::clone_impl<T>
559     enable_current_exception( T const & x )
560         {
561         return exception_detail::clone_impl<T>(x);
562         }
563     }
564
565 #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
566 #pragma warning(pop)
567 #endif
568
569 #endif // #ifndef BOOST_EXCEPTION_274DA366004E11DCB1DDFE2E56D89593