ICU 結合文字かを判定する

ICUライブラリを使って、一つのコードポイントが結合文字(Combining Character)かを判定するコードです。

#include <string>
#include <stdexcept>
#include <unicode/normalizer2.h>
 
// 結合文字か判定する
bool is_combining_character(char32_t codeunit)
{
    UErrorCode error_code = U_ZERO_ERROR;
    const icu::Normalizer2* normalizer = icu::Normalizer2::getNFCInstance(error_code);
    if (U_FAILURE(error_code)) {
        throw std::runtime_error(
                std::string("failed icu::Normalizer2::getNFCInstance() : ")
                  + u_errorName(error_code));
    }
 
    return normalizer->getCombiningClass(UChar32(codeunit)) > 0;
}
 
#include <iostream>
int main()
{
    std::cout << std::boolalpha;
    std::cout << is_combining_character(U'a') << std::endl;          // false
    std::cout << is_combining_character(U'\U0000032F') << std::endl; // true
    std::cout << is_combining_character(U' ̎') << std::endl;          // true
}

いま作ってるエンコード文字列クラスで、コードポイントのインタフェースだけでなく、文字のインタフェースを用意しようと思ってるので、この関数はそのための部品。

ICUを使った機能は、オプションとして提供するつもりです。

ICUを使って実装する機能は、これと正規化