Run Code
|
API
|
Code Wall
|
Misc
|
Feedback
|
Login
|
Theme
|
Privacy
|
Patreon
rang_warnings
#ifndef RANG_DOT_HPP #define RANG_DOT_HPP #pragma warning( push ) #pragma warning( disable : 4820) #include <windows.h> #include <io.h> #pragma warning( pop ) #ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING #define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 #endif #pragma warning( push ) #pragma warning( disable : 4820) #include <algorithm> #include <atomic> #include <cstdlib> #include <cstring> #include <iostream> #pragma warning( pop ) namespace rang { enum class style { reset = 0, bold = 1, dim = 2, italic = 3, underline = 4, blink = 5, rblink = 6, reversed = 7, conceal = 8, crossed = 9 }; enum class fg { black = 30, red = 31, green = 32, yellow = 33, blue = 34, magenta = 35, cyan = 36, gray = 37, reset = 39 }; enum class bg { black = 40, red = 41, green = 42, yellow = 43, blue = 44, magenta = 45, cyan = 46, gray = 47, reset = 49 }; enum class fgB { black = 90, red = 91, green = 92, yellow = 93, blue = 94, magenta = 95, cyan = 96, gray = 97 }; enum class bgB { black = 100, red = 101, green = 102, yellow = 103, blue = 104, magenta = 105, cyan = 106, gray = 107 }; enum class control { Off = 0, Auto = 1, Force = 2 }; enum class winTerm { Auto = 0, Ansi = 1, Native = 2 }; namespace rang_implementation { inline std::atomic<control> &controlMode() noexcept { static std::atomic<control> value(control::Auto); return value; } inline std::atomic<winTerm> &winTermMode() noexcept { static std::atomic<winTerm> termMode(winTerm::Auto); return termMode; } inline bool supportsColor() noexcept { static constexpr bool result = true; return result; } inline bool isMsysPty(int fd) noexcept { const auto ptrGetFileInformationByHandleEx = reinterpret_cast<decltype(&GetFileInformationByHandleEx)>( GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetFileInformationByHandleEx")); if (!ptrGetFileInformationByHandleEx) { return false; } HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd)); if (h == INVALID_HANDLE_VALUE) { return false; } if (GetFileType(h) != FILE_TYPE_PIPE) { return false; } constexpr const DWORD size = sizeof(FILE_NAME_INFO) + sizeof(WCHAR) * (MAX_PATH + 1); alignas(FILE_NAME_INFO) char buffer[size]; FILE_NAME_INFO *nameinfo = reinterpret_cast<FILE_NAME_INFO *>(&buffer[0]); if (ptrGetFileInformationByHandleEx(h, FileNameInfo, nameinfo, size - sizeof(WCHAR))) { nameinfo->FileName[nameinfo->FileNameLength / sizeof(WCHAR)] = L'\0'; PWSTR name = nameinfo->FileName; if ((!wcsstr(name, L"msys-") && !wcsstr(name, L"cygwin-")) || !wcsstr(name, L"-pty")) { return false; } } return true; } inline bool isTerminal(const std::streambuf *osbuf) noexcept { using std::cerr; using std::clog; using std::cout; if (osbuf == cout.rdbuf()) { static const bool cout_term = (_isatty(_fileno(stdout)) || isMsysPty(_fileno(stdout))); return cout_term; } else if (osbuf == cerr.rdbuf() || osbuf == clog.rdbuf()) { static const bool cerr_term = (_isatty(_fileno(stderr)) || isMsysPty(_fileno(stderr))); return cerr_term; } return false; } template <typename T> using enableStd = typename std::enable_if< std::is_same<T, rang::style>::value || std::is_same<T, rang::fg>::value || std::is_same<T, rang::bg>::value || std::is_same<T, rang::fgB>::value || std::is_same<T, rang::bgB>::value, std::ostream &>::type; struct SGR { BYTE fgColor; BYTE bgColor; BYTE bold; BYTE underline; BOOLEAN inverse; BOOLEAN conceal; }; enum class AttrColor : BYTE { black = 0, red = 4, green = 2, yellow = 6, blue = 1, magenta = 5, cyan = 3, gray = 7 }; inline HANDLE getConsoleHandle(const std::streambuf *osbuf) noexcept { if (osbuf == std::cout.rdbuf()) { static const HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); return hStdout; } else if (osbuf == std::cerr.rdbuf() || osbuf == std::clog.rdbuf()) { static const HANDLE hStderr = GetStdHandle(STD_ERROR_HANDLE); return hStderr; } return INVALID_HANDLE_VALUE; } inline bool setWinTermAnsiColors(const std::streambuf *osbuf) noexcept { HANDLE h = getConsoleHandle(osbuf); if (h == INVALID_HANDLE_VALUE) { return false; } DWORD dwMode = 0; if (!GetConsoleMode(h, &dwMode)) { return false; } dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; if (!SetConsoleMode(h, dwMode)) { return false; } return true; } inline bool supportsAnsi(const std::streambuf *osbuf) noexcept { using std::cerr; using std::clog; using std::cout; if (osbuf == cout.rdbuf()) { static const bool cout_ansi = (isMsysPty(_fileno(stdout)) || setWinTermAnsiColors(osbuf)); return cout_ansi; } else if (osbuf == cerr.rdbuf() || osbuf == clog.rdbuf()) { static const bool cerr_ansi = (isMsysPty(_fileno(stderr)) || setWinTermAnsiColors(osbuf)); return cerr_ansi; } return false; } inline const SGR &defaultState() noexcept { static const SGR defaultSgr = []() -> SGR { CONSOLE_SCREEN_BUFFER_INFO info; WORD attrib = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info) || GetConsoleScreenBufferInfo(GetStdHandle(STD_ERROR_HANDLE), &info)) { attrib = info.wAttributes; } SGR sgr = { 0, 0, 0, 0, FALSE, FALSE }; sgr.fgColor = attrib & 0x0F; sgr.bgColor = (attrib & 0xF0) >> 4; return sgr; }(); return defaultSgr; } inline BYTE ansi2attr(BYTE rgb) noexcept { static const AttrColor rev[8] = { AttrColor::black, AttrColor::red, AttrColor::green, AttrColor::yellow, AttrColor::blue, AttrColor::magenta, AttrColor::cyan, AttrColor::gray }; return static_cast<BYTE>(rev[rgb]); } inline void setWinSGR(rang::bg col, SGR &state) noexcept { if (col != rang::bg::reset) { state.bgColor = ansi2attr(static_cast<BYTE>(col) - 40); } else { state.bgColor = defaultState().bgColor; } } inline void setWinSGR(rang::fg col, SGR &state) noexcept { if (col != rang::fg::reset) { state.fgColor = ansi2attr(static_cast<BYTE>(col) - 30); } else { state.fgColor = defaultState().fgColor; } } inline void setWinSGR(rang::bgB col, SGR &state) noexcept { state.bgColor = (BACKGROUND_INTENSITY >> 4) | ansi2attr(static_cast<BYTE>(col) - 100); } inline void setWinSGR(rang::fgB col, SGR &state) noexcept { state.fgColor = FOREGROUND_INTENSITY | ansi2attr(static_cast<BYTE>(col) - 90); } inline void setWinSGR(rang::style style, SGR &state) noexcept { switch (style) { case rang::style::reset: state = defaultState(); break; case rang::style::bold: state.bold = FOREGROUND_INTENSITY; break; case rang::style::underline: case rang::style::blink: state.underline = BACKGROUND_INTENSITY; break; case rang::style::reversed: state.inverse = TRUE; break; case rang::style::conceal: state.conceal = TRUE; break; default: break; } } inline SGR ¤t_state() noexcept { static SGR state = defaultState(); return state; } inline WORD SGR2Attr(const SGR &state) noexcept { WORD attrib = 0; if (state.conceal) { if (state.inverse) { attrib = (state.fgColor << 4) | state.fgColor; if (state.bold) attrib |= FOREGROUND_INTENSITY | BACKGROUND_INTENSITY; } else { attrib = (state.bgColor << 4) | state.bgColor; if (state.underline) attrib |= FOREGROUND_INTENSITY | BACKGROUND_INTENSITY; } } else if (state.inverse) { attrib = (state.fgColor << 4) | state.bgColor; if (state.bold) attrib |= BACKGROUND_INTENSITY; if (state.underline) attrib |= FOREGROUND_INTENSITY; } else { attrib = state.fgColor | (state.bgColor << 4) | state.bold | state.underline; } return attrib; } template <typename T> inline void setWinColorAnsi(std::ostream &os, T const value) { os << "\033[" << static_cast<int>(value) << "m"; } template <typename T> inline void setWinColorNative(std::ostream &os, T const value) { const HANDLE h = getConsoleHandle(os.rdbuf()); if (h != INVALID_HANDLE_VALUE) { setWinSGR(value, current_state()); // Out all buffered text to console with previous settings: os.flush(); SetConsoleTextAttribute(h, SGR2Attr(current_state())); } } template <typename T> inline enableStd<T> setColor(std::ostream &os, T const value) { if (winTermMode() == winTerm::Auto) { if (supportsAnsi(os.rdbuf())) { setWinColorAnsi(os, value); } else { setWinColorNative(os, value); } } else if (winTermMode() == winTerm::Ansi) { setWinColorAnsi(os, value); } else { setWinColorNative(os, value); } return os; } } // namespace rang_implementation template <typename T> inline rang_implementation::enableStd<T> operator<<(std::ostream &os, const T value) { const control option = rang_implementation::controlMode(); switch (option) { case control::Auto: return rang_implementation::supportsColor() && rang_implementation::isTerminal(os.rdbuf()) ? rang_implementation::setColor(os, value) : os; case control::Force: return rang_implementation::setColor(os, value); default: return os; } } inline void setWinTermMode(const rang::winTerm value) noexcept { rang_implementation::winTermMode() = value; } inline void setControlMode(const control value) noexcept { rang_implementation::controlMode() = value; } } // namespace rang #endif /* ifndef RANG_DOT_HPP */ int main() { std::cout << rang::fg::blue << "Hello World" << std::endl; }
run
|
edit
|
history
|
help
0
MSVC noexcept - works
hangman
make_integer_sequence
Title
MSVC alias template
C++ Macro overload
MSVC bug in __fastcall implementation !!!
MyCodeWindows
hangman
복소수 클래스 생성하기