|
8 | 8 | //! These wrappers do not depend on the standard library and never panic.
|
9 | 9 |
|
10 | 10 | #![no_std]
|
| 11 | +#![cfg_attr(feature = "nightly", feature(core_intrinsics))] |
11 | 12 |
|
12 | 13 | use access::{ReadOnly, ReadWrite, Readable, Writable, WriteOnly};
|
| 14 | +#[cfg(feature = "nightly")] |
| 15 | +use core::intrinsics; |
13 | 16 | use core::{
|
14 | 17 | marker::PhantomData,
|
15 | 18 | ops::Deref,
|
@@ -158,36 +161,99 @@ where
|
158 | 161 | }
|
159 | 162 | }
|
160 | 163 |
|
161 |
| -impl<T, A> Volatile<&[T], A> { |
162 |
| - pub fn index<I>(&self, index: I) -> Volatile<&I::Output, A> |
| 164 | +/// Methods for volatile slices |
| 165 | +impl<T, R, A> Volatile<R, A> |
| 166 | +where |
| 167 | + R: Deref<Target = [T]>, |
| 168 | +{ |
| 169 | + pub fn index<'a, I>(&'a self, index: I) -> Volatile<&'a I::Output, A> |
163 | 170 | where
|
164 | 171 | I: SliceIndex<[T]>,
|
| 172 | + T: 'a, |
165 | 173 | {
|
166 | 174 | Volatile {
|
167 | 175 | reference: self.reference.index(index),
|
168 | 176 | access: self.access,
|
169 | 177 | }
|
170 | 178 | }
|
171 |
| -} |
172 | 179 |
|
173 |
| -impl<T, A> Volatile<&mut [T], A> { |
174 |
| - pub fn index<I>(&self, index: I) -> Volatile<&I::Output, A> |
| 180 | + pub fn index_mut<'a, I>(&'a mut self, index: I) -> Volatile<&mut I::Output, A> |
175 | 181 | where
|
176 | 182 | I: SliceIndex<[T]>,
|
| 183 | + R: DerefMut, |
| 184 | + T: 'a, |
177 | 185 | {
|
178 | 186 | Volatile {
|
179 |
| - reference: self.reference.index(index), |
| 187 | + reference: self.reference.index_mut(index), |
180 | 188 | access: self.access,
|
181 | 189 | }
|
182 | 190 | }
|
183 | 191 |
|
184 |
| - pub fn index_mut<I>(&mut self, index: I) -> Volatile<&mut I::Output, A> |
| 192 | + #[cfg(feature = "nightly")] |
| 193 | + pub fn copy_into_slice(&self, dst: &mut [T]) |
185 | 194 | where
|
186 |
| - I: SliceIndex<[T]>, |
| 195 | + T: Copy, |
187 | 196 | {
|
188 |
| - Volatile { |
189 |
| - reference: self.reference.index_mut(index), |
190 |
| - access: self.access, |
| 197 | + assert_eq!( |
| 198 | + self.reference.len(), |
| 199 | + dst.len(), |
| 200 | + "destination and source slices have different lengths" |
| 201 | + ); |
| 202 | + unsafe { |
| 203 | + intrinsics::volatile_copy_nonoverlapping_memory( |
| 204 | + dst.as_mut_ptr(), |
| 205 | + self.reference.as_ptr(), |
| 206 | + self.reference.len(), |
| 207 | + ); |
| 208 | + } |
| 209 | + } |
| 210 | + |
| 211 | + /// Copies all elements from `src` into `self`, using a volatile memcpy. |
| 212 | + /// |
| 213 | + /// The length of `src` must be the same as `self`. |
| 214 | + /// |
| 215 | + /// ## Panics |
| 216 | + /// |
| 217 | + /// This function will panic if the two slices have different lengths. |
| 218 | + /// |
| 219 | + /// ## Examples |
| 220 | + /// |
| 221 | + /// Copying two elements from a slice into another: |
| 222 | + /// |
| 223 | + /// ``` |
| 224 | + /// use volatile::Volatile; |
| 225 | + /// |
| 226 | + /// let src = [1, 2, 3, 4]; |
| 227 | + /// let mut dst = [0, 0]; |
| 228 | + /// // the `Volatile` type does not work with arrays, so convert `dst` to a slice |
| 229 | + /// let slice = &mut dst[..]; |
| 230 | + /// let mut volatile = Volatile::new(slice); |
| 231 | + /// |
| 232 | + /// // Because the slices have to be the same length, |
| 233 | + /// // we slice the source slice from four elements |
| 234 | + /// // to two. It will panic if we don't do this. |
| 235 | + /// volatile.copy_from_slice(&src[2..]); |
| 236 | + /// |
| 237 | + /// assert_eq!(src, [1, 2, 3, 4]); |
| 238 | + /// assert_eq!(dst, [3, 4]); |
| 239 | + /// ``` |
| 240 | + #[cfg(feature = "nightly")] |
| 241 | + pub fn copy_from_slice(&mut self, src: &[T]) |
| 242 | + where |
| 243 | + T: Copy, |
| 244 | + R: DerefMut, |
| 245 | + { |
| 246 | + assert_eq!( |
| 247 | + self.reference.len(), |
| 248 | + src.len(), |
| 249 | + "destination and source slices have different lengths" |
| 250 | + ); |
| 251 | + unsafe { |
| 252 | + intrinsics::volatile_copy_nonoverlapping_memory( |
| 253 | + self.reference.as_mut_ptr(), |
| 254 | + src.as_ptr(), |
| 255 | + self.reference.len(), |
| 256 | + ); |
191 | 257 | }
|
192 | 258 | }
|
193 | 259 | }
|
|
0 commit comments