YSTest  PreAlpha_b500_20140530
The YSLib Test Project
 全部  命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义  
smap.hpp
浏览该文件的文档.
1 /*
2  © 2009-2014 FrankHB.
3 
4  This file is part of the YSLib project, and may only be used,
5  modified, and distributed under the terms of the YSLib project
6  license, LICENSE.TXT. By continuing to use, modify, or distribute
7  this file you indicate that you have read the license and
8  understand and accept it fully.
9 */
10 
28 #ifndef INC_CHRLib_smap_hpp_
29 #define INC_CHRLib_smap_hpp_ 1
30 
31 #include "YModules.h"
32 #include YFM_CHRLib_CharacterMapping
33 #include <ystdex/cstdio.h>
34 #include <ystdex/any.h> // for ystdex::pseudo_object;
35 
36 namespace CHRLib
37 {
38 
43 template<typename _tIn, typename _tState>
44 inline bool
45 FillByte(_tIn& i, _tState& st)
46 {
47  static_assert(std::is_constructible<const byte, decltype(*i)>::value,
48  "Invalid mapping source type found.");
49  static_assert(!std::is_volatile<ystdex::remove_reference_t<_tState>>::value,
50  "Volatile state is not supported.");
51 
53  return false;
54 
55  const byte r(*i);
56 
57  yunseq(++i, GetSequenceOf(st)[GetCountOf(st)++] = r);
58  return true;
59 }
60 
61 
67 template<Encoding>
69 {};
70 
71 template<>
72 struct GUCS2Mapper<CharSet::UTF_8>
73 {
78  static yconstfn bool
80  {
81  return b == 0xC0 || b == 0xC1 || b > 0xF4;
82  }
83 
92  template<typename _tObj, typename _tIn, typename _tState>
93  static ConversionResult
94  Map(_tObj& uc, _tIn&& i, _tState&& st)
95  {
96  const auto seq(GetSequenceOf(st));
97 
98  switch(GetCountOf(st))
99  {
100  case 0:
101  if(YB_UNLIKELY(!FillByte(i, st)))
103  if(seq[0] < 0x80)
104  {
105  uc = seq[0];
106  break;
107  }
108  if(YB_UNLIKELY(IsInvalid(seq[0]) || ((seq[0] & 0xC0) != 0xC0)))
110  case 1:
111  if(YB_UNLIKELY(!FillByte(i, st)))
113  if(YB_UNLIKELY(IsInvalid(seq[1]) || ((seq[1] & 0xC0) != 0x80)))
115  if(((seq[0] ^ 0xC0) & 0xE0) == 0)
116  {
117  uc = ((seq[0] & 0x1C) >> 2 << 8)
118  | ((seq[0] & 0x03) << 6)
119  | (seq[1] & 0x3F);
120  break;
121  }
122  case 2:
123  if(YB_UNLIKELY(!FillByte(i, st)))
125  if(YB_UNLIKELY(IsInvalid(seq[2]) || ((seq[2] & 0xC0) != 0x80)))
127  if(((seq[0] ^ 0xE0) & 0xF0) == 0)
128  {
129  uc = (((seq[0] & 0x0F) << 4 | (seq[1] & 0x3C) >> 2) << 8)
130  | ((seq[1] & 0x3) << 6) | (seq[2] & 0x3F);
131  break;
132  }
133  case 3:
134  if(YB_UNLIKELY(!FillByte(i, st)))
136  if(YB_UNLIKELY(IsInvalid(seq[3]) || ((seq[3] & 0xC0) != 0x80)))
138  if(YB_LIKELY(((seq[0] ^ 0xF0) & 0xF8) == 0))
139  {
140  uc = (((seq[0] & 0x0F) << 4 | (seq[1] & 0x3C) >> 2) << 8)
141  | ((seq[1] & 0x3) << 6) | (seq[2] & 0x3F);
142  break;
143  }
145  default:
147  }
148  return ConversionResult::OK;
149  }
150 
151  template<typename _tOut>
152  static byte
153  InverseMap(_tOut d, const ucs2_t& s)
154  {
155  size_t l(0);
156 
157  if(s < 0x80)
158  {
159  *d = s;
160  return 1;
161  }
162  if(s < 0x800)
163  l = 2;
164  else
165  {
166  *d = 0xE0 | s >> 12;
167  ++d;
168  l = 3;
169  }
170  *d = 0x80 | (s >> 6 & 0x3F);
171  *++d = 0x80 | (s & 0x3F);
172  return l;
173  }
174 };
175 
176 template<>
177 struct GUCS2Mapper<CharSet::UTF_16BE>
178 {
179  template<typename _tObj, typename _tIn, typename _tState>
180  static ConversionResult
181  Map(_tObj& uc, _tIn&& i, _tState&& st)
182  {
183  const auto seq(GetSequenceOf(st));
184 
185  switch(GetCountOf(st))
186  {
187  case 0:
188  if(YB_UNLIKELY(!FillByte(i, st)))
190  case 1:
191  if(YB_UNLIKELY(!FillByte(i, st)))
193  uc = seq[0] << 8 | seq[1];
194  break;
195  default:
197  }
198  return ConversionResult::OK;
199  }
200 };
201 
202 template<>
203 struct GUCS2Mapper<CharSet::UTF_16LE>
204 {
205  template<typename _tObj, typename _tIn, typename _tState>
206  static ConversionResult
207  Map(_tObj& uc, _tIn&& i, _tState&& st)
208  {
209  const auto seq(GetSequenceOf(st));
210 
211  switch(GetCountOf(st))
212  {
213  case 0:
214  if(YB_UNLIKELY(!FillByte(i, st)))
216  case 1:
217  if(YB_UNLIKELY(!FillByte(i, st)))
219  uc = seq[0] | seq[1] << 8;
220  break;
221  default:
223  }
224  return ConversionResult::OK;
225  }
226 };
228 
229 
235 template<Encoding, typename... _tParams>
237 UCS2Mapper_Map(_tParams&&...)
238 {
240 }
241 template<Encoding _vEnc, typename _tDst, typename _tSrc, typename _tState>
243 UCS2Mapper_Map(_tDst&& d, _tSrc&& s, _tState&& st, decltype(
244  &GUCS2Mapper<_vEnc>::template Map<_tDst, _tSrc, _tState>) = {})
245 {
246  return GUCS2Mapper<_vEnc>::Map(d, s, st);
247 }
248 
249 template<Encoding _vEnc, typename _tDst, typename _tSrc>
252 {
253  return 0;
254 }
255 template<Encoding _vEnc, typename _tDst>
257 UCS2Mapper_InverseMap(_tDst&& d, const ucs2_t& s,
258  decltype(&GUCS2Mapper<_vEnc>::template InverseMap<_tDst>) = {})
259 {
260  return GUCS2Mapper<_vEnc>::InverseMap(d, s);
261 }
262 
263 
264 template<Encoding _vEnc, typename _tIn, typename _tState>
266 UCS2Mapper(ucs2_t& uc, _tIn&& i, _tState&& st)
267 {
268  return UCS2Mapper_Map<_vEnc>(uc, i, std::move(st));
269 }
270 template<Encoding _vEnc, typename _tIn, typename _tState>
272 UCS2Mapper(_tIn&& i, _tState&& st)
273 {
274  return UCS2Mapper_Map<_vEnc>(ystdex::pseudo_output(), i, st);
275 }
276 template<Encoding _vEnc>
277 byte
278 UCS2Mapper(char* d, const ucs2_t& s)
279 {
280  yconstraint(d);
281  return UCS2Mapper_InverseMap<_vEnc>(d, s);
282 }
284 
285 } // namespace CHRLib;
286 
287 #endif
288 
yconstfn ConversionResult UCS2Mapper_Map(_tParams &&...)
取映射函数。
Definition: smap.hpp:237
ConversionResult
编码转换结果。
Definition: chrmap.h:75
static ConversionResult Map(_tObj &uc, _tIn &&i, _tState &&st)
Definition: smap.hpp:207
ISO C 标准输入/输出扩展。
yconstexpr Encoding UTF_16LE(csUTF16LE)
bool FillByte(_tIn &i, _tState &st)
以输入迭代器指向内容填充有效输入迭代器指定的字节。
Definition: smap.hpp:45
yconstexpr Encoding UTF_16BE(csUTF16BE)
静态编码映射模板及 Unicode 编码特化。
Definition: smap.hpp:68
static yconstfn bool IsInvalid(byte b)
检查 UTF-8 文本序列中非法字节。
Definition: smap.hpp:79
typename remove_reference< _type >::type remove_reference_t
Definition: type_op.hpp:234
static ConversionResult Map(_tObj &uc, _tIn &&i, _tState &&st)
映射: UTF-8 。
Definition: smap.hpp:94
unsigned char byte
字节类型。
Definition: ydef.h:555
数据校验失败(如不构成代码点的字节序列)。
static ConversionResult Map(_tObj &uc, _tIn &&i, _tState &&st)
Definition: smap.hpp:181
#define YB_UNLIKELY(expr)
分支预测提示。
Definition: ydef.h:298
#define yunseq
无序列依赖表达式组求值。
Definition: ydef.h:748
源数据不可达(如越界)。
#define yconstraint
约束:接口语义。
Definition: cassert.h:47
#define yconstfn
指定编译时常量函数。
Definition: ydef.h:463
static byte InverseMap(_tOut d, const ucs2_t &s)
Definition: smap.hpp:153
动态泛型类型。
char16_t ucs2_t
UCS-2 字符类型。
Definition: chrdef.h:44
#define yconstexpr
指定编译时常量表达式。
Definition: ydef.h:462
bool is_undereferenceable(const any_input_iterator< _type, _tDifference, _tPointer, _tReference > &i)
std::FILE Encoding
Definition: chrproc.h:85
yconstexpr ConversionResult UCS2Mapper(ucs2_t &uc, _tIn &&i, _tState &&st)
Definition: smap.hpp:266
bounds & r
Definition: ydraw.h:220
#define YB_LIKELY(expr)
Definition: ydef.h:297
yconstexpr Encoding UTF_8(csUTF8)
未处理(超过被处理的界限)。
伪输出对象。
Definition: any.h:865
yconstfn byte UCS2Mapper_InverseMap(_tDst, _tSrc)
Definition: smap.hpp:251