1 // utakataで利用される、Unicode文字及び文字列を統合して扱うことが
2 // 可能である、Unicodeオブジェクトを定義します。
3 // UniCharは、Unicode文字1文字に対応し、各種オペレータオーバロードを
4 // 提供し、組込型と同様な利用ができるようになっています。
5 // UniStringは、UniCharを集めたUnicode文字列を表現し、UniChar単位での
7 #ifndef _UTAKATA_SRC_UNICODE_H_
8 #define _UTAKATA_SRC_UNICODE_H_
14 #include "lib/range.h"
19 typedef unsigned int unicode_t;
21 // Unicode一文字を表現するためのオブジェクトです。
22 // unicodeはunsigned intで表現され、組込型と同様の利用ができるように
24 // 各operator overloadは、同様の機能を提供する各関数によって機能が
25 // 実装されており、各operator overloadを利用しないことも可能です。
26 class UniChar : private akebono::crtp::less_than_comparable<UniChar>,
27 private akebono::crtp::equal_comparable<UniChar> {
30 // Schemeシステム内で最大値となるUnicode値です。この値以上の
32 static const unsigned int kOutOfUnicode = 0x110000;
33 static const unsigned int kExclusionMin = 0xD800;
34 static const unsigned int kExclusionMax = 0xDFFF;
36 UniChar() : rawcode_(0x0000) {}
39 UniChar(const UniChar& ch) : rawcode_(ch.rawcode_) {}
40 explicit UniChar(unicode_t code) : rawcode_(code) {}
42 UniChar& operator=(const UniChar& ch) {
48 // Equalのコメントを参照してください。
49 bool operator==(const UniChar& code) const {return rawcode_ == code.rawcode_;}
51 // Lessのコメントを参照してください。
52 bool operator<(const UniChar& code) const {return rawcode_ < code.rawcode_;}
54 // 内部で保持している、実際のunicodeの値を返します。
55 unicode_t rawcode() const {return rawcode_;}
59 // 渡されたchのrawcodeを交換します。
60 void swap(UniChar& ch) {
61 std::swap(rawcode_, ch.rawcode_);
67 // 渡されたUniCharが、ascii文字の範囲内である場合、trueを返します。
68 inline bool IsAscii(const UniChar& unichar) {
69 return unichar.rawcode() >= 0 && unichar.rawcode() <= 0x7F;
72 // 渡されたUniCharが、数値項目に該当しているかを返します。
73 inline bool IsNumeric(const UniChar& unichar) {
74 return ('0' <= unichar.rawcode() && unichar.rawcode() <= '9');
77 // 渡されたUniCharが、小文字のアルファベットに該当しているかどうかを返します。
78 inline bool IsAlphabetUpperCase(const UniChar& unichar) {
79 return ('A' <= unichar.rawcode() && unichar.rawcode() <= 'Z');
82 // 渡されたUniCharが、大文字のアルファベットに該当しているかどうかを返します。
83 inline bool IsAlphabetLowerCase(const UniChar& unichar) {
84 return ('a' <= unichar.rawcode() && unichar.rawcode() <= 'z');
87 // 渡されたUniCharが、アルファベットに該当しているかどうかを返します。
89 inline bool IsAlphabet(const UniChar& unichar) {
90 return IsAlphabetLowerCase(unichar) || IsAlphabetUpperCase(unichar);
93 // 渡されたUniCharが、unicodeの有効範囲である場合trueを返します。
94 inline bool IsValidUnicode(const UniChar& unichar) {
95 return UniChar::kOutOfUnicode > unichar.rawcode() &&
96 !(UniChar::kExclusionMin <= unichar.rawcode() &&
97 unichar.rawcode() <= UniChar::kExclusionMax);
101 // UniCharを連結したコンテナのラッパーとして機能し、擬似的な
103 // 相互での比較などもサポートし、utakataの内部全般で
104 // 標準として使用することが想定されています。
105 // また、内部へのiteratorを取得することができるため、標準
106 // アルゴリズムを利用することができます。
107 class UniString : private akebono::crtp::less_than_comparable<UniString>,
108 private akebono::crtp::equal_comparable<UniString> {
110 // 内部で利用されるiteratorを定義します。
111 typedef std::vector<UniChar>::iterator iterator;
112 typedef std::vector<UniChar>::const_iterator const_iterator;
114 UniString() : unicode_chars_() {}
115 // 第一引数のchをnum個数分の文字列で初期化します。
116 UniString(const UniChar& ch, int num) : unicode_chars_(num, ch) {}
118 UniString(const UniString& str) : unicode_chars_(str.unicode_chars_) {}
120 // 複数のunsigned intをUniCharとして変換し、文字列を構成します。
121 explicit UniString(const std::vector<unsigned int>& multis);
123 // std::stringの限定的な変換を行います。この時、内部バイトは意識されず、
124 // 単純にstd::stringの一文字をUniStringの一文字として、単純に変換します。
125 explicit UniString(const std::string& str);
126 virtual ~UniString() {}
128 // 渡されたUniCharを、numだけ連続した文字列を代入します。
129 // assignでは、代入前の値は破棄されます。
130 void Assign(const UniChar& ch, int num);
132 // 渡したUniStringをコピーします。コピー前の値は破棄されます。
133 void Assign(const UniString& str);
135 // 複数のunsigned intをUniCharとして変換し、文字列を構成します。
136 // また、この関数はコンストラクタの内部で利用されます。
137 void Assign(const std::vector<unsigned int>& multis);
139 // std::stringの限定的な変換を行います。この時、内部バイトは意識されず、
140 // 単純にstd::stringの一文字をUniStringの一文字として、単純に変換します。
141 // また、この関数はコンストラクタの内部で利用されます。
142 void Assign(const std::string& str);
144 // 文字列の先頭を指すiteratorを取得します。
145 const_iterator Begin() const {return unicode_chars_.begin();}
146 iterator Begin() {return unicode_chars_.begin();}
148 // 文字列の末尾を指すiteratorを取得します。
149 const_iterator End() const {return unicode_chars_.end();}
150 iterator End() {return unicode_chars_.end();}
152 // 指定したインデックスのデータを取得します。
153 // インデックスが有効では無い場合、std::range_error例外が
155 const UniChar& At(size_t index) const {return unicode_chars_.at(index);}
156 UniChar& At(size_t index) {
157 return const_cast<UniChar&>(
158 static_cast<const UniString*>(this)->At(index));
162 size_t GetSize() const {return unicode_chars_.size();}
164 // 文字列が空である場合にtrueを返します。
165 bool IsEmpty() const {return unicode_chars_.empty();}
167 // 渡されたUniStringをコピーします。
168 UniString& operator=(const UniString& str);
170 // 渡されたデータを、それぞれUniStringの末尾に追加します。
171 void Append(const UniString& str);
172 void Append(const UniChar& ch);
174 // 渡されたUniStringと内容が完全に一致している場合trueを返します。
175 // ここでの完全一致とは、文字列長と文字列の内容が完全に一致している
177 bool operator==(const UniString& str) const;
179 // 渡されたUniStringの先頭から比較していき、先頭から一致しているか、
180 // それ以外が < である場合、trueを返します。
181 bool operator<(const UniString& str) const;
183 // itの位置に、[begin, last)のデータを挿入します。
184 // beginとlastが異なるUniStringのiteratorであってはなりません。
185 void Insert(iterator It, iterator begin, iterator Last);
186 void Insert(iterator it, const_iterator begin, const_iterator last);
190 // 渡されたUniStringのデータを入れ替えます。
191 void Swap(UniString& str) {std::swap(unicode_chars_, str.unicode_chars_);}
193 // UniCharのコンテナです。擬似的な文字列を表現します。
194 std::vector<UniChar> unicode_chars_;
199 // utakata::unicode名前空間内で利用される、コンテナからUniStringへの
200 // 変換を行うための関数オブジェクトです。
202 struct UnicodeConverter : public std::unary_function<T, void> {
203 UnicodeConverter(UniString& string)
206 // 渡されたデータを、UniCharに変換語、string_の末尾に追加していきます。
207 void operator()(const T& t) {
208 string_.Append(utakata::unicode::UniChar(static_cast<unicode_t>(t)));
213 // 渡された型をUnicodeConverterのテンプレート引数として利用し、UnicodeConverterを生成します。
214 // この時、TはT::value_typeを保持している必要があります。
215 template <typename T>
216 utakata::unicode::detail::UnicodeConverter<typename T::value_type>
217 MakeConverter(const T& container, unicode::UniString& string) {
218 return utakata::unicode::detail::UnicodeConverter<typename T::value_type>(string);
222 // 渡されたUnicodeから、beginの位置から末尾までの文字列をUniStringで返します。
223 // beginが有効範囲外であった場合、std::range_eror例外が発生します。
224 UniString Substring(const UniString& str, unsigned int begin);
226 // 渡されたUnicodeから、[begin, end)の範囲の文字列を取得します。
227 // beginがend以降であったり、endがbegin以前である場合、空のUniStringが
229 // begin、endのいずれかが有効範囲外であった場合、std::range_error例外が
231 UniString Substring(const UniString& str, unsigned int begin, unsigned int end);
233 // 渡されたunicode_tの配列を、一要素が一UniCharであるとしてUniStringを作成
235 UniString Convert(const std::vector<unicode_t>& byte_list);
237 // 渡したstd::stringを、一文字を一UniCharであるとしてUniStringを作成して
238 // 返します。std::stringのエンコードは無視されます。
239 UniString Convert(const std::string& target);
241 // 渡されたUniStringを、std::stringに変換します。変換規則は、UniStringの
242 // 一文字を、std::stringの1文字として強制的に変換します。
243 std::string Convert(const UniString& string);
245 // 渡されたデータを、targetの末尾に追加します。
246 // この時、T は akebono::range::for_eachの引数として渡せるものである場合、
248 // T として渡された型は、akebono::rangeの関数が適用可能である必要があります。
249 template <typename T>
250 bool Append(UniString& target, const T& multis) {
251 akebono::range::for_each(
252 multis, unicode::detail::MakeConverter(multis, target));
256 // lib/range.hを利用する際に必要となるbeginとendの特殊化関数を定義します。
258 inline UniString::iterator begin(UniString& c) {return c.Begin();}
260 inline UniString::const_iterator begin(const UniString& c) {return c.Begin();}
262 inline UniString::iterator end(UniString& c) {return c.End();}
264 inline UniString::const_iterator end(const UniString& c) {return c.End();}
268 #endif /* _UTAKATA_SRC_UNICODE_H_ */