Advertisement
ddto

Untitled

Aug 10th, 2024
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.41 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <cstdint>
  4. #include <type_traits>
  5. #include <format>
  6. #include <locale>
  7. #include <locale.h>
  8. #include <codecvt>
  9.  
  10. #if defined(_WIN64) || defined(_WIN32)
  11.  
  12. #include "WinDef.h"
  13.  
  14. #ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
  15. #define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
  16. #endif
  17.  
  18. #ifndef MS_STDLIB_BUGS
  19. #if ( _MSC_VER || __MINGW32__ || __MSVCRT__ )
  20. #define MS_STDLIB_BUGS 1
  21. #else
  22. #define MS_STDLIB_BUGS 0
  23. #endif
  24. #endif
  25.  
  26. #if MS_STDLIB_BUGS
  27. #include <io.h>
  28. #include <fcntl.h>
  29. #endif
  30.  
  31. #endif
  32.  
  33. // API ---------------------------------
  34.  
  35. namespace spc
  36. {
  37.     namespace con
  38.     {
  39.         inline void Init(); // must be called before any printing
  40.  
  41.         inline std::wstring Utf8ToUtf16(const String& str8);
  42.         inline String Utf16ToUtf8(const std::wstring& str16);
  43.  
  44.         inline void Print(const String& str);
  45.         inline void PrintN(const String& str);
  46.         inline void Input(String& str);
  47.  
  48.         enum ColorANSI : uint8_t
  49.         {
  50.             NONE            = 0,
  51.             BLACK           = 30,
  52.             RED             = 31,
  53.             GREEN           = 32,
  54.             YELLOW          = 33,
  55.             BLUE            = 34,
  56.             MAGENTA         = 35,
  57.             CYAN            = 36,
  58.             WHITE           = 37,
  59.             BRIGHT_BLACK    = 90,
  60.             BRIGHT_RED      = 91,
  61.             BRIGHT_GREEN    = 92,
  62.             BRIGHT_YELLOW   = 93,
  63.             BRIGHT_BLUE     = 94,
  64.             BRIGHT_MAGENTA  = 95,
  65.             BRIGHT_CYAN     = 96,
  66.             BRIGHT_WHITE    = 97
  67.         };
  68.  
  69.         inline String SetStringColor(const String& str, ColorANSI txtCol, ColorANSI bgCol);
  70.     }
  71. }
  72.  
  73. // -------------------------------------
  74.  
  75. namespace spc
  76. {
  77.  
  78. #if defined(_WIN64) || defined(_WIN32)
  79.     // Windows ----------
  80.  
  81.     static HANDLE stdoutHandle;
  82.     static DWORD outModeInit;
  83.  
  84.     namespace con
  85.     {
  86.         // internal functions
  87.         namespace itrn
  88.         {
  89.             inline void EnableANSI()
  90.         {
  91.             DWORD outMode = 0;
  92.             stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE);
  93.  
  94.             if (stdoutHandle == INVALID_HANDLE_VALUE)
  95.             {
  96.                 exit(GetLastError());
  97.             }
  98.  
  99.             if (!GetConsoleMode(stdoutHandle, &outMode))
  100.             {
  101.                 exit(GetLastError());
  102.             }
  103.  
  104.             outModeInit = outMode;
  105.             outMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
  106.  
  107.             if (!SetConsoleMode(stdoutHandle, outMode))
  108.             {
  109.                 exit(GetLastError());
  110.             }
  111.         }
  112.  
  113.             inline void InitLocale()
  114.             {
  115.             #if MS_STDLIB_BUGS
  116.                 constexpr char cp_utf16le[] = ".1200";
  117.                 setlocale(LC_ALL, cp_utf16le);
  118.                 _setmode(_fileno(stdout), _O_WTEXT);
  119.             #else
  120.                 constexpr char locale_name[] = "en_US.utf8";
  121.                 setlocale(LC_ALL, locale_name);
  122.                 std::locale::global(std::locale(locale_name));
  123.                 std::wcin.imbue(std::locale())
  124.                     std::wcout.imbue(std::locale());
  125.             #endif
  126.             }
  127.  
  128.             // for getting underlying value from enum class members
  129.             template<typename T>
  130.             constexpr inline auto GetUnderlying(T ecm) -> typename std::underlying_type<T>::type
  131.             {
  132.                 return static_cast<typename std::underlying_type<T>::type>(ecm);
  133.             }
  134.         }
  135.         // -----------------
  136.         inline void Init()
  137.         {
  138.             itrn::InitLocale();
  139.             itrn::EnableANSI();
  140.             SetConsoleOutputCP(65001);
  141.         }
  142.  
  143.         inline std::wstring Utf8ToUtf16(const String& str)
  144.         {
  145.             if (str.empty()) return std::wstring();
  146.  
  147.             int required = MultiByteToWideChar(CP_THREAD_ACP, 0, str.data(), (int)str.size(), NULL, 0);
  148.             if (required == 0) return std::wstring();
  149.  
  150.             std::wstring wstr;
  151.             wstr.resize(required);
  152.  
  153.             int converted = MultiByteToWideChar(CP_THREAD_ACP, 0, str.data(), (int)str.size(), &wstr[0], wstr.capacity());
  154.             if (converted == 0) return std::wstring();
  155.  
  156.             return wstr;
  157.         }
  158.  
  159.         inline std::string Utf16ToUtf8(const std::wstring& wstr)
  160.         {
  161.             if (wstr.empty()) return std::string();
  162.  
  163.             int required = WideCharToMultiByte(CP_THREAD_ACP, 0, wstr.data(), (int)wstr.size(), NULL, 0, NULL, NULL);
  164.             if (0 == required) return std::string();
  165.  
  166.             std::string str;
  167.             str.resize(required);
  168.  
  169.             int converted = WideCharToMultiByte(CP_THREAD_ACP, 0, wstr.data(), (int)wstr.size(), &str[0], str.capacity(), NULL, NULL);
  170.             if (0 == converted) return std::string();
  171.  
  172.             return str;
  173.         }
  174.  
  175.         inline void Print(const String& str)
  176.         {
  177.             std::wcout << Utf8ToUtf16(str);
  178.         }
  179.  
  180.         inline void PrintN(const String& str)
  181.         {
  182.             std::wcout << Utf8ToUtf16(str) << L'\n';
  183.         }
  184.  
  185.         inline void Input(String& str)
  186.         {
  187.             std::wstring wstr;
  188.             std::wcin >> wstr;
  189.             str = Utf16ToUtf8(wstr);
  190.         }
  191.  
  192.         inline String SetStringColor(const String& str, ColorANSI txtCol, ColorANSI bgCol)
  193.         {
  194.             if (bgCol == ColorANSI::NONE)
  195.                 return std::format("\x1b[{}m{}\x1b[0m", itrn::GetUnderlying(txtCol), str);
  196.  
  197.             return std::format("\x1b[{};{}m{}\x1b[0m",
  198.                 itrn::GetUnderlying(txtCol), itrn::GetUnderlying(bgCol) + 10, str);
  199.         }
  200.     }
  201.  
  202. #elif defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))
  203.     // Unix -------------
  204.  
  205.     namespace con
  206.     {
  207.         inline void Init() {}
  208.  
  209.         inline void Print(const String& str) { std::cout << str; }
  210.         inline void PrintN(const String& str) { std::cout << str << '\n'; }
  211.         inline void Input(String& str) { std::cin >> str; }
  212.  
  213.         inline String SetStringColor(const String& str, ColorANSI txtCol, ColorANSI bgCol)
  214.         {
  215.             if (bgCol == ColorANSI::NONE)
  216.                 return std::format("\x1b[{}m{}\x1b[0m", itrn::GetUnderlying(txtCol), str);
  217.  
  218.             return std::format("\x1b[{};{}m{}\x1b[0m",
  219.                 itrn::GetUnderlying(txtCol), itrn::GetUnderlying(bgCol) + 10, str);
  220.         }
  221.     }
  222.  
  223. #else
  224.  
  225. #error "Platform not supported"
  226.  
  227. #endif
  228.  
  229. }
  230.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement