Skip to content

Commit e694a19

Browse files
committed
Add get_pin_ref and get_pin_mut methods to slice
1 parent 430feb2 commit e694a19

File tree

1 file changed

+60
-0
lines changed

1 file changed

+60
-0
lines changed

library/core/src/slice/mod.rs

+60
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use crate::num::NonZeroUsize;
1515
use crate::ops::{FnMut, Range, RangeBounds};
1616
use crate::option::Option;
1717
use crate::option::Option::{None, Some};
18+
use crate::pin::Pin;
1819
use crate::ptr;
1920
use crate::result::Result;
2021
use crate::result::Result::{Err, Ok};
@@ -307,6 +308,65 @@ impl<T> [T] {
307308
index.get_mut(self)
308309
}
309310

311+
/// Returns a pinned reference to an element or subslice depending on the
312+
/// type of index (see [`get`]) or `None` if the index is out of bounds.
313+
///
314+
/// [`get`]: #method.get
315+
///
316+
/// # Examples
317+
///
318+
/// ```
319+
/// #![feature(slice_get_pin)]
320+
/// use std::pin::Pin;
321+
///
322+
/// let v = vec![0, 1, 2].into_boxed_slice();
323+
/// let pinned = Pin::from(v);
324+
///
325+
/// let x: Option<Pin<&i32>> = pinned.as_ref().get_pin_ref(1);
326+
/// assert_eq!(&1, &*x.unwrap());
327+
/// ```
328+
#[unstable(feature = "slice_get_pin", issue = "none")]
329+
#[inline]
330+
pub fn get_pin_ref<I>(self: Pin<&Self>, index: I) -> Option<Pin<&I::Output>>
331+
where
332+
I: SliceIndex<Self>,
333+
{
334+
// SAFETY: `x` is guaranteed to be pinned because it comes from `self`
335+
// which is pinned.
336+
unsafe { self.get_ref().get(index).map(|x| Pin::new_unchecked(x)) }
337+
}
338+
339+
/// Returns a pinned mutable reference to an element or subslice depending on the
340+
/// type of index (see [`get`]) or `None` if the index is out of bounds.
341+
///
342+
/// [`get`]: #method.get
343+
///
344+
/// # Examples
345+
///
346+
/// ```
347+
/// #![feature(slice_get_pin)]
348+
/// use std::pin::Pin;
349+
///
350+
/// let v = vec![0, 1, 2].into_boxed_slice();
351+
/// let mut pinned = Pin::from(v);
352+
///
353+
/// if let Some(mut elem) = pinned.as_mut().get_pin_mut(1) {
354+
/// elem.set(10);
355+
/// }
356+
/// assert_eq!(&*pinned, &[0, 10, 2]);
357+
/// ```
358+
#[unstable(feature = "slice_get_pin", issue = "none")]
359+
#[inline]
360+
pub fn get_pin_mut<I>(self: Pin<&mut Self>, index: I) -> Option<Pin<&mut I::Output>>
361+
where
362+
I: SliceIndex<Self>,
363+
{
364+
// SAFETY: `get_unchecked_mut` is never used to move the slice inside `self` (`SliceIndex`
365+
// is sealed and all `SliceIndex::get_mut` implementations never move elements).
366+
// `x` is guaranteed to be pinned because it comes from `self` which is pinned.
367+
unsafe { self.get_unchecked_mut().get_mut(index).map(|x| Pin::new_unchecked(x)) }
368+
}
369+
310370
/// Returns a reference to an element or subslice, without doing bounds
311371
/// checking.
312372
///

0 commit comments

Comments
 (0)