1 //! This module is full of hackery and dark magic.
2 //! Either spend a day fixing it and quietly submit a PR or don't mention it to anybody.
3 use core::cell::UnsafeCell;
4 use core::{mem, ptr};
5 
ptr_size_bits() -> usize6 pub const fn ptr_size_bits() -> usize {
7     mem::size_of::<usize>() * 8
8 }
9 
map_in_place_2<T, U, F: FnOnce(U, T) -> T>((k, v): (U, &mut T), f: F)10 pub fn map_in_place_2<T, U, F: FnOnce(U, T) -> T>((k, v): (U, &mut T), f: F) {
11     unsafe {
12         // # Safety
13         //
14         // If the closure panics, we must abort otherwise we could double drop `T`
15         let _promote_panic_to_abort = AbortOnPanic;
16 
17         ptr::write(v, f(k, ptr::read(v)));
18     }
19 }
20 
21 /// # Safety
22 ///
23 /// Requires that you ensure the reference does not become invalid.
24 /// The object has to outlive the reference.
change_lifetime_const<'a, 'b, T>(x: &'a T) -> &'b T25 pub unsafe fn change_lifetime_const<'a, 'b, T>(x: &'a T) -> &'b T {
26     &*(x as *const T)
27 }
28 
29 /// # Safety
30 ///
31 /// Requires that you ensure the reference does not become invalid.
32 /// The object has to outlive the reference.
change_lifetime_mut<'a, 'b, T>(x: &'a mut T) -> &'b mut T33 pub unsafe fn change_lifetime_mut<'a, 'b, T>(x: &'a mut T) -> &'b mut T {
34     &mut *(x as *mut T)
35 }
36 
37 /// A simple wrapper around `T`
38 ///
39 /// This is to prevent UB when using `HashMap::get_key_value`, because
40 /// `HashMap` doesn't expose an api to get the key and value, where
41 /// the value is a `&mut T`.
42 ///
43 /// See [#10](https://github.com/xacrimon/dashmap/issues/10) for details
44 ///
45 /// This type is meant to be an implementation detail, but must be exposed due to the `Dashmap::shards`
46 #[repr(transparent)]
47 pub struct SharedValue<T> {
48     value: UnsafeCell<T>,
49 }
50 
51 impl<T: Clone> Clone for SharedValue<T> {
clone(&self) -> Self52     fn clone(&self) -> Self {
53         let inner = self.get().clone();
54 
55         Self {
56             value: UnsafeCell::new(inner),
57         }
58     }
59 }
60 
61 unsafe impl<T: Send> Send for SharedValue<T> {}
62 
63 unsafe impl<T: Sync> Sync for SharedValue<T> {}
64 
65 impl<T> SharedValue<T> {
66     /// Create a new `SharedValue<T>`
new(value: T) -> Self67     pub const fn new(value: T) -> Self {
68         Self {
69             value: UnsafeCell::new(value),
70         }
71     }
72 
73     /// Get a shared reference to `T`
get(&self) -> &T74     pub fn get(&self) -> &T {
75         unsafe { &*self.value.get() }
76     }
77 
78     /// Get an unique reference to `T`
get_mut(&mut self) -> &mut T79     pub fn get_mut(&mut self) -> &mut T {
80         unsafe { &mut *self.value.get() }
81     }
82 
83     /// Unwraps the value
into_inner(self) -> T84     pub fn into_inner(self) -> T {
85         self.value.into_inner()
86     }
87 
88     /// Get a mutable raw pointer to the underlying value
as_ptr(&self) -> *mut T89     pub(crate) fn as_ptr(&self) -> *mut T {
90         self.value.get()
91     }
92 }
93 
94 struct AbortOnPanic;
95 
96 impl Drop for AbortOnPanic {
drop(&mut self)97     fn drop(&mut self) {
98         if std::thread::panicking() {
99             std::process::abort()
100         }
101     }
102 }
103