Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-04-19 08:44:21

0001 /*
0002  * Distributed under the Boost Software License, Version 1.0.
0003  * (See accompanying file LICENSE_1_0.txt or copy at
0004  * https://www.boost.org/LICENSE_1_0.txt)
0005  *
0006  * Copyright (c) 2023 Andrey Semashev
0007  */
0008 /*!
0009  * \file scope/exception_checker.hpp
0010  *
0011  * This header contains definition of \c exception_checker type.
0012  */
0013 
0014 #ifndef BOOST_SCOPE_EXCEPTION_CHECKER_HPP_INCLUDED_
0015 #define BOOST_SCOPE_EXCEPTION_CHECKER_HPP_INCLUDED_
0016 
0017 #include <boost/assert.hpp>
0018 #include <boost/scope/detail/config.hpp>
0019 #include <boost/core/uncaught_exceptions.hpp>
0020 #include <boost/scope/detail/header.hpp>
0021 
0022 #ifdef BOOST_HAS_PRAGMA_ONCE
0023 #pragma once
0024 #endif
0025 
0026 namespace boost {
0027 namespace scope {
0028 
0029 /*!
0030  * \brief A predicate for checking whether an exception is being thrown.
0031  *
0032  * On construction, the predicate captures the current number of uncaught exceptions,
0033  * which it then compares with the number of uncaught exceptions at the point when it
0034  * is called. If the number increased then a new exception is detected and the predicate
0035  * returns \c true.
0036  *
0037  * \note This predicate is designed for a specific use case with scope guards created on
0038  *       the stack. It is incompatible with C++20 coroutines and similar facilities (e.g.
0039  *       fibers and userspace context switching), where the thread of execution may be
0040  *       suspended after the predicate captures the number of uncaught exceptions and
0041  *       then resumed in a different context, where the number of uncaught exceptions
0042  *       has changed. Similarly, it is incompatible with usage patterns where the predicate
0043  *       is cached after construction and is invoked after the thread has left the scope
0044  *       where the predicate was constructed (e.g. when the predicate is stored as a class
0045  *       data member or a namespace-scope variable).
0046  */
0047 class exception_checker
0048 {
0049 public:
0050     //! Predicate result type
0051     using result_type = bool;
0052 
0053 private:
0054     unsigned int m_uncaught_count;
0055 
0056 public:
0057     /*!
0058      * \brief Constructs the predicate.
0059      *
0060      * Upon construction, the predicate saves the current number of uncaught exceptions.
0061      * This information will be used when calling the predicate to detect if a new
0062      * exception is being thrown.
0063      *
0064      * **Throws:** Nothing.
0065      */
0066     exception_checker() noexcept :
0067         m_uncaught_count(boost::core::uncaught_exceptions())
0068     {
0069     }
0070 
0071     /*!
0072      * \brief Checks if an exception is being thrown.
0073      *
0074      * **Throws:** Nothing.
0075      *
0076      * \returns \c true if the number of uncaught exceptions at the point of call is
0077      *          greater than that at the point of construction of the predicate,
0078      *          otherwise \c false.
0079      */
0080     result_type operator()() const noexcept
0081     {
0082         const unsigned int uncaught_count = boost::core::uncaught_exceptions();
0083         // If this assertion fails, the predicate is likely being used in an unsupported
0084         // way, where it is called in a different scope or thread context from where
0085         // it was constructed.
0086         BOOST_ASSERT((uncaught_count - m_uncaught_count) <= 1u);
0087         return uncaught_count > m_uncaught_count;
0088     }
0089 };
0090 
0091 /*!
0092  * \brief Creates a predicate for checking whether an exception is being thrown
0093  *
0094  * **Throws:** Nothing.
0095  */
0096 inline exception_checker check_exception() noexcept
0097 {
0098     return exception_checker();
0099 }
0100 
0101 } // namespace scope
0102 } // namespace boost
0103 
0104 #include <boost/scope/detail/footer.hpp>
0105 
0106 #endif // BOOST_SCOPE_EXCEPTION_CHECKER_HPP_INCLUDED_