Skip to content

Commit 197eeef

Browse files
committed
Make methods generic using Deref trait
1 parent e1f8ad5 commit 197eeef

File tree

1 file changed

+17
-34
lines changed

1 file changed

+17
-34
lines changed

src/lib.rs

Lines changed: 17 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
use access::{ReadOnly, ReadWrite, Readable, Writable, WriteOnly};
1313
use core::{
1414
marker::PhantomData,
15-
ops::{Index, IndexMut},
15+
ops::Deref,
16+
ops::{DerefMut, Index, IndexMut},
1617
ptr,
1718
slice::SliceIndex,
1819
};
@@ -35,6 +36,7 @@ pub struct Volatile<R, A = ReadWrite> {
3536
access: PhantomData<A>,
3637
}
3738

39+
/// Construction functions
3840
impl<R> Volatile<R> {
3941
/// Construct a new volatile instance wrapping the given reference.
4042
///
@@ -70,8 +72,10 @@ impl<R> Volatile<R> {
7072
}
7173
}
7274

73-
impl<T, A> Volatile<&T, A>
75+
/// Methods for references to `Copy` types
76+
impl<R, T, A> Volatile<R, A>
7477
where
78+
R: Deref<Target = T>,
7579
T: Copy,
7680
{
7781
/// Performs a volatile read of the contained value.
@@ -80,48 +84,25 @@ where
8084
/// away by the compiler, but by themselves do not have atomic ordering
8185
/// guarantees. To also get atomicity, consider looking at the `Atomic` wrapper type.
8286
///
83-
/// ## Example
87+
/// ## Examples
8488
///
8589
/// ```rust
8690
/// use volatile::Volatile;
8791
///
8892
/// let value = 42;
89-
/// let volatile = Volatile::new(&value);
93+
/// let shared_reference = Volatile::new(&value);
94+
/// assert_eq!(shared_reference.read(), 42);
9095
///
91-
/// assert_eq!(volatile.read(), 42);
96+
/// let mut value = 50;
97+
/// let mut_reference = Volatile::new(&mut value);
98+
/// assert_eq!(mut_reference.read(), 50);
9299
/// ```
93100
pub fn read(&self) -> T
94101
where
95102
A: Readable,
96103
{
97104
// UNSAFE: Safe, as we know that our internal value exists.
98-
unsafe { ptr::read_volatile(self.reference) }
99-
}
100-
}
101-
102-
impl<T: Copy, A> Volatile<&mut T, A> {
103-
/// Performs a volatile read of the contained value.
104-
///
105-
/// Returns a copy of the read value. Volatile reads are guaranteed not to be optimized
106-
/// away by the compiler, but by themselves do not have atomic ordering
107-
/// guarantees. To also get atomicity, consider looking at the `Atomic` wrapper type.
108-
///
109-
/// ## Example
110-
///
111-
/// ```rust
112-
/// use volatile::Volatile;
113-
///
114-
/// let mut value = 10;
115-
/// let volatile = Volatile::new(&mut value);
116-
///
117-
/// assert_eq!(volatile.read(), 10);
118-
/// ```
119-
pub fn read(&self) -> T
120-
where
121-
A: Readable,
122-
{
123-
// UNSAFE: Safe, as we know that our internal value exists.
124-
unsafe { ptr::read_volatile(self.reference) }
105+
unsafe { ptr::read_volatile(&*self.reference) }
125106
}
126107

127108
/// Performs a volatile write, setting the contained value to the given `value`.
@@ -144,9 +125,10 @@ impl<T: Copy, A> Volatile<&mut T, A> {
144125
pub fn write(&mut self, value: T)
145126
where
146127
A: Writable,
128+
R: DerefMut,
147129
{
148130
// UNSAFE: Safe, as we know that our internal value exists.
149-
unsafe { ptr::write_volatile(self.reference, value) };
131+
unsafe { ptr::write_volatile(&mut *self.reference, value) };
150132
}
151133

152134
/// Updates the contained value using the given closure and volatile instructions.
@@ -166,8 +148,9 @@ impl<T: Copy, A> Volatile<&mut T, A> {
166148
/// ```
167149
pub fn update<F>(&mut self, f: F)
168150
where
169-
F: FnOnce(&mut T),
170151
A: Readable + Writable,
152+
R: DerefMut,
153+
F: FnOnce(&mut T),
171154
{
172155
let mut value = self.read();
173156
f(&mut value);

0 commit comments

Comments
 (0)