| 829 | // |
| 830 | |
| 831 | std::string unicode_cpt_to_utf8(uint32_t cpt) { |
| 832 | std::string result; |
| 833 | |
| 834 | if (/* 0x00 <= cpt && */ cpt <= 0x7f) { |
| 835 | result.push_back(cpt); |
| 836 | return result; |
| 837 | } |
| 838 | if (0x80 <= cpt && cpt <= 0x7ff) { |
| 839 | result.push_back(0xc0 | ((cpt >> 6) & 0x1f)); |
| 840 | result.push_back(0x80 | (cpt & 0x3f)); |
| 841 | return result; |
| 842 | } |
| 843 | if (0x800 <= cpt && cpt <= 0xffff) { |
| 844 | result.push_back(0xe0 | ((cpt >> 12) & 0x0f)); |
| 845 | result.push_back(0x80 | ((cpt >> 6) & 0x3f)); |
| 846 | result.push_back(0x80 | (cpt & 0x3f)); |
| 847 | return result; |
| 848 | } |
| 849 | if (0x10000 <= cpt && cpt <= 0x10ffff) { |
| 850 | result.push_back(0xf0 | ((cpt >> 18) & 0x07)); |
| 851 | result.push_back(0x80 | ((cpt >> 12) & 0x3f)); |
| 852 | result.push_back(0x80 | ((cpt >> 6) & 0x3f)); |
| 853 | result.push_back(0x80 | (cpt & 0x3f)); |
| 854 | return result; |
| 855 | } |
| 856 | |
| 857 | throw std::invalid_argument("invalid codepoint"); |
| 858 | } |
| 859 | |
| 860 | std::vector<uint32_t> unicode_cpts_normalize_nfd(const std::vector<uint32_t> & cpts) { |
| 861 | auto comp = [] (const uint32_t cpt, const range_nfd & range) { |