]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/log/utility/exception_handler.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / log / utility / exception_handler.hpp
1 /*
2 * Copyright Andrey Semashev 2007 - 2015.
3 * Distributed under the Boost Software License, Version 1.0.
4 * (See accompanying file LICENSE_1_0.txt or copy at
5 * http://www.boost.org/LICENSE_1_0.txt)
6 */
7 /*!
8 * \file exception_handler.hpp
9 * \author Andrey Semashev
10 * \date 12.07.2009
11 *
12 * This header contains tools for exception handlers support in different parts of the library.
13 */
14
15 #ifndef BOOST_LOG_UTILITY_EXCEPTION_HANDLER_HPP_INCLUDED_
16 #define BOOST_LOG_UTILITY_EXCEPTION_HANDLER_HPP_INCLUDED_
17
18 #include <new> // std::nothrow_t
19 #include <boost/mpl/bind.hpp>
20 #include <boost/mpl/quote.hpp>
21 #include <boost/mpl/fold.hpp>
22 #include <boost/mpl/placeholders.hpp>
23 #include <boost/mpl/has_xxx.hpp>
24 #include <boost/mpl/vector.hpp>
25 #include <boost/core/enable_if.hpp>
26 #include <boost/preprocessor/cat.hpp>
27 #include <boost/preprocessor/repetition/enum_params.hpp>
28 #include <boost/preprocessor/repetition/repeat_from_to.hpp>
29 #include <boost/log/detail/config.hpp>
30 #include <boost/log/utility/functional/nop.hpp>
31 #include <boost/log/detail/header.hpp>
32
33 #ifdef BOOST_HAS_PRAGMA_ONCE
34 #pragma once
35 #endif
36
37 #ifndef BOOST_LOG_MAX_EXCEPTION_TYPES
38 //! Maximum number of exception types that can be specified for exception handlers
39 #define BOOST_LOG_MAX_EXCEPTION_TYPES 10
40 #endif
41
42 namespace boost {
43
44 BOOST_LOG_OPEN_NAMESPACE
45
46 namespace aux {
47
48 BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_exception_types, exception_types, false)
49
50 //! Root class for the exception handler class hierarchy
51 template< typename HandlerT >
52 class eh_root
53 {
54 public:
55 //! The exception handler type
56 typedef HandlerT handler_type;
57 //! The handler result type
58 typedef void result_type;
59
60 protected:
61 //! Exception handler
62 handler_type m_Handler;
63
64 public:
65 //! Initializing constructor
66 explicit eh_root(handler_type const& handler) : m_Handler(handler)
67 {
68 }
69
70 //! Exception launcher
71 void operator()() const
72 {
73 throw;
74 }
75 };
76
77 //! A cons-list element of the exception handler class hierarchy
78 template< typename ExceptionT, typename BaseT >
79 class eh_cons :
80 public BaseT
81 {
82 //! Base type
83 typedef BaseT base_type;
84
85 public:
86 //! The exception handler type
87 typedef typename base_type::handler_type handler_type;
88
89 public:
90 //! Initializing constructor
91 explicit eh_cons(handler_type const& handler) : base_type(handler)
92 {
93 }
94
95 //! Exception launcher
96 void operator()() const
97 {
98 try
99 {
100 base_type::operator()();
101 }
102 catch (ExceptionT& e)
103 {
104 this->m_Handler(e);
105 }
106 }
107 };
108
109 template< template< typename, typename > class EHT, typename HandlerT >
110 struct make_self_contained_exception_handler
111 {
112 typedef EHT< typename HandlerT::exception_types, HandlerT > type;
113 };
114
115 } // namespace aux
116
117 /*!
118 * An exception handler functional object. The handler aggregates a user-defined
119 * functional object that will be called when one of the specified exception types
120 * is caught.
121 */
122 template< typename SequenceT, typename HandlerT >
123 class exception_handler :
124 public mpl::fold<
125 SequenceT,
126 aux::eh_root< HandlerT >,
127 mpl::bind< mpl::quote2< aux::eh_cons >, mpl::_2, mpl::_1 >
128 >::type
129 {
130 //! Base type
131 typedef typename mpl::fold<
132 SequenceT,
133 aux::eh_root< HandlerT >,
134 mpl::bind< mpl::quote2< aux::eh_cons >, mpl::_2, mpl::_1 >
135 >::type base_type;
136
137 public:
138 #ifndef BOOST_LOG_DOXYGEN_PASS
139 typedef typename base_type::handler_type handler_type;
140 #else
141 //! The exception handler type
142 typedef HandlerT handler_type;
143 //! The handler result type
144 typedef void result_type;
145 #endif
146
147 public:
148 /*!
149 * Initializing constructor. Creates an exception handler with the specified
150 * function object that will receive the exception.
151 */
152 explicit exception_handler(handler_type const& handler) : base_type(handler)
153 {
154 }
155
156 /*!
157 * Exception launcher. Rethrows the current exception in order to detect its type
158 * and pass it to the aggregated function object.
159 *
160 * \note Must be called from within a \c catch statement.
161 */
162 void operator()() const
163 {
164 base_type::operator()();
165 }
166 };
167
168 /*!
169 * A no-throw exception handler functional object. Acts similar to \c exception_handler,
170 * but in case if the exception cannot be handled the exception is not propagated
171 * from the handler. Instead the user-defined functional object is called with
172 * no parameters.
173 */
174 template< typename SequenceT, typename HandlerT >
175 class nothrow_exception_handler :
176 public exception_handler< SequenceT, HandlerT >
177 {
178 //! Base type
179 typedef exception_handler< SequenceT, HandlerT > base_type;
180
181 public:
182 #ifndef BOOST_LOG_DOXYGEN_PASS
183 typedef typename base_type::handler_type handler_type;
184 #else
185 //! The exception handler type
186 typedef HandlerT handler_type;
187 //! The handler result type
188 typedef void result_type;
189 #endif
190
191 public:
192 /*!
193 * Initializing constructor. Creates an exception handler with the specified
194 * function object that will receive the exception.
195 */
196 explicit nothrow_exception_handler(handler_type const& handler) : base_type(handler)
197 {
198 }
199
200 /*!
201 * Exception launcher. Rethrows the current exception in order to detect its type
202 * and pass it to the aggregated function object. If the type of the exception
203 * could not be detected, the user-defined handler is called with no arguments.
204 *
205 * \note Must be called from within a \c catch statement.
206 */
207 void operator()() const
208 {
209 try
210 {
211 base_type::operator()();
212 }
213 catch (...)
214 {
215 this->m_Handler();
216 }
217 }
218 };
219
220 /*!
221 * The function creates an empty exception handler that effectively suppresses any exception
222 */
223 inline nop make_exception_suppressor()
224 {
225 return nop();
226 }
227
228 #ifndef BOOST_LOG_DOXYGEN_PASS
229
230 template< typename HandlerT >
231 inline typename boost::lazy_enable_if_c<
232 aux::has_exception_types< HandlerT >::value,
233 aux::make_self_contained_exception_handler< exception_handler, HandlerT >
234 >::type make_exception_handler(HandlerT const& handler)
235 {
236 typedef typename aux::make_self_contained_exception_handler< exception_handler, HandlerT >::type eh_t;
237 return eh_t(handler);
238 }
239
240 template< typename HandlerT >
241 inline typename boost::lazy_enable_if_c<
242 aux::has_exception_types< HandlerT >::value,
243 aux::make_self_contained_exception_handler< nothrow_exception_handler, HandlerT >
244 >::type make_exception_handler(HandlerT const& handler, std::nothrow_t const&)
245 {
246 typedef typename aux::make_self_contained_exception_handler< nothrow_exception_handler, HandlerT >::type eh_t;
247 return eh_t(handler);
248 }
249
250 #define BOOST_LOG_MAKE_EXCEPTION_HANDLER_INTERNAL(z, n, data)\
251 template< BOOST_PP_ENUM_PARAMS(n, typename T), typename HandlerT >\
252 inline exception_handler<\
253 BOOST_PP_CAT(mpl::vector, n)< BOOST_PP_ENUM_PARAMS(n, T) >,\
254 HandlerT\
255 > make_exception_handler(HandlerT const& handler)\
256 {\
257 typedef exception_handler<\
258 BOOST_PP_CAT(mpl::vector, n)< BOOST_PP_ENUM_PARAMS(n, T) >,\
259 HandlerT\
260 > eh_t;\
261 return eh_t(handler);\
262 }\
263 template< BOOST_PP_ENUM_PARAMS(n, typename T), typename HandlerT >\
264 inline nothrow_exception_handler<\
265 BOOST_PP_CAT(mpl::vector, n)< BOOST_PP_ENUM_PARAMS(n, T) >,\
266 HandlerT\
267 > make_exception_handler(HandlerT const& handler, std::nothrow_t const&)\
268 {\
269 typedef nothrow_exception_handler<\
270 BOOST_PP_CAT(mpl::vector, n)< BOOST_PP_ENUM_PARAMS(n, T) >,\
271 HandlerT\
272 > eh_t;\
273 return eh_t(handler);\
274 }
275
276 BOOST_PP_REPEAT_FROM_TO(1, BOOST_LOG_MAX_EXCEPTION_TYPES, BOOST_LOG_MAKE_EXCEPTION_HANDLER_INTERNAL, ~)
277
278 #undef BOOST_LOG_MAKE_EXCEPTION_HANDLER_INTERNAL
279
280 #else // BOOST_LOG_DOXYGEN_PASS
281
282 /*!
283 * The function creates an exception handler functional object. The handler will call to the
284 * user-specified functional object with an exception as its argument.
285 *
286 * \param handler User-defined functional object that will receive exceptions.
287 * \return A nullary functional object that should be called from within a \c catch statement.
288 *
289 * \note This form requires the user-defined functional object to have an \c exception_types
290 * nested type. This type should be an MPL sequence of all expected exception types.
291 */
292 template< typename HandlerT >
293 exception_handler< typename HandlerT::exception_types, HandlerT >
294 make_exception_handler(HandlerT const& handler);
295
296 /*!
297 * The function creates an exception handler functional object. The handler will call to the
298 * user-specified functional object with an exception as its argument. If the exception type
299 * cannot be identified, the handler will call the user-defined functor with no arguments,
300 * instead of propagating exception to the caller.
301 *
302 * \overload
303 *
304 * \param handler User-defined functional object that will receive exceptions.
305 * \return A nullary functional object that should be called from within a \c catch statement.
306 *
307 * \note This form requires the user-defined functional object to have an \c exception_types
308 * nested type. This type should be an MPL sequence of all expected exception types.
309 */
310 template< typename HandlerT >
311 nothrow_exception_handler< typename HandlerT::exception_types, HandlerT >
312 make_exception_handler(HandlerT const& handler, std::nothrow_t const&);
313
314 /*!
315 * The function creates an exception handler functional object. The handler will call to the
316 * user-specified functional object with an exception as its argument. All expected exception
317 * types should be specified as first template parameters explicitly, in the order they would
318 * be specified in a corresponding <tt>try/catch</tt> statement.
319 *
320 * \overload
321 *
322 * \param handler User-defined functional object that will receive exceptions.
323 * \return A nullary functional object that should be called from within a \c catch statement.
324 */
325 template< typename... ExceptionsT, typename HandlerT >
326 exception_handler< MPL_sequence_of_ExceptionsT, HandlerT >
327 make_exception_handler(HandlerT const& handler);
328
329 /*!
330 * The function creates an exception handler functional object. The handler will call to the
331 * user-specified functional object with an exception as its argument. If the exception type
332 * cannot be identified, the handler will call the user-defined functor with no arguments,
333 * instead of propagating exception to the caller. All expected exception types should be
334 * specified as first template parameters explicitly, in the order they would be specified in
335 * a corresponding <tt>try/catch</tt> statement.
336 *
337 * \overload
338 *
339 * \param handler User-defined functional object that will receive exceptions.
340 * \return A nullary functional object that should be called from within a \c catch statement.
341 */
342 template< typename... ExceptionsT, typename HandlerT >
343 nothrow_exception_handler< MPL_sequence_of_ExceptionsT, HandlerT >
344 make_exception_handler(HandlerT const& handler, std::nothrow_t const&);
345
346 #endif // BOOST_LOG_DOXYGEN_PASS
347
348 BOOST_LOG_CLOSE_NAMESPACE // namespace log
349
350 } // namespace boost
351
352 #include <boost/log/detail/footer.hpp>
353
354 #endif // BOOST_LOG_UTILITY_EXCEPTION_HANDLER_HPP_INCLUDED_