1
0
mirror of https://github.com/catchorg/Catch2.git synced 2025-04-30 04:23:52 +00:00
Catch2/src/catch2/internal/catch_console_colour.hpp
2022-04-11 18:32:35 +02:00

142 lines
4.2 KiB
C++

// Copyright Catch2 Authors
// 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)
// SPDX-License-Identifier: BSL-1.0
#ifndef CATCH_CONSOLE_COLOUR_HPP_INCLUDED
#define CATCH_CONSOLE_COLOUR_HPP_INCLUDED
#include <catch2/internal/catch_unique_ptr.hpp>
#include <iosfwd>
#include <cstdint>
namespace Catch {
enum class ColourMode : std::uint8_t;
class IConfig;
class IStream;
struct Colour {
enum Code {
None = 0,
White,
Red,
Green,
Blue,
Cyan,
Yellow,
Grey,
Bright = 0x10,
BrightRed = Bright | Red,
BrightGreen = Bright | Green,
LightGrey = Bright | Grey,
BrightWhite = Bright | White,
BrightYellow = Bright | Yellow,
// By intention
FileName = LightGrey,
Warning = BrightYellow,
ResultError = BrightRed,
ResultSuccess = BrightGreen,
ResultExpectedFailure = Warning,
Error = BrightRed,
Success = Green,
OriginalExpression = Cyan,
ReconstructedExpression = BrightYellow,
SecondaryText = LightGrey,
Headers = White
};
};
class ColourImpl {
protected:
//! The associated stream of this ColourImpl instance
IStream const* m_stream;
public:
ColourImpl( IStream const* stream ): m_stream( stream ) {}
//! RAII wrapper around writing specific colour of text using specific
//! colour impl into a stream.
class ColourGuard {
ColourImpl const* m_colourImpl;
Colour::Code m_code;
bool m_engaged = false;
public:
//! Does **not** engage the guard/start the colour
ColourGuard( Colour::Code code,
ColourImpl const* colour );
ColourGuard( ColourGuard const& rhs ) = delete;
ColourGuard& operator=( ColourGuard const& rhs ) = delete;
ColourGuard( ColourGuard&& rhs ) noexcept;
ColourGuard& operator=( ColourGuard&& rhs ) noexcept;
//! Removes colour _if_ the guard was engaged
~ColourGuard();
/**
* Explicitly engages colour for given stream.
*
* The API based on operator<< should be preferred.
*/
ColourGuard& engage( std::ostream& stream ) &;
/**
* Explicitly engages colour for given stream.
*
* The API based on operator<< should be preferred.
*/
ColourGuard&& engage( std::ostream& stream ) &&;
private:
//! Engages the guard and starts using colour
friend std::ostream& operator<<( std::ostream& lhs,
ColourGuard& guard ) {
guard.engageImpl( lhs );
return lhs;
}
//! Engages the guard and starts using colour
friend std::ostream& operator<<( std::ostream& lhs,
ColourGuard&& guard) {
guard.engageImpl( lhs );
return lhs;
}
void engageImpl( std::ostream& stream );
};
virtual ~ColourImpl(); // = default
/**
* Creates a guard object for given colour and this colour impl
*
* **Important:**
* the guard starts disengaged, and has to be engaged explicitly.
*/
ColourGuard guardColour( Colour::Code colourCode );
private:
virtual void use( Colour::Code colourCode ) const = 0;
};
//! Provides ColourImpl based on global config and target compilation platform
Detail::unique_ptr<ColourImpl> makeColourImpl( ColourMode colourSelection,
IStream const* stream );
//! Checks if specific colour impl has been compiled into the binary
bool isColourImplAvailable( ColourMode colourSelection );
} // end namespace Catch
#endif // CATCH_CONSOLE_COLOUR_HPP_INCLUDED