annotate DEPENDENCIES/generic/include/boost/log/utility/exception_handler.hpp @ 133:4acb5d8d80b6 tip

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