LCOV - code coverage report
Current view: top level - opt/homebrew/include/boost/test - execution_monitor.hpp (source / functions) Hit Total Coverage
Test: test_dash_coverage.info Lines: 0 3 0.0 %
Date: 2026-06-25 07:23:51 Functions: 0 9 0.0 %

          Line data    Source code
       1             : //  (C) Copyright Gennadiy Rozental 2001.
       2             : //  (C) Copyright Beman Dawes 2001.
       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             : //  See http://www.boost.org/libs/test for the library home page.
       8             : //
       9             : //!@file
      10             : //!@brief Defines public interface of the Execution Monitor and related classes
      11             : // ***************************************************************************
      12             : 
      13             : #ifndef BOOST_TEST_EXECUTION_MONITOR_HPP_071894GER
      14             : #define BOOST_TEST_EXECUTION_MONITOR_HPP_071894GER
      15             : 
      16             : // Boost.Test
      17             : #include <boost/test/detail/global_typedef.hpp>
      18             : #include <boost/test/detail/fwd_decl.hpp>
      19             : #include <boost/test/detail/throw_exception.hpp>
      20             : 
      21             : #include <boost/test/utils/class_properties.hpp>
      22             : 
      23             : // Boost
      24             : #include <boost/shared_ptr.hpp>
      25             : #include <boost/scoped_array.hpp>
      26             : #include <boost/type.hpp>
      27             : #include <boost/cstdlib.hpp>
      28             : #include <boost/function/function0.hpp>
      29             : 
      30             : #include <boost/test/detail/suppress_warnings.hpp>
      31             : 
      32             : #ifdef BOOST_SEH_BASED_SIGNAL_HANDLING
      33             : 
      34             : // for the FP constants and control routines
      35             : #include <float.h>
      36             : 
      37             : #ifndef EM_INVALID
      38             : #define EM_INVALID _EM_INVALID
      39             : #endif
      40             : 
      41             : #ifndef EM_DENORMAL
      42             : #define EM_DENORMAL _EM_DENORMAL
      43             : #endif
      44             : 
      45             : #ifndef EM_ZERODIVIDE
      46             : #define EM_ZERODIVIDE _EM_ZERODIVIDE
      47             : #endif
      48             : 
      49             : #ifndef EM_OVERFLOW
      50             : #define EM_OVERFLOW _EM_OVERFLOW
      51             : #endif
      52             : 
      53             : #ifndef EM_UNDERFLOW
      54             : #define EM_UNDERFLOW _EM_UNDERFLOW
      55             : #endif
      56             : 
      57             : #ifndef MCW_EM
      58             : #define MCW_EM _MCW_EM
      59             : #endif
      60             : 
      61             : #else // based on ISO C standard
      62             : 
      63             : #if !defined(BOOST_NO_FENV_H)
      64             :   #include <boost/detail/fenv.hpp>
      65             : #endif
      66             : 
      67             : #endif
      68             : 
      69             : #if defined(BOOST_SEH_BASED_SIGNAL_HANDLING) && !defined(UNDER_CE)
      70             :   //! Indicates tha the floating point exception handling is supported
      71             :   //! through SEH
      72             :   #define BOOST_TEST_FPE_SUPPORT_WITH_SEH__
      73             : #elif !defined(BOOST_SEH_BASED_SIGNAL_HANDLING) && !defined(UNDER_CE)
      74             :   #if !defined(BOOST_NO_FENV_H) && !defined(BOOST_CLANG) && \
      75             :       defined(__GLIBC__) && defined(__USE_GNU) && \
      76             :       !(defined(__UCLIBC__) || defined(__nios2__) || defined(__microblaze__))
      77             :   //! Indicates that floating point exception handling is supported for the
      78             :   //! non SEH version of it, for the GLIBC extensions only
      79             :   // see discussions on the related topic: https://svn.boost.org/trac/boost/ticket/11756
      80             :   #define BOOST_TEST_FPE_SUPPORT_WITH_GLIBC_EXTENSIONS__
      81             :   #endif
      82             : #endif
      83             : 
      84             : 
      85             : // Additional macro documentations not being generated without this hack
      86             : #ifdef BOOST_TEST_DOXYGEN_DOC__
      87             : 
      88             : //! Disables the support of the alternative stack
      89             : //! during the compilation of the Boost.test framework. This is especially useful
      90             : //! in case it is not possible to detect the lack of alternative stack support for
      91             : //! your compiler (for instance, ESXi).
      92             : #define BOOST_TEST_DISABLE_ALT_STACK
      93             : 
      94             : #endif
      95             : 
      96             : //____________________________________________________________________________//
      97             : 
      98             : namespace boost {
      99             : 
     100             : /// @defgroup ExecutionMonitor Function Execution Monitor
     101             : /// @{
     102             : /// @section Intro Introduction
     103             : /// Sometimes we need to call a function and make sure that no user or system originated exceptions are being thrown by it. Uniform exception reporting
     104             : /// is also may be convenient. That's the purpose of the Boost.Test's Execution Monitor.
     105             : ///
     106             : /// The Execution Monitor is a lower-level component of the Boost Test Library. It is the base for implementing all other Boost.Test components, but also
     107             : /// can be used standalone to get controlled execution of error-prone functions with a uniform error notification. The Execution Monitor calls a user-supplied
     108             : /// function in a controlled environment, relieving users from messy error detection.
     109             : ///
     110             : /// The Execution Monitor usage is demonstrated in the example exec_mon_example.
     111             : ///
     112             : /// @section DesignRationale Design Rationale
     113             : ///
     114             : /// The Execution Monitor design assumes that it can be used when no (or almost no) memory available. Also the Execution Monitor
     115             : /// is intended to be portable to as many platforms as possible.
     116             : ///
     117             : /// @section UserGuide User's guide
     118             : /// The Execution Monitor is designed to solve the problem of executing potentially dangerous function that may result in any number of error conditions,
     119             : /// in monitored environment that should prevent any undesirable exceptions to propagate out of function call and produce consistent result report for all outcomes.
     120             : /// The Execution Monitor is able to produce informative report for all standard C++ exceptions and intrinsic types. All other exceptions are reported as unknown.
     121             : /// If you prefer different message for your exception type or need to perform any action, the Execution Monitor supports custom exception translators.
     122             : /// There are several other parameters of the monitored environment can be configured by setting appropriate properties of the Execution Monitor.
     123             : ///
     124             : /// All symbols in the Execution Monitor implementation are located in the namespace boost. To use the Execution Monitor you need to:
     125             : /// -# include @c boost/test/execution_monitor.hpp
     126             : /// -# Make an instance of execution_monitor.
     127             : /// -# Optionally register custom exception translators for exception classes which require special processing.
     128             : ///
     129             : /// @subsection FuncExec Monitored function execution
     130             : ///
     131             : /// The class execution_monitor can monitor functions with the following signatures:
     132             : /// - int ()
     133             : /// - void ()
     134             : ///
     135             : /// This function is expected to be self sufficient part of your application. You can't pass any arguments to this function directly. Instead you
     136             : /// should bind them into executable nullary function using bind function (either standard or boost variant). Neither you can return any other value,
     137             : /// but an integer result code. If necessary you can bind output parameters by reference or use some other more complicated nullary functor, which
     138             : /// maintains state. This includes class methods, static class methods etc.
     139             : ///
     140             : /// To start the monitored function, invoke the method execution_monitor::execute and pass the monitored function as an argument. If the call succeeds,
     141             : /// the method returns the result code produced by the monitored function. If any of the following conditions occur:
     142             : /// - Uncaught C++ exception
     143             : /// - Hardware or software signal, trap, or other exception
     144             : /// - Timeout reached
     145             : /// - Debug assert event occurred (under Microsoft Visual C++ or compatible compiler)
     146             : ///
     147             : /// then the method throws the execution_exception. The exception contains unique error_code value identifying the error condition and the detailed message
     148             : /// that can be used to report the error.
     149             : ///
     150             : /// @subsection Reporting Errors reporting and translation
     151             : ///
     152             : /// If you need to report an error inside monitored function execution you have to throw an exception. Do not use the execution_exception - it's not intended
     153             : /// to be used for this purpose. The simplest choice is to use one of the following C++ types as an exception:
     154             : /// - C string
     155             : /// - std:string
     156             : /// - any exception class in std::exception hierarchy
     157             : /// - boost::exception
     158             : ///
     159             : /// execution_monitor will catch and report these types of exceptions. If exception is thrown which is unknown to execution_monitor, it can only
     160             : /// report the fact of the exception. So in case if you prefer to use your own exception types or can't govern what exceptions are generated by monitored
     161             : /// function and would like to see proper error message in a report, execution_monitor can be configured with custom "translator" routine, which will have
     162             : /// a chance to either record the fact of the exception itself or translate it into one of standard exceptions and rethrow (or both). The translator routine
     163             : /// is registered per exception type and is invoked when exception of this class (or one inherited from it) is thrown inside monitored routine. You can
     164             : /// register as many independent translators as you like. See execution_monitor::register_exception_translator specification for requirements on translator
     165             : /// function.
     166             : ///
     167             : /// Finally, if you need to abort the monitored function execution without reporting any errors, you can throw an exception execution_aborted. As a result
     168             : /// the execution is aborted and zero result code is produced by the method execution_monitor::execute.
     169             : ///
     170             : /// @subsection Parameters Supported parameters
     171             : ///
     172             : /// The Execution Monitor behavior is configurable through the set of parameters (properties) associated with the instance of the monitor. See execution_monitor
     173             : /// specification for a list of supported parameters and their semantic.
     174             : 
     175             : // ************************************************************************** //
     176             : // **************        detail::translator_holder_base        ************** //
     177             : // ************************************************************************** //
     178             : 
     179             : namespace detail {
     180             : 
     181             : class translator_holder_base;
     182             : typedef boost::shared_ptr<translator_holder_base> translator_holder_base_ptr;
     183             : 
     184             : class BOOST_TEST_DECL translator_holder_base {
     185             : protected:
     186             :     typedef boost::unit_test::const_string const_string;
     187             : public:
     188             :     // Constructor
     189             :     translator_holder_base( translator_holder_base_ptr next, const_string tag )
     190             :     : m_next( next )
     191             :     , m_tag( std::string() + tag )
     192             :     {
     193             :     }
     194             : 
     195             :     // Destructor
     196             :     virtual     ~translator_holder_base() {}
     197             : 
     198             :     // translator holder interface
     199             :     // invokes the function F inside the try/catch guarding against specific exception
     200             :     virtual int operator()( boost::function<int ()> const& F ) = 0;
     201             : 
     202             :     // erases specific translator holder from the chain
     203             :     translator_holder_base_ptr erase( translator_holder_base_ptr this_, const_string tag )
     204             :     {
     205             :         if( m_next )
     206             :             m_next = m_next->erase( m_next, tag );
     207             : 
     208             :         return m_tag == tag ? m_next : this_;
     209             :     }
     210             : #ifndef BOOST_NO_RTTI
     211             :     virtual translator_holder_base_ptr erase( translator_holder_base_ptr this_, std::type_info const& ) = 0;
     212             :     template<typename ExceptionType>
     213             :     translator_holder_base_ptr erase( translator_holder_base_ptr this_, boost::type<ExceptionType>* = 0 )
     214             :     {
     215             :         if( m_next )
     216             :             m_next = m_next->erase<ExceptionType>( m_next );
     217             : 
     218             :         return erase( this_, typeid(ExceptionType) );
     219             :     }
     220             : #endif
     221             : 
     222             : protected:
     223             :     // Data members
     224             :     translator_holder_base_ptr  m_next;
     225             :     std::string                 m_tag;
     226             : };
     227             : 
     228             : } // namespace detail
     229             : 
     230             : // ************************************************************************** //
     231             : /// @class execution_exception
     232             : /// @brief This class is used to report any kind of an failure during execution of a monitored function inside of execution_monitor
     233             : ///
     234             : /// The instance of this class is thrown out of execution_monitor::execute invocation when failure is detected. Regardless of a kind of failure occurred
     235             : /// the instance will provide a uniform way to catch and report it.
     236             : ///
     237             : /// One important design rationale for this class is that we should be ready to work after fatal memory corruptions or out of memory conditions. To facilitate
     238             : /// this class never allocates any memory and assumes that strings it refers to are either some constants or live in a some kind of persistent (preallocated) memory.
     239             : // ************************************************************************** //
     240             : 
     241             : class BOOST_SYMBOL_VISIBLE execution_exception {
     242             :     typedef boost::unit_test::const_string const_string;
     243             : public:
     244             :     /// These values are sometimes used as program return codes.
     245             :     /// The particular values have been chosen to avoid conflicts with
     246             :     /// commonly used program return codes: values < 100 are often user
     247             :     /// assigned, values > 255 are sometimes used to report system errors.
     248             :     /// Gaps in values allow for orderly expansion.
     249             :     ///
     250             :     /// @note(1) Only uncaught C++ exceptions are treated as errors.
     251             :     /// If a function catches a C++ exception, it never reaches
     252             :     /// the execution_monitor.
     253             :     ///
     254             :     /// The implementation decides what is a system_fatal_error and what is
     255             :     /// just a system_exception. Fatal errors are so likely to have corrupted
     256             :     /// machine state (like a stack overflow or addressing exception) that it
     257             :     /// is unreasonable to continue execution.
     258             :     ///
     259             :     /// @note(2) These errors include Unix signals and Windows structured
     260             :     /// exceptions. They are often initiated by hardware traps.
     261             :     enum error_code {
     262             :         no_error               = 0,   ///< for completeness only; never returned
     263             :         user_error             = 200, ///< user reported non-fatal error
     264             :         cpp_exception_error    = 205, ///< see note (1) above
     265             :         system_error           = 210, ///< see note (2) above
     266             :         timeout_error          = 215, ///< only detectable on certain platforms
     267             :         user_fatal_error       = 220, ///< user reported fatal error
     268             :         system_fatal_error     = 225  ///< see note (2) above
     269             :     };
     270             : 
     271             :     /// Simple model for the location of failure in a source code
     272             :     struct BOOST_TEST_DECL location {
     273             :         explicit    location( char const* file_name = 0, size_t line_num = 0, char const* func = 0 );
     274             :         explicit    location( const_string file_name, size_t line_num = 0, char const* func = 0 );
     275             : 
     276             :         const_string    m_file_name;    ///< File name
     277             :         size_t          m_line_num;     ///< Line number
     278             :         const_string    m_function;     ///< Function name
     279             :     };
     280             : 
     281             :     /// @name Constructors
     282             : 
     283             :     /// Constructs instance based on message, location and error code
     284             : 
     285             :     /// @param[in] ec           error code
     286             :     /// @param[in] what_msg     error message
     287             :     /// @param[in] location     error location
     288             :     execution_exception( error_code ec, const_string what_msg, location const& location );
     289             : 
     290             :     /// @name Access methods
     291             : 
     292             :     /// Exception error code
     293           0 :     error_code      code() const    { return m_error_code; }
     294             :     /// Exception message
     295           0 :     const_string    what() const    { return m_what; }
     296             :     /// Exception location
     297           0 :     location const& where() const   { return m_location; }
     298             :     ///@}
     299             : 
     300             : private:
     301             :     // Data members
     302             :     error_code      m_error_code;
     303             :     const_string    m_what;
     304             :     location        m_location;
     305             : }; // execution_exception
     306             : 
     307             : // ************************************************************************** //
     308             : /// @brief Function execution monitor
     309             : 
     310             : /// This class is used to uniformly detect and report an occurrence of several types of signals and exceptions, reducing various
     311             : /// errors to a uniform execution_exception that is returned to a caller.
     312             : ///
     313             : /// The execution_monitor behavior can be customized through a set of public parameters (properties) associated with the execution_monitor instance.
     314             : /// All parameters are implemented as public unit_test::readwrite_property data members of the class execution_monitor.
     315             : // ************************************************************************** //
     316             : 
     317             : class BOOST_TEST_DECL execution_monitor {
     318             :     typedef boost::unit_test::const_string const_string;
     319             : public:
     320             : 
     321             :     /// Default constructor initializes all execution monitor properties
     322             :     execution_monitor();
     323             : 
     324             :     /// Should monitor catch system errors.
     325             :     ///
     326             :     /// The @em p_catch_system_errors property is a boolean flag (default value is true) specifying whether or not execution_monitor should trap system
     327             :     /// errors/system level exceptions/signals, which would cause program to crash in a regular case (without execution_monitor).
     328             :     /// Set this property to false, for example, if you wish to force coredump file creation. The Unit Test Framework provides a
     329             :     /// runtime parameter @c \-\-catch_system_errors=yes to alter the behavior in monitored test cases.
     330             :     unit_test::readwrite_property<bool> p_catch_system_errors;
     331             : 
     332             :     ///  Should monitor try to attach debugger in case of caught system error.
     333             :     ///
     334             :     /// The @em p_auto_start_dbg property is a boolean flag (default value is false) specifying whether or not execution_monitor should try to attach debugger
     335             :     /// in case system error is caught.
     336             :     unit_test::readwrite_property<bool> p_auto_start_dbg;
     337             : 
     338             : 
     339             :     ///  Specifies the seconds that elapse before a timer_error occurs.
     340             :     ///
     341             :     /// The @em p_timeout property is an integer timeout (in microseconds) for monitored function execution. Use this parameter to monitor code with possible deadlocks
     342             :     /// or infinite loops. This feature is only available for some operating systems (not yet Microsoft Windows).
     343             :     unit_test::readwrite_property<unsigned long int>  p_timeout;
     344             : 
     345             :     ///  Should monitor use alternative stack for the signal catching.
     346             :     ///
     347             :     /// The @em p_use_alt_stack property is a boolean flag (default value is false) specifying whether or not execution_monitor should use an alternative stack
     348             :     /// for the sigaction based signal catching. When enabled the signals are delivered to the execution_monitor on a stack different from current execution
     349             :     /// stack, which is safer in case if it is corrupted by monitored function. For more details on alternative stack handling see appropriate manuals.
     350             :     unit_test::readwrite_property<bool> p_use_alt_stack;
     351             : 
     352             :     /// Should monitor try to detect hardware floating point exceptions (!= 0), and which specific exception to catch.
     353             :     ///
     354             :     /// The @em p_detect_fp_exceptions property is a boolean flag (default value is false) specifying whether or not execution_monitor should install hardware
     355             :     /// traps for the floating point exception on platforms where it's supported.
     356             :     unit_test::readwrite_property<unsigned> p_detect_fp_exceptions;
     357             : 
     358             : 
     359             :     // @name Monitoring entry points
     360             : 
     361             :     /// @brief Execution monitor entry point for functions returning integer value
     362             :     ///
     363             :     /// This method executes supplied function F inside a try/catch block and also may include other unspecified platform dependent error detection code.
     364             :     ///
     365             :     /// This method throws an execution_exception on an uncaught C++ exception, a hardware or software signal, trap, or other user exception.
     366             :     ///
     367             :     /// @note execute() doesn't consider it an error for F to return a non-zero value.
     368             :     /// @param[in] F  Function to monitor
     369             :     /// @returns  value returned by function call F().
     370             :     /// @see vexecute
     371             :     int         execute( boost::function<int ()> const& F );
     372             : 
     373             :     /// @brief Execution monitor entry point for functions returning void
     374             :     ///
     375             :     /// This method is semantically identical to execution_monitor::execute, but doesn't produce any result code.
     376             :     /// @param[in] F  Function to monitor
     377             :     /// @see execute
     378             :     void         vexecute( boost::function<void ()> const& F );
     379             :     // @}
     380             : 
     381             :     // @name Exception translator registration
     382             : 
     383             :     /// @brief Registers custom (user supplied) exception translator
     384             : 
     385             :     /// This method template registers a translator for an exception type specified as a first template argument. For example
     386             :     /// @code
     387             :     ///    void myExceptTr( MyException const& ex ) { /*do something with the exception here*/}
     388             :     ///    em.register_exception_translator<MyException>( myExceptTr );
     389             :     /// @endcode
     390             :     /// The translator should be any unary function/functor object which accepts MyException const&. This can be free standing function
     391             :     /// or bound class method. The second argument is an optional string tag you can associate with this translator routine. The only reason
     392             :     /// to specify the tag is if you plan to erase the translator eventually. This can be useful in scenario when you reuse the same
     393             :     /// execution_monitor instance to monitor different routines and need to register a translator specific to the routine being monitored.
     394             :     /// While it is possible to erase the translator based on an exception type it was registered for, tag string provides simpler way of doing this.
     395             :     /// @tparam ExceptionType type of the exception we register a translator for
     396             :     /// @tparam ExceptionTranslator type of the translator we register for this exception
     397             :     /// @param[in] tr         translator function object with the signature <em> void (ExceptionType const&)</em>
     398             :     /// @param[in] tag        tag associated with this translator
     399             :     template<typename ExceptionType, typename ExceptionTranslator>
     400             :     void        register_exception_translator( ExceptionTranslator const& tr, const_string tag = const_string(), boost::type<ExceptionType>* = 0 );
     401             : 
     402             :     /// @brief Erases custom exception translator based on a tag
     403             : 
     404             :     /// Use the same tag as the one used during translator registration
     405             :     /// @param[in] tag  tag associated with translator you wants to erase
     406             :     void        erase_exception_translator( const_string tag )
     407             :     {
     408             :         m_custom_translators = m_custom_translators->erase( m_custom_translators, tag );
     409             :     }
     410             : #ifndef BOOST_NO_RTTI
     411             :     /// @brief Erases custom exception translator based on an exception type
     412             :     ///
     413             :     /// tparam ExceptionType Exception type for which you want to erase the translator
     414             :     template<typename ExceptionType>
     415             :     void        erase_exception_translator( boost::type<ExceptionType>* = 0 )
     416             :     {
     417             :         m_custom_translators = m_custom_translators->erase<ExceptionType>( m_custom_translators );
     418             :     }
     419             :     //@}
     420             : #endif
     421             : 
     422             : private:
     423             :     // implementation helpers
     424             :     int         catch_signals( boost::function<int ()> const& F );
     425             : 
     426             :     // Data members
     427             :     detail::translator_holder_base_ptr  m_custom_translators;
     428             :     boost::scoped_array<char>           m_alt_stack;
     429             : }; // execution_monitor
     430             : 
     431             : // ************************************************************************** //
     432             : // **************          detail::translator_holder           ************** //
     433             : // ************************************************************************** //
     434             : 
     435             : namespace detail {
     436             : 
     437             : template<typename ExceptionType, typename ExceptionTranslator>
     438             : class translator_holder : public translator_holder_base
     439             : {
     440             : public:
     441             :     explicit    translator_holder( ExceptionTranslator const& tr, translator_holder_base_ptr& next, const_string tag = const_string() )
     442             :     : translator_holder_base( next, tag ), m_translator( tr ) {}
     443             : 
     444             :     // translator holder interface
     445             :     int operator()( boost::function<int ()> const& F ) BOOST_OVERRIDE
     446             :     {
     447             :         BOOST_TEST_I_TRY {
     448             :             return m_next ? (*m_next)( F ) : F();
     449             :         }
     450             :         BOOST_TEST_I_CATCH( ExceptionType, e ) {
     451             :             m_translator( e );
     452             :             return boost::exit_exception_failure;
     453             :         }
     454             :     }
     455             : #ifndef BOOST_NO_RTTI
     456             :     translator_holder_base_ptr erase( translator_holder_base_ptr this_, std::type_info const& ti ) BOOST_OVERRIDE
     457             :     {
     458             :         return ti == typeid(ExceptionType) ? m_next : this_;
     459             :     }
     460             : #endif
     461             : 
     462             : private:
     463             :     // Data members
     464             :     ExceptionTranslator m_translator;
     465             : };
     466             : 
     467             : } // namespace detail
     468             : 
     469             : template<typename ExceptionType, typename ExceptionTranslator>
     470             : void
     471             : execution_monitor::register_exception_translator( ExceptionTranslator const& tr, const_string tag, boost::type<ExceptionType>* )
     472             : {
     473             :     m_custom_translators.reset(
     474             :         new detail::translator_holder<ExceptionType,ExceptionTranslator>( tr, m_custom_translators, tag ) );
     475             : }
     476             : 
     477             : // ************************************************************************** //
     478             : /// @class execution_aborted
     479             : /// @brief This is a trivial default constructible class. Use it to report graceful abortion of a monitored function execution.
     480             : // ************************************************************************** //
     481             : 
     482             : struct BOOST_SYMBOL_VISIBLE execution_aborted {};
     483             : 
     484             : // ************************************************************************** //
     485             : // **************                  system_error                ************** //
     486             : // ************************************************************************** //
     487             : 
     488             : class system_error {
     489             : public:
     490             :     // Constructor
     491             :     explicit    system_error( char const* exp );
     492             : 
     493             :     long const          p_errno;
     494             :     char const* const   p_failed_exp;
     495             : };
     496             : 
     497             : //!@internal
     498             : #define BOOST_TEST_SYS_ASSERT( cond ) BOOST_TEST_I_ASSRT( cond, ::boost::system_error( BOOST_STRINGIZE( exp ) ) )
     499             : 
     500             : // ************************************************************************** //
     501             : // **************Floating point exception management interface ************** //
     502             : // ************************************************************************** //
     503             : 
     504             : namespace fpe {
     505             : 
     506             : enum masks {
     507             :     BOOST_FPE_OFF       = 0,
     508             : 
     509             : #if defined(BOOST_TEST_FPE_SUPPORT_WITH_SEH__) /* *** */
     510             :     BOOST_FPE_DIVBYZERO = EM_ZERODIVIDE,
     511             :     BOOST_FPE_INEXACT   = EM_INEXACT,
     512             :     BOOST_FPE_INVALID   = EM_INVALID,
     513             :     BOOST_FPE_OVERFLOW  = EM_OVERFLOW,
     514             :     BOOST_FPE_UNDERFLOW = EM_UNDERFLOW|EM_DENORMAL,
     515             : 
     516             :     BOOST_FPE_ALL       = MCW_EM,
     517             : 
     518             : #elif !defined(BOOST_TEST_FPE_SUPPORT_WITH_GLIBC_EXTENSIONS__)/* *** */
     519             :     BOOST_FPE_DIVBYZERO = BOOST_FPE_OFF,
     520             :     BOOST_FPE_INEXACT   = BOOST_FPE_OFF,
     521             :     BOOST_FPE_INVALID   = BOOST_FPE_OFF,
     522             :     BOOST_FPE_OVERFLOW  = BOOST_FPE_OFF,
     523             :     BOOST_FPE_UNDERFLOW = BOOST_FPE_OFF,
     524             :     BOOST_FPE_ALL       = BOOST_FPE_OFF,
     525             : #else /* *** */
     526             : 
     527             : #if defined(FE_DIVBYZERO)
     528             :     BOOST_FPE_DIVBYZERO = FE_DIVBYZERO,
     529             : #else
     530             :     BOOST_FPE_DIVBYZERO = BOOST_FPE_OFF,
     531             : #endif
     532             : 
     533             : #if defined(FE_INEXACT)
     534             :     BOOST_FPE_INEXACT   = FE_INEXACT,
     535             : #else
     536             :     BOOST_FPE_INEXACT   = BOOST_FPE_OFF,
     537             : #endif
     538             : 
     539             : #if defined(FE_INVALID)
     540             :     BOOST_FPE_INVALID   = FE_INVALID,
     541             : #else
     542             :     BOOST_FPE_INVALID   = BOOST_FPE_OFF,
     543             : #endif
     544             : 
     545             : #if defined(FE_OVERFLOW)
     546             :     BOOST_FPE_OVERFLOW  = FE_OVERFLOW,
     547             : #else
     548             :     BOOST_FPE_OVERFLOW  = BOOST_FPE_OFF,
     549             : #endif
     550             : 
     551             : #if defined(FE_UNDERFLOW)
     552             :     BOOST_FPE_UNDERFLOW = FE_UNDERFLOW,
     553             : #else
     554             :     BOOST_FPE_UNDERFLOW = BOOST_FPE_OFF,
     555             : #endif
     556             : 
     557             : #if defined(FE_ALL_EXCEPT)
     558             :     BOOST_FPE_ALL       = FE_ALL_EXCEPT,
     559             : #else
     560             :     BOOST_FPE_ALL       = BOOST_FPE_OFF,
     561             : #endif
     562             : 
     563             : #endif /* *** */
     564             :     BOOST_FPE_INV       = BOOST_FPE_ALL+1
     565             : };
     566             : 
     567             : //____________________________________________________________________________//
     568             : 
     569             : // return the previous set of enabled exceptions when successful, and BOOST_FPE_INV otherwise
     570             : unsigned BOOST_TEST_DECL enable( unsigned mask );
     571             : unsigned BOOST_TEST_DECL disable( unsigned mask );
     572             : 
     573             : //____________________________________________________________________________//
     574             : 
     575             : } // namespace fpe
     576             : 
     577             : ///@}
     578             : 
     579             : }  // namespace boost
     580             : 
     581             : 
     582             : #include <boost/test/detail/enable_warnings.hpp>
     583             : 
     584             : #endif

Generated by: LCOV version 1.16