/ externals / catch / src / catch2 / catch_message.hpp
catch_message.hpp
  1  
  2  //              Copyright Catch2 Authors
  3  // Distributed under the Boost Software License, Version 1.0.
  4  //   (See accompanying file LICENSE.txt or copy at
  5  //        https://www.boost.org/LICENSE_1_0.txt)
  6  
  7  // SPDX-License-Identifier: BSL-1.0
  8  #ifndef CATCH_MESSAGE_HPP_INCLUDED
  9  #define CATCH_MESSAGE_HPP_INCLUDED
 10  
 11  #include <catch2/internal/catch_config_prefix_messages.hpp>
 12  #include <catch2/internal/catch_result_type.hpp>
 13  #include <catch2/internal/catch_reusable_string_stream.hpp>
 14  #include <catch2/internal/catch_stream_end_stop.hpp>
 15  #include <catch2/internal/catch_message_info.hpp>
 16  #include <catch2/catch_tostring.hpp>
 17  #include <catch2/interfaces/catch_interfaces_capture.hpp>
 18  
 19  #include <string>
 20  #include <vector>
 21  
 22  namespace Catch {
 23  
 24      struct SourceLineInfo;
 25      class IResultCapture;
 26  
 27      struct MessageStream {
 28  
 29          template<typename T>
 30          MessageStream& operator << ( T const& value ) {
 31              m_stream << value;
 32              return *this;
 33          }
 34  
 35          ReusableStringStream m_stream;
 36      };
 37  
 38      struct MessageBuilder : MessageStream {
 39          MessageBuilder( StringRef macroName,
 40                          SourceLineInfo const& lineInfo,
 41                          ResultWas::OfType type ):
 42              m_info(macroName, lineInfo, type) {}
 43  
 44          template<typename T>
 45          MessageBuilder&& operator << ( T const& value ) && {
 46              m_stream << value;
 47              return CATCH_MOVE(*this);
 48          }
 49  
 50          MessageInfo m_info;
 51      };
 52  
 53      class ScopedMessage {
 54      public:
 55          explicit ScopedMessage( MessageBuilder&& builder );
 56          ScopedMessage( ScopedMessage& duplicate ) = delete;
 57          ScopedMessage( ScopedMessage&& old ) noexcept;
 58          ~ScopedMessage();
 59  
 60          MessageInfo m_info;
 61          bool m_moved = false;
 62      };
 63  
 64      class Capturer {
 65          std::vector<MessageInfo> m_messages;
 66          IResultCapture& m_resultCapture;
 67          size_t m_captured = 0;
 68      public:
 69          Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names );
 70  
 71          Capturer(Capturer const&) = delete;
 72          Capturer& operator=(Capturer const&) = delete;
 73  
 74          ~Capturer();
 75  
 76          void captureValue( size_t index, std::string const& value );
 77  
 78          template<typename T>
 79          void captureValues( size_t index, T const& value ) {
 80              captureValue( index, Catch::Detail::stringify( value ) );
 81          }
 82  
 83          template<typename T, typename... Ts>
 84          void captureValues( size_t index, T const& value, Ts const&... values ) {
 85              captureValue( index, Catch::Detail::stringify(value) );
 86              captureValues( index+1, values... );
 87          }
 88      };
 89  
 90  } // end namespace Catch
 91  
 92  ///////////////////////////////////////////////////////////////////////////////
 93  #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
 94      do { \
 95          Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \
 96          catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
 97          INTERNAL_CATCH_REACT( catchAssertionHandler ) \
 98      } while( false )
 99  
100  ///////////////////////////////////////////////////////////////////////////////
101  #define INTERNAL_CATCH_CAPTURE( varName, macroName, ... ) \
102      Catch::Capturer varName( macroName##_catch_sr,        \
103                               CATCH_INTERNAL_LINEINFO,     \
104                               Catch::ResultWas::Info,      \
105                               #__VA_ARGS__##_catch_sr );   \
106      varName.captureValues( 0, __VA_ARGS__ )
107  
108  ///////////////////////////////////////////////////////////////////////////////
109  #define INTERNAL_CATCH_INFO( macroName, log ) \
110      const Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log )
111  
112  ///////////////////////////////////////////////////////////////////////////////
113  #define INTERNAL_CATCH_UNSCOPED_INFO( macroName, log ) \
114      Catch::getResultCapture().emplaceUnscopedMessage( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log )
115  
116  
117  #if defined(CATCH_CONFIG_PREFIX_MESSAGES) && !defined(CATCH_CONFIG_DISABLE)
118  
119    #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
120    #define CATCH_UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "CATCH_UNSCOPED_INFO", msg )
121    #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
122    #define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE", __VA_ARGS__ )
123  
124  #elif defined(CATCH_CONFIG_PREFIX_MESSAGES) && defined(CATCH_CONFIG_DISABLE)
125  
126    #define CATCH_INFO( msg )          (void)(0)
127    #define CATCH_UNSCOPED_INFO( msg ) (void)(0)
128    #define CATCH_WARN( msg )          (void)(0)
129    #define CATCH_CAPTURE( ... )       (void)(0)
130  
131  #elif !defined(CATCH_CONFIG_PREFIX_MESSAGES) && !defined(CATCH_CONFIG_DISABLE)
132  
133    #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
134    #define UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "UNSCOPED_INFO", msg )
135    #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
136    #define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE", __VA_ARGS__ )
137  
138  #elif !defined(CATCH_CONFIG_PREFIX_MESSAGES) && defined(CATCH_CONFIG_DISABLE)
139  
140    #define INFO( msg )          (void)(0)
141    #define UNSCOPED_INFO( msg ) (void)(0)
142    #define WARN( msg )          (void)(0)
143    #define CAPTURE( ... )       (void)(0)
144  
145  #endif // end of user facing macro declarations
146  
147  
148  
149  
150  #endif // CATCH_MESSAGE_HPP_INCLUDED