char32_tとXpressiveと

H.23/11/05
Egtra
Boost.勉強会#6 札幌
char32_tとXpressiveと

• Egtra
  – @egtra
 – http://dev.activebasic.com/egtra/
char32_t……

• とchar16_t
  – C++11の新しいデータ型
  – typedefではない
  – UTF‐32とUTF‐16
  – 4バイトと2バイト
char32_tとchar16_t

• 新しいデータ型
  – void f(char c);
  – void f(wchar_t c);
  – void f(char16_t c);
  – void f(char32_t c);
char32_tとchar16_t

• リテラル
  – char c = 'a';
  – wchar_t c = L'a';
  – char16_t c = u'a';
  – char32_t c = U'a';
char32_tとchar16_t

• リテラル
  – char s1[] = "hoge";
  – wchar_t s2[] = L"hoge";
  – char16_t s3[] = u"hoge";
  – char32_t s4[] = U"hoge";
  – char s5[] = u8"hoge";
char32_tとchar16_t

• リテラル
  – char const* s1 = "foo";
  – wchar_t const* s2 = L"foo";
  – char16_t const* s3 = u"foo";
  – char32_t const* s4 = U"foo";
  – char const* s5 = u8"foo";
char32_tとchar16_t

• std::basic_string<>
  – std::string
  – std::wstring
  – std::u16string
  – std::u32string
char32_tとchar16_t

• どこで使える?
  – GCC 4.4/4.5
  – Clang 2.9
  – Visual C++ 2010?
char32_tとchar16_t

• Visual C++ 2010
  – typedef!!!
  – v11(次バージョン)でも変わらず

 – u""やU""やu8""も非対応
char32_tとchar16_t

• 以上
  – 君も今日からchar16/32_t使い
  – UTF‐16/32なデータのところに
    char16/32_t使おう!
char32_tとchar16_t

• 以上
  – 君も今日からchar16/32_t使い
  – 私は使っていません
    •Visual C++ 2010なので……
char32_tとchar16_t

• 以上と思った?
  – 足りないものだらけですね
char32_tとchar16_t (続)

• 入出力
  – u16streamとかu32streamとか
    ありません
  – 適当にtypedefしましょう
char32_tとchar16_t (続)

• <codecvt>
  – codecvt_utf8
   •UTF‐8とUTF‐32
 – codecvt_utf16
   •UTF‐16とUTF‐32
 – codecvt_utf8_utf16
char32_tとchar16_t (続)
• UTF‐8のファイルをchar32_tとして読む
 typedef basic_ifstream<char32_t>
   u32ifstream;
 u32ifstream ifs("hoge.txt");
 locale loc(locale(),
   new codecvt_utf8<char32_t>());
 ifs.imbue(loc);
char32_tとchar16_t (続)
• UTF‐8のファイルをchar32_tとして読む
 typedef basic_ifstream<char32_t>
   u32ifstream;
 u32ifstream ifs("hoge.txt");
 – 実はこれでいける(はず)
char32_tとchar16_t (続)

• なぜ? std::locale::classic()
  – 下を持っている
    •codecvt<char, wchar_t>
    •codecvt<char, char16_t>
    •codecvt<char, char32_t>
char32_tとchar16_t (続)

• 特殊化
 codecvt<char, char16_t>
 codecvt<char, char32_t>
 – UTF‐8とUTF‐16/32との変換
 – これで揃った?
char32_tとchar16_t (続)

• codecvtで可能な変換
  – char(マルチバイト)
     ⇄ wchar_t (C++98/03)
  – char (UTF‐8) ⇄ UTF‐16
  – char (UTF‐8) ⇄ UTF‐32
  – UTF‐16 ⇄ UTF‐32
char32_tとchar16_t (続)

• マルチバイトとUTFの変換は?


 –ない!

 – iconvなどを使いましょう
char32_tとchar16_t (続)

• wchar_tは?
  – UTF‐16/32とは限らない
     •例: ja_JP.eucJPな*BSD
char32_tとchar16_t (続)

• マルチバイトとUTFの変換は?
  – 解その2: Boost.Locale?
    •今回は説明しません
char32_tとchar16_t (続)

• std::basic_regex<>
  – charとwchar_t版しかありません
     •なのでBoost.Regex(ICU版)を
      使いましょう
char32_tとchar16_t (続)

• 以上
おまけ

• Boost.XpressiveでUTF‐32の
 文字列を使いたい
 – やっつけで対応させた
おまけ

• traitsクラスを作る
  – やっつけなので
    null_regex_traits<char32_t>
    から派生
  struct u32_traits : …… {
おまけ

• traitsクラスを作る
    struct locale_type {};
おまけ

• traitsクラスを作る
    enum char_class {
     InvalidClass = 0,
     Lu = 1,
     Ll = 1 << 1,
     ……
おまけ

• traitsクラスを作る
     NewLine = 1 << ……,
    };
    typedef boost::uint_value_t<
     NewLine>::least_t
     char_class_type;
おまけ

• traitsクラスを作る
  private:
    static std::unordered_map<
     char_type, char_class_type>
     LoadCategoryMap();
  – isctype内で使用
おまけ

• traitsクラスを作る
 namespace Property {
  boost::proto::terminal<
   boost::xpressive::detail::
   posix_charset_placeholder>::type
   const L = {{"L", false}};
 ……

char32_tとXpressiveと