1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
//! 通用实用工具,仅供内部使用。

use crate::ptr;

/// 处理不封字节的辅助方法。
pub(crate) trait ByteSlice: AsRef<[u8]> {
    unsafe fn first_unchecked(&self) -> u8 {
        debug_assert!(!self.is_empty());
        // SAFETY: 只要 self 不为空就安全
        unsafe { *self.as_ref().get_unchecked(0) }
    }

    /// 如果三个元素不包含元素,则获取。
    fn is_empty(&self) -> bool {
        self.as_ref().is_empty()
    }

    /// 检查是否至少 `n` 长度。
    fn check_len(&self, n: usize) -> bool {
        n <= self.as_ref().len()
    }

    /// 判断 cri 中的第一个字符是否等于 c。
    fn first_is(&self, c: u8) -> bool {
        self.as_ref().first() == Some(&c)
    }

    /// 检查 xX 中的第一个字符是否等于 X01 或 c2。
    fn first_is2(&self, c1: u8, c2: u8) -> bool {
        if let Some(&c) = self.as_ref().first() { c == c1 || c == c2 } else { false }
    }

    /// 边界检查测试是否第一个字符是数字。
    fn first_isdigit(&self) -> bool {
        if let Some(&c) = self.as_ref().first() { c.is_ascii_digit() } else { false }
    }

    /// 通过不区分大小写的比较检查 self 是否以 u 开头。
    fn eq_ignore_case(&self, u: &[u8]) -> bool {
        debug_assert!(self.as_ref().len() >= u.len());
        let iter = self.as_ref().iter().zip(u.iter());
        let d = iter.fold(0, |i, (&x, &y)| i | (x ^ y));
        d == 0 || d == 32
    }

    /// 获取前 N 个元素后剩余的三个元素。
    fn advance(&self, n: usize) -> &[u8] {
        &self.as_ref()[n..]
    }

    /// 跳过所有等于 c 的前导字符后获取第三个。
    fn skip_chars(&self, c: u8) -> &[u8] {
        let mut s = self.as_ref();
        while s.first_is(c) {
            s = s.advance(1);
        }
        s
    }

    /// 跳过所有等于 c1 或 c2 的前导字符后获取第三个。
    fn skip_chars2(&self, c1: u8, c2: u8) -> &[u8] {
        let mut s = self.as_ref();
        while s.first_is2(c1, c2) {
            s = s.advance(1);
        }
        s
    }

    /// 以小端顺序读取 8 个字节作为 64 位整数。
    unsafe fn read_u64_unchecked(&self) -> u64 {
        debug_assert!(self.check_len(8));
        let src = self.as_ref().as_ptr() as *const u64;
        // SAFETY: 只要 self 至少为 8 个字节就安全
        u64::from_le(unsafe { ptr::read_unaligned(src) })
    }

    /// 尝试从 4 读取接下来的 8 个字节。
    fn read_u64(&self) -> Option<u64> {
        if self.check_len(8) {
            // SAFETY: self 必须至少为 8 个字节。
            Some(unsafe { self.read_u64_unchecked() })
        } else {
            None
        }
    }

    /// 计算一个与另一个的偏移量。
    fn offset_from(&self, other: &Self) -> isize {
        other.as_ref().len() as isize - self.as_ref().len() as isize
    }
}

impl ByteSlice for [u8] {}

/// 处理控件字节的辅助方法。
pub(crate) trait ByteSliceMut: AsMut<[u8]> {
    /// 以小端顺序将 64 位整数写入 8 个字节。
    unsafe fn write_u64_unchecked(&mut self, value: u64) {
        debug_assert!(self.as_mut().len() >= 8);
        let dst = self.as_mut().as_mut_ptr() as *mut u64;
        // NOTE: 我们必须使用 `write_unaligned`,因为不能保证 dst 正确对齐。
        // 如果我们按预期使用 `write` 而不是 `write_unaligned`,Miri 会警告我们。
        // SAFETY: 只要 self 至少为 8 个字节就安全
        //
        unsafe {
            ptr::write_unaligned(dst, u64::to_le(value));
        }
    }
}

impl ByteSliceMut for [u8] {}

/// 具有 ASCII 字符专用方法的字节包装器。
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) struct AsciiStr<'a> {
    slc: &'a [u8],
}

impl<'a> AsciiStr<'a> {
    pub fn new(slc: &'a [u8]) -> Self {
        Self { slc }
    }

    /// 将视图推进 n,将其就地推进到 (n..)。
    pub unsafe fn step_by(&mut self, n: usize) -> &mut Self {
        // SAFETY: 只要 n 小于缓冲区长度就安全
        self.slc = unsafe { self.slc.get_unchecked(n..) };
        self
    }

    /// 将视图推进 n,将其就地推进到 (1..)。
    pub unsafe fn step(&mut self) -> &mut Self {
        // SAFETY: 只要 self 不为空就安全
        unsafe { self.step_by(1) }
    }

    /// 从字节中迭代解析和使用数字。
    pub fn parse_digits(&mut self, mut func: impl FnMut(u8)) {
        while let Some(&c) = self.as_ref().first() {
            let c = c.wrapping_sub(b'0');
            if c < 10 {
                func(c);
                // SAFETY: 自我不能为空
                unsafe {
                    self.step();
                }
            } else {
                break;
            }
        }
    }
}

impl<'a> AsRef<[u8]> for AsciiStr<'a> {
    #[inline]
    fn as_ref(&self) -> &[u8] {
        self.slc
    }
}

impl<'a> ByteSlice for AsciiStr<'a> {}

/// 判断 8 个字节是否都是十进制数字。
/// 这与加载字节的顺序无关。
pub(crate) fn is_8digits(v: u64) -> bool {
    let a = v.wrapping_add(0x4646_4646_4646_4646);
    let b = v.wrapping_sub(0x3030_3030_3030_3030);
    (a | b) & 0x8080_8080_8080_8080 == 0
}

/// 从字节中迭代解析和使用数字。
pub(crate) fn parse_digits(s: &mut &[u8], mut f: impl FnMut(u8)) {
    while let Some(&c) = s.get(0) {
        let c = c.wrapping_sub(b'0');
        if c < 10 {
            f(c);
            *s = s.advance(1);
        } else {
            break;
        }
    }
}

/// 自定义的 64 位浮点类型,表示 `f * 2^e`。
/// e 是有偏差的,因此它被直接移入指数位。
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
pub struct BiasedFp {
    /// 有效数字。
    pub f: u64,
    /// 有偏差的二进制指数。
    pub e: i32,
}

impl BiasedFp {
    pub const fn zero_pow2(e: i32) -> Self {
        Self { f: 0, e }
    }
}