scell/
lib.rs

1//! The intention of this crate is to allow the use of a `Rc<RefCell<T>>` throughout code where, after enough testing
2//! has been done, the `unchecked` feature can be enabled, which will convert SCell into a `Rc<UnsafeCell<T>>`.
3//!
4//! SCell provides all of the things that the combination of `Rc<RefCell<T>>` normally allow and some more, such as
5//! implementations for `PartialOrd` and `Ord`.
6//!
7//! If you plan to do significant testing in `debug` mode, add the `unchecked` feature to this crate in `release` mode.
8//! Otherwise, it might be best to enable optimizations in `debug` so you can test in `debug` or to create a new
9//! profile for testing of optimized binaries that still do the runtime checking that RefCell provides. Once you have
10//! performed your testing, use a compile mode with the `unchecked` feature enabled for this crate and it will remove
11//! the overhead from `RefCell`, but not from `Rc` since it still needs to know when to `drop()` the value.
12//!
13//! Alternatively, feel free to use this crate for normal use in graphs, meshes, and other recurrent data structures
14//! with lots of interconnectivity where the borrow checker simply can't help. Later, if your code works fine and you
15//! need the performance back from `RefCell`, just use the `unchecked` feature and your code will be good to go.
16
17#[cfg(not(feature = "unchecked"))]
18mod checked;
19#[cfg(not(feature = "unchecked"))]
20pub use checked::*;
21
22#[cfg(feature = "unchecked")]
23mod unchecked;
24#[cfg(feature = "unchecked")]
25pub use unchecked::*;
26
27use std::cmp::Ordering;
28use std::fmt::{Formatter, Display, Debug, Error, Pointer};
29use std::hash::{Hasher, Hash};
30
31impl<T: ?Sized> PartialEq for SCell<T>
32    where T: PartialEq
33{
34    #[inline]
35    fn eq(&self, other: &Self) -> bool {
36        *self.borrow() == *other.borrow()
37    }
38
39    #[inline]
40    fn ne(&self, other: &Self) -> bool {
41        *self.borrow() != *other.borrow()
42    }
43}
44
45impl<T: ?Sized> Eq for SCell<T> where T: Eq {}
46
47impl<T: ?Sized> PartialOrd for SCell<T>
48    where T: PartialOrd
49{
50    #[inline]
51    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
52        self.borrow().partial_cmp(&*other.borrow())
53    }
54
55    #[inline]
56    fn lt(&self, other: &Self) -> bool {
57        *self.borrow() < *other.borrow()
58    }
59
60    #[inline]
61    fn le(&self, other: &Self) -> bool {
62        *self.borrow() <= *other.borrow()
63    }
64
65    #[inline]
66    fn gt(&self, other: &Self) -> bool {
67        *self.borrow() > *other.borrow()
68    }
69
70    #[inline]
71    fn ge(&self, other: &Self) -> bool {
72        *self.borrow() >= *other.borrow()
73    }
74}
75
76impl<T: ?Sized> Ord for SCell<T>
77    where T: Ord
78{
79    #[inline]
80    fn cmp(&self, other: &Self) -> Ordering {
81        self.borrow().cmp(&*other.borrow())
82    }
83}
84
85impl<T: ?Sized> Hash for SCell<T>
86    where T: Hash
87{
88    #[inline]
89    fn hash<H>(&self, state: &mut H)
90        where H: Hasher
91    {
92        self.borrow().hash(state);
93    }
94}
95
96impl<T: ?Sized> Display for SCell<T>
97    where T: Display
98{
99    #[inline]
100    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
101        self.borrow().fmt(f)
102    }
103}
104
105impl<T: ?Sized> Debug for SCell<T>
106    where T: Debug
107{
108    #[inline]
109    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
110        self.borrow().fmt(f)
111    }
112}
113
114impl<T> From<T> for SCell<T> {
115    #[inline]
116    fn from(t: T) -> Self {
117        SCell::new(t)
118    }
119}