Advertisement
ddto

Untitled

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