整理
This commit is contained in:
106
include/boost/scope/exception_checker.hpp
Normal file
106
include/boost/scope/exception_checker.hpp
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* https://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* Copyright (c) 2023 Andrey Semashev
|
||||
*/
|
||||
/*!
|
||||
* \file scope/exception_checker.hpp
|
||||
*
|
||||
* This header contains definition of \c exception_checker type.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_SCOPE_EXCEPTION_CHECKER_HPP_INCLUDED_
|
||||
#define BOOST_SCOPE_EXCEPTION_CHECKER_HPP_INCLUDED_
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/scope/detail/config.hpp>
|
||||
#include <boost/core/uncaught_exceptions.hpp>
|
||||
#include <boost/scope/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace scope {
|
||||
|
||||
/*!
|
||||
* \brief A predicate for checking whether an exception is being thrown.
|
||||
*
|
||||
* On construction, the predicate captures the current number of uncaught exceptions,
|
||||
* which it then compares with the number of uncaught exceptions at the point when it
|
||||
* is called. If the number increased then a new exception is detected and the predicate
|
||||
* returns \c true.
|
||||
*
|
||||
* \note This predicate is designed for a specific use case with scope guards created on
|
||||
* the stack. It is incompatible with C++20 coroutines and similar facilities (e.g.
|
||||
* fibers and userspace context switching), where the thread of execution may be
|
||||
* suspended after the predicate captures the number of uncaught exceptions and
|
||||
* then resumed in a different context, where the number of uncaught exceptions
|
||||
* has changed. Similarly, it is incompatible with usage patterns where the predicate
|
||||
* is cached after construction and is invoked after the thread has left the scope
|
||||
* where the predicate was constructed (e.g. when the predicate is stored as a class
|
||||
* data member or a namespace-scope variable).
|
||||
*/
|
||||
class exception_checker
|
||||
{
|
||||
public:
|
||||
//! Predicate result type
|
||||
using result_type = bool;
|
||||
|
||||
private:
|
||||
unsigned int m_uncaught_count;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* \brief Constructs the predicate.
|
||||
*
|
||||
* Upon construction, the predicate saves the current number of uncaught exceptions.
|
||||
* This information will be used when calling the predicate to detect if a new
|
||||
* exception is being thrown.
|
||||
*
|
||||
* **Throws:** Nothing.
|
||||
*/
|
||||
exception_checker() noexcept :
|
||||
m_uncaught_count(boost::core::uncaught_exceptions())
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks if an exception is being thrown.
|
||||
*
|
||||
* **Throws:** Nothing.
|
||||
*
|
||||
* \returns \c true if the number of uncaught exceptions at the point of call is
|
||||
* greater than that at the point of construction of the predicate,
|
||||
* otherwise \c false.
|
||||
*/
|
||||
result_type operator()() const noexcept
|
||||
{
|
||||
const unsigned int uncaught_count = boost::core::uncaught_exceptions();
|
||||
// If this assertion fails, the predicate is likely being used in an unsupported
|
||||
// way, where it is called in a different scope or thread context from where
|
||||
// it was constructed.
|
||||
BOOST_ASSERT((uncaught_count - m_uncaught_count) <= 1u);
|
||||
return uncaught_count > m_uncaught_count;
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Creates a predicate for checking whether an exception is being thrown
|
||||
*
|
||||
* **Throws:** Nothing.
|
||||
*/
|
||||
inline exception_checker check_exception() noexcept
|
||||
{
|
||||
return exception_checker();
|
||||
}
|
||||
|
||||
} // namespace scope
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/scope/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_SCOPE_EXCEPTION_CHECKER_HPP_INCLUDED_
|
||||
Reference in New Issue
Block a user