## 20.2 ユーザー定義の型の特性とファセットの定義

ユーザー定義の型には、特性クラス、コード変換ファセット、文字分類ファセットがそれぞれに必要です。特性クラスでは、変換 `state_type` を定義し、さらに、型の配列のコピーや配列の比較などの演算を定義します。コード変換ファセットでは、単純な `char` との変換機能を提供します。`ctype` ファセットには、新しい型と単純 `char` との変換用のメソッドなどの文字分類ルーチンと操作ルーチンがあります。

次のコードは、`Echar` の特性クラス宣言を示したものです。

>     struct Etraits
>     {
>       typedef Echar                char_type;
>       typedef long                 int_type;

>       typedef long                 off_type;
>       typedef mbstate_t            state_type;
>       typedef fpos<state_type>     pos_type;

>       static void assign (char_type& c1, const char_type& c2);
>       static bool eq(const char_type& c1,const char_type& c2);
>       static bool lt (const char_type& c1, const char_type& c2);
>       static int compare (const char_type* s1, const char_type* s2,
>                           size_t n);
>       static size_t length(const char_type *s);
>       static const char_type*
>           find (const char_type* s, int n, const char_type& a);
>       static char_type* move (char_type* s1, const char_type* s2,
>                               size_t n);
>       static char_type* copy(char_type *dst,const char_type *src,
>                               size_t n);
>       static char_type* assign (char_type* s, size_t n,
>                                  const char_type& a);
>       static int_type not_eof(const int_type& c);
>       static char_type to_char_type(const int_type& c);
>       static int_type to_int_type(const char_type& c);
>       static bool eq_int_type(const int_type& c1,const int_type& c2);
>       static state_type get_state(pos_type pos);
>       static int_type eof();
>     };

特性クラスのメンバー関数の詳細については、『標準 C++ クラスライブラリ・リファレンス 』の `char_traits` の節を参照してください。

新しいコード変換ファセットを作成するには、`codecvt` テンプレートから情報を継承し、すべての限定公開の仮想関数に実装を提供します。`codecvt` に定義された公開インタフェースを通じて、入出力ストリームは限定公開の関数を呼び出します。また、単一の `size_t` 引数を使用して、その引数で `codecvt` を初期化するコンストラクタも用意する必要があります。

`Echar` 用のコード変換ファセットには、次のような宣言部があります。

>     class Ecodecvt : public codecvt<Echar,char,Estate>
>     {
>       public:
>            _EXPLICIT Ecodecvt (size_t refs = 0) :
>                codecvt<Echar,char,Estate>(refs) {;}

>       protected:
>               virtual ~Ecodecvt() {;}
>               virtual result do_out(Estate& state, const Echar* from,
>                                     const Echar* from_end,
>                                     const Echar*& from_next,
>                                     char* to, char* to_limit,
>                                     char*& to_next) const;
>              virtual result do_in(Estate& state,
>                                   const char* from,
>                                   const char* from_end,
>                                   const char*& from_next,
>                                   Echar* to, Echar* to_limit,
>                                   Echar*& to_next) const;
>              virtual result do_unshift(Estate& state,
>                                        char* to, char* to_limit,
>                                        char*& to_next) const;
>              virtual int do_encoding() const throw();
>              virtual bool do_always_noconv() const throw();
>              virtual int do_length(const Estate&, const char* from,
>                                    const char* end, size_t maxm) const;
>              virtual int do_max_length() const throw();
>       };

コード変換ファセットの定義の詳細については、第 19 章を参照してください。メンバー関数の示唆については、『標準 C++ クラスライブラリ・リファレンス 』の `codecvt` の節を参照してください。

文字分類ファセットを作成するには、`ctype` テンプレートから情報を継承し、すべての限定公開の仮想関数に実装を提供します。また、単一の `size_t` 引数を使用して、その引数で `ctype` を初期化するコンストラクタも用意する必要があります。

`widen` 関数では、単純 `char` からユーザー定義の文字型への変換を定義します。narrow 関数には、ユーザー定義型から単純 `char` への変換機能があります。

`Echar` の文字分類ファセットには次のような宣言部があります。

>     class Ectype : public ctype<Echar>
>     {
>          public:
>            typedef Echar char_type;
>            _EXPLICIT Ectype (size_t refs = 0) :
>                ctype<Echar>(refs) {;}         // refs を ctype コンストラクタに
>                                               // 必ず渡す必要がある

>          protected:
>            inline virtual ~Ectype ();
>            virtual bool do_is(mask m, Echar c) const;
>            virtual const Echar* do_is(
>                                       const Echar* low,
>                                       const Echar* high,
>                                       mask* vec) const;
>            virtual const Echar* do_scan_is(
>                                            mask m, const Echar* low,
>                                            const Echar* high) const;
>            virtual const Echar* do_scan_not(
>                                             mask m, const Echar* low,
>                                             const Echar* high) const;
>            virtual Echar        do_toupper(Echar e)  const;
>            virtual const Echar* do_toupper(Echar* low,
>                                            const Echar* high) const;
>            virtual Echar        do_tolower(Echar)  const;
>            virtual const Echar* do_tolower(Echar* low,
>                                            const Echar* high) const;
>            virtual Echar        do_widen(char) const;
>            virtual const char*  do_widen(const char* lo,
>                                          const char* hi,
>                                          Echar* dest) const;
>            virtual char         do_narrow(Echar, char dfault) const;
>            virtual const Echar* do_narrow(const Echar* lo,
>                                           const Echar* hi,char dfault,
>                                           char* dest) const;

>     };

Copyright (c) 1998, Rogue Wave Software, Inc.
このマニュアルに関する誤りのご指摘やご質問は、電子メールにてお送りください。

OEM リリース, 1998 年 6 月