write_only/reference/
volatile.rs1use core::marker::PhantomData;
6
7use crate::Write;
8
9pub struct VolatileWriteOnlyRef<'a, T: 'a> {
11 data: *mut T,
12 _phantom: PhantomData<&'a T>,
13}
14
15impl<'a, T: 'a> VolatileWriteOnlyRef<'a, T> {
16 #[inline]
42 pub unsafe fn from_ptr(data: *mut T) -> Self {
43 Self {
44 data,
45 _phantom: PhantomData,
46 }
47 }
48}
49
50impl<'a, T: 'a> Write<T> for VolatileWriteOnlyRef<'a, T> {
51 #[inline]
52 fn write(&mut self, guard: T) {
53 unsafe {
54 self.data.write_volatile(guard);
55 }
56 }
57}
58
59impl<'a, T: 'a> From<&'a mut T> for VolatileWriteOnlyRef<'a, T> {
60 #[inline]
61 fn from(borrow: &'a mut T) -> Self {
62 unsafe { Self::from_ptr(borrow as *mut T) }
63 }
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69
70 use droptest::prelude::*;
71
72 #[test]
73 fn from_ptr() {
74 let registry = DropRegistry::default();
75 let (id, mut guard) = registry.new_guard_for(1).by_id();
76
77 let reference = unsafe { VolatileWriteOnlyRef::from_ptr(&mut guard) };
78
79 std::mem::drop(reference);
80
81 assert_no_drop!(registry, id);
82 }
83
84 #[test]
85 fn from() {
86 let registry = DropRegistry::default();
87 let (id, mut guard) = registry.new_guard_for(1).by_id();
88
89 let reference = VolatileWriteOnlyRef::from(&mut guard);
90
91 std::mem::drop(reference);
92
93 assert_no_drop!(registry, id);
94 }
95
96 #[test]
97 fn write() {
98 let registry = DropRegistry::default();
99 let (old_id, mut guard) = registry.new_guard_for(1).by_id();
100 let (new_id, new_guard) = registry.new_guard_for(2).by_id();
101
102 let mut reference = VolatileWriteOnlyRef::from(&mut guard);
103
104 reference.write(new_guard);
105
106 assert_eq!(guard.value(), &2);
107
108 assert_no_drop!(registry, old_id);
109 assert_no_drop!(registry, new_id);
110
111 std::mem::drop(guard);
112
113 assert_no_drop!(registry, old_id);
114 assert_drop!(registry, new_id);
115 }
116}