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