@@ -28,7 +28,7 @@ use crate::fmt;
2828use crate :: intrinsics:: { assume, exact_div, unchecked_sub, is_aligned_and_not_null} ;
2929use crate :: isize;
3030use crate :: iter:: * ;
31- use crate :: ops:: { FnMut , self } ;
31+ use crate :: ops:: { FnMut , Range , self } ;
3232use crate :: option:: Option ;
3333use crate :: option:: Option :: { None , Some } ;
3434use crate :: result:: Result ;
@@ -407,6 +407,86 @@ impl<T> [T] {
407407 self as * mut [ T ] as * mut T
408408 }
409409
410+ /// Returns the two raw pointers spanning the slice.
411+ ///
412+ /// The returned range is half-open, which means that the end pointer
413+ /// points *one past* the last element of the slice. This way, an empty
414+ /// slice is represented by two equal pointers, and the difference between
415+ /// the two pointers represents the size of the size.
416+ ///
417+ /// See [`as_ptr`] for warnings on using these pointers. The end pointer
418+ /// requires extra caution, as it does not point to a valid element in the
419+ /// slice.
420+ ///
421+ /// This function is useful for interacting with foreign interfaces which
422+ /// use two pointers to refer to a range of elements in memory, as is
423+ /// common in C++.
424+ ///
425+ /// It can also be useful to check if a pointer to an element refers to an
426+ /// element of this slice:
427+ ///
428+ /// ```
429+ /// #![feature(slice_ptr_range)]
430+ ///
431+ /// let a = [1, 2, 3];
432+ /// let x = &a[1] as *const _;
433+ /// let y = &5 as *const _;
434+ ///
435+ /// assert!(a.as_ptr_range().contains(&x));
436+ /// assert!(!a.as_ptr_range().contains(&y));
437+ /// ```
438+ ///
439+ /// [`as_ptr`]: #method.as_ptr
440+ #[ unstable( feature = "slice_ptr_range" , issue = "65807" ) ]
441+ #[ inline]
442+ pub fn as_ptr_range ( & self ) -> Range < * const T > {
443+ // The `add` here is safe, because:
444+ //
445+ // - Both pointers are part of the same object, as pointing directly
446+ // past the object also counts.
447+ //
448+ // - The size of the slice is never larger than isize::MAX bytes, as
449+ // noted here:
450+ // - https://github.com/rust-lang/unsafe-code-guidelines/issues/102#issuecomment-473340447
451+ // - https://doc.rust-lang.org/reference/behavior-considered-undefined.html
452+ // - https://doc.rust-lang.org/core/slice/fn.from_raw_parts.html#safety
453+ // (This doesn't seem normative yet, but the very same assumption is
454+ // made in many places, including the Index implementation of slices.)
455+ //
456+ // - There is no wrapping around involved, as slices do not wrap past
457+ // the end of the address space.
458+ //
459+ // See the documentation of pointer::add.
460+ let start = self . as_ptr ( ) ;
461+ let end = unsafe { start. add ( self . len ( ) ) } ;
462+ start..end
463+ }
464+
465+ /// Returns the two unsafe mutable pointers spanning the slice.
466+ ///
467+ /// The returned range is half-open, which means that the end pointer
468+ /// points *one past* the last element of the slice. This way, an empty
469+ /// slice is represented by two equal pointers, and the difference between
470+ /// the two pointers represents the size of the size.
471+ ///
472+ /// See [`as_mut_ptr`] for warnings on using these pointers. The end
473+ /// pointer requires extra caution, as it does not point to a valid element
474+ /// in the slice.
475+ ///
476+ /// This function is useful for interacting with foreign interfaces which
477+ /// use two pointers to refer to a range of elements in memory, as is
478+ /// common in C++.
479+ ///
480+ /// [`as_mut_ptr`]: #method.as_mut_ptr
481+ #[ unstable( feature = "slice_ptr_range" , issue = "65807" ) ]
482+ #[ inline]
483+ pub fn as_mut_ptr_range ( & mut self ) -> Range < * mut T > {
484+ // See as_ptr_range() above for why `add` here is safe.
485+ let start = self . as_mut_ptr ( ) ;
486+ let end = unsafe { start. add ( self . len ( ) ) } ;
487+ start..end
488+ }
489+
410490 /// Swaps two elements in the slice.
411491 ///
412492 /// # Arguments
0 commit comments