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
pub use super::defs::*;

/// 维护一段相同权限的地址区间的线段
pub trait Segment: Sized {
    /// 删除这段区间
    fn remove(&mut self, args: ArgsType);
    /// 拆分这段区间。self 结构变成左半边,返回右半边
    ///
    /// 注意pos 参数为绝对位置而非相对位置
    fn split(&mut self, pos: usize, args: ArgsType) -> Self;
    /// 修改区间的属性
    fn modify(&mut self, new_flag: IdentType, args: ArgsType);

    /// 按 pos 拆分区间,只保留左半边
    ///
    /// 注意pos 参数为绝对位置而非相对位置
    fn shrink_to_left(&mut self, pos: usize, args: ArgsType) {
        self.split(pos, args).remove(args);
    }
    /// 按 pos 拆分区间,只保留右半边
    ///
    /// 注意pos 参数为绝对位置而非相对位置
    fn shrink_to_right(&mut self, pos: usize, args: ArgsType) {
        let right = self.split(pos, args);
        self.remove(args);
        *self = right;
    }
    /// 按 pos_left 和 pos_right 把区间拆成三段,**默认不检查 pos_left <= pos_right**。
    /// 然后 self 结构变成左半边区间,删除中间的区间,返回右半边区间
    ///
    /// 注意pos 参数为绝对位置而非相对位置
    fn split_and_remove_middle(
        &mut self,
        pos_left: usize,
        pos_right: usize,
        args: ArgsType,
    ) -> Self {
        let right = self.split(pos_right, args);
        self.split(pos_left, args).remove(args);
        right
    }
    /// 按 pos 拆分区间,并将左半边区间的属性修改为 new_flag。
    /// self 结构变成左半边,返回右半边
    ///
    /// 注意pos 参数为绝对位置而非相对位置
    fn modify_left(&mut self, pos: usize, new_flag: IdentType, args: ArgsType) -> Self {
        let right = self.split(pos, args);
        self.modify(new_flag, args);
        right
    }
    /// 按 pos 拆分区间,并将右半边区间的属性修改为 new_flag。
    /// self 结构变成左半边,返回右半边
    ///
    /// 注意pos 参数为绝对位置而非相对位置
    fn modify_right(&mut self, pos: usize, new_flag: IdentType, args: ArgsType) -> Self {
        let mut right = self.split(pos, args);
        right.modify(new_flag, args);
        right
    }
    /// 按 pos_left 和 pos_right 把区间拆成三段,**默认不检查 pos_left <= pos_right**,
    /// 然后修改中间一段的属性。
    /// self 结构变成左半边,返回中间和右半边
    ///
    /// 注意pos 参数为绝对位置而非相对位置
    fn modify_middle(
        &mut self,
        pos_left: usize,
        pos_right: usize,
        new_flag: IdentType,
        args: ArgsType,
    ) -> (Self, Self) {
        let right = self.split(pos_right, args);
        let mut middle = self.split(pos_left, args);
        middle.modify(new_flag, args);
        (middle, right)
    }
}