]> git.lizzy.rs Git - rust.git/blob - src/libcore/ptr/const_ptr.rs
22c741d4651a5fcc2580a13d45580a12266a2d8c
[rust.git] / src / libcore / ptr / const_ptr.rs
1 use super::*;
2 use crate::cmp::Ordering::{self, Equal, Greater, Less};
3 use crate::intrinsics;
4 use crate::mem;
5 use crate::slice::SliceIndex;
6
7 #[lang = "const_ptr"]
8 impl<T: ?Sized> *const T {
9     /// Returns `true` if the pointer is null.
10     ///
11     /// Note that unsized types have many possible null pointers, as only the
12     /// raw data pointer is considered, not their length, vtable, etc.
13     /// Therefore, two pointers that are null may still not compare equal to
14     /// each other.
15     ///
16     /// # Examples
17     ///
18     /// Basic usage:
19     ///
20     /// ```
21     /// let s: &str = "Follow the rabbit";
22     /// let ptr: *const u8 = s.as_ptr();
23     /// assert!(!ptr.is_null());
24     /// ```
25     #[stable(feature = "rust1", since = "1.0.0")]
26     #[inline]
27     pub fn is_null(self) -> bool {
28         // Compare via a cast to a thin pointer, so fat pointers are only
29         // considering their "data" part for null-ness.
30         (self as *const u8) == null()
31     }
32
33     /// Casts to a pointer of another type.
34     #[stable(feature = "ptr_cast", since = "1.38.0")]
35     #[rustc_const_stable(feature = "const_ptr_cast", since = "1.38.0")]
36     #[inline]
37     pub const fn cast<U>(self) -> *const U {
38         self as _
39     }
40
41     /// Returns `None` if the pointer is null, or else returns a reference to
42     /// the value wrapped in `Some`.
43     ///
44     /// # Safety
45     ///
46     /// While this method and its mutable counterpart are useful for
47     /// null-safety, it is important to note that this is still an unsafe
48     /// operation because the returned value could be pointing to invalid
49     /// memory.
50     ///
51     /// When calling this method, you have to ensure that *either* the pointer is NULL *or*
52     /// all of the following is true:
53     /// - it is properly aligned
54     /// - it must point to an initialized instance of T; in particular, the pointer must be
55     ///   "dereferenceable" in the sense defined [here].
56     ///
57     /// This applies even if the result of this method is unused!
58     /// (The part about being initialized is not yet fully decided, but until
59     /// it is, the only safe approach is to ensure that they are indeed initialized.)
60     ///
61     /// Additionally, the lifetime `'a` returned is arbitrarily chosen and does
62     /// not necessarily reflect the actual lifetime of the data. *You* must enforce
63     /// Rust's aliasing rules. In particular, for the duration of this lifetime,
64     /// the memory the pointer points to must not get mutated (except inside `UnsafeCell`).
65     ///
66     /// [here]: crate::ptr#safety
67     ///
68     /// # Examples
69     ///
70     /// Basic usage:
71     ///
72     /// ```
73     /// let ptr: *const u8 = &10u8 as *const u8;
74     ///
75     /// unsafe {
76     ///     if let Some(val_back) = ptr.as_ref() {
77     ///         println!("We got back the value: {}!", val_back);
78     ///     }
79     /// }
80     /// ```
81     ///
82     /// # Null-unchecked version
83     ///
84     /// If you are sure the pointer can never be null and are looking for some kind of
85     /// `as_ref_unchecked` that returns the `&T` instead of `Option<&T>`, know that you can
86     /// dereference the pointer directly.
87     ///
88     /// ```
89     /// let ptr: *const u8 = &10u8 as *const u8;
90     ///
91     /// unsafe {
92     ///     let val_back = &*ptr;
93     ///     println!("We got back the value: {}!", val_back);
94     /// }
95     /// ```
96     #[stable(feature = "ptr_as_ref", since = "1.9.0")]
97     #[inline]
98     pub unsafe fn as_ref<'a>(self) -> Option<&'a T> {
99         // SAFETY: the caller must guarantee that `self` is valid
100         // for a reference if it isn't null.
101         if self.is_null() { None } else { unsafe { Some(&*self) } }
102     }
103
104     /// Calculates the offset from a pointer.
105     ///
106     /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
107     /// offset of `3 * size_of::<T>()` bytes.
108     ///
109     /// # Safety
110     ///
111     /// If any of the following conditions are violated, the result is Undefined
112     /// Behavior:
113     ///
114     /// * Both the starting and resulting pointer must be either in bounds or one
115     ///   byte past the end of the same allocated object. Note that in Rust,
116     ///   every (stack-allocated) variable is considered a separate allocated object.
117     ///
118     /// * The computed offset, **in bytes**, cannot overflow an `isize`.
119     ///
120     /// * The offset being in bounds cannot rely on "wrapping around" the address
121     ///   space. That is, the infinite-precision sum, **in bytes** must fit in a usize.
122     ///
123     /// The compiler and standard library generally tries to ensure allocations
124     /// never reach a size where an offset is a concern. For instance, `Vec`
125     /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so
126     /// `vec.as_ptr().add(vec.len())` is always safe.
127     ///
128     /// Most platforms fundamentally can't even construct such an allocation.
129     /// For instance, no known 64-bit platform can ever serve a request
130     /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
131     /// However, some 32-bit and 16-bit platforms may successfully serve a request for
132     /// more than `isize::MAX` bytes with things like Physical Address
133     /// Extension. As such, memory acquired directly from allocators or memory
134     /// mapped files *may* be too large to handle with this function.
135     ///
136     /// Consider using [`wrapping_offset`] instead if these constraints are
137     /// difficult to satisfy. The only advantage of this method is that it
138     /// enables more aggressive compiler optimizations.
139     ///
140     /// [`wrapping_offset`]: #method.wrapping_offset
141     ///
142     /// # Examples
143     ///
144     /// Basic usage:
145     ///
146     /// ```
147     /// let s: &str = "123";
148     /// let ptr: *const u8 = s.as_ptr();
149     ///
150     /// unsafe {
151     ///     println!("{}", *ptr.offset(1) as char);
152     ///     println!("{}", *ptr.offset(2) as char);
153     /// }
154     /// ```
155     #[stable(feature = "rust1", since = "1.0.0")]
156     #[must_use = "returns a new pointer rather than modifying its argument"]
157     #[rustc_const_unstable(feature = "const_ptr_offset", issue = "71499")]
158     #[inline]
159     pub const unsafe fn offset(self, count: isize) -> *const T
160     where
161         T: Sized,
162     {
163         // SAFETY: the caller must uphold the safety contract for `offset`.
164         unsafe { intrinsics::offset(self, count) }
165     }
166
167     /// Calculates the offset from a pointer using wrapping arithmetic.
168     ///
169     /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
170     /// offset of `3 * size_of::<T>()` bytes.
171     ///
172     /// # Safety
173     ///
174     /// The resulting pointer does not need to be in bounds, but it is
175     /// potentially hazardous to dereference (which requires `unsafe`).
176     ///
177     /// In particular, the resulting pointer remains attached to the same allocated
178     /// object that `self` points to. It may *not* be used to access a
179     /// different allocated object. Note that in Rust,
180     /// every (stack-allocated) variable is considered a separate allocated object.
181     ///
182     /// In other words, `x.wrapping_offset(y.wrapping_offset_from(x))` is
183     /// *not* the same as `y`, and dereferencing it is undefined behavior
184     /// unless `x` and `y` point into the same allocated object.
185     ///
186     /// Compared to [`offset`], this method basically delays the requirement of staying
187     /// within the same allocated object: [`offset`] is immediate Undefined Behavior when
188     /// crossing object boundaries; `wrapping_offset` produces a pointer but still leads
189     /// to Undefined Behavior if that pointer is dereferenced. [`offset`] can be optimized
190     /// better and is thus preferable in performance-sensitive code.
191     ///
192     /// If you need to cross object boundaries, cast the pointer to an integer and
193     /// do the arithmetic there.
194     ///
195     /// [`offset`]: #method.offset
196     ///
197     /// # Examples
198     ///
199     /// Basic usage:
200     ///
201     /// ```
202     /// // Iterate using a raw pointer in increments of two elements
203     /// let data = [1u8, 2, 3, 4, 5];
204     /// let mut ptr: *const u8 = data.as_ptr();
205     /// let step = 2;
206     /// let end_rounded_up = ptr.wrapping_offset(6);
207     ///
208     /// // This loop prints "1, 3, 5, "
209     /// while ptr != end_rounded_up {
210     ///     unsafe {
211     ///         print!("{}, ", *ptr);
212     ///     }
213     ///     ptr = ptr.wrapping_offset(step);
214     /// }
215     /// ```
216     #[stable(feature = "ptr_wrapping_offset", since = "1.16.0")]
217     #[must_use = "returns a new pointer rather than modifying its argument"]
218     #[rustc_const_unstable(feature = "const_ptr_offset", issue = "71499")]
219     #[inline]
220     pub const fn wrapping_offset(self, count: isize) -> *const T
221     where
222         T: Sized,
223     {
224         // SAFETY: the `arith_offset` intrinsic has no prerequisites to be called.
225         unsafe { intrinsics::arith_offset(self, count) }
226     }
227
228     /// Calculates the distance between two pointers. The returned value is in
229     /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
230     ///
231     /// This function is the inverse of [`offset`].
232     ///
233     /// [`offset`]: #method.offset
234     /// [`wrapping_offset_from`]: #method.wrapping_offset_from
235     ///
236     /// # Safety
237     ///
238     /// If any of the following conditions are violated, the result is Undefined
239     /// Behavior:
240     ///
241     /// * Both the starting and other pointer must be either in bounds or one
242     ///   byte past the end of the same allocated object. Note that in Rust,
243     ///   every (stack-allocated) variable is considered a separate allocated object.
244     ///
245     /// * The distance between the pointers, **in bytes**, cannot overflow an `isize`.
246     ///
247     /// * The distance between the pointers, in bytes, must be an exact multiple
248     ///   of the size of `T`.
249     ///
250     /// * The distance being in bounds cannot rely on "wrapping around" the address space.
251     ///
252     /// The compiler and standard library generally try to ensure allocations
253     /// never reach a size where an offset is a concern. For instance, `Vec`
254     /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so
255     /// `ptr_into_vec.offset_from(vec.as_ptr())` is always safe.
256     ///
257     /// Most platforms fundamentally can't even construct such an allocation.
258     /// For instance, no known 64-bit platform can ever serve a request
259     /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
260     /// However, some 32-bit and 16-bit platforms may successfully serve a request for
261     /// more than `isize::MAX` bytes with things like Physical Address
262     /// Extension. As such, memory acquired directly from allocators or memory
263     /// mapped files *may* be too large to handle with this function.
264     ///
265     /// Consider using [`wrapping_offset_from`] instead if these constraints are
266     /// difficult to satisfy. The only advantage of this method is that it
267     /// enables more aggressive compiler optimizations.
268     ///
269     /// # Panics
270     ///
271     /// This function panics if `T` is a Zero-Sized Type ("ZST").
272     ///
273     /// # Examples
274     ///
275     /// Basic usage:
276     ///
277     /// ```
278     /// #![feature(ptr_offset_from)]
279     ///
280     /// let a = [0; 5];
281     /// let ptr1: *const i32 = &a[1];
282     /// let ptr2: *const i32 = &a[3];
283     /// unsafe {
284     ///     assert_eq!(ptr2.offset_from(ptr1), 2);
285     ///     assert_eq!(ptr1.offset_from(ptr2), -2);
286     ///     assert_eq!(ptr1.offset(2), ptr2);
287     ///     assert_eq!(ptr2.offset(-2), ptr1);
288     /// }
289     /// ```
290     #[unstable(feature = "ptr_offset_from", issue = "41079")]
291     #[rustc_const_unstable(feature = "const_ptr_offset_from", issue = "41079")]
292     #[inline]
293     pub const unsafe fn offset_from(self, origin: *const T) -> isize
294     where
295         T: Sized,
296     {
297         let pointee_size = mem::size_of::<T>();
298         assert!(0 < pointee_size && pointee_size <= isize::MAX as usize);
299         // SAFETY: the caller must uphold the safety contract for `ptr_offset_from`.
300         unsafe { intrinsics::ptr_offset_from(self, origin) }
301     }
302
303     /// Returns whether two pointers are guaranteed to be equal.
304     ///
305     /// At runtime this function behaves like `self == other`.
306     /// However, in some contexts (e.g., compile-time evaluation),
307     /// it is not always possible to determine equality of two pointers, so this function may
308     /// spuriously return `false` for pointers that later actually turn out to be equal.
309     /// But when it returns `true`, the pointers are guaranteed to be equal.
310     ///
311     /// This function is the mirror of [`guaranteed_ne`], but not its inverse. There are pointer
312     /// comparisons for which both functions return `false`.
313     ///
314     /// [`guaranteed_ne`]: #method.guaranteed_ne
315     ///
316     /// The return value may change depending on the compiler version and unsafe code may not
317     /// rely on the result of this function for soundness. It is suggested to only use this function
318     /// for performance optimizations where spurious `false` return values by this function do not
319     /// affect the outcome, but just the performance.
320     /// The consequences of using this method to make runtime and compile-time code behave
321     /// differently have not been explored. This method should not be used to introduce such
322     /// differences, and it should also not be stabilized before we have a better understanding
323     /// of this issue.
324     #[unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
325     #[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
326     #[inline]
327     #[cfg(not(bootstrap))]
328     pub const fn guaranteed_eq(self, other: *const T) -> bool
329     where
330         T: Sized,
331     {
332         intrinsics::ptr_guaranteed_eq(self, other)
333     }
334
335     /// Returns whether two pointers are guaranteed to be inequal.
336     ///
337     /// At runtime this function behaves like `self != other`.
338     /// However, in some contexts (e.g., compile-time evaluation),
339     /// it is not always possible to determine the inequality of two pointers, so this function may
340     /// spuriously return `false` for pointers that later actually turn out to be inequal.
341     /// But when it returns `true`, the pointers are guaranteed to be inequal.
342     ///
343     /// This function is the mirror of [`guaranteed_eq`], but not its inverse. There are pointer
344     /// comparisons for which both functions return `false`.
345     ///
346     /// [`guaranteed_eq`]: #method.guaranteed_eq
347     ///
348     /// The return value may change depending on the compiler version and unsafe code may not
349     /// rely on the result of this function for soundness. It is suggested to only use this function
350     /// for performance optimizations where spurious `false` return values by this function do not
351     /// affect the outcome, but just the performance.
352     /// The consequences of using this method to make runtime and compile-time code behave
353     /// differently have not been explored. This method should not be used to introduce such
354     /// differences, and it should also not be stabilized before we have a better understanding
355     /// of this issue.
356     #[unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
357     #[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
358     #[inline]
359     #[cfg(not(bootstrap))]
360     pub const fn guaranteed_ne(self, other: *const T) -> bool
361     where
362         T: Sized,
363     {
364         intrinsics::ptr_guaranteed_ne(self, other)
365     }
366
367     /// Calculates the distance between two pointers. The returned value is in
368     /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
369     ///
370     /// If the address different between the two pointers is not a multiple of
371     /// `mem::size_of::<T>()` then the result of the division is rounded towards
372     /// zero.
373     ///
374     /// Though this method is safe for any two pointers, note that its result
375     /// will be mostly useless if the two pointers aren't into the same allocated
376     /// object, for example if they point to two different local variables.
377     ///
378     /// # Panics
379     ///
380     /// This function panics if `T` is a zero-sized type.
381     ///
382     /// # Examples
383     ///
384     /// Basic usage:
385     ///
386     /// ```
387     /// #![feature(ptr_wrapping_offset_from)]
388     ///
389     /// let a = [0; 5];
390     /// let ptr1: *const i32 = &a[1];
391     /// let ptr2: *const i32 = &a[3];
392     /// assert_eq!(ptr2.wrapping_offset_from(ptr1), 2);
393     /// assert_eq!(ptr1.wrapping_offset_from(ptr2), -2);
394     /// assert_eq!(ptr1.wrapping_offset(2), ptr2);
395     /// assert_eq!(ptr2.wrapping_offset(-2), ptr1);
396     ///
397     /// let ptr1: *const i32 = 3 as _;
398     /// let ptr2: *const i32 = 13 as _;
399     /// assert_eq!(ptr2.wrapping_offset_from(ptr1), 2);
400     /// ```
401     #[unstable(feature = "ptr_wrapping_offset_from", issue = "41079")]
402     #[rustc_deprecated(
403         since = "1.46.0",
404         reason = "Pointer distances across allocation \
405         boundaries are not typically meaningful. \
406         Use integer subtraction if you really need this."
407     )]
408     #[inline]
409     pub fn wrapping_offset_from(self, origin: *const T) -> isize
410     where
411         T: Sized,
412     {
413         let pointee_size = mem::size_of::<T>();
414         assert!(0 < pointee_size && pointee_size <= isize::MAX as usize);
415
416         let d = isize::wrapping_sub(self as _, origin as _);
417         d.wrapping_div(pointee_size as _)
418     }
419
420     /// Calculates the offset from a pointer (convenience for `.offset(count as isize)`).
421     ///
422     /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
423     /// offset of `3 * size_of::<T>()` bytes.
424     ///
425     /// # Safety
426     ///
427     /// If any of the following conditions are violated, the result is Undefined
428     /// Behavior:
429     ///
430     /// * Both the starting and resulting pointer must be either in bounds or one
431     ///   byte past the end of the same allocated object. Note that in Rust,
432     ///   every (stack-allocated) variable is considered a separate allocated object.
433     ///
434     /// * The computed offset, **in bytes**, cannot overflow an `isize`.
435     ///
436     /// * The offset being in bounds cannot rely on "wrapping around" the address
437     ///   space. That is, the infinite-precision sum must fit in a `usize`.
438     ///
439     /// The compiler and standard library generally tries to ensure allocations
440     /// never reach a size where an offset is a concern. For instance, `Vec`
441     /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so
442     /// `vec.as_ptr().add(vec.len())` is always safe.
443     ///
444     /// Most platforms fundamentally can't even construct such an allocation.
445     /// For instance, no known 64-bit platform can ever serve a request
446     /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
447     /// However, some 32-bit and 16-bit platforms may successfully serve a request for
448     /// more than `isize::MAX` bytes with things like Physical Address
449     /// Extension. As such, memory acquired directly from allocators or memory
450     /// mapped files *may* be too large to handle with this function.
451     ///
452     /// Consider using [`wrapping_add`] instead if these constraints are
453     /// difficult to satisfy. The only advantage of this method is that it
454     /// enables more aggressive compiler optimizations.
455     ///
456     /// [`wrapping_add`]: #method.wrapping_add
457     ///
458     /// # Examples
459     ///
460     /// Basic usage:
461     ///
462     /// ```
463     /// let s: &str = "123";
464     /// let ptr: *const u8 = s.as_ptr();
465     ///
466     /// unsafe {
467     ///     println!("{}", *ptr.add(1) as char);
468     ///     println!("{}", *ptr.add(2) as char);
469     /// }
470     /// ```
471     #[stable(feature = "pointer_methods", since = "1.26.0")]
472     #[must_use = "returns a new pointer rather than modifying its argument"]
473     #[rustc_const_unstable(feature = "const_ptr_offset", issue = "71499")]
474     #[inline]
475     pub const unsafe fn add(self, count: usize) -> Self
476     where
477         T: Sized,
478     {
479         // SAFETY: the caller must uphold the safety contract for `offset`.
480         unsafe { self.offset(count as isize) }
481     }
482
483     /// Calculates the offset from a pointer (convenience for
484     /// `.offset((count as isize).wrapping_neg())`).
485     ///
486     /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
487     /// offset of `3 * size_of::<T>()` bytes.
488     ///
489     /// # Safety
490     ///
491     /// If any of the following conditions are violated, the result is Undefined
492     /// Behavior:
493     ///
494     /// * Both the starting and resulting pointer must be either in bounds or one
495     ///   byte past the end of the same allocated object. Note that in Rust,
496     ///   every (stack-allocated) variable is considered a separate allocated object.
497     ///
498     /// * The computed offset cannot exceed `isize::MAX` **bytes**.
499     ///
500     /// * The offset being in bounds cannot rely on "wrapping around" the address
501     ///   space. That is, the infinite-precision sum must fit in a usize.
502     ///
503     /// The compiler and standard library generally tries to ensure allocations
504     /// never reach a size where an offset is a concern. For instance, `Vec`
505     /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so
506     /// `vec.as_ptr().add(vec.len()).sub(vec.len())` is always safe.
507     ///
508     /// Most platforms fundamentally can't even construct such an allocation.
509     /// For instance, no known 64-bit platform can ever serve a request
510     /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
511     /// However, some 32-bit and 16-bit platforms may successfully serve a request for
512     /// more than `isize::MAX` bytes with things like Physical Address
513     /// Extension. As such, memory acquired directly from allocators or memory
514     /// mapped files *may* be too large to handle with this function.
515     ///
516     /// Consider using [`wrapping_sub`] instead if these constraints are
517     /// difficult to satisfy. The only advantage of this method is that it
518     /// enables more aggressive compiler optimizations.
519     ///
520     /// [`wrapping_sub`]: #method.wrapping_sub
521     ///
522     /// # Examples
523     ///
524     /// Basic usage:
525     ///
526     /// ```
527     /// let s: &str = "123";
528     ///
529     /// unsafe {
530     ///     let end: *const u8 = s.as_ptr().add(3);
531     ///     println!("{}", *end.sub(1) as char);
532     ///     println!("{}", *end.sub(2) as char);
533     /// }
534     /// ```
535     #[stable(feature = "pointer_methods", since = "1.26.0")]
536     #[must_use = "returns a new pointer rather than modifying its argument"]
537     #[rustc_const_unstable(feature = "const_ptr_offset", issue = "71499")]
538     #[inline]
539     pub const unsafe fn sub(self, count: usize) -> Self
540     where
541         T: Sized,
542     {
543         // SAFETY: the caller must uphold the safety contract for `offset`.
544         unsafe { self.offset((count as isize).wrapping_neg()) }
545     }
546
547     /// Calculates the offset from a pointer using wrapping arithmetic.
548     /// (convenience for `.wrapping_offset(count as isize)`)
549     ///
550     /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
551     /// offset of `3 * size_of::<T>()` bytes.
552     ///
553     /// # Safety
554     ///
555     /// The resulting pointer does not need to be in bounds, but it is
556     /// potentially hazardous to dereference (which requires `unsafe`).
557     ///
558     /// In particular, the resulting pointer remains attached to the same allocated
559     /// object that `self` points to. It may *not* be used to access a
560     /// different allocated object. Note that in Rust,
561     /// every (stack-allocated) variable is considered a separate allocated object.
562     ///
563     /// Compared to [`add`], this method basically delays the requirement of staying
564     /// within the same allocated object: [`add`] is immediate Undefined Behavior when
565     /// crossing object boundaries; `wrapping_add` produces a pointer but still leads
566     /// to Undefined Behavior if that pointer is dereferenced. [`add`] can be optimized
567     /// better and is thus preferable in performance-sensitive code.
568     ///
569     /// If you need to cross object boundaries, cast the pointer to an integer and
570     /// do the arithmetic there.
571     ///
572     /// [`add`]: #method.add
573     ///
574     /// # Examples
575     ///
576     /// Basic usage:
577     ///
578     /// ```
579     /// // Iterate using a raw pointer in increments of two elements
580     /// let data = [1u8, 2, 3, 4, 5];
581     /// let mut ptr: *const u8 = data.as_ptr();
582     /// let step = 2;
583     /// let end_rounded_up = ptr.wrapping_add(6);
584     ///
585     /// // This loop prints "1, 3, 5, "
586     /// while ptr != end_rounded_up {
587     ///     unsafe {
588     ///         print!("{}, ", *ptr);
589     ///     }
590     ///     ptr = ptr.wrapping_add(step);
591     /// }
592     /// ```
593     #[stable(feature = "pointer_methods", since = "1.26.0")]
594     #[must_use = "returns a new pointer rather than modifying its argument"]
595     #[rustc_const_unstable(feature = "const_ptr_offset", issue = "71499")]
596     #[inline]
597     pub const fn wrapping_add(self, count: usize) -> Self
598     where
599         T: Sized,
600     {
601         self.wrapping_offset(count as isize)
602     }
603
604     /// Calculates the offset from a pointer using wrapping arithmetic.
605     /// (convenience for `.wrapping_offset((count as isize).wrapping_sub())`)
606     ///
607     /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
608     /// offset of `3 * size_of::<T>()` bytes.
609     ///
610     /// # Safety
611     ///
612     /// The resulting pointer does not need to be in bounds, but it is
613     /// potentially hazardous to dereference (which requires `unsafe`).
614     ///
615     /// In particular, the resulting pointer remains attached to the same allocated
616     /// object that `self` points to. It may *not* be used to access a
617     /// different allocated object. Note that in Rust,
618     /// every (stack-allocated) variable is considered a separate allocated object.
619     ///
620     /// Compared to [`sub`], this method basically delays the requirement of staying
621     /// within the same allocated object: [`sub`] is immediate Undefined Behavior when
622     /// crossing object boundaries; `wrapping_sub` produces a pointer but still leads
623     /// to Undefined Behavior if that pointer is dereferenced. [`sub`] can be optimized
624     /// better and is thus preferable in performance-sensitive code.
625     ///
626     /// If you need to cross object boundaries, cast the pointer to an integer and
627     /// do the arithmetic there.
628     ///
629     /// [`sub`]: #method.sub
630     ///
631     /// # Examples
632     ///
633     /// Basic usage:
634     ///
635     /// ```
636     /// // Iterate using a raw pointer in increments of two elements (backwards)
637     /// let data = [1u8, 2, 3, 4, 5];
638     /// let mut ptr: *const u8 = data.as_ptr();
639     /// let start_rounded_down = ptr.wrapping_sub(2);
640     /// ptr = ptr.wrapping_add(4);
641     /// let step = 2;
642     /// // This loop prints "5, 3, 1, "
643     /// while ptr != start_rounded_down {
644     ///     unsafe {
645     ///         print!("{}, ", *ptr);
646     ///     }
647     ///     ptr = ptr.wrapping_sub(step);
648     /// }
649     /// ```
650     #[stable(feature = "pointer_methods", since = "1.26.0")]
651     #[must_use = "returns a new pointer rather than modifying its argument"]
652     #[rustc_const_unstable(feature = "const_ptr_offset", issue = "71499")]
653     #[inline]
654     pub const fn wrapping_sub(self, count: usize) -> Self
655     where
656         T: Sized,
657     {
658         self.wrapping_offset((count as isize).wrapping_neg())
659     }
660
661     /// Reads the value from `self` without moving it. This leaves the
662     /// memory in `self` unchanged.
663     ///
664     /// See [`ptr::read`] for safety concerns and examples.
665     ///
666     /// [`ptr::read`]: ./ptr/fn.read.html
667     #[stable(feature = "pointer_methods", since = "1.26.0")]
668     #[inline]
669     pub unsafe fn read(self) -> T
670     where
671         T: Sized,
672     {
673         // SAFETY: the caller must uphold the safety contract for `read`.
674         unsafe { read(self) }
675     }
676
677     /// Performs a volatile read of the value from `self` without moving it. This
678     /// leaves the memory in `self` unchanged.
679     ///
680     /// Volatile operations are intended to act on I/O memory, and are guaranteed
681     /// to not be elided or reordered by the compiler across other volatile
682     /// operations.
683     ///
684     /// See [`ptr::read_volatile`] for safety concerns and examples.
685     ///
686     /// [`ptr::read_volatile`]: ./ptr/fn.read_volatile.html
687     #[stable(feature = "pointer_methods", since = "1.26.0")]
688     #[inline]
689     pub unsafe fn read_volatile(self) -> T
690     where
691         T: Sized,
692     {
693         // SAFETY: the caller must uphold the safety contract for `read_volatile`.
694         unsafe { read_volatile(self) }
695     }
696
697     /// Reads the value from `self` without moving it. This leaves the
698     /// memory in `self` unchanged.
699     ///
700     /// Unlike `read`, the pointer may be unaligned.
701     ///
702     /// See [`ptr::read_unaligned`] for safety concerns and examples.
703     ///
704     /// [`ptr::read_unaligned`]: ./ptr/fn.read_unaligned.html
705     #[stable(feature = "pointer_methods", since = "1.26.0")]
706     #[inline]
707     pub unsafe fn read_unaligned(self) -> T
708     where
709         T: Sized,
710     {
711         // SAFETY: the caller must uphold the safety contract for `read_unaligned`.
712         unsafe { read_unaligned(self) }
713     }
714
715     /// Copies `count * size_of<T>` bytes from `self` to `dest`. The source
716     /// and destination may overlap.
717     ///
718     /// NOTE: this has the *same* argument order as [`ptr::copy`].
719     ///
720     /// See [`ptr::copy`] for safety concerns and examples.
721     ///
722     /// [`ptr::copy`]: ./ptr/fn.copy.html
723     #[stable(feature = "pointer_methods", since = "1.26.0")]
724     #[inline]
725     pub unsafe fn copy_to(self, dest: *mut T, count: usize)
726     where
727         T: Sized,
728     {
729         // SAFETY: the caller must uphold the safety contract for `copy`.
730         unsafe { copy(self, dest, count) }
731     }
732
733     /// Copies `count * size_of<T>` bytes from `self` to `dest`. The source
734     /// and destination may *not* overlap.
735     ///
736     /// NOTE: this has the *same* argument order as [`ptr::copy_nonoverlapping`].
737     ///
738     /// See [`ptr::copy_nonoverlapping`] for safety concerns and examples.
739     ///
740     /// [`ptr::copy_nonoverlapping`]: ./ptr/fn.copy_nonoverlapping.html
741     #[stable(feature = "pointer_methods", since = "1.26.0")]
742     #[inline]
743     pub unsafe fn copy_to_nonoverlapping(self, dest: *mut T, count: usize)
744     where
745         T: Sized,
746     {
747         // SAFETY: the caller must uphold the safety contract for `copy_nonoverlapping`.
748         unsafe { copy_nonoverlapping(self, dest, count) }
749     }
750
751     /// Computes the offset that needs to be applied to the pointer in order to make it aligned to
752     /// `align`.
753     ///
754     /// If it is not possible to align the pointer, the implementation returns
755     /// `usize::MAX`. It is permissible for the implementation to *always*
756     /// return `usize::MAX`. Only your algorithm's performance can depend
757     /// on getting a usable offset here, not its correctness.
758     ///
759     /// The offset is expressed in number of `T` elements, and not bytes. The value returned can be
760     /// used with the `wrapping_add` method.
761     ///
762     /// There are no guarantees whatsoever that offsetting the pointer will not overflow or go
763     /// beyond the allocation that the pointer points into. It is up to the caller to ensure that
764     /// the returned offset is correct in all terms other than alignment.
765     ///
766     /// # Panics
767     ///
768     /// The function panics if `align` is not a power-of-two.
769     ///
770     /// # Examples
771     ///
772     /// Accessing adjacent `u8` as `u16`
773     ///
774     /// ```
775     /// # fn foo(n: usize) {
776     /// # use std::mem::align_of;
777     /// # unsafe {
778     /// let x = [5u8, 6u8, 7u8, 8u8, 9u8];
779     /// let ptr = &x[n] as *const u8;
780     /// let offset = ptr.align_offset(align_of::<u16>());
781     /// if offset < x.len() - n - 1 {
782     ///     let u16_ptr = ptr.add(offset) as *const u16;
783     ///     assert_ne!(*u16_ptr, 500);
784     /// } else {
785     ///     // while the pointer can be aligned via `offset`, it would point
786     ///     // outside the allocation
787     /// }
788     /// # } }
789     /// ```
790     #[stable(feature = "align_offset", since = "1.36.0")]
791     pub fn align_offset(self, align: usize) -> usize
792     where
793         T: Sized,
794     {
795         if !align.is_power_of_two() {
796             panic!("align_offset: align is not a power-of-two");
797         }
798         // SAFETY: `align` has been checked to be a power of 2 above
799         unsafe { align_offset(self, align) }
800     }
801 }
802
803 #[lang = "const_slice_ptr"]
804 impl<T> *const [T] {
805     /// Returns the length of a raw slice.
806     ///
807     /// The returned value is the number of **elements**, not the number of bytes.
808     ///
809     /// This function is safe, even when the raw slice cannot be cast to a slice
810     /// reference because the pointer is null or unaligned.
811     ///
812     /// # Examples
813     ///
814     /// ```rust
815     /// #![feature(slice_ptr_len)]
816     ///
817     /// use std::ptr;
818     ///
819     /// let slice: *const [i8] = ptr::slice_from_raw_parts(ptr::null(), 3);
820     /// assert_eq!(slice.len(), 3);
821     /// ```
822     #[inline]
823     #[unstable(feature = "slice_ptr_len", issue = "71146")]
824     #[rustc_const_unstable(feature = "const_slice_ptr_len", issue = "71146")]
825     pub const fn len(self) -> usize {
826         // SAFETY: this is safe because `*const [T]` and `FatPtr<T>` have the same layout.
827         // Only `std` can make this guarantee.
828         unsafe { Repr { rust: self }.raw }.len
829     }
830
831     /// Returns a raw pointer to the slice's buffer.
832     ///
833     /// This is equivalent to casting `self` to `*const T`, but more type-safe.
834     ///
835     /// # Examples
836     ///
837     /// ```rust
838     /// #![feature(slice_ptr_get)]
839     /// use std::ptr;
840     ///
841     /// let slice: *const [i8] = ptr::slice_from_raw_parts(ptr::null(), 3);
842     /// assert_eq!(slice.as_ptr(), 0 as *const i8);
843     /// ```
844     #[inline]
845     #[unstable(feature = "slice_ptr_get", issue = "none")]
846     #[rustc_const_unstable(feature = "slice_ptr_get", issue = "none")]
847     pub const fn as_ptr(self) -> *const T {
848         self as *const T
849     }
850
851     /// Returns a raw pointer to an element or subslice, without doing bounds
852     /// checking.
853     ///
854     /// Calling this method with an out-of-bounds index or when `self` is not dereferencable
855     /// is *[undefined behavior]* even if the resulting pointer is not used.
856     ///
857     /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
858     ///
859     /// # Examples
860     ///
861     /// ```
862     /// #![feature(slice_ptr_get)]
863     ///
864     /// let x = &[1, 2, 4] as *const [i32];
865     ///
866     /// unsafe {
867     ///     assert_eq!(x.get_unchecked(1), x.as_ptr().add(1));
868     /// }
869     /// ```
870     #[unstable(feature = "slice_ptr_get", issue = "none")]
871     #[inline]
872     pub unsafe fn get_unchecked<I>(self, index: I) -> *const I::Output
873     where
874         I: SliceIndex<[T]>,
875     {
876         // SAFETY: the caller ensures that `self` is dereferencable and `index` in-bounds.
877         unsafe { index.get_unchecked(self) }
878     }
879 }
880
881 // Equality for pointers
882 #[stable(feature = "rust1", since = "1.0.0")]
883 impl<T: ?Sized> PartialEq for *const T {
884     #[inline]
885     fn eq(&self, other: &*const T) -> bool {
886         *self == *other
887     }
888 }
889
890 #[stable(feature = "rust1", since = "1.0.0")]
891 impl<T: ?Sized> Eq for *const T {}
892
893 // Comparison for pointers
894 #[stable(feature = "rust1", since = "1.0.0")]
895 impl<T: ?Sized> Ord for *const T {
896     #[inline]
897     fn cmp(&self, other: &*const T) -> Ordering {
898         if self < other {
899             Less
900         } else if self == other {
901             Equal
902         } else {
903             Greater
904         }
905     }
906 }
907
908 #[stable(feature = "rust1", since = "1.0.0")]
909 impl<T: ?Sized> PartialOrd for *const T {
910     #[inline]
911     fn partial_cmp(&self, other: &*const T) -> Option<Ordering> {
912         Some(self.cmp(other))
913     }
914
915     #[inline]
916     fn lt(&self, other: &*const T) -> bool {
917         *self < *other
918     }
919
920     #[inline]
921     fn le(&self, other: &*const T) -> bool {
922         *self <= *other
923     }
924
925     #[inline]
926     fn gt(&self, other: &*const T) -> bool {
927         *self > *other
928     }
929
930     #[inline]
931     fn ge(&self, other: &*const T) -> bool {
932         *self >= *other
933     }
934 }