ctype with comment
#ifndef ASCII_CTYPE_H
#define ASCII_CTYPE_H
#define ASCIIRANGE(c, start, len) (char32_t((c) - (start)) < char32_t(len))
inline bool aislower(char32_t c) { return ASCIIRANGE(c, 0x61, 26); }
// {97,122} A-Z
inline bool aisupper(char32_t c) { return ASCIIRANGE(c, 0x41, 26); }
// {65,90} a-z
inline bool aisdigit(char32_t c) { return ASCIIRANGE(c, 0x30, 10); }
// {48,57} 0-9
inline bool aisbdigit(char32_t c) { return ASCIIRANGE(c, 0x30, 2); }
// {48,49}
inline bool aisodigit(char32_t c) { return ASCIIRANGE(c, 0x30, 8); }
// {48,55}
inline bool aisxdigit(char32_t c) { return ASCIIRANGE(c | 32, 0x61, 6) || aisdigit(c); }
// {48,57} {97,102} {65,70} 0-9a-fA-F
inline bool aisalpha(char32_t c) { return ASCIIRANGE(c | 32, 0x61, 26); }
// {65,90} {97,122} a-zA-Z
inline bool aisprint(char32_t c) { return ASCIIRANGE(c, 0x20, 95); }
// printable ascii
inline bool aisgraph(char32_t c) { return ASCIIRANGE(c, 0x21, 94); }
// printable ascii without space / visible ascii
inline bool aisspace(char32_t c) { return ASCIIRANGE(c, 0x9, 5) || c == 0x20; }
// {9,13}
inline bool aisalnum(char32_t c) { return aisalpha(c) || aisdigit(c); }
// latin letter or digit 0-9a-zA-Z
inline bool aispunct(char32_t c) { return !aisalnum(c) && aisgraph(c); }
// visible letter excluding 0-9a-zA-Z
inline bool aisblank(char32_t c) { return c == 0x20 || c == 0x9; }
// space or tab
inline bool aiscntrl(char32_t c) { return c < 0x20 || c == 0x7f; }
// 127 or {0,31}
inline char32_t atolower(char32_t c) { return isupper(c) ? c + 0x20 : c; }
// u->l o->o
inline char32_t atoupper(char32_t c) { return islower(c) ? c - 0x20 : c; }
// l->u o->o
#undef ASCIIRANGE
#endif