diff --git a/include/indicators/display_width.hpp b/include/indicators/display_width.hpp index 468c5c6..fb7f541 100644 --- a/include/indicators/display_width.hpp +++ b/include/indicators/display_width.hpp @@ -3,19 +3,14 @@ #define INDICATORS_DISPLAY_WIDTH #include -#if defined __has_include -#if __has_include () -#define INDICATORS_HAVE_CODECVT 1 -#endif -#endif #include #include #include +#include #include namespace unicode { -#if INDICATORS_HAVE_CODECVT namespace details { /* @@ -140,42 +135,54 @@ static inline int mk_wcwidth(wchar_t ucs) { /* sorted list of non-overlapping intervals of non-spacing characters */ /* generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" */ static const struct interval combining[] = { - {0x0300, 0x036F}, {0x0483, 0x0486}, {0x0488, 0x0489}, {0x0591, 0x05BD}, - {0x05BF, 0x05BF}, {0x05C1, 0x05C2}, {0x05C4, 0x05C5}, {0x05C7, 0x05C7}, - {0x0600, 0x0603}, {0x0610, 0x0615}, {0x064B, 0x065E}, {0x0670, 0x0670}, - {0x06D6, 0x06E4}, {0x06E7, 0x06E8}, {0x06EA, 0x06ED}, {0x070F, 0x070F}, - {0x0711, 0x0711}, {0x0730, 0x074A}, {0x07A6, 0x07B0}, {0x07EB, 0x07F3}, - {0x0901, 0x0902}, {0x093C, 0x093C}, {0x0941, 0x0948}, {0x094D, 0x094D}, - {0x0951, 0x0954}, {0x0962, 0x0963}, {0x0981, 0x0981}, {0x09BC, 0x09BC}, - {0x09C1, 0x09C4}, {0x09CD, 0x09CD}, {0x09E2, 0x09E3}, {0x0A01, 0x0A02}, - {0x0A3C, 0x0A3C}, {0x0A41, 0x0A42}, {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, - {0x0A70, 0x0A71}, {0x0A81, 0x0A82}, {0x0ABC, 0x0ABC}, {0x0AC1, 0x0AC5}, - {0x0AC7, 0x0AC8}, {0x0ACD, 0x0ACD}, {0x0AE2, 0x0AE3}, {0x0B01, 0x0B01}, - {0x0B3C, 0x0B3C}, {0x0B3F, 0x0B3F}, {0x0B41, 0x0B43}, {0x0B4D, 0x0B4D}, - {0x0B56, 0x0B56}, {0x0B82, 0x0B82}, {0x0BC0, 0x0BC0}, {0x0BCD, 0x0BCD}, - {0x0C3E, 0x0C40}, {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, {0x0C55, 0x0C56}, - {0x0CBC, 0x0CBC}, {0x0CBF, 0x0CBF}, {0x0CC6, 0x0CC6}, {0x0CCC, 0x0CCD}, - {0x0CE2, 0x0CE3}, {0x0D41, 0x0D43}, {0x0D4D, 0x0D4D}, {0x0DCA, 0x0DCA}, - {0x0DD2, 0x0DD4}, {0x0DD6, 0x0DD6}, {0x0E31, 0x0E31}, {0x0E34, 0x0E3A}, - {0x0E47, 0x0E4E}, {0x0EB1, 0x0EB1}, {0x0EB4, 0x0EB9}, {0x0EBB, 0x0EBC}, - {0x0EC8, 0x0ECD}, {0x0F18, 0x0F19}, {0x0F35, 0x0F35}, {0x0F37, 0x0F37}, - {0x0F39, 0x0F39}, {0x0F71, 0x0F7E}, {0x0F80, 0x0F84}, {0x0F86, 0x0F87}, - {0x0F90, 0x0F97}, {0x0F99, 0x0FBC}, {0x0FC6, 0x0FC6}, {0x102D, 0x1030}, - {0x1032, 0x1032}, {0x1036, 0x1037}, {0x1039, 0x1039}, {0x1058, 0x1059}, - {0x1160, 0x11FF}, {0x135F, 0x135F}, {0x1712, 0x1714}, {0x1732, 0x1734}, - {0x1752, 0x1753}, {0x1772, 0x1773}, {0x17B4, 0x17B5}, {0x17B7, 0x17BD}, - {0x17C6, 0x17C6}, {0x17C9, 0x17D3}, {0x17DD, 0x17DD}, {0x180B, 0x180D}, - {0x18A9, 0x18A9}, {0x1920, 0x1922}, {0x1927, 0x1928}, {0x1932, 0x1932}, - {0x1939, 0x193B}, {0x1A17, 0x1A18}, {0x1B00, 0x1B03}, {0x1B34, 0x1B34}, - {0x1B36, 0x1B3A}, {0x1B3C, 0x1B3C}, {0x1B42, 0x1B42}, {0x1B6B, 0x1B73}, - {0x1DC0, 0x1DCA}, {0x1DFE, 0x1DFF}, {0x200B, 0x200F}, {0x202A, 0x202E}, - {0x2060, 0x2063}, {0x206A, 0x206F}, {0x20D0, 0x20EF}, {0x302A, 0x302F}, - {0x3099, 0x309A}, {0xA806, 0xA806}, {0xA80B, 0xA80B}, {0xA825, 0xA826}, - {0xFB1E, 0xFB1E}, {0xFE00, 0xFE0F}, {0xFE20, 0xFE23}, {0xFEFF, 0xFEFF}, - {0xFFF9, 0xFFFB}, {0x10A01, 0x10A03}, {0x10A05, 0x10A06}, {0x10A0C, 0x10A0F}, - {0x10A38, 0x10A3A}, {0x10A3F, 0x10A3F}, {0x1D167, 0x1D169}, {0x1D173, 0x1D182}, - {0x1D185, 0x1D18B}, {0x1D1AA, 0x1D1AD}, {0x1D242, 0x1D244}, {0xE0001, 0xE0001}, - {0xE0020, 0xE007F}, {0xE0100, 0xE01EF}}; + {0x0300, 0x036F}, {0x0483, 0x0486}, {0x0488, 0x0489}, + {0x0591, 0x05BD}, {0x05BF, 0x05BF}, {0x05C1, 0x05C2}, + {0x05C4, 0x05C5}, {0x05C7, 0x05C7}, {0x0600, 0x0603}, + {0x0610, 0x0615}, {0x064B, 0x065E}, {0x0670, 0x0670}, + {0x06D6, 0x06E4}, {0x06E7, 0x06E8}, {0x06EA, 0x06ED}, + {0x070F, 0x070F}, {0x0711, 0x0711}, {0x0730, 0x074A}, + {0x07A6, 0x07B0}, {0x07EB, 0x07F3}, {0x0901, 0x0902}, + {0x093C, 0x093C}, {0x0941, 0x0948}, {0x094D, 0x094D}, + {0x0951, 0x0954}, {0x0962, 0x0963}, {0x0981, 0x0981}, + {0x09BC, 0x09BC}, {0x09C1, 0x09C4}, {0x09CD, 0x09CD}, + {0x09E2, 0x09E3}, {0x0A01, 0x0A02}, {0x0A3C, 0x0A3C}, + {0x0A41, 0x0A42}, {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, + {0x0A70, 0x0A71}, {0x0A81, 0x0A82}, {0x0ABC, 0x0ABC}, + {0x0AC1, 0x0AC5}, {0x0AC7, 0x0AC8}, {0x0ACD, 0x0ACD}, + {0x0AE2, 0x0AE3}, {0x0B01, 0x0B01}, {0x0B3C, 0x0B3C}, + {0x0B3F, 0x0B3F}, {0x0B41, 0x0B43}, {0x0B4D, 0x0B4D}, + {0x0B56, 0x0B56}, {0x0B82, 0x0B82}, {0x0BC0, 0x0BC0}, + {0x0BCD, 0x0BCD}, {0x0C3E, 0x0C40}, {0x0C46, 0x0C48}, + {0x0C4A, 0x0C4D}, {0x0C55, 0x0C56}, {0x0CBC, 0x0CBC}, + {0x0CBF, 0x0CBF}, {0x0CC6, 0x0CC6}, {0x0CCC, 0x0CCD}, + {0x0CE2, 0x0CE3}, {0x0D41, 0x0D43}, {0x0D4D, 0x0D4D}, + {0x0DCA, 0x0DCA}, {0x0DD2, 0x0DD4}, {0x0DD6, 0x0DD6}, + {0x0E31, 0x0E31}, {0x0E34, 0x0E3A}, {0x0E47, 0x0E4E}, + {0x0EB1, 0x0EB1}, {0x0EB4, 0x0EB9}, {0x0EBB, 0x0EBC}, + {0x0EC8, 0x0ECD}, {0x0F18, 0x0F19}, {0x0F35, 0x0F35}, + {0x0F37, 0x0F37}, {0x0F39, 0x0F39}, {0x0F71, 0x0F7E}, + {0x0F80, 0x0F84}, {0x0F86, 0x0F87}, {0x0F90, 0x0F97}, + {0x0F99, 0x0FBC}, {0x0FC6, 0x0FC6}, {0x102D, 0x1030}, + {0x1032, 0x1032}, {0x1036, 0x1037}, {0x1039, 0x1039}, + {0x1058, 0x1059}, {0x1160, 0x11FF}, {0x135F, 0x135F}, + {0x1712, 0x1714}, {0x1732, 0x1734}, {0x1752, 0x1753}, + {0x1772, 0x1773}, {0x17B4, 0x17B5}, {0x17B7, 0x17BD}, + {0x17C6, 0x17C6}, {0x17C9, 0x17D3}, {0x17DD, 0x17DD}, + {0x180B, 0x180D}, {0x18A9, 0x18A9}, {0x1920, 0x1922}, + {0x1927, 0x1928}, {0x1932, 0x1932}, {0x1939, 0x193B}, + {0x1A17, 0x1A18}, {0x1B00, 0x1B03}, {0x1B34, 0x1B34}, + {0x1B36, 0x1B3A}, {0x1B3C, 0x1B3C}, {0x1B42, 0x1B42}, + {0x1B6B, 0x1B73}, {0x1DC0, 0x1DCA}, {0x1DFE, 0x1DFF}, + {0x200B, 0x200F}, {0x202A, 0x202E}, {0x2060, 0x2063}, + {0x206A, 0x206F}, {0x20D0, 0x20EF}, {0x302A, 0x302F}, + {0x3099, 0x309A}, {0xA806, 0xA806}, {0xA80B, 0xA80B}, + {0xA825, 0xA826}, {0xFB1E, 0xFB1E}, {0xFE00, 0xFE0F}, + {0xFE20, 0xFE23}, {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, + {0x10A01, 0x10A03}, {0x10A05, 0x10A06}, {0x10A0C, 0x10A0F}, + {0x10A38, 0x10A3A}, {0x10A3F, 0x10A3F}, {0x1D167, 0x1D169}, + {0x1D173, 0x1D182}, {0x1D185, 0x1D18B}, {0x1D1AA, 0x1D1AD}, + {0x1D242, 0x1D244}, {0xE0001, 0xE0001}, {0xE0020, 0xE007F}, + {0xE0100, 0xE01EF}}; /* test for 8-bit control characters */ if (ucs == 0) @@ -189,17 +196,20 @@ static inline int mk_wcwidth(wchar_t ucs) { /* if we arrive here, ucs is not a combining or C0/C1 control character */ - return 1 + (ucs >= 0x1100 && - (ucs <= 0x115f || /* Hangul Jamo init. consonants */ - ucs == 0x2329 || ucs == 0x232a || - (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs != 0x303f) || /* CJK ... Yi */ - (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */ - (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */ - (ucs >= 0xfe10 && ucs <= 0xfe19) || /* Vertical forms */ - (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */ - (ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */ - (ucs >= 0xffe0 && ucs <= 0xffe6) || (ucs >= 0x20000 && ucs <= 0x2fffd) || - (ucs >= 0x30000 && ucs <= 0x3fffd))); + return 1 + + (ucs >= 0x1100 && + (ucs <= 0x115f || /* Hangul Jamo init. consonants */ + ucs == 0x2329 || ucs == 0x232a || + (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs != 0x303f) || /* CJK ... Yi */ + (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */ + (ucs >= 0xf900 && + ucs <= 0xfaff) || /* CJK Compatibility Ideographs */ + (ucs >= 0xfe10 && ucs <= 0xfe19) || /* Vertical forms */ + (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */ + (ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */ + (ucs >= 0xffe0 && ucs <= 0xffe6) || + (ucs >= 0x20000 && ucs <= 0x2fffd) || + (ucs >= 0x30000 && ucs <= 0x3fffd))); } static inline int mk_wcswidth(const wchar_t *pwcs, size_t n) { @@ -227,38 +237,58 @@ static inline int mk_wcwidth_cjk(wchar_t ucs) { /* sorted list of non-overlapping intervals of East Asian Ambiguous * characters, generated by "uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf c" */ static const struct interval ambiguous[] = { - {0x00A1, 0x00A1}, {0x00A4, 0x00A4}, {0x00A7, 0x00A8}, {0x00AA, 0x00AA}, {0x00AE, 0x00AE}, - {0x00B0, 0x00B4}, {0x00B6, 0x00BA}, {0x00BC, 0x00BF}, {0x00C6, 0x00C6}, {0x00D0, 0x00D0}, - {0x00D7, 0x00D8}, {0x00DE, 0x00E1}, {0x00E6, 0x00E6}, {0x00E8, 0x00EA}, {0x00EC, 0x00ED}, - {0x00F0, 0x00F0}, {0x00F2, 0x00F3}, {0x00F7, 0x00FA}, {0x00FC, 0x00FC}, {0x00FE, 0x00FE}, - {0x0101, 0x0101}, {0x0111, 0x0111}, {0x0113, 0x0113}, {0x011B, 0x011B}, {0x0126, 0x0127}, - {0x012B, 0x012B}, {0x0131, 0x0133}, {0x0138, 0x0138}, {0x013F, 0x0142}, {0x0144, 0x0144}, - {0x0148, 0x014B}, {0x014D, 0x014D}, {0x0152, 0x0153}, {0x0166, 0x0167}, {0x016B, 0x016B}, - {0x01CE, 0x01CE}, {0x01D0, 0x01D0}, {0x01D2, 0x01D2}, {0x01D4, 0x01D4}, {0x01D6, 0x01D6}, - {0x01D8, 0x01D8}, {0x01DA, 0x01DA}, {0x01DC, 0x01DC}, {0x0251, 0x0251}, {0x0261, 0x0261}, - {0x02C4, 0x02C4}, {0x02C7, 0x02C7}, {0x02C9, 0x02CB}, {0x02CD, 0x02CD}, {0x02D0, 0x02D0}, - {0x02D8, 0x02DB}, {0x02DD, 0x02DD}, {0x02DF, 0x02DF}, {0x0391, 0x03A1}, {0x03A3, 0x03A9}, - {0x03B1, 0x03C1}, {0x03C3, 0x03C9}, {0x0401, 0x0401}, {0x0410, 0x044F}, {0x0451, 0x0451}, - {0x2010, 0x2010}, {0x2013, 0x2016}, {0x2018, 0x2019}, {0x201C, 0x201D}, {0x2020, 0x2022}, - {0x2024, 0x2027}, {0x2030, 0x2030}, {0x2032, 0x2033}, {0x2035, 0x2035}, {0x203B, 0x203B}, - {0x203E, 0x203E}, {0x2074, 0x2074}, {0x207F, 0x207F}, {0x2081, 0x2084}, {0x20AC, 0x20AC}, - {0x2103, 0x2103}, {0x2105, 0x2105}, {0x2109, 0x2109}, {0x2113, 0x2113}, {0x2116, 0x2116}, - {0x2121, 0x2122}, {0x2126, 0x2126}, {0x212B, 0x212B}, {0x2153, 0x2154}, {0x215B, 0x215E}, - {0x2160, 0x216B}, {0x2170, 0x2179}, {0x2190, 0x2199}, {0x21B8, 0x21B9}, {0x21D2, 0x21D2}, - {0x21D4, 0x21D4}, {0x21E7, 0x21E7}, {0x2200, 0x2200}, {0x2202, 0x2203}, {0x2207, 0x2208}, - {0x220B, 0x220B}, {0x220F, 0x220F}, {0x2211, 0x2211}, {0x2215, 0x2215}, {0x221A, 0x221A}, - {0x221D, 0x2220}, {0x2223, 0x2223}, {0x2225, 0x2225}, {0x2227, 0x222C}, {0x222E, 0x222E}, - {0x2234, 0x2237}, {0x223C, 0x223D}, {0x2248, 0x2248}, {0x224C, 0x224C}, {0x2252, 0x2252}, - {0x2260, 0x2261}, {0x2264, 0x2267}, {0x226A, 0x226B}, {0x226E, 0x226F}, {0x2282, 0x2283}, - {0x2286, 0x2287}, {0x2295, 0x2295}, {0x2299, 0x2299}, {0x22A5, 0x22A5}, {0x22BF, 0x22BF}, - {0x2312, 0x2312}, {0x2460, 0x24E9}, {0x24EB, 0x254B}, {0x2550, 0x2573}, {0x2580, 0x258F}, - {0x2592, 0x2595}, {0x25A0, 0x25A1}, {0x25A3, 0x25A9}, {0x25B2, 0x25B3}, {0x25B6, 0x25B7}, - {0x25BC, 0x25BD}, {0x25C0, 0x25C1}, {0x25C6, 0x25C8}, {0x25CB, 0x25CB}, {0x25CE, 0x25D1}, - {0x25E2, 0x25E5}, {0x25EF, 0x25EF}, {0x2605, 0x2606}, {0x2609, 0x2609}, {0x260E, 0x260F}, - {0x2614, 0x2615}, {0x261C, 0x261C}, {0x261E, 0x261E}, {0x2640, 0x2640}, {0x2642, 0x2642}, - {0x2660, 0x2661}, {0x2663, 0x2665}, {0x2667, 0x266A}, {0x266C, 0x266D}, {0x266F, 0x266F}, - {0x273D, 0x273D}, {0x2776, 0x277F}, {0xE000, 0xF8FF}, {0xFFFD, 0xFFFD}, {0xF0000, 0xFFFFD}, - {0x100000, 0x10FFFD}}; + {0x00A1, 0x00A1}, {0x00A4, 0x00A4}, {0x00A7, 0x00A8}, + {0x00AA, 0x00AA}, {0x00AE, 0x00AE}, {0x00B0, 0x00B4}, + {0x00B6, 0x00BA}, {0x00BC, 0x00BF}, {0x00C6, 0x00C6}, + {0x00D0, 0x00D0}, {0x00D7, 0x00D8}, {0x00DE, 0x00E1}, + {0x00E6, 0x00E6}, {0x00E8, 0x00EA}, {0x00EC, 0x00ED}, + {0x00F0, 0x00F0}, {0x00F2, 0x00F3}, {0x00F7, 0x00FA}, + {0x00FC, 0x00FC}, {0x00FE, 0x00FE}, {0x0101, 0x0101}, + {0x0111, 0x0111}, {0x0113, 0x0113}, {0x011B, 0x011B}, + {0x0126, 0x0127}, {0x012B, 0x012B}, {0x0131, 0x0133}, + {0x0138, 0x0138}, {0x013F, 0x0142}, {0x0144, 0x0144}, + {0x0148, 0x014B}, {0x014D, 0x014D}, {0x0152, 0x0153}, + {0x0166, 0x0167}, {0x016B, 0x016B}, {0x01CE, 0x01CE}, + {0x01D0, 0x01D0}, {0x01D2, 0x01D2}, {0x01D4, 0x01D4}, + {0x01D6, 0x01D6}, {0x01D8, 0x01D8}, {0x01DA, 0x01DA}, + {0x01DC, 0x01DC}, {0x0251, 0x0251}, {0x0261, 0x0261}, + {0x02C4, 0x02C4}, {0x02C7, 0x02C7}, {0x02C9, 0x02CB}, + {0x02CD, 0x02CD}, {0x02D0, 0x02D0}, {0x02D8, 0x02DB}, + {0x02DD, 0x02DD}, {0x02DF, 0x02DF}, {0x0391, 0x03A1}, + {0x03A3, 0x03A9}, {0x03B1, 0x03C1}, {0x03C3, 0x03C9}, + {0x0401, 0x0401}, {0x0410, 0x044F}, {0x0451, 0x0451}, + {0x2010, 0x2010}, {0x2013, 0x2016}, {0x2018, 0x2019}, + {0x201C, 0x201D}, {0x2020, 0x2022}, {0x2024, 0x2027}, + {0x2030, 0x2030}, {0x2032, 0x2033}, {0x2035, 0x2035}, + {0x203B, 0x203B}, {0x203E, 0x203E}, {0x2074, 0x2074}, + {0x207F, 0x207F}, {0x2081, 0x2084}, {0x20AC, 0x20AC}, + {0x2103, 0x2103}, {0x2105, 0x2105}, {0x2109, 0x2109}, + {0x2113, 0x2113}, {0x2116, 0x2116}, {0x2121, 0x2122}, + {0x2126, 0x2126}, {0x212B, 0x212B}, {0x2153, 0x2154}, + {0x215B, 0x215E}, {0x2160, 0x216B}, {0x2170, 0x2179}, + {0x2190, 0x2199}, {0x21B8, 0x21B9}, {0x21D2, 0x21D2}, + {0x21D4, 0x21D4}, {0x21E7, 0x21E7}, {0x2200, 0x2200}, + {0x2202, 0x2203}, {0x2207, 0x2208}, {0x220B, 0x220B}, + {0x220F, 0x220F}, {0x2211, 0x2211}, {0x2215, 0x2215}, + {0x221A, 0x221A}, {0x221D, 0x2220}, {0x2223, 0x2223}, + {0x2225, 0x2225}, {0x2227, 0x222C}, {0x222E, 0x222E}, + {0x2234, 0x2237}, {0x223C, 0x223D}, {0x2248, 0x2248}, + {0x224C, 0x224C}, {0x2252, 0x2252}, {0x2260, 0x2261}, + {0x2264, 0x2267}, {0x226A, 0x226B}, {0x226E, 0x226F}, + {0x2282, 0x2283}, {0x2286, 0x2287}, {0x2295, 0x2295}, + {0x2299, 0x2299}, {0x22A5, 0x22A5}, {0x22BF, 0x22BF}, + {0x2312, 0x2312}, {0x2460, 0x24E9}, {0x24EB, 0x254B}, + {0x2550, 0x2573}, {0x2580, 0x258F}, {0x2592, 0x2595}, + {0x25A0, 0x25A1}, {0x25A3, 0x25A9}, {0x25B2, 0x25B3}, + {0x25B6, 0x25B7}, {0x25BC, 0x25BD}, {0x25C0, 0x25C1}, + {0x25C6, 0x25C8}, {0x25CB, 0x25CB}, {0x25CE, 0x25D1}, + {0x25E2, 0x25E5}, {0x25EF, 0x25EF}, {0x2605, 0x2606}, + {0x2609, 0x2609}, {0x260E, 0x260F}, {0x2614, 0x2615}, + {0x261C, 0x261C}, {0x261E, 0x261E}, {0x2640, 0x2640}, + {0x2642, 0x2642}, {0x2660, 0x2661}, {0x2663, 0x2665}, + {0x2667, 0x266A}, {0x266C, 0x266D}, {0x266F, 0x266F}, + {0x273D, 0x273D}, {0x2776, 0x277F}, {0xE000, 0xF8FF}, + {0xFFFD, 0xFFFD}, {0xF0000, 0xFFFFD}, {0x100000, 0x10FFFD}}; /* binary search in table of non-spacing characters */ if (bisearch(ucs, ambiguous, sizeof(ambiguous) / sizeof(struct interval) - 1)) @@ -280,15 +310,17 @@ static inline int mk_wcswidth_cjk(const wchar_t *pwcs, size_t n) { } // convert UTF-8 string to wstring -static inline std::wstring utf8_decode(const std::string &str) { - std::wstring_convert> myconv; - return myconv.from_bytes(str); -} - -// convert wstring to UTF-8 string -static inline std::string utf8_encode(const std::wstring &str) { - std::wstring_convert> myconv; - return myconv.to_bytes(str); +static inline std::wstring utf8_decode(const std::string &s) { + std::string curLocale = setlocale(LC_ALL, ""); + const char *_Source = s.c_str(); + size_t _Dsize = mbstowcs(NULL, _Source, 0) + 1; + wchar_t *_Dest = new wchar_t[_Dsize]; + wmemset(_Dest, 0, _Dsize); + mbstowcs(_Dest, _Source, _Dsize); + std::wstring result = _Dest; + delete[] _Dest; + setlocale(LC_ALL, curLocale.c_str()); + return result; } } // namespace details @@ -302,18 +334,6 @@ static inline int display_width(const std::wstring &input) { return details::mk_wcswidth(input.c_str(), input.size()); } -#else - -static inline int display_width(const std::string &input) { - return input.length(); -} - -static inline int display_width(const std::wstring &input) { - return input.length(); -} - -#endif - } // namespace unicode #endif \ No newline at end of file diff --git a/single_include/indicators/indicators.hpp b/single_include/indicators/indicators.hpp index b9121ca..d92ebc6 100644 --- a/single_include/indicators/indicators.hpp +++ b/single_include/indicators/indicators.hpp @@ -1025,34 +1025,8 @@ SOFTWARE. #include // #include -#ifndef INDICATORS_COLOR -#define INDICATORS_COLOR - -namespace indicators { -enum class Color { grey, red, green, yellow, blue, magenta, cyan, white, unspecified }; -} - -#endif - // #include -#ifndef INDICATORS_FONT_STYLE -#define INDICATORS_FONT_STYLE - -namespace indicators { -enum class FontStyle { bold, dark, italic, underline, blink, reverse, concealed, crossed }; -} - -#endif - // #include -#ifndef INDICATORS_PROGRESS_TYPE -#define INDICATORS_PROGRESS_TYPE - -namespace indicators { -enum class ProgressType { incremental, decremental }; -} - -#endif #include #include #include @@ -1369,19 +1343,14 @@ static inline void move_left(int cols) { std::cout << "\033[" << cols << "D"; } #define INDICATORS_DISPLAY_WIDTH #include -#if __has_include() -#include -#define INDICATORS_HAVE_CODECVT 1 -#define _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING -#endif #include #include #include +#include #include namespace unicode { -#if INDICATORS_HAVE_CODECVT namespace details { /* @@ -1506,42 +1475,54 @@ static inline int mk_wcwidth(wchar_t ucs) { /* sorted list of non-overlapping intervals of non-spacing characters */ /* generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" */ static const struct interval combining[] = { - {0x0300, 0x036F}, {0x0483, 0x0486}, {0x0488, 0x0489}, {0x0591, 0x05BD}, - {0x05BF, 0x05BF}, {0x05C1, 0x05C2}, {0x05C4, 0x05C5}, {0x05C7, 0x05C7}, - {0x0600, 0x0603}, {0x0610, 0x0615}, {0x064B, 0x065E}, {0x0670, 0x0670}, - {0x06D6, 0x06E4}, {0x06E7, 0x06E8}, {0x06EA, 0x06ED}, {0x070F, 0x070F}, - {0x0711, 0x0711}, {0x0730, 0x074A}, {0x07A6, 0x07B0}, {0x07EB, 0x07F3}, - {0x0901, 0x0902}, {0x093C, 0x093C}, {0x0941, 0x0948}, {0x094D, 0x094D}, - {0x0951, 0x0954}, {0x0962, 0x0963}, {0x0981, 0x0981}, {0x09BC, 0x09BC}, - {0x09C1, 0x09C4}, {0x09CD, 0x09CD}, {0x09E2, 0x09E3}, {0x0A01, 0x0A02}, - {0x0A3C, 0x0A3C}, {0x0A41, 0x0A42}, {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, - {0x0A70, 0x0A71}, {0x0A81, 0x0A82}, {0x0ABC, 0x0ABC}, {0x0AC1, 0x0AC5}, - {0x0AC7, 0x0AC8}, {0x0ACD, 0x0ACD}, {0x0AE2, 0x0AE3}, {0x0B01, 0x0B01}, - {0x0B3C, 0x0B3C}, {0x0B3F, 0x0B3F}, {0x0B41, 0x0B43}, {0x0B4D, 0x0B4D}, - {0x0B56, 0x0B56}, {0x0B82, 0x0B82}, {0x0BC0, 0x0BC0}, {0x0BCD, 0x0BCD}, - {0x0C3E, 0x0C40}, {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, {0x0C55, 0x0C56}, - {0x0CBC, 0x0CBC}, {0x0CBF, 0x0CBF}, {0x0CC6, 0x0CC6}, {0x0CCC, 0x0CCD}, - {0x0CE2, 0x0CE3}, {0x0D41, 0x0D43}, {0x0D4D, 0x0D4D}, {0x0DCA, 0x0DCA}, - {0x0DD2, 0x0DD4}, {0x0DD6, 0x0DD6}, {0x0E31, 0x0E31}, {0x0E34, 0x0E3A}, - {0x0E47, 0x0E4E}, {0x0EB1, 0x0EB1}, {0x0EB4, 0x0EB9}, {0x0EBB, 0x0EBC}, - {0x0EC8, 0x0ECD}, {0x0F18, 0x0F19}, {0x0F35, 0x0F35}, {0x0F37, 0x0F37}, - {0x0F39, 0x0F39}, {0x0F71, 0x0F7E}, {0x0F80, 0x0F84}, {0x0F86, 0x0F87}, - {0x0F90, 0x0F97}, {0x0F99, 0x0FBC}, {0x0FC6, 0x0FC6}, {0x102D, 0x1030}, - {0x1032, 0x1032}, {0x1036, 0x1037}, {0x1039, 0x1039}, {0x1058, 0x1059}, - {0x1160, 0x11FF}, {0x135F, 0x135F}, {0x1712, 0x1714}, {0x1732, 0x1734}, - {0x1752, 0x1753}, {0x1772, 0x1773}, {0x17B4, 0x17B5}, {0x17B7, 0x17BD}, - {0x17C6, 0x17C6}, {0x17C9, 0x17D3}, {0x17DD, 0x17DD}, {0x180B, 0x180D}, - {0x18A9, 0x18A9}, {0x1920, 0x1922}, {0x1927, 0x1928}, {0x1932, 0x1932}, - {0x1939, 0x193B}, {0x1A17, 0x1A18}, {0x1B00, 0x1B03}, {0x1B34, 0x1B34}, - {0x1B36, 0x1B3A}, {0x1B3C, 0x1B3C}, {0x1B42, 0x1B42}, {0x1B6B, 0x1B73}, - {0x1DC0, 0x1DCA}, {0x1DFE, 0x1DFF}, {0x200B, 0x200F}, {0x202A, 0x202E}, - {0x2060, 0x2063}, {0x206A, 0x206F}, {0x20D0, 0x20EF}, {0x302A, 0x302F}, - {0x3099, 0x309A}, {0xA806, 0xA806}, {0xA80B, 0xA80B}, {0xA825, 0xA826}, - {0xFB1E, 0xFB1E}, {0xFE00, 0xFE0F}, {0xFE20, 0xFE23}, {0xFEFF, 0xFEFF}, - {0xFFF9, 0xFFFB}, {0x10A01, 0x10A03}, {0x10A05, 0x10A06}, {0x10A0C, 0x10A0F}, - {0x10A38, 0x10A3A}, {0x10A3F, 0x10A3F}, {0x1D167, 0x1D169}, {0x1D173, 0x1D182}, - {0x1D185, 0x1D18B}, {0x1D1AA, 0x1D1AD}, {0x1D242, 0x1D244}, {0xE0001, 0xE0001}, - {0xE0020, 0xE007F}, {0xE0100, 0xE01EF}}; + {0x0300, 0x036F}, {0x0483, 0x0486}, {0x0488, 0x0489}, + {0x0591, 0x05BD}, {0x05BF, 0x05BF}, {0x05C1, 0x05C2}, + {0x05C4, 0x05C5}, {0x05C7, 0x05C7}, {0x0600, 0x0603}, + {0x0610, 0x0615}, {0x064B, 0x065E}, {0x0670, 0x0670}, + {0x06D6, 0x06E4}, {0x06E7, 0x06E8}, {0x06EA, 0x06ED}, + {0x070F, 0x070F}, {0x0711, 0x0711}, {0x0730, 0x074A}, + {0x07A6, 0x07B0}, {0x07EB, 0x07F3}, {0x0901, 0x0902}, + {0x093C, 0x093C}, {0x0941, 0x0948}, {0x094D, 0x094D}, + {0x0951, 0x0954}, {0x0962, 0x0963}, {0x0981, 0x0981}, + {0x09BC, 0x09BC}, {0x09C1, 0x09C4}, {0x09CD, 0x09CD}, + {0x09E2, 0x09E3}, {0x0A01, 0x0A02}, {0x0A3C, 0x0A3C}, + {0x0A41, 0x0A42}, {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, + {0x0A70, 0x0A71}, {0x0A81, 0x0A82}, {0x0ABC, 0x0ABC}, + {0x0AC1, 0x0AC5}, {0x0AC7, 0x0AC8}, {0x0ACD, 0x0ACD}, + {0x0AE2, 0x0AE3}, {0x0B01, 0x0B01}, {0x0B3C, 0x0B3C}, + {0x0B3F, 0x0B3F}, {0x0B41, 0x0B43}, {0x0B4D, 0x0B4D}, + {0x0B56, 0x0B56}, {0x0B82, 0x0B82}, {0x0BC0, 0x0BC0}, + {0x0BCD, 0x0BCD}, {0x0C3E, 0x0C40}, {0x0C46, 0x0C48}, + {0x0C4A, 0x0C4D}, {0x0C55, 0x0C56}, {0x0CBC, 0x0CBC}, + {0x0CBF, 0x0CBF}, {0x0CC6, 0x0CC6}, {0x0CCC, 0x0CCD}, + {0x0CE2, 0x0CE3}, {0x0D41, 0x0D43}, {0x0D4D, 0x0D4D}, + {0x0DCA, 0x0DCA}, {0x0DD2, 0x0DD4}, {0x0DD6, 0x0DD6}, + {0x0E31, 0x0E31}, {0x0E34, 0x0E3A}, {0x0E47, 0x0E4E}, + {0x0EB1, 0x0EB1}, {0x0EB4, 0x0EB9}, {0x0EBB, 0x0EBC}, + {0x0EC8, 0x0ECD}, {0x0F18, 0x0F19}, {0x0F35, 0x0F35}, + {0x0F37, 0x0F37}, {0x0F39, 0x0F39}, {0x0F71, 0x0F7E}, + {0x0F80, 0x0F84}, {0x0F86, 0x0F87}, {0x0F90, 0x0F97}, + {0x0F99, 0x0FBC}, {0x0FC6, 0x0FC6}, {0x102D, 0x1030}, + {0x1032, 0x1032}, {0x1036, 0x1037}, {0x1039, 0x1039}, + {0x1058, 0x1059}, {0x1160, 0x11FF}, {0x135F, 0x135F}, + {0x1712, 0x1714}, {0x1732, 0x1734}, {0x1752, 0x1753}, + {0x1772, 0x1773}, {0x17B4, 0x17B5}, {0x17B7, 0x17BD}, + {0x17C6, 0x17C6}, {0x17C9, 0x17D3}, {0x17DD, 0x17DD}, + {0x180B, 0x180D}, {0x18A9, 0x18A9}, {0x1920, 0x1922}, + {0x1927, 0x1928}, {0x1932, 0x1932}, {0x1939, 0x193B}, + {0x1A17, 0x1A18}, {0x1B00, 0x1B03}, {0x1B34, 0x1B34}, + {0x1B36, 0x1B3A}, {0x1B3C, 0x1B3C}, {0x1B42, 0x1B42}, + {0x1B6B, 0x1B73}, {0x1DC0, 0x1DCA}, {0x1DFE, 0x1DFF}, + {0x200B, 0x200F}, {0x202A, 0x202E}, {0x2060, 0x2063}, + {0x206A, 0x206F}, {0x20D0, 0x20EF}, {0x302A, 0x302F}, + {0x3099, 0x309A}, {0xA806, 0xA806}, {0xA80B, 0xA80B}, + {0xA825, 0xA826}, {0xFB1E, 0xFB1E}, {0xFE00, 0xFE0F}, + {0xFE20, 0xFE23}, {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, + {0x10A01, 0x10A03}, {0x10A05, 0x10A06}, {0x10A0C, 0x10A0F}, + {0x10A38, 0x10A3A}, {0x10A3F, 0x10A3F}, {0x1D167, 0x1D169}, + {0x1D173, 0x1D182}, {0x1D185, 0x1D18B}, {0x1D1AA, 0x1D1AD}, + {0x1D242, 0x1D244}, {0xE0001, 0xE0001}, {0xE0020, 0xE007F}, + {0xE0100, 0xE01EF}}; /* test for 8-bit control characters */ if (ucs == 0) @@ -1555,17 +1536,20 @@ static inline int mk_wcwidth(wchar_t ucs) { /* if we arrive here, ucs is not a combining or C0/C1 control character */ - return 1 + (ucs >= 0x1100 && - (ucs <= 0x115f || /* Hangul Jamo init. consonants */ - ucs == 0x2329 || ucs == 0x232a || - (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs != 0x303f) || /* CJK ... Yi */ - (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */ - (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */ - (ucs >= 0xfe10 && ucs <= 0xfe19) || /* Vertical forms */ - (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */ - (ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */ - (ucs >= 0xffe0 && ucs <= 0xffe6) || (ucs >= 0x20000 && ucs <= 0x2fffd) || - (ucs >= 0x30000 && ucs <= 0x3fffd))); + return 1 + + (ucs >= 0x1100 && + (ucs <= 0x115f || /* Hangul Jamo init. consonants */ + ucs == 0x2329 || ucs == 0x232a || + (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs != 0x303f) || /* CJK ... Yi */ + (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */ + (ucs >= 0xf900 && + ucs <= 0xfaff) || /* CJK Compatibility Ideographs */ + (ucs >= 0xfe10 && ucs <= 0xfe19) || /* Vertical forms */ + (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */ + (ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */ + (ucs >= 0xffe0 && ucs <= 0xffe6) || + (ucs >= 0x20000 && ucs <= 0x2fffd) || + (ucs >= 0x30000 && ucs <= 0x3fffd))); } static inline int mk_wcswidth(const wchar_t *pwcs, size_t n) { @@ -1593,38 +1577,58 @@ static inline int mk_wcwidth_cjk(wchar_t ucs) { /* sorted list of non-overlapping intervals of East Asian Ambiguous * characters, generated by "uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf c" */ static const struct interval ambiguous[] = { - {0x00A1, 0x00A1}, {0x00A4, 0x00A4}, {0x00A7, 0x00A8}, {0x00AA, 0x00AA}, {0x00AE, 0x00AE}, - {0x00B0, 0x00B4}, {0x00B6, 0x00BA}, {0x00BC, 0x00BF}, {0x00C6, 0x00C6}, {0x00D0, 0x00D0}, - {0x00D7, 0x00D8}, {0x00DE, 0x00E1}, {0x00E6, 0x00E6}, {0x00E8, 0x00EA}, {0x00EC, 0x00ED}, - {0x00F0, 0x00F0}, {0x00F2, 0x00F3}, {0x00F7, 0x00FA}, {0x00FC, 0x00FC}, {0x00FE, 0x00FE}, - {0x0101, 0x0101}, {0x0111, 0x0111}, {0x0113, 0x0113}, {0x011B, 0x011B}, {0x0126, 0x0127}, - {0x012B, 0x012B}, {0x0131, 0x0133}, {0x0138, 0x0138}, {0x013F, 0x0142}, {0x0144, 0x0144}, - {0x0148, 0x014B}, {0x014D, 0x014D}, {0x0152, 0x0153}, {0x0166, 0x0167}, {0x016B, 0x016B}, - {0x01CE, 0x01CE}, {0x01D0, 0x01D0}, {0x01D2, 0x01D2}, {0x01D4, 0x01D4}, {0x01D6, 0x01D6}, - {0x01D8, 0x01D8}, {0x01DA, 0x01DA}, {0x01DC, 0x01DC}, {0x0251, 0x0251}, {0x0261, 0x0261}, - {0x02C4, 0x02C4}, {0x02C7, 0x02C7}, {0x02C9, 0x02CB}, {0x02CD, 0x02CD}, {0x02D0, 0x02D0}, - {0x02D8, 0x02DB}, {0x02DD, 0x02DD}, {0x02DF, 0x02DF}, {0x0391, 0x03A1}, {0x03A3, 0x03A9}, - {0x03B1, 0x03C1}, {0x03C3, 0x03C9}, {0x0401, 0x0401}, {0x0410, 0x044F}, {0x0451, 0x0451}, - {0x2010, 0x2010}, {0x2013, 0x2016}, {0x2018, 0x2019}, {0x201C, 0x201D}, {0x2020, 0x2022}, - {0x2024, 0x2027}, {0x2030, 0x2030}, {0x2032, 0x2033}, {0x2035, 0x2035}, {0x203B, 0x203B}, - {0x203E, 0x203E}, {0x2074, 0x2074}, {0x207F, 0x207F}, {0x2081, 0x2084}, {0x20AC, 0x20AC}, - {0x2103, 0x2103}, {0x2105, 0x2105}, {0x2109, 0x2109}, {0x2113, 0x2113}, {0x2116, 0x2116}, - {0x2121, 0x2122}, {0x2126, 0x2126}, {0x212B, 0x212B}, {0x2153, 0x2154}, {0x215B, 0x215E}, - {0x2160, 0x216B}, {0x2170, 0x2179}, {0x2190, 0x2199}, {0x21B8, 0x21B9}, {0x21D2, 0x21D2}, - {0x21D4, 0x21D4}, {0x21E7, 0x21E7}, {0x2200, 0x2200}, {0x2202, 0x2203}, {0x2207, 0x2208}, - {0x220B, 0x220B}, {0x220F, 0x220F}, {0x2211, 0x2211}, {0x2215, 0x2215}, {0x221A, 0x221A}, - {0x221D, 0x2220}, {0x2223, 0x2223}, {0x2225, 0x2225}, {0x2227, 0x222C}, {0x222E, 0x222E}, - {0x2234, 0x2237}, {0x223C, 0x223D}, {0x2248, 0x2248}, {0x224C, 0x224C}, {0x2252, 0x2252}, - {0x2260, 0x2261}, {0x2264, 0x2267}, {0x226A, 0x226B}, {0x226E, 0x226F}, {0x2282, 0x2283}, - {0x2286, 0x2287}, {0x2295, 0x2295}, {0x2299, 0x2299}, {0x22A5, 0x22A5}, {0x22BF, 0x22BF}, - {0x2312, 0x2312}, {0x2460, 0x24E9}, {0x24EB, 0x254B}, {0x2550, 0x2573}, {0x2580, 0x258F}, - {0x2592, 0x2595}, {0x25A0, 0x25A1}, {0x25A3, 0x25A9}, {0x25B2, 0x25B3}, {0x25B6, 0x25B7}, - {0x25BC, 0x25BD}, {0x25C0, 0x25C1}, {0x25C6, 0x25C8}, {0x25CB, 0x25CB}, {0x25CE, 0x25D1}, - {0x25E2, 0x25E5}, {0x25EF, 0x25EF}, {0x2605, 0x2606}, {0x2609, 0x2609}, {0x260E, 0x260F}, - {0x2614, 0x2615}, {0x261C, 0x261C}, {0x261E, 0x261E}, {0x2640, 0x2640}, {0x2642, 0x2642}, - {0x2660, 0x2661}, {0x2663, 0x2665}, {0x2667, 0x266A}, {0x266C, 0x266D}, {0x266F, 0x266F}, - {0x273D, 0x273D}, {0x2776, 0x277F}, {0xE000, 0xF8FF}, {0xFFFD, 0xFFFD}, {0xF0000, 0xFFFFD}, - {0x100000, 0x10FFFD}}; + {0x00A1, 0x00A1}, {0x00A4, 0x00A4}, {0x00A7, 0x00A8}, + {0x00AA, 0x00AA}, {0x00AE, 0x00AE}, {0x00B0, 0x00B4}, + {0x00B6, 0x00BA}, {0x00BC, 0x00BF}, {0x00C6, 0x00C6}, + {0x00D0, 0x00D0}, {0x00D7, 0x00D8}, {0x00DE, 0x00E1}, + {0x00E6, 0x00E6}, {0x00E8, 0x00EA}, {0x00EC, 0x00ED}, + {0x00F0, 0x00F0}, {0x00F2, 0x00F3}, {0x00F7, 0x00FA}, + {0x00FC, 0x00FC}, {0x00FE, 0x00FE}, {0x0101, 0x0101}, + {0x0111, 0x0111}, {0x0113, 0x0113}, {0x011B, 0x011B}, + {0x0126, 0x0127}, {0x012B, 0x012B}, {0x0131, 0x0133}, + {0x0138, 0x0138}, {0x013F, 0x0142}, {0x0144, 0x0144}, + {0x0148, 0x014B}, {0x014D, 0x014D}, {0x0152, 0x0153}, + {0x0166, 0x0167}, {0x016B, 0x016B}, {0x01CE, 0x01CE}, + {0x01D0, 0x01D0}, {0x01D2, 0x01D2}, {0x01D4, 0x01D4}, + {0x01D6, 0x01D6}, {0x01D8, 0x01D8}, {0x01DA, 0x01DA}, + {0x01DC, 0x01DC}, {0x0251, 0x0251}, {0x0261, 0x0261}, + {0x02C4, 0x02C4}, {0x02C7, 0x02C7}, {0x02C9, 0x02CB}, + {0x02CD, 0x02CD}, {0x02D0, 0x02D0}, {0x02D8, 0x02DB}, + {0x02DD, 0x02DD}, {0x02DF, 0x02DF}, {0x0391, 0x03A1}, + {0x03A3, 0x03A9}, {0x03B1, 0x03C1}, {0x03C3, 0x03C9}, + {0x0401, 0x0401}, {0x0410, 0x044F}, {0x0451, 0x0451}, + {0x2010, 0x2010}, {0x2013, 0x2016}, {0x2018, 0x2019}, + {0x201C, 0x201D}, {0x2020, 0x2022}, {0x2024, 0x2027}, + {0x2030, 0x2030}, {0x2032, 0x2033}, {0x2035, 0x2035}, + {0x203B, 0x203B}, {0x203E, 0x203E}, {0x2074, 0x2074}, + {0x207F, 0x207F}, {0x2081, 0x2084}, {0x20AC, 0x20AC}, + {0x2103, 0x2103}, {0x2105, 0x2105}, {0x2109, 0x2109}, + {0x2113, 0x2113}, {0x2116, 0x2116}, {0x2121, 0x2122}, + {0x2126, 0x2126}, {0x212B, 0x212B}, {0x2153, 0x2154}, + {0x215B, 0x215E}, {0x2160, 0x216B}, {0x2170, 0x2179}, + {0x2190, 0x2199}, {0x21B8, 0x21B9}, {0x21D2, 0x21D2}, + {0x21D4, 0x21D4}, {0x21E7, 0x21E7}, {0x2200, 0x2200}, + {0x2202, 0x2203}, {0x2207, 0x2208}, {0x220B, 0x220B}, + {0x220F, 0x220F}, {0x2211, 0x2211}, {0x2215, 0x2215}, + {0x221A, 0x221A}, {0x221D, 0x2220}, {0x2223, 0x2223}, + {0x2225, 0x2225}, {0x2227, 0x222C}, {0x222E, 0x222E}, + {0x2234, 0x2237}, {0x223C, 0x223D}, {0x2248, 0x2248}, + {0x224C, 0x224C}, {0x2252, 0x2252}, {0x2260, 0x2261}, + {0x2264, 0x2267}, {0x226A, 0x226B}, {0x226E, 0x226F}, + {0x2282, 0x2283}, {0x2286, 0x2287}, {0x2295, 0x2295}, + {0x2299, 0x2299}, {0x22A5, 0x22A5}, {0x22BF, 0x22BF}, + {0x2312, 0x2312}, {0x2460, 0x24E9}, {0x24EB, 0x254B}, + {0x2550, 0x2573}, {0x2580, 0x258F}, {0x2592, 0x2595}, + {0x25A0, 0x25A1}, {0x25A3, 0x25A9}, {0x25B2, 0x25B3}, + {0x25B6, 0x25B7}, {0x25BC, 0x25BD}, {0x25C0, 0x25C1}, + {0x25C6, 0x25C8}, {0x25CB, 0x25CB}, {0x25CE, 0x25D1}, + {0x25E2, 0x25E5}, {0x25EF, 0x25EF}, {0x2605, 0x2606}, + {0x2609, 0x2609}, {0x260E, 0x260F}, {0x2614, 0x2615}, + {0x261C, 0x261C}, {0x261E, 0x261E}, {0x2640, 0x2640}, + {0x2642, 0x2642}, {0x2660, 0x2661}, {0x2663, 0x2665}, + {0x2667, 0x266A}, {0x266C, 0x266D}, {0x266F, 0x266F}, + {0x273D, 0x273D}, {0x2776, 0x277F}, {0xE000, 0xF8FF}, + {0xFFFD, 0xFFFD}, {0xF0000, 0xFFFFD}, {0x100000, 0x10FFFD}}; /* binary search in table of non-spacing characters */ if (bisearch(ucs, ambiguous, sizeof(ambiguous) / sizeof(struct interval) - 1)) @@ -1646,15 +1650,17 @@ static inline int mk_wcswidth_cjk(const wchar_t *pwcs, size_t n) { } // convert UTF-8 string to wstring -static inline std::wstring utf8_decode(const std::string &str) { - std::wstring_convert> myconv; - return myconv.from_bytes(str); -} - -// convert wstring to UTF-8 string -static inline std::string utf8_encode(const std::wstring &str) { - std::wstring_convert> myconv; - return myconv.to_bytes(str); +static inline std::wstring utf8_decode(const std::string &s) { + std::string curLocale = setlocale(LC_ALL, ""); + const char *_Source = s.c_str(); + size_t _Dsize = mbstowcs(NULL, _Source, 0) + 1; + wchar_t *_Dest = new wchar_t[_Dsize]; + wmemset(_Dest, 0, _Dsize); + mbstowcs(_Dest, _Source, _Dsize); + std::wstring result = _Dest; + delete[] _Dest; + setlocale(LC_ALL, curLocale.c_str()); + return result; } } // namespace details @@ -1668,1160 +1674,11 @@ static inline int display_width(const std::wstring &input) { return details::mk_wcswidth(input.c_str(), input.size()); } -#else - -static inline int display_width(const std::string &input) { - return input.length(); -} - -static inline int display_width(const std::wstring &input) { - return input.length(); -} - -#endif - } // namespace unicode #endif // #include -/* -Activity Indicators for Modern C++ -https://github.com/p-ranav/indicators - -Licensed under the MIT License . -SPDX-License-Identifier: MIT -Copyright (c) 2019 Dawid Pilarski . - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ -#ifndef INDICATORS_SETTING -#define INDICATORS_SETTING - -#include -// #include -// #include -// #include -#include -#include -#include -#include -#include - -namespace indicators { - -namespace details { - -template struct if_else; - -template <> struct if_else { using type = std::true_type; }; - -template <> struct if_else { using type = std::false_type; }; - -template struct if_else_type; - -template struct if_else_type { - using type = True; -}; - -template struct if_else_type { - using type = False; -}; - -template struct conjuction; - -template <> struct conjuction<> : std::true_type {}; - -template -struct conjuction - : if_else_type>::type {}; - -template struct disjunction; - -template <> struct disjunction<> : std::false_type {}; - -template -struct disjunction - : if_else_type>::type {}; - -enum class ProgressBarOption { - bar_width = 0, - prefix_text, - postfix_text, - start, - end, - fill, - lead, - remainder, - max_postfix_text_len, - completed, - show_percentage, - show_elapsed_time, - show_remaining_time, - saved_start_time, - foreground_color, - spinner_show, - spinner_states, - font_styles, - hide_bar_when_complete, - min_progress, - max_progress, - progress_type, - stream -}; - -template struct Setting { - template ::value>::type> - explicit Setting(Args &&... args) : value(std::forward(args)...) {} - Setting(const Setting &) = default; - Setting(Setting &&) = default; - - static constexpr auto id = Id; - using type = T; - - T value{}; -}; - -template struct is_setting : std::false_type {}; - -template struct is_setting> : std::true_type {}; - -template -struct are_settings : if_else...>::value>::type {}; - -template <> struct are_settings<> : std::true_type {}; - -template struct is_setting_from_tuple; - -template struct is_setting_from_tuple> : std::true_type {}; - -template -struct is_setting_from_tuple> - : if_else...>::value>::type {}; - -template -struct are_settings_from_tuple - : if_else...>::value>::type {}; - -template struct always_true { static constexpr auto value = true; }; - -template Default &&get_impl(Default &&def) { - return std::forward(def); -} - -template -auto get_impl(Default && /*def*/, T &&first, Args &&... /*tail*/) -> - typename std::enable_if<(std::decay::type::id == Id), - decltype(std::forward(first))>::type { - return std::forward(first); -} - -template -auto get_impl(Default &&def, T && /*first*/, Args &&... tail) -> - typename std::enable_if<(std::decay::type::id != Id), - decltype(get_impl(std::forward(def), - std::forward(tail)...))>::type { - return get_impl(std::forward(def), std::forward(tail)...); -} - -template ::value, void>::type> -auto get(Default &&def, Args &&... args) - -> decltype(details::get_impl(std::forward(def), std::forward(args)...)) { - return details::get_impl(std::forward(def), std::forward(args)...); -} - -template using StringSetting = Setting; - -template using IntegerSetting = Setting; - -template using BooleanSetting = Setting; - -template struct option_idx; - -template -struct option_idx, counter> - : if_else_type<(Id == T::id), std::integral_constant, - option_idx, counter + 1>>::type {}; - -template struct option_idx, counter> { - static_assert(always_true<(ProgressBarOption)Id>::value, "No such option was found"); -}; - -template -auto get_value(Settings &&settings) - -> decltype((std::get::type>::value>( - std::declval()))) { - return std::get::type>::value>( - std::forward(settings)); -} - -} // namespace details - -namespace option { -using BarWidth = details::IntegerSetting; -using PrefixText = details::StringSetting; -using PostfixText = details::StringSetting; -using Start = details::StringSetting; -using End = details::StringSetting; -using Fill = details::StringSetting; -using Lead = details::StringSetting; -using Remainder = details::StringSetting; -using MaxPostfixTextLen = details::IntegerSetting; -using Completed = details::BooleanSetting; -using ShowPercentage = details::BooleanSetting; -using ShowElapsedTime = details::BooleanSetting; -using ShowRemainingTime = details::BooleanSetting; -using SavedStartTime = details::BooleanSetting; -using ForegroundColor = details::Setting; -using ShowSpinner = details::BooleanSetting; -using SpinnerStates = - details::Setting, details::ProgressBarOption::spinner_states>; -using HideBarWhenComplete = - details::BooleanSetting; -using FontStyles = - details::Setting, details::ProgressBarOption::font_styles>; -using MinProgress = details::IntegerSetting; -using MaxProgress = details::IntegerSetting; -using ProgressType = details::Setting; -using Stream = details::Setting; -} // namespace option -} // namespace indicators - -#endif -// #include //! -//! termcolor -//! ~~~~~~~~~ -//! -//! termcolor is a header-only c++ library for printing colored messages -//! to the terminal. Written just for fun with a help of the Force. -//! -//! :copyright: (c) 2013 by Ihor Kalnytskyi -//! :license: BSD, see LICENSE for details -//! - -#ifndef TERMCOLOR_HPP_ -#define TERMCOLOR_HPP_ - -#include -#include - -// Detect target's platform and set some macros in order to wrap platform -// specific code this library depends on. -#if defined(_WIN32) || defined(_WIN64) -# define TERMCOLOR_TARGET_WINDOWS -#elif defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)) -# define TERMCOLOR_TARGET_POSIX -#endif - -// If implementation has not been explicitly set, try to choose one based on -// target platform. -#if !defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) && !defined(TERMCOLOR_USE_WINDOWS_API) && !defined(TERMCOLOR_USE_NOOP) -# if defined(TERMCOLOR_TARGET_POSIX) -# define TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES -# define TERMCOLOR_AUTODETECTED_IMPLEMENTATION -# elif defined(TERMCOLOR_TARGET_WINDOWS) -# define TERMCOLOR_USE_WINDOWS_API -# define TERMCOLOR_AUTODETECTED_IMPLEMENTATION -# endif -#endif - -// These headers provide isatty()/fileno() functions, which are used for -// testing whether a standard stream refers to the terminal. -#if defined(TERMCOLOR_TARGET_POSIX) -# include -#elif defined(TERMCOLOR_TARGET_WINDOWS) -#if defined(_MSC_VER) -#if !defined(NOMINMAX) -#define NOMINMAX -#endif -#endif -# include -# include -#endif - - -namespace termcolor -{ - // Forward declaration of the `_internal` namespace. - // All comments are below. - namespace _internal - { - inline int colorize_index(); - inline FILE* get_standard_stream(const std::ostream& stream); - inline bool is_colorized(std::ostream& stream); - inline bool is_atty(const std::ostream& stream); - - #if defined(TERMCOLOR_TARGET_WINDOWS) - inline void win_change_attributes(std::ostream& stream, int foreground, int background=-1); - #endif - } - - inline - std::ostream& colorize(std::ostream& stream) - { - stream.iword(_internal::colorize_index()) = 1L; - return stream; - } - - inline - std::ostream& nocolorize(std::ostream& stream) - { - stream.iword(_internal::colorize_index()) = 0L; - return stream; - } - - inline - std::ostream& reset(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[00m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, -1, -1); - #endif - } - return stream; - } - - inline - std::ostream& bold(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[1m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - #endif - } - return stream; - } - - inline - std::ostream& dark(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[2m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - #endif - } - return stream; - } - - inline - std::ostream& italic(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[3m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - #endif - } - return stream; - } - - inline - std::ostream& underline(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[4m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, -1, COMMON_LVB_UNDERSCORE); - #endif - } - return stream; - } - - inline - std::ostream& blink(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[5m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - #endif - } - return stream; - } - - inline - std::ostream& reverse(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[7m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - #endif - } - return stream; - } - - inline - std::ostream& concealed(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[8m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - #endif - } - return stream; - } - - inline - std::ostream& crossed(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[9m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - #endif - } - return stream; - } - - template inline - std::ostream& color(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - char command[12]; - std::snprintf(command, sizeof(command), "\033[38;5;%dm", code); - stream << command; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - #endif - } - return stream; - } - - template inline - std::ostream& on_color(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - char command[12]; - std::snprintf(command, sizeof(command), "\033[48;5;%dm", code); - stream << command; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - #endif - } - return stream; - } - - template inline - std::ostream& color(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - char command[20]; - std::snprintf(command, sizeof(command), "\033[38;2;%d;%d;%dm", r, g, b); - stream << command; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - #endif - } - return stream; - } - - template inline - std::ostream& on_color(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - char command[20]; - std::snprintf(command, sizeof(command), "\033[48;2;%d;%d;%dm", r, g, b); - stream << command; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - #endif - } - return stream; - } - - inline - std::ostream& grey(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[30m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, - 0 // grey (black) - ); - #endif - } - return stream; - } - - inline - std::ostream& red(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[31m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, - FOREGROUND_RED - ); - #endif - } - return stream; - } - - inline - std::ostream& green(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[32m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, - FOREGROUND_GREEN - ); - #endif - } - return stream; - } - - inline - std::ostream& yellow(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[33m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, - FOREGROUND_GREEN | FOREGROUND_RED - ); - #endif - } - return stream; - } - - inline - std::ostream& blue(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[34m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, - FOREGROUND_BLUE - ); - #endif - } - return stream; - } - - inline - std::ostream& magenta(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[35m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, - FOREGROUND_BLUE | FOREGROUND_RED - ); - #endif - } - return stream; - } - - inline - std::ostream& cyan(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[36m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, - FOREGROUND_BLUE | FOREGROUND_GREEN - ); - #endif - } - return stream; - } - - inline - std::ostream& white(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[37m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, - FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED - ); - #endif - } - return stream; - } - - - inline - std::ostream& bright_grey(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[90m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, - 0 | FOREGROUND_INTENSITY // grey (black) - ); - #endif - } - return stream; - } - - inline - std::ostream& bright_red(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[91m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, - FOREGROUND_RED | FOREGROUND_INTENSITY - ); - #endif - } - return stream; - } - - inline - std::ostream& bright_green(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[92m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, - FOREGROUND_GREEN | FOREGROUND_INTENSITY - ); - #endif - } - return stream; - } - - inline - std::ostream& bright_yellow(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[93m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, - FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY - ); - #endif - } - return stream; - } - - inline - std::ostream& bright_blue(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[94m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, - FOREGROUND_BLUE | FOREGROUND_INTENSITY - ); - #endif - } - return stream; - } - - inline - std::ostream& bright_magenta(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[95m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, - FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY - ); - #endif - } - return stream; - } - - inline - std::ostream& bright_cyan(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[96m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, - FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY - ); - #endif - } - return stream; - } - - inline - std::ostream& bright_white(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[97m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, - FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY - ); - #endif - } - return stream; - } - - - inline - std::ostream& on_grey(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[40m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, -1, - 0 // grey (black) - ); - #endif - } - return stream; - } - - inline - std::ostream& on_red(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[41m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, -1, - BACKGROUND_RED - ); - #endif - } - return stream; - } - - inline - std::ostream& on_green(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[42m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, -1, - BACKGROUND_GREEN - ); - #endif - } - return stream; - } - - inline - std::ostream& on_yellow(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[43m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, -1, - BACKGROUND_GREEN | BACKGROUND_RED - ); - #endif - } - return stream; - } - - inline - std::ostream& on_blue(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[44m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, -1, - BACKGROUND_BLUE - ); - #endif - } - return stream; - } - - inline - std::ostream& on_magenta(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[45m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, -1, - BACKGROUND_BLUE | BACKGROUND_RED - ); - #endif - } - return stream; - } - - inline - std::ostream& on_cyan(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[46m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, -1, - BACKGROUND_GREEN | BACKGROUND_BLUE - ); - #endif - } - return stream; - } - - inline - std::ostream& on_white(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[47m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, -1, - BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED - ); - #endif - } - - return stream; - } - - - inline - std::ostream& on_bright_grey(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[100m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, -1, - 0 | BACKGROUND_INTENSITY // grey (black) - ); - #endif - } - return stream; - } - - inline - std::ostream& on_bright_red(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[101m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, -1, - BACKGROUND_RED | BACKGROUND_INTENSITY - ); - #endif - } - return stream; - } - - inline - std::ostream& on_bright_green(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[102m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, -1, - BACKGROUND_GREEN | BACKGROUND_INTENSITY - ); - #endif - } - return stream; - } - - inline - std::ostream& on_bright_yellow(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[103m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, -1, - BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY - ); - #endif - } - return stream; - } - - inline - std::ostream& on_bright_blue(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[104m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, -1, - BACKGROUND_BLUE | BACKGROUND_INTENSITY - ); - #endif - } - return stream; - } - - inline - std::ostream& on_bright_magenta(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[105m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, -1, - BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_INTENSITY - ); - #endif - } - return stream; - } - - inline - std::ostream& on_bright_cyan(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[106m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, -1, - BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY - ); - #endif - } - return stream; - } - - inline - std::ostream& on_bright_white(std::ostream& stream) - { - if (_internal::is_colorized(stream)) - { - #if defined(TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES) - stream << "\033[107m"; - #elif defined(TERMCOLOR_USE_WINDOWS_API) - _internal::win_change_attributes(stream, -1, - BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_INTENSITY - ); - #endif - } - - return stream; - } - - - - //! Since C++ hasn't a way to hide something in the header from - //! the outer access, I have to introduce this namespace which - //! is used for internal purpose and should't be access from - //! the user code. - namespace _internal - { - // An index to be used to access a private storage of I/O streams. See - // colorize / nocolorize I/O manipulators for details. Due to the fact - // that static variables ain't shared between translation units, inline - // function with local static variable is used to do the trick and share - // the variable value between translation units. - inline int colorize_index() - { - static int colorize_index = std::ios_base::xalloc(); - return colorize_index; - } - - //! Since C++ hasn't a true way to extract stream handler - //! from the a given `std::ostream` object, I have to write - //! this kind of hack. - inline - FILE* get_standard_stream(const std::ostream& stream) - { - if (&stream == &std::cout) - return stdout; - else if ((&stream == &std::cerr) || (&stream == &std::clog)) - return stderr; - - return nullptr; - } - - // Say whether a given stream should be colorized or not. It's always - // true for ATTY streams and may be true for streams marked with - // colorize flag. - inline - bool is_colorized(std::ostream& stream) - { - return is_atty(stream) || static_cast(stream.iword(colorize_index())); - } - - //! Test whether a given `std::ostream` object refers to - //! a terminal. - inline - bool is_atty(const std::ostream& stream) - { - FILE* std_stream = get_standard_stream(stream); - - // Unfortunately, fileno() ends with segmentation fault - // if invalid file descriptor is passed. So we need to - // handle this case gracefully and assume it's not a tty - // if standard stream is not detected, and 0 is returned. - if (!std_stream) - return false; - - #if defined(TERMCOLOR_TARGET_POSIX) - return ::isatty(fileno(std_stream)); - #elif defined(TERMCOLOR_TARGET_WINDOWS) - return ::_isatty(_fileno(std_stream)); - #else - return false; - #endif - } - - #if defined(TERMCOLOR_TARGET_WINDOWS) - //! Change Windows Terminal colors attribute. If some - //! parameter is `-1` then attribute won't changed. - inline void win_change_attributes(std::ostream& stream, int foreground, int background) - { - // yeah, i know.. it's ugly, it's windows. - static WORD defaultAttributes = 0; - - // Windows doesn't have ANSI escape sequences and so we use special - // API to change Terminal output color. That means we can't - // manipulate colors by means of "std::stringstream" and hence - // should do nothing in this case. - if (!_internal::is_atty(stream)) - return; - - // get terminal handle - HANDLE hTerminal = INVALID_HANDLE_VALUE; - if (&stream == &std::cout) - hTerminal = GetStdHandle(STD_OUTPUT_HANDLE); - else if (&stream == &std::cerr) - hTerminal = GetStdHandle(STD_ERROR_HANDLE); - - // save default terminal attributes if it unsaved - if (!defaultAttributes) - { - CONSOLE_SCREEN_BUFFER_INFO info; - if (!GetConsoleScreenBufferInfo(hTerminal, &info)) - return; - defaultAttributes = info.wAttributes; - } - - // restore all default settings - if (foreground == -1 && background == -1) - { - SetConsoleTextAttribute(hTerminal, defaultAttributes); - return; - } - - // get current settings - CONSOLE_SCREEN_BUFFER_INFO info; - if (!GetConsoleScreenBufferInfo(hTerminal, &info)) - return; - - if (foreground != -1) - { - info.wAttributes &= ~(info.wAttributes & 0x0F); - info.wAttributes |= static_cast(foreground); - } - - if (background != -1) - { - info.wAttributes &= ~(info.wAttributes & 0xF0); - info.wAttributes |= static_cast(background); - } - - SetConsoleTextAttribute(hTerminal, info.wAttributes); - } - #endif // TERMCOLOR_TARGET_WINDOWS - - } // namespace _internal - -} // namespace termcolor - - -#undef TERMCOLOR_TARGET_POSIX -#undef TERMCOLOR_TARGET_WINDOWS - -#if defined(TERMCOLOR_AUTODETECTED_IMPLEMENTATION) -# undef TERMCOLOR_USE_ANSI_ESCAPE_SEQUENCES -# undef TERMCOLOR_USE_WINDOWS_API -#endif - -#endif // TERMCOLOR_HPP_ - +// #include #include #include @@ -3044,228 +1901,6 @@ private: #define INDICATORS_PROGRESS_BAR // #include -#ifndef INDICATORS_STREAM_HELPER -#define INDICATORS_STREAM_HELPER - -// #include -// #include -// #include - -#include -#include -#include -#include -#include -#include - -#include -#include - -namespace indicators { -namespace details { - -inline void set_stream_color(std::ostream &os, Color color) { - switch (color) { - case Color::grey: - os << termcolor::grey; - break; - case Color::red: - os << termcolor::red; - break; - case Color::green: - os << termcolor::green; - break; - case Color::yellow: - os << termcolor::yellow; - break; - case Color::blue: - os << termcolor::blue; - break; - case Color::magenta: - os << termcolor::magenta; - break; - case Color::cyan: - os << termcolor::cyan; - break; - case Color::white: - os << termcolor::white; - break; - default: - assert(false); - } -} - -inline void set_font_style(std::ostream &os, FontStyle style) { - switch (style) { - case FontStyle::bold: - os << termcolor::bold; - break; - case FontStyle::dark: - os << termcolor::dark; - break; - case FontStyle::italic: - os << termcolor::italic; - break; - case FontStyle::underline: - os << termcolor::underline; - break; - case FontStyle::blink: - os << termcolor::blink; - break; - case FontStyle::reverse: - os << termcolor::reverse; - break; - case FontStyle::concealed: - os << termcolor::concealed; - break; - case FontStyle::crossed: - os << termcolor::crossed; - break; - default: - break; - } -} - -inline std::ostream &write_duration(std::ostream &os, std::chrono::nanoseconds ns) { - using namespace std; - using namespace std::chrono; - using days = duration>; - char fill = os.fill(); - os.fill('0'); - auto d = duration_cast(ns); - ns -= d; - auto h = duration_cast(ns); - ns -= h; - auto m = duration_cast(ns); - ns -= m; - auto s = duration_cast(ns); - if (d.count() > 0) - os << setw(2) << d.count() << "d:"; - if (h.count() > 0) - os << setw(2) << h.count() << "h:"; - os << setw(2) << m.count() << "m:" << setw(2) << s.count() << 's'; - os.fill(fill); - return os; -} - -class BlockProgressScaleWriter { -public: - BlockProgressScaleWriter(std::ostream &os, size_t bar_width) : os(os), bar_width(bar_width) {} - - std::ostream &write(float progress) { - std::string fill_text{"█"}; - std::vector lead_characters{" ", "▏", "▎", "▍", "▌", "▋", "▊", "▉"}; - auto value = (std::min)(1.0f, (std::max)(0.0f, progress / 100.0f)); - auto whole_width = std::floor(value * bar_width); - auto remainder_width = fmod((value * bar_width), 1.0f); - auto part_width = std::floor(remainder_width * lead_characters.size()); - std::string lead_text = lead_characters[size_t(part_width)]; - if ((bar_width - whole_width - 1) < 0) - lead_text = ""; - for (size_t i = 0; i < whole_width; ++i) - os << fill_text; - os << lead_text; - for (size_t i = 0; i < (bar_width - whole_width - 1); ++i) - os << " "; - return os; - } - -private: - std::ostream &os; - size_t bar_width = 0; -}; - -class ProgressScaleWriter { -public: - ProgressScaleWriter(std::ostream &os, size_t bar_width, const std::string &fill, - const std::string &lead, const std::string &remainder) - : os(os), bar_width(bar_width), fill(fill), lead(lead), remainder(remainder) {} - - std::ostream &write(float progress) { - auto pos = static_cast(progress * bar_width / 100.0); - for (size_t i = 0, current_display_width = 0; i < bar_width;) { - std::string next; - - if (i < pos) { - next = fill; - current_display_width = unicode::display_width(fill); - } else if (i == pos) { - next = lead; - current_display_width = unicode::display_width(lead); - } else { - next = remainder; - current_display_width = unicode::display_width(remainder); - } - - i += current_display_width; - - if (i > bar_width) { - // `next` is larger than the allowed bar width - // fill with empty space instead - os << std::string((bar_width - (i - current_display_width)), ' '); - break; - } - - os << next; - } - return os; - } - -private: - std::ostream &os; - size_t bar_width = 0; - std::string fill; - std::string lead; - std::string remainder; -}; - -class IndeterminateProgressScaleWriter { -public: - IndeterminateProgressScaleWriter(std::ostream &os, size_t bar_width, const std::string &fill, - const std::string &lead) - : os(os), bar_width(bar_width), fill(fill), lead(lead) {} - - std::ostream &write(size_t progress) { - for (size_t i = 0; i < bar_width;) { - std::string next; - size_t current_display_width = 0; - - if (i < progress) { - next = fill; - current_display_width = unicode::display_width(fill); - } else if (i == progress) { - next = lead; - current_display_width = unicode::display_width(lead); - } else { - next = fill; - current_display_width = unicode::display_width(fill); - } - - i += current_display_width; - - if (i > bar_width) { - // `next` is larger than the allowed bar width - // fill with empty space instead - os << std::string((bar_width - (i - current_display_width)), ' '); - break; - } - - os << next; - } - return os; - } - -private: - std::ostream &os; - size_t bar_width = 0; - std::string fill; - std::string lead; -}; - -} // namespace details -} // namespace indicators - -#endif #include #include @@ -3274,49 +1909,6 @@ private: // #include // #include // #include -#ifndef INDICATORS_TERMINAL_SIZE -#define INDICATORS_TERMINAL_SIZE -#include - - -#if defined(_WIN32) -#include - -namespace indicators { - -static inline std::pair terminal_size() { - CONSOLE_SCREEN_BUFFER_INFO csbi; - int cols, rows; - GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi); - cols = csbi.srWindow.Right - csbi.srWindow.Left + 1; - rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1; - return {static_cast(rows), static_cast(cols)}; -} - -static inline size_t terminal_width() { return terminal_size().second; } - -} // namespace indicators - -#else - -#include //ioctl() and TIOCGWINSZ -#include // for STDOUT_FILENO - -namespace indicators { - -static inline std::pair terminal_size() { - struct winsize size{}; - ioctl(STDOUT_FILENO, TIOCGWINSZ, &size); - return {static_cast(size.ws_row), static_cast(size.ws_col)}; -} - -static inline size_t terminal_width() { return terminal_size().second; } - -} // namespace indicators - -#endif - -#endif #include #include #include @@ -4205,55 +2797,6 @@ public: // #include // #include -#ifndef INDICATORS_CURSOR_MOVEMENT -#define INDICATORS_CURSOR_MOVEMENT - -#if defined(_MSC_VER) -#if !defined(NOMINMAX) -#define NOMINMAX -#endif -#include -#include -#else -#include -#endif - -namespace indicators { - -#ifdef _MSC_VER - -static inline void move(int x, int y) { - auto hStdout = GetStdHandle(STD_OUTPUT_HANDLE); - if (!hStdout) - return; - - CONSOLE_SCREEN_BUFFER_INFO csbiInfo; - GetConsoleScreenBufferInfo(hStdout, &csbiInfo); - - COORD cursor; - - cursor.X = csbiInfo.dwCursorPosition.X + x; - cursor.Y = csbiInfo.dwCursorPosition.Y + y; - SetConsoleCursorPosition(hStdout, cursor); -} - -static inline void move_up(int lines) { move(0, -lines); } -static inline void move_down(int lines) { move(0, -lines); } -static inline void move_right(int cols) { move(cols, 0); } -static inline void move_left(int cols) { move(-cols, 0); } - -#else - -static inline void move_up(int lines) { std::cout << "\033[" << lines << "A"; } -static inline void move_down(int lines) { std::cout << "\033[" << lines << "B"; } -static inline void move_right(int cols) { std::cout << "\033[" << cols << "C"; } -static inline void move_left(int cols) { std::cout << "\033[" << cols << "D"; } - -#endif - -} // namespace indicators - -#endif // #include namespace indicators { @@ -4335,71 +2878,6 @@ public: // #include // #include // #include -#ifndef INDICATORS_CURSOR_CONTROL -#define INDICATORS_CURSOR_CONTROL - -#if defined(_MSC_VER) -#if !defined(NOMINMAX) -#define NOMINMAX -#endif -#include -#include -#else -#include -#endif - -namespace indicators { - -#if defined(_MSC_VER) - -static inline void show_console_cursor(bool const show) { - HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE); - - CONSOLE_CURSOR_INFO cursorInfo; - - GetConsoleCursorInfo(out, &cursorInfo); - cursorInfo.bVisible = show; // set the cursor visibility - SetConsoleCursorInfo(out, &cursorInfo); -} - -static inline void erase_line() { - auto hStdout = GetStdHandle(STD_OUTPUT_HANDLE); - if (!hStdout) - return; - - CONSOLE_SCREEN_BUFFER_INFO csbiInfo; - GetConsoleScreenBufferInfo(hStdout, &csbiInfo); - - COORD cursor; - - cursor.X = 0; - cursor.Y = csbiInfo.dwCursorPosition.Y; - - DWORD count = 0; - - FillConsoleOutputCharacterA(hStdout, ' ', csbiInfo.dwSize.X, cursor, &count); - - FillConsoleOutputAttribute(hStdout, csbiInfo.wAttributes, csbiInfo.dwSize.X, - cursor, &count); - - SetConsoleCursorPosition(hStdout, cursor); -} - -#else - -static inline void show_console_cursor(bool const show) { - std::fputs(show ? "\033[?25h" : "\033[?25l", stdout); -} - -static inline void erase_line() { - std::fputs("\r\033[K", stdout); -} - -#endif - -} // namespace indicators - -#endif // #include // #include #include