cons/lib.rs
1/*!
2# cons
3[](https://crates.io/crates/cons)
4[](https://crates.io/crates/cons)
5[](https://docs.rs/cons/)
6[](https://opensource.org/licenses/MIT)
7
8Quick and simple hash-consing implementations for a variety of internally mutable `HashMap`s/`HashSet`s (use the features to select the ones you want).
9*/
10use std::rc::Rc;
11use std::sync::Arc;
12
13/// A trait implemented by sets which can be used for hash-consing values of type `C` using keys of type `Q`
14pub trait Cons<C, Q> {
15 /// Cons a key of type `Q` into a cached key of type `C`
16 fn cons(&self, key: Q) -> C;
17}
18
19/// A trait implemented by values which can be garbage collected
20pub trait CanGC {
21 /// Whether this value only has a single reference to it, and therefore can be garbage collected
22 fn single_reference(&self) -> bool;
23 /// Whether this value has two or less references to it, and therefore can be garbage collected by an object holding
24 /// the other reference
25 fn double_reference(&self) -> bool;
26}
27
28/// A trait implemented by sets which can be used to un-cons values of type `C`
29pub trait Uncons<C> {
30 /// Garbage collect a value of type `C`, removing it if there cannot be any other references to it.
31 /// If this is the case, return `true`, otherwise return `false`.
32 #[inline(always)]
33 fn gc(&self, key: &mut C) -> bool
34 where
35 C: CanGC,
36 {
37 if key.double_reference() {
38 self.uncons(key)
39 } else {
40 false
41 }
42 }
43 /// Unconditionally remove a value of type `C`. Return whether it was in the set
44 fn uncons(&self, key: &mut C) -> bool;
45}
46
47impl<C> CanGC for Arc<C> {
48 #[inline]
49 fn single_reference(&self) -> bool {
50 Arc::weak_count(self) + Arc::strong_count(self) <= 1
51 }
52 #[inline(always)]
53 fn double_reference(&self) -> bool {
54 Arc::weak_count(self) + Arc::strong_count(self) <= 2
55 }
56}
57
58impl<C> CanGC for Rc<C> {
59 #[inline]
60 fn single_reference(&self) -> bool {
61 Rc::weak_count(self) + Rc::strong_count(self) <= 1
62 }
63 #[inline(always)]
64 fn double_reference(&self) -> bool {
65 Rc::weak_count(self) + Rc::strong_count(self) <= 2
66 }
67}
68
69#[cfg(feature = "elysees")]
70mod elysees_impl;#[cfg(feature = "flurry-cons")]
71pub mod flurry_cons;