mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-10-31 20:27:11 +01:00 
			
		
		
		
	Moved a lot of stream related stuff out of the public headers and replaced more ostream dependencies with iosfwd
This commit is contained in:
		| @@ -7,7 +7,7 @@ | ||||
|  | ||||
| #include "catch_config.hpp" | ||||
| #include "catch_enforce.h" | ||||
| #include "catch_stream.h" | ||||
| #include "catch_stringref.h" | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
| @@ -58,16 +58,7 @@ namespace Catch { | ||||
|     Verbosity Config::verbosity() const                { return m_data.verbosity; } | ||||
|  | ||||
|     IStream const* Config::openStream() { | ||||
|         if( m_data.outputFilename.empty() ) | ||||
|             return new CoutStream(); | ||||
|         else if( m_data.outputFilename[0] == '%' ) { | ||||
|             if( m_data.outputFilename == "%debug" ) | ||||
|                 return new DebugOutStream(); | ||||
|             else | ||||
|                 CATCH_ERROR( "Unrecognised stream: '" << m_data.outputFilename << "'" ); | ||||
|         } | ||||
|         else | ||||
|             return new FileStream( m_data.outputFilename ); | ||||
|         return Catch::makeStream(m_data.outputFilename); | ||||
|     } | ||||
|  | ||||
| } // end namespace Catch | ||||
|   | ||||
| @@ -14,13 +14,15 @@ | ||||
|  | ||||
| #ifdef CATCH_PLATFORM_MAC | ||||
|  | ||||
|     #include <assert.h> | ||||
|     #include <stdbool.h> | ||||
|     #include <sys/types.h> | ||||
|     #include <unistd.h> | ||||
|     #include <sys/sysctl.h> | ||||
| #  include <assert.h> | ||||
| #  include <stdbool.h> | ||||
| #  include <sys/types.h> | ||||
| #  include <unistd.h> | ||||
| #  include <sys/sysctl.h> | ||||
| #  include <cstddef> | ||||
| #  include <ostream> | ||||
|  | ||||
|     namespace Catch { | ||||
| namespace Catch { | ||||
|  | ||||
|         // The following function is taken directly from the following technical note: | ||||
|         // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
| #include "catch_tostring.h" | ||||
| #include "catch_stringref.h" | ||||
|  | ||||
| #include <ostream> | ||||
| #include <iosfwd> | ||||
|  | ||||
| #ifdef _MSC_VER | ||||
| #pragma warning(push) | ||||
|   | ||||
| @@ -11,88 +11,129 @@ | ||||
| #include "catch_enforce.h" | ||||
| #include "catch_stream.h" | ||||
| #include "catch_debug_console.h" | ||||
| #include "catch_stringref.h" | ||||
|  | ||||
| #include <stdexcept> | ||||
| #include <cstdio> | ||||
| #include <iostream> | ||||
| #include <fstream> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     template<typename WriterF, std::size_t bufferSize=256> | ||||
|     class StreamBufImpl : public StreamBufBase { | ||||
|         char data[bufferSize]; | ||||
|         WriterF m_writer; | ||||
|     Catch::IStream::~IStream() = default; | ||||
|  | ||||
|     public: | ||||
|         StreamBufImpl() { | ||||
|             setp( data, data + sizeof(data) ); | ||||
|         } | ||||
|     namespace detail { namespace { | ||||
|         template<typename WriterF, std::size_t bufferSize=256> | ||||
|         class StreamBufImpl : public std::streambuf { | ||||
|             char data[bufferSize]; | ||||
|             WriterF m_writer; | ||||
|  | ||||
|         ~StreamBufImpl() noexcept { | ||||
|             StreamBufImpl::sync(); | ||||
|         } | ||||
|  | ||||
|     private: | ||||
|         int overflow( int c ) override { | ||||
|             sync(); | ||||
|  | ||||
|             if( c != EOF ) { | ||||
|                 if( pbase() == epptr() ) | ||||
|                     m_writer( std::string( 1, static_cast<char>( c ) ) ); | ||||
|                 else | ||||
|                     sputc( static_cast<char>( c ) ); | ||||
|         public: | ||||
|             StreamBufImpl() { | ||||
|                 setp( data, data + sizeof(data) ); | ||||
|             } | ||||
|             return 0; | ||||
|         } | ||||
|  | ||||
|         int sync() override { | ||||
|             if( pbase() != pptr() ) { | ||||
|                 m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) ); | ||||
|                 setp( pbase(), epptr() ); | ||||
|             ~StreamBufImpl() noexcept { | ||||
|                 StreamBufImpl::sync(); | ||||
|             } | ||||
|             return 0; | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|         private: | ||||
|             int overflow( int c ) override { | ||||
|                 sync(); | ||||
|  | ||||
|                 if( c != EOF ) { | ||||
|                     if( pbase() == epptr() ) | ||||
|                         m_writer( std::string( 1, static_cast<char>( c ) ) ); | ||||
|                     else | ||||
|                         sputc( static_cast<char>( c ) ); | ||||
|                 } | ||||
|                 return 0; | ||||
|             } | ||||
|  | ||||
|             int sync() override { | ||||
|                 if( pbase() != pptr() ) { | ||||
|                     m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) ); | ||||
|                     setp( pbase(), epptr() ); | ||||
|                 } | ||||
|                 return 0; | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         /////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
|         struct OutputDebugWriter { | ||||
|  | ||||
|             void operator()( std::string const&str ) { | ||||
|                 writeToDebugConsole( str ); | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         /////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
|         class FileStream : public IStream { | ||||
|             mutable std::ofstream m_ofs; | ||||
|         public: | ||||
|             FileStream( StringRef filename ) { | ||||
|                 m_ofs.open( filename.c_str() ); | ||||
|                 CATCH_ENFORCE( !m_ofs.fail(), "Unable to open file: '" << filename << "'" ); | ||||
|             } | ||||
|             ~FileStream() override = default; | ||||
|         public: // IStream | ||||
|             std::ostream& stream() const override { | ||||
|                 return m_ofs; | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         /////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
|         class CoutStream : public IStream { | ||||
|             mutable std::ostream m_os; | ||||
|         public: | ||||
|             // Store the streambuf from cout up-front because | ||||
|             // cout may get redirected when running tests | ||||
|             CoutStream() : m_os( Catch::cout().rdbuf() ) {} | ||||
|             ~CoutStream() override = default; | ||||
|  | ||||
|         public: // IStream | ||||
|             std::ostream& stream() const override { return m_os; } | ||||
|         }; | ||||
|  | ||||
|         /////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
|         class DebugOutStream : public IStream { | ||||
|             std::unique_ptr<StreamBufImpl<OutputDebugWriter>> m_streamBuf; | ||||
|             mutable std::ostream m_os; | ||||
|         public: | ||||
|             DebugOutStream() | ||||
|             :   m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ), | ||||
|                 m_os( m_streamBuf.get() ) | ||||
|             {} | ||||
|  | ||||
|             ~DebugOutStream() override = default; | ||||
|  | ||||
|         public: // IStream | ||||
|             std::ostream& stream() const override { return m_os; } | ||||
|         }; | ||||
|  | ||||
|     }} // namespace anon::detail | ||||
|  | ||||
|     /////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
|  | ||||
|     Catch::IStream::~IStream() = default; | ||||
|  | ||||
|     FileStream::FileStream( std::string const& filename ) { | ||||
|         m_ofs.open( filename.c_str() ); | ||||
|         CATCH_ENFORCE( !m_ofs.fail(), "Unable to open file: '" << filename << "'" ); | ||||
|     } | ||||
|  | ||||
|     std::ostream& FileStream::stream() const { | ||||
|         return m_ofs; | ||||
|     } | ||||
|  | ||||
|     struct OutputDebugWriter { | ||||
|  | ||||
|         void operator()( std::string const&str ) { | ||||
|             writeToDebugConsole( str ); | ||||
|     auto makeStream( StringRef const &filename ) -> IStream const* { | ||||
|         if( filename.empty() ) | ||||
|             return new detail::CoutStream(); | ||||
|         else if( filename[0] == '%' ) { | ||||
|             if( filename == "%debug" ) | ||||
|                 return new detail::DebugOutStream(); | ||||
|             else | ||||
|                 CATCH_ERROR( "Unrecognised stream: '" << filename << "'" ); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     DebugOutStream::DebugOutStream() | ||||
|     :   m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ), | ||||
|         m_os( m_streamBuf.get() ) | ||||
|     {} | ||||
|  | ||||
|     std::ostream& DebugOutStream::stream() const { | ||||
|         return m_os; | ||||
|         else | ||||
|             return new detail::FileStream( filename ); | ||||
|     } | ||||
|  | ||||
|     // Store the streambuf from cout up-front because | ||||
|     // cout may get redirected when running tests | ||||
|     CoutStream::CoutStream() | ||||
|     :   m_os( Catch::cout().rdbuf() ) | ||||
|     {} | ||||
|     /////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
|     std::ostream& CoutStream::stream() const { | ||||
|         return m_os; | ||||
|     } | ||||
|  | ||||
| #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions | ||||
|     std::ostream& cout() { | ||||
|   | ||||
| @@ -9,12 +9,7 @@ | ||||
| #ifndef TWOBLUECUBES_CATCH_STREAM_H_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED | ||||
|  | ||||
| #include "catch_streambuf.h" | ||||
|  | ||||
| #include <streambuf> | ||||
| #include <ostream> | ||||
| #include <fstream> | ||||
| #include <memory> | ||||
| #include <iosfwd> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
| @@ -22,43 +17,14 @@ namespace Catch { | ||||
|     std::ostream& cerr(); | ||||
|     std::ostream& clog(); | ||||
|  | ||||
|     class StringRef; | ||||
|  | ||||
|     struct IStream { | ||||
|         virtual ~IStream(); | ||||
|         virtual std::ostream& stream() const = 0; | ||||
|     }; | ||||
|  | ||||
|     class FileStream : public IStream { | ||||
|         mutable std::ofstream m_ofs; | ||||
|     public: | ||||
|         FileStream( std::string const& filename ); | ||||
|         ~FileStream() override = default; | ||||
|     public: // IStream | ||||
|         std::ostream& stream() const override; | ||||
|     }; | ||||
|  | ||||
|  | ||||
|     class CoutStream : public IStream { | ||||
|         mutable std::ostream m_os; | ||||
|     public: | ||||
|         CoutStream(); | ||||
|         ~CoutStream() override = default; | ||||
|  | ||||
|     public: // IStream | ||||
|         std::ostream& stream() const override; | ||||
|     }; | ||||
|  | ||||
|  | ||||
|     class DebugOutStream : public IStream { | ||||
|         std::unique_ptr<StreamBufBase> m_streamBuf; | ||||
|         mutable std::ostream m_os; | ||||
|     public: | ||||
|         DebugOutStream(); | ||||
|         ~DebugOutStream() override = default; | ||||
|  | ||||
|     public: // IStream | ||||
|         std::ostream& stream() const override; | ||||
|     }; | ||||
|     auto makeStream( StringRef const &filename ) -> IStream const*; | ||||
| } | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_STREAM_H_INCLUDED | ||||
|   | ||||
| @@ -1,12 +0,0 @@ | ||||
| /* | ||||
|  *  Created by Martin on 31/08/2017. | ||||
|  * | ||||
|  *  Distributed under the Boost Software License, Version 1.0. (See accompanying | ||||
|  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||||
|  */ | ||||
|  | ||||
| #include "catch_streambuf.h" | ||||
|  | ||||
| namespace Catch { | ||||
|     StreamBufBase::~StreamBufBase() = default; | ||||
| } | ||||
| @@ -1,21 +0,0 @@ | ||||
| /* | ||||
|  *  Created by Phil on 27/11/2012. | ||||
|  *  Copyright 2012 Two Blue Cubes Ltd. All rights reserved. | ||||
|  * | ||||
|  *  Distributed under the Boost Software License, Version 1.0. (See accompanying | ||||
|  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||||
|  */ | ||||
| #ifndef TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED | ||||
|  | ||||
| #include <streambuf> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     class StreamBufBase : public std::streambuf { | ||||
|     public: | ||||
|         virtual ~StreamBufBase(); | ||||
|     }; | ||||
| } | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED | ||||
		Reference in New Issue
	
	Block a user
	 Phil Nash
					Phil Nash