pub const S_BASE: u32 = 0xAC00;
pub const L_BASE: u32 = 0x1100;
pub const V_BASE: u32 = 0x1161;
pub const T_BASE: u32 = 0x11A7;
pub const L_COUNT: u32 = 19;
pub const V_COUNT: u32 = 21;
pub const T_COUNT: u32 = 28;
pub const N_COUNT: u32 = (V_COUNT * T_COUNT);
pub const S_COUNT: u32 = (L_COUNT * N_COUNT);
#[allow(unsafe_code)]
#[inline(always)]
pub fn decompose<F>(s: char, f: &mut F)
where F: FnMut(char)
{
use std::mem::transmute;
let si = s as u32 - S_BASE;
let li = si / N_COUNT;
unsafe {
(*f)(transmute(L_BASE + li));
let vi = (si % N_COUNT) / T_COUNT;
(*f)(transmute(V_BASE + vi));
let ti = si % T_COUNT;
if ti > 0 {
(*f)(transmute(T_BASE + ti));
}
}
}
#[allow(unsafe_code)]
#[inline(always)]
pub fn compose(a: char, b: char) -> Option<char> {
use std::mem::transmute;
let l = a as u32;
let v = b as u32;
if L_BASE <= l && l < (L_BASE + L_COUNT) && V_BASE <= v && v < (V_BASE + V_COUNT) {
let r = S_BASE + (l - L_BASE) * N_COUNT + (v - V_BASE) * T_COUNT;
return unsafe { Some(transmute(r)) };
}
if S_BASE <= l && l <= (S_BASE+S_COUNT-T_COUNT) && T_BASE <= v && v < (T_BASE+T_COUNT) && (l - S_BASE) % T_COUNT == 0 {
let r = l + (v - T_BASE);
return unsafe { Some(transmute(r)) };
}
None
}