8
8
9
9
#include < boost/leaf/config.hpp>
10
10
#include < boost/leaf/error.hpp>
11
-
12
- #ifndef BOOST_LEAF_NO_EXCEPTIONS
13
-
14
11
#include < exception>
15
12
16
- #define BOOST_LEAF_EXCEPTION ::boost::leaf::leaf_detail::inject_loc{__FILE__,__LINE__,__FUNCTION__}+::boost::leaf::exception
17
- #define BOOST_LEAF_THROW_EXCEPTION ::boost::leaf::leaf_detail::throw_with_loc{__FILE__,__LINE__,__FUNCTION__}+::boost::leaf::exception
13
+ #ifdef BOOST_LEAF_NO_EXCEPTIONS
18
14
19
- // //////////////////////////////////////
15
+ namespace boost
16
+ {
17
+ [[noreturn]] void throw_exception ( std::exception const & ); // user defined
18
+ }
20
19
21
20
namespace boost { namespace leaf {
22
21
23
22
namespace leaf_detail
24
23
{
25
- struct throw_with_loc
24
+ template <class T >
25
+ [[noreturn]] void throw_exception_impl ( T && e )
26
26
{
27
- char const * const file;
28
- int const line;
29
- char const * const fn;
27
+ ::boost::throw_exception (std::move(e));
28
+ }
30
29
31
- template <class Ex >
32
- [[noreturn]] friend void operator +( throw_with_loc loc, Ex const & ex )
33
- {
34
- ex.load_source_location_ (loc.file , loc.line , loc.fn );
35
- ::boost::leaf::throw_exception (ex);
36
- }
30
+ class BOOST_LEAF_SYMBOL_VISIBLE exception_base
31
+ {
32
+ public:
33
+
34
+ virtual error_id get_error_id () const noexcept = 0;
35
+
36
+ protected:
37
+
38
+ exception_base () noexcept { }
39
+ ~exception_base () noexcept { }
37
40
};
38
41
}
39
42
40
43
} }
41
44
42
- // //////////////////////////////////////
45
+ #else
46
+
47
+ #include < memory>
43
48
44
49
namespace boost { namespace leaf {
45
50
46
51
namespace leaf_detail
47
52
{
48
- inline void enforce_std_exception ( std::exception const & ) noexcept { }
53
+ template <class T >
54
+ [[noreturn]] void throw_exception_impl ( T && e )
55
+ {
56
+ throw std::move (e);
57
+ }
49
58
50
59
class BOOST_LEAF_SYMBOL_VISIBLE exception_base
51
60
{
52
61
std::shared_ptr<void const > auto_id_bump_;
62
+
53
63
public:
54
64
55
65
virtual error_id get_error_id () const noexcept = 0;
@@ -63,6 +73,44 @@ namespace leaf_detail
63
73
64
74
~exception_base () noexcept { }
65
75
};
76
+ }
77
+
78
+ } }
79
+
80
+ #endif
81
+
82
+ // //////////////////////////////////////
83
+
84
+ #define BOOST_LEAF_THROW_EXCEPTION ::boost::leaf::leaf_detail::throw_with_loc{__FILE__,__LINE__,__FUNCTION__}+::boost::leaf::leaf_detail::make_exception
85
+
86
+ namespace boost { namespace leaf {
87
+
88
+ namespace leaf_detail
89
+ {
90
+ struct throw_with_loc
91
+ {
92
+ char const * const file;
93
+ int const line;
94
+ char const * const fn;
95
+
96
+ template <class Ex >
97
+ [[noreturn]] friend void operator +( throw_with_loc loc, Ex && ex )
98
+ {
99
+ ex.load_source_location_ (loc.file , loc.line , loc.fn );
100
+ ::boost::leaf::leaf_detail::throw_exception_impl (std::move(ex));
101
+ }
102
+ };
103
+ }
104
+
105
+ } }
106
+
107
+ // //////////////////////////////////////
108
+
109
+ namespace boost { namespace leaf {
110
+
111
+ namespace leaf_detail
112
+ {
113
+ inline void enforce_std_exception ( std::exception const & ) noexcept { }
66
114
67
115
template <class Ex >
68
116
class BOOST_LEAF_SYMBOL_VISIBLE exception:
@@ -112,52 +160,62 @@ namespace leaf_detail
112
160
{
113
161
constexpr static const bool value = std::is_base_of<std::exception,typename std::remove_reference<T>::type>::value || at_least_one_derives_from_std_exception<Rest...>::value;
114
162
};
115
- }
116
163
117
- template <class Ex , class ... E>
118
- inline
119
- typename std::enable_if<std::is_base_of<std::exception,typename std::remove_reference<Ex>::type>::value, leaf_detail:: exception<typename std::remove_reference<Ex>::type>>::type
120
- exception ( error_id err, Ex && ex, E && ... e ) noexcept
121
- {
122
- static_assert (!leaf_detail:: at_least_one_derives_from_std_exception<E...>::value, " Error objects passed to leaf::exception may not derive from std::exception" );
123
- return leaf_detail:: exception<typename std::remove_reference<Ex>::type>( err.load (std::forward<E>(e)...), std::forward<Ex>(ex) );
124
- }
164
+ template <class Ex , class ... E>
165
+ inline
166
+ typename std::enable_if<std::is_base_of<std::exception,typename std::remove_reference<Ex>::type>::value, exception<typename std::remove_reference<Ex>::type>>::type
167
+ make_exception ( error_id err, Ex && ex, E && ... e ) noexcept
168
+ {
169
+ static_assert (!at_least_one_derives_from_std_exception<E...>::value, " Error objects passed to leaf::exception may not derive from std::exception" );
170
+ return exception<typename std::remove_reference<Ex>::type>( err.load (std::forward<E>(e)...), std::forward<Ex>(ex) );
171
+ }
125
172
126
- template <class E1 , class ... E>
127
- inline
128
- typename std::enable_if<!std::is_base_of<std::exception,typename std::remove_reference<E1 >::type>::value, leaf_detail:: exception<std::exception>>::type
129
- exception ( error_id err, E1 && car, E && ... cdr ) noexcept
130
- {
131
- static_assert (!leaf_detail:: at_least_one_derives_from_std_exception<E...>::value, " Error objects passed to leaf::exception may not derive from std::exception" );
132
- return leaf_detail:: exception<std::exception>( err.load (std::forward<E1 >(car), std::forward<E>(cdr)...) );
133
- }
173
+ template <class E1 , class ... E>
174
+ inline
175
+ typename std::enable_if<!std::is_base_of<std::exception,typename std::remove_reference<E1 >::type>::value, exception<std::exception>>::type
176
+ make_exception ( error_id err, E1 && car, E && ... cdr ) noexcept
177
+ {
178
+ static_assert (!at_least_one_derives_from_std_exception<E...>::value, " Error objects passed to leaf::exception may not derive from std::exception" );
179
+ return exception<std::exception>( err.load (std::forward<E1 >(car), std::forward<E>(cdr)...) );
180
+ }
134
181
135
- inline leaf_detail:: exception<std::exception> exception ( error_id err ) noexcept
136
- {
137
- return leaf_detail:: exception<std::exception>(err);
138
- }
182
+ inline exception<std::exception> make_exception ( error_id err ) noexcept
183
+ {
184
+ return exception<std::exception>(err);
185
+ }
139
186
140
- template <class Ex , class ... E>
141
- inline
142
- typename std::enable_if<std::is_base_of<std::exception,typename std::remove_reference<Ex>::type>::value, leaf_detail:: exception<typename std::remove_reference<Ex>::type>>::type
143
- exception ( Ex && ex, E && ... e ) noexcept
144
- {
145
- static_assert (!leaf_detail:: at_least_one_derives_from_std_exception<E...>::value, " Error objects passed to leaf::exception may not derive from std::exception" );
146
- return leaf_detail:: exception<typename std::remove_reference<Ex>::type>( new_error ().load (std::forward<E>(e)...), std::forward<Ex>(ex) );
147
- }
187
+ template <class Ex , class ... E>
188
+ inline
189
+ typename std::enable_if<std::is_base_of<std::exception,typename std::remove_reference<Ex>::type>::value, exception<typename std::remove_reference<Ex>::type>>::type
190
+ make_exception ( Ex && ex, E && ... e ) noexcept
191
+ {
192
+ static_assert (!at_least_one_derives_from_std_exception<E...>::value, " Error objects passed to leaf::exception may not derive from std::exception" );
193
+ return exception<typename std::remove_reference<Ex>::type>( new_error ().load (std::forward<E>(e)...), std::forward<Ex>(ex) );
194
+ }
148
195
149
- template <class E1 , class ... E>
150
- inline
151
- typename std::enable_if<!std::is_base_of<std::exception,typename std::remove_reference<E1 >::type>::value, leaf_detail::exception<std::exception>>::type
152
- exception ( E1 && car, E && ... cdr ) noexcept
153
- {
154
- static_assert (!leaf_detail::at_least_one_derives_from_std_exception<E...>::value, " Error objects passed to leaf::exception may not derive from std::exception" );
155
- return leaf_detail::exception<std::exception>( new_error ().load (std::forward<E1 >(car), std::forward<E>(cdr)...) );
196
+ template <class E1 , class ... E>
197
+ inline
198
+ typename std::enable_if<!std::is_base_of<std::exception,typename std::remove_reference<E1 >::type>::value, exception<std::exception>>::type
199
+ make_exception ( E1 && car, E && ... cdr ) noexcept
200
+ {
201
+ static_assert (!at_least_one_derives_from_std_exception<E...>::value, " Error objects passed to leaf::exception may not derive from std::exception" );
202
+ return exception<std::exception>( new_error ().load (std::forward<E1 >(car), std::forward<E>(cdr)...) );
203
+ }
204
+
205
+ inline exception<std::exception> make_exception () noexcept
206
+ {
207
+ return exception<std::exception>(leaf::new_error ());
208
+ }
156
209
}
157
210
158
- inline leaf_detail::exception<std::exception> exception () noexcept
211
+ template <class ... E>
212
+ [[noreturn]] void throw_exception ( E && ... e )
159
213
{
160
- return leaf_detail::exception<std::exception>(leaf::new_error ());
214
+ // Warning: setting a breakpoint here will not intercept exceptions thrown
215
+ // via BOOST_LEAF_THROW_EXCEPTION or originating in the few other throw
216
+ // points elsewhere in LEAF. To intercept all of those exceptions as well,
217
+ // set a breakpoint inside boost::leaf::leaf_detail::throw_exception_impl.
218
+ leaf_detail::throw_exception_impl (leaf_detail::make_exception (std::forward<E>(e)...));
161
219
}
162
220
163
221
// //////////////////////////////////////
@@ -223,5 +281,3 @@ exception_to_result( F && f ) noexcept
223
281
} }
224
282
225
283
#endif
226
-
227
- #endif
0 commit comments