#hash-set #mutable #iter-mut

mut_set_derive

HashSet的iter_mut和get_mut的安全实现

23个不稳定版本 (3个破坏性更新)

新功能 0.4.0 2024年8月13日
0.3.10 2024年8月13日
0.3.7 2024年7月30日
0.3.5 2024年5月15日
0.1.2 2024年3月28日

53#hash-set

Download history 97/week @ 2024-04-23 63/week @ 2024-04-30 157/week @ 2024-05-07 167/week @ 2024-05-14 23/week @ 2024-05-21 1/week @ 2024-05-28 2/week @ 2024-06-04 6/week @ 2024-06-11 1/week @ 2024-06-18 40/week @ 2024-07-02 44/week @ 2024-07-23 253/week @ 2024-07-30 78/week @ 2024-08-06

每月375次下载
2 个crate中使用 (通过 mut_set)

MIT 许可证

25KB
588

mut_set

License github crates.io Docs

使用readonly库的思想实现HashSet,支持iter_mutget_mut

使用以下命令添加crate

cargo add mut_set mut_set_derive

或将其添加到Cargo.toml

[dependencies]
mut_set = "0.3"
mut_set_derive = "0.3"

示例

#[derive(Debug)]
#[mut_set_derive::item]
pub(super) struct MyItem<T1, T2>
where
    T1: Sized,
{
    #[id]
    pub id1: usize,
    pub ctx1: T1,
    pub(in crate::derive) ctx2: T2,
    #[id]
    pub id2: String,
}

#[test]
fn test() {
    let mut set = mut_set::MutSet::new();
    println!("{:?}", set);
    set.insert(MyItem {
        id1: 2,
        id2: "www".to_string(),
        ctx1: -1,
        ctx2: "ccc".to_string(),
    });
    set.insert(MyItem {
        id1: 1,
        id2: "ww".to_string(),
        ctx1: -2,
        ctx2: "cc".to_string(),
    });
    println!("{:?}", set);
    for v in set.iter() {
        println!("{:?}", v);
    }
    for v in set.iter_mut() {
        v.ctx1 = 0;
        println!("{:?}", v.id1);
        // In `iter_mut` IDs write will be prohibited
        // v.id1 = 0;
    }
    println!("{:?}", set);
    let id1 = MyItem::id(2, "www".to_string());
    println!("{:?}", set.get(&id1));
    for v in set.into_iter() {
        println!("{:?}", v);
    }
}

mut_set是如何工作的

该宏将实现tests/src/basic_expand.rs中的所有功能。

Xxx为例

  • 创建两个结构体ImmutIdXxxXxxId。其中ImmutIdXxxXxx相同,但具有私有的id字段,而XxxId只包含id字段。
  • 重新排列,使所有id字段都位于结构体的开头。通过使用#[repr(C)],我们可以使用原始指针操作来(零成本?)转换XxxImmutIdXxxXxxId
  • impl mut_set::Itemfor Xxx<ImmutIdItem = ImmutIdXxx>
  • MutSet<T: Item> = HashMap<u64, T::ImmutIdItem>,其中u64是哈希值。
  • 包装迭代函数
    • iter(&self) -> Iter<&Xxx>
    • into_iter(self) -> Iter<Xxx>
    • iter_mut(&mut self) -> Iter<&mutImmutIdXxx>

其他特性

  • 如果您想向 ImmutIdXxx/XxxId 添加一些 derive/proc_macro,可以向 mut_set_derive::::item 添加参数,以指定应该添加到 ImmutIdXxx/XxxIdderive,以及字段的过滤器。例如:

    #[mut_set_derive::item(
    macro(derive(Debug, Clone);
          derive(derivative::Derivative);
          derivative(Default);),
    attr_filter(derivative;)
    )]
    struct Xxx {
        #[id]
        id: usize,
        #[derivative(Default(value = "8"))]
        #[some_attr]
        ctx: usize,
    }
    

    将实现

    #[derive(Debug, Clone)]
    #[derive(derivative::Derivative)]
    #[derivative(Default)]
    struct ImmutIdXxx {
        id: usize,
        #[derivative(Default(value = "8"))]
        ctx: usize,
    }
    
    #[derive(Debug, Clone)]
    #[derive(derivative::Derivative)]
    #[derivative(Default)]
    struct XxxId {
        id: usize,
    }
    

    在这里,some_attr 不在 attr_filter() 中,因此它将被移除。更多信息请参阅 tests/src/derive.rstests/src/derive_expand.rs

依赖关系

~260–700KB
~17K SLoC