]> git.lyx.org Git - lyx.git/blob - boost/boost/exception/enable_current_exception.hpp
update boost to version 1.36
[lyx.git] / boost / boost / exception / enable_current_exception.hpp
1 //Copyright (c) 2006-2008 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 UUID_78CC85B2914F11DC8F47B48E55D89593
7 #define UUID_78CC85B2914F11DC8F47B48E55D89593
8
9 #include <boost/exception/exception.hpp>
10 #include <boost/exception/detail/cloning_base.hpp>
11 #include <boost/detail/atomic_count.hpp>
12 #include <boost/assert.hpp>
13 #include <new>
14
15 namespace
16 boost
17     {
18     namespace
19     exception_detail
20         {
21         class
22         clone_base:
23             public counted_base
24             {
25             public:
26
27             virtual void rethrow() const=0;
28             };
29
30         struct
31         bad_alloc_impl:
32             public clone_base,
33             public std::bad_alloc
34             {
35             void
36             add_ref() const
37                 {
38                 }
39
40             void
41             release() const
42                 {
43                 }
44
45             void
46             rethrow() const
47                 {
48                 throw *this;
49                 }
50             };
51
52         template <class T>
53         clone_base * make_clone( T const & );
54
55         template <class T>
56         class
57         clone_impl:
58             public T,
59             public cloning_base
60             {
61             public:
62
63             explicit
64             clone_impl( T const & x ):
65                 T(x)
66                 {
67                 if( boost::exception * be1=dynamic_cast<boost::exception *>(this) )
68                     if( boost::exception const * be2=dynamic_cast<boost::exception const *>(&x) )
69                         *be1 = *be2;
70                 }
71
72             private:
73
74             clone_base const *
75             clone() const
76                 {
77                 return make_clone<T>(*this);
78                 }
79             };
80
81         template <class T>
82         class
83         exception_clone:
84             public T,
85             public clone_base
86             {
87             public:
88
89             explicit
90             exception_clone( T const & x ):
91                 T(x),
92                 count_(0)
93                 {
94                 if( boost::exception * be1=dynamic_cast<boost::exception *>(this) )
95                     if( boost::exception const * be2=dynamic_cast<boost::exception const *>(&x) )
96                         *be1 = *be2;
97                 }
98
99             private:
100
101             detail::atomic_count mutable count_;
102
103             void
104             add_ref() const
105                 {
106                 ++count_;
107                 }
108
109             void
110             release() const
111                 {
112                 if( !--count_ )
113                     delete this;
114                 }
115
116             void
117             rethrow() const
118                 {
119                 throw clone_impl<T>(*this);
120                 }
121             };
122
123         template <class T>
124         inline
125         clone_base *
126         make_clone( T const & x )
127             {
128             try
129                 {
130                 return new exception_clone<T>(x);
131                 }
132             catch(
133             std::bad_alloc & )
134                 {
135                 static bad_alloc_impl bad_alloc;
136                 return &bad_alloc;
137                 }
138             catch(
139             ... )
140                 {
141                 BOOST_ASSERT(0);
142                 return 0;
143                 }
144             }
145         }
146
147     template <class T>
148     inline
149     exception_detail::clone_impl<T>
150     enable_current_exception( T const & x )
151         {
152         return exception_detail::clone_impl<T>(x);
153         }
154     }
155
156 #endif