hash_on_write/
borrowed.rs

1use core::{
2    cmp::Ordering,
3    cell::Cell,
4    fmt::{self, Debug, Formatter},
5    hash::{Hash, Hasher},
6    marker::PhantomData,
7    mem::transmute,
8    ops::{Deref, DerefMut},
9};
10use std::collections::hash_map::DefaultHasher;
11
12use crate::HashStorer;
13
14/// A transparent hash wrapper, hash with behavior like [`How`]
15///
16/// # Examples
17/// ```
18/// # use hash_on_write::{How, Borrowed};
19/// # use std::collections::HashSet;
20/// let mut set: HashSet<How<String>> = HashSet::new();
21///
22/// assert!(! set.contains(Borrowed::make_ref("a")));
23/// set.insert("a".to_owned().into());
24/// assert!(set.contains(Borrowed::make_ref("a")));
25/// ```
26///
27/// [`How`]: crate::How
28#[repr(transparent)]
29pub struct Borrowed<T: ?Sized, H = DefaultHasher, S = Cell<u64>> {
30    _hasher: PhantomData<H>,
31    _state: PhantomData<S>,
32    pub value: T,
33}
34impl<T, H, S> Borrowed<T, H, S> {
35    /// Create a [`Borrowed`]
36    ///
37    /// # Examples
38    /// ```
39    /// # use hash_on_write::Borrowed;
40    /// let x: Borrowed<i32, (), ()> = Borrowed::new(2);
41    /// assert_eq!(x.value, 2);
42    /// ```
43    ///
44    /// [`Borrowed`]: crate::Borrowed
45    #[inline]
46    pub fn new(value: T) -> Self {
47        Self {
48            _hasher: PhantomData,
49            _state: PhantomData,
50            value,
51        }
52    }
53}
54impl<T: ?Sized, H, S> Borrowed<T, H, S> {
55    /// transmute reference to [`Borrowed`] reference
56    ///
57    /// # Examples
58    /// ```
59    /// # use hash_on_write::Borrowed;
60    /// let x: &Borrowed<str, (), ()> = Borrowed::make_ref("foo");
61    /// assert_eq!(x.value, *"foo");
62    /// ```
63    ///
64    /// [`Borrowed`]: crate::Borrowed
65    #[inline]
66    pub fn make_ref(value: &T) -> &Self {
67        unsafe { transmute(value) }
68    }
69
70    /// transmute mutable reference to [`Borrowed`] mutable reference
71    ///
72    /// # Examples
73    /// ```
74    /// # use hash_on_write::Borrowed;
75    /// let mut arr = [1, 2];
76    /// let x: &mut Borrowed<[i32], (), ()> = Borrowed::make_mut(&mut arr);
77    /// assert_eq!(x.value, [1, 2]);
78    /// ```
79    ///
80    /// [`Borrowed`]: crate::Borrowed
81    #[inline]
82    pub fn make_mut(value: &mut T) -> &mut Self {
83        unsafe { transmute(value) }
84    }
85}
86impl<T: ?Sized, H, S> AsRef<Self> for Borrowed<T, H, S> {
87    fn as_ref(&self) -> &Self {
88        self
89    }
90}
91impl<T: ?Sized, H, S> AsMut<Self> for Borrowed<T, H, S> {
92    fn as_mut(&mut self) -> &mut Self {
93        self
94    }
95}
96impl<T: ?Sized, H, S> AsRef<T> for Borrowed<T, H, S> {
97    fn as_ref(&self) -> &T {
98        self
99    }
100}
101impl<T: ?Sized, H, S> AsMut<T> for Borrowed<T, H, S> {
102    fn as_mut(&mut self) -> &mut T {
103        self
104    }
105}
106impl<T: ?Sized + Debug, H, S> Debug for Borrowed<T, H, S> {
107    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
108        f.debug_tuple("Borrowed")
109            .field(&&self.value)
110            .finish()
111    }
112}
113impl<T: Copy, H, S> Copy for Borrowed<T, H, S> { }
114impl<T: Clone, H, S> Clone for Borrowed<T, H, S> {
115    fn clone(&self) -> Self {
116        Self::new(self.value.clone())
117    }
118}
119impl<T: ?Sized + PartialEq, H, S> PartialEq for Borrowed<T, H, S> {
120    fn eq(&self, other: &Self) -> bool {
121        self.value.eq(&other.value)
122    }
123}
124impl<T: ?Sized + PartialEq, H, S> PartialEq<T> for Borrowed<T, H, S> {
125    fn eq(&self, other: &T) -> bool {
126        **self == *other
127    }
128}
129impl<T: ?Sized + PartialOrd, H, S> PartialOrd for Borrowed<T, H, S> {
130    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
131        self.value.partial_cmp(&other.value)
132    }
133}
134impl<T: ?Sized + PartialOrd, H, S> PartialOrd<T> for Borrowed<T, H, S> {
135    fn partial_cmp(&self, other: &T) -> Option<Ordering> {
136        (**self).partial_cmp(other)
137    }
138}
139impl<T: ?Sized + Ord, H, S> Ord for Borrowed<T, H, S> {
140    fn cmp(&self, other: &Self) -> Ordering {
141        self.value.cmp(&other.value)
142    }
143}
144impl<T: ?Sized + Eq, H, S> Eq for Borrowed<T, H, S> { }
145impl<T, H, S> Hash for Borrowed<T, H, S>
146where T: ?Sized + Hash,
147      H: Hasher + Default,
148      S: HashStorer + Default,
149{
150    fn hash<H1: Hasher>(&self, state: &mut H1) {
151        S::hash_one::<_, H>(&self.value)
152            .hash(state)
153    }
154}
155impl<T: ?Sized, H, S> DerefMut for Borrowed<T, H, S> {
156    fn deref_mut(&mut self) -> &mut Self::Target {
157        &mut self.value
158    }
159}
160impl<T: ?Sized, H, S> Deref for Borrowed<T, H, S> {
161    type Target = T;
162
163    fn deref(&self) -> &Self::Target {
164        &self.value
165    }
166}