]> git.lizzy.rs Git - rust.git/blob - library/core/src/ptr/const_ptr.rs
a16970e9fd1802863411b74ac32da08acf1a24b2
[rust.git] / library / core / src / 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     pub const fn guaranteed_eq(self, other: *const T) -> bool
328     where
329         T: Sized,
330     {
331         intrinsics::ptr_guaranteed_eq(self, other)
332     }
333
334     /// Returns whether two pointers are guaranteed to be unequal.
335     ///
336     /// At runtime this function behaves like `self != other`.
337     /// However, in some contexts (e.g., compile-time evaluation),
338     /// it is not always possible to determine the inequality of two pointers, so this function may
339     /// spuriously return `false` for pointers that later actually turn out to be unequal.
340     /// But when it returns `true`, the pointers are guaranteed to be unequal.
341     ///
342     /// This function is the mirror of [`guaranteed_eq`], but not its inverse. There are pointer
343     /// comparisons for which both functions return `false`.
344     ///
345     /// [`guaranteed_eq`]: #method.guaranteed_eq
346     ///
347     /// The return value may change depending on the compiler version and unsafe code may not
348     /// rely on the result of this function for soundness. It is suggested to only use this function
349     /// for performance optimizations where spurious `false` return values by this function do not
350     /// affect the outcome, but just the performance.
351     /// The consequences of using this method to make runtime and compile-time code behave
352     /// differently have not been explored. This method should not be used to introduce such
353     /// differences, and it should also not be stabilized before we have a better understanding
354     /// of this issue.
355     #[unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
356     #[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
357     #[inline]
358     pub const fn guaranteed_ne(self, other: *const T) -> bool
359     where
360         T: Sized,
361     {
362         intrinsics::ptr_guaranteed_ne(self, other)
363     }
364
365     /// Calculates the distance between two pointers. The returned value is in
366     /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
367     ///
368     /// If the address different between the two pointers is not a multiple of
369     /// `mem::size_of::<T>()` then the result of the division is rounded towards
370     /// zero.
371     ///
372     /// Though this method is safe for any two pointers, note that its result
373     /// will be mostly useless if the two pointers aren't into the same allocated
374     /// object, for example if they point to two different local variables.
375     ///
376     /// # Panics
377     ///
378     /// This function panics if `T` is a zero-sized type.
379     ///
380     /// # Examples
381     ///
382     /// Basic usage:
383     ///
384     /// ```
385     /// #![feature(ptr_wrapping_offset_from)]
386     ///
387     /// let a = [0; 5];
388     /// let ptr1: *const i32 = &a[1];
389     /// let ptr2: *const i32 = &a[3];
390     /// assert_eq!(ptr2.wrapping_offset_from(ptr1), 2);
391     /// assert_eq!(ptr1.wrapping_offset_from(ptr2), -2);
392     /// assert_eq!(ptr1.wrapping_offset(2), ptr2);
393     /// assert_eq!(ptr2.wrapping_offset(-2), ptr1);
394     ///
395     /// let ptr1: *const i32 = 3 as _;
396     /// let ptr2: *const i32 = 13 as _;
397     /// assert_eq!(ptr2.wrapping_offset_from(ptr1), 2);
398     /// ```
399     #[unstable(feature = "ptr_wrapping_offset_from", issue = "41079")]
400     #[rustc_deprecated(
401         since = "1.46.0",
402         reason = "Pointer distances across allocation \
403         boundaries are not typically meaningful. \
404         Use integer subtraction if you really need this."
405     )]
406     #[inline]
407     pub fn wrapping_offset_from(self, origin: *const T) -> isize
408     where
409         T: Sized,
410     {
411         let pointee_size = mem::size_of::<T>();
412         assert!(0 < pointee_size && pointee_size <= isize::MAX as usize);
413
414         let d = isize::wrapping_sub(self as _, origin as _);
415         d.wrapping_div(pointee_size as _)
416     }
417
418     /// Calculates the offset from a pointer (convenience for `.offset(count as isize)`).
419     ///
420     /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
421     /// offset of `3 * size_of::<T>()` bytes.
422     ///
423     /// # Safety
424     ///
425     /// If any of the following conditions are violated, the result is Undefined
426     /// Behavior:
427     ///
428     /// * Both the starting and resulting pointer must be either in bounds or one
429     ///   byte past the end of the same allocated object. Note that in Rust,
430     ///   every (stack-allocated) variable is considered a separate allocated object.
431     ///
432     /// * The computed offset, **in bytes**, cannot overflow an `isize`.
433     ///
434     /// * The offset being in bounds cannot rely on "wrapping around" the address
435     ///   space. That is, the infinite-precision sum must fit in a `usize`.
436     ///
437     /// The compiler and standard library generally tries to ensure allocations
438     /// never reach a size where an offset is a concern. For instance, `Vec`
439     /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so
440     /// `vec.as_ptr().add(vec.len())` is always safe.
441     ///
442     /// Most platforms fundamentally can't even construct such an allocation.
443     /// For instance, no known 64-bit platform can ever serve a request
444     /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
445     /// However, some 32-bit and 16-bit platforms may successfully serve a request for
446     /// more than `isize::MAX` bytes with things like Physical Address
447     /// Extension. As such, memory acquired directly from allocators or memory
448     /// mapped files *may* be too large to handle with this function.
449     ///
450     /// Consider using [`wrapping_add`] instead if these constraints are
451     /// difficult to satisfy. The only advantage of this method is that it
452     /// enables more aggressive compiler optimizations.
453     ///
454     /// [`wrapping_add`]: #method.wrapping_add
455     ///
456     /// # Examples
457     ///
458     /// Basic usage:
459     ///
460     /// ```
461     /// let s: &str = "123";
462     /// let ptr: *const u8 = s.as_ptr();
463     ///
464     /// unsafe {
465     ///     println!("{}", *ptr.add(1) as char);
466     ///     println!("{}", *ptr.add(2) as char);
467     /// }
468     /// ```
469     #[stable(feature = "pointer_methods", since = "1.26.0")]
470     #[must_use = "returns a new pointer rather than modifying its argument"]
471     #[rustc_const_unstable(feature = "const_ptr_offset", issue = "71499")]
472     #[inline]
473     pub const unsafe fn add(self, count: usize) -> Self
474     where
475         T: Sized,
476     {
477         // SAFETY: the caller must uphold the safety contract for `offset`.
478         unsafe { self.offset(count as isize) }
479     }
480
481     /// Calculates the offset from a pointer (convenience for
482     /// `.offset((count as isize).wrapping_neg())`).
483     ///
484     /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
485     /// offset of `3 * size_of::<T>()` bytes.
486     ///
487     /// # Safety
488     ///
489     /// If any of the following conditions are violated, the result is Undefined
490     /// Behavior:
491     ///
492     /// * Both the starting and resulting pointer must be either in bounds or one
493     ///   byte past the end of the same allocated object. Note that in Rust,
494     ///   every (stack-allocated) variable is considered a separate allocated object.
495     ///
496     /// * The computed offset cannot exceed `isize::MAX` **bytes**.
497     ///
498     /// * The offset being in bounds cannot rely on "wrapping around" the address
499     ///   space. That is, the infinite-precision sum must fit in a usize.
500     ///
501     /// The compiler and standard library generally tries to ensure allocations
502     /// never reach a size where an offset is a concern. For instance, `Vec`
503     /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so
504     /// `vec.as_ptr().add(vec.len()).sub(vec.len())` is always safe.
505     ///
506     /// Most platforms fundamentally can't even construct such an allocation.
507     /// For instance, no known 64-bit platform can ever serve a request
508     /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
509     /// However, some 32-bit and 16-bit platforms may successfully serve a request for
510     /// more than `isize::MAX` bytes with things like Physical Address
511     /// Extension. As such, memory acquired directly from allocators or memory
512     /// mapped files *may* be too large to handle with this function.
513     ///
514     /// Consider using [`wrapping_sub`] instead if these constraints are
515     /// difficult to satisfy. The only advantage of this method is that it
516     /// enables more aggressive compiler optimizations.
517     ///
518     /// [`wrapping_sub`]: #method.wrapping_sub
519     ///
520     /// # Examples
521     ///
522     /// Basic usage:
523     ///
524     /// ```
525     /// let s: &str = "123";
526     ///
527     /// unsafe {
528     ///     let end: *const u8 = s.as_ptr().add(3);
529     ///     println!("{}", *end.sub(1) as char);
530     ///     println!("{}", *end.sub(2) as char);
531     /// }
532     /// ```
533     #[stable(feature = "pointer_methods", since = "1.26.0")]
534     #[must_use = "returns a new pointer rather than modifying its argument"]
535     #[rustc_const_unstable(feature = "const_ptr_offset", issue = "71499")]
536     #[inline]
537     pub const unsafe fn sub(self, count: usize) -> Self
538     where
539         T: Sized,
540     {
541         // SAFETY: the caller must uphold the safety contract for `offset`.
542         unsafe { self.offset((count as isize).wrapping_neg()) }
543     }
544
545     /// Calculates the offset from a pointer using wrapping arithmetic.
546     /// (convenience for `.wrapping_offset(count as isize)`)
547     ///
548     /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
549     /// offset of `3 * size_of::<T>()` bytes.
550     ///
551     /// # Safety
552     ///
553     /// The resulting pointer does not need to be in bounds, but it is
554     /// potentially hazardous to dereference (which requires `unsafe`).
555     ///
556     /// In particular, the resulting pointer remains attached to the same allocated
557     /// object that `self` points to. It may *not* be used to access a
558     /// different allocated object. Note that in Rust,
559     /// every (stack-allocated) variable is considered a separate allocated object.
560     ///
561     /// Compared to [`add`], this method basically delays the requirement of staying
562     /// within the same allocated object: [`add`] is immediate Undefined Behavior when
563     /// crossing object boundaries; `wrapping_add` produces a pointer but still leads
564     /// to Undefined Behavior if that pointer is dereferenced. [`add`] can be optimized
565     /// better and is thus preferable in performance-sensitive code.
566     ///
567     /// If you need to cross object boundaries, cast the pointer to an integer and
568     /// do the arithmetic there.
569     ///
570     /// [`add`]: #method.add
571     ///
572     /// # Examples
573     ///
574     /// Basic usage:
575     ///
576     /// ```
577     /// // Iterate using a raw pointer in increments of two elements
578     /// let data = [1u8, 2, 3, 4, 5];
579     /// let mut ptr: *const u8 = data.as_ptr();
580     /// let step = 2;
581     /// let end_rounded_up = ptr.wrapping_add(6);
582     ///
583     /// // This loop prints "1, 3, 5, "
584     /// while ptr != end_rounded_up {
585     ///     unsafe {
586     ///         print!("{}, ", *ptr);
587     ///     }
588     ///     ptr = ptr.wrapping_add(step);
589     /// }
590     /// ```
591     #[stable(feature = "pointer_methods", since = "1.26.0")]
592     #[must_use = "returns a new pointer rather than modifying its argument"]
593     #[rustc_const_unstable(feature = "const_ptr_offset", issue = "71499")]
594     #[inline]
595     pub const fn wrapping_add(self, count: usize) -> Self
596     where
597         T: Sized,
598     {
599         self.wrapping_offset(count as isize)
600     }
601
602     /// Calculates the offset from a pointer using wrapping arithmetic.
603     /// (convenience for `.wrapping_offset((count as isize).wrapping_sub())`)
604     ///
605     /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
606     /// offset of `3 * size_of::<T>()` bytes.
607     ///
608     /// # Safety
609     ///
610     /// The resulting pointer does not need to be in bounds, but it is
611     /// potentially hazardous to dereference (which requires `unsafe`).
612     ///
613     /// In particular, the resulting pointer remains attached to the same allocated
614     /// object that `self` points to. It may *not* be used to access a
615     /// different allocated object. Note that in Rust,
616     /// every (stack-allocated) variable is considered a separate allocated object.
617     ///
618     /// Compared to [`sub`], this method basically delays the requirement of staying
619     /// within the same allocated object: [`sub`] is immediate Undefined Behavior when
620     /// crossing object boundaries; `wrapping_sub` produces a pointer but still leads
621     /// to Undefined Behavior if that pointer is dereferenced. [`sub`] can be optimized
622     /// better and is thus preferable in performance-sensitive code.
623     ///
624     /// If you need to cross object boundaries, cast the pointer to an integer and
625     /// do the arithmetic there.
626     ///
627     /// [`sub`]: #method.sub
628     ///
629     /// # Examples
630     ///
631     /// Basic usage:
632     ///
633     /// ```
634     /// // Iterate using a raw pointer in increments of two elements (backwards)
635     /// let data = [1u8, 2, 3, 4, 5];
636     /// let mut ptr: *const u8 = data.as_ptr();
637     /// let start_rounded_down = ptr.wrapping_sub(2);
638     /// ptr = ptr.wrapping_add(4);
639     /// let step = 2;
640     /// // This loop prints "5, 3, 1, "
641     /// while ptr != start_rounded_down {
642     ///     unsafe {
643     ///         print!("{}, ", *ptr);
644     ///     }
645     ///     ptr = ptr.wrapping_sub(step);
646     /// }
647     /// ```
648     #[stable(feature = "pointer_methods", since = "1.26.0")]
649     #[must_use = "returns a new pointer rather than modifying its argument"]
650     #[rustc_const_unstable(feature = "const_ptr_offset", issue = "71499")]
651     #[inline]
652     pub const fn wrapping_sub(self, count: usize) -> Self
653     where
654         T: Sized,
655     {
656         self.wrapping_offset((count as isize).wrapping_neg())
657     }
658
659     /// Sets the pointer value to `ptr`.
660     ///
661     /// In case `self` is a (fat) pointer to an unsized type, this operation
662     /// will only affect the pointer part, whereas for (thin) pointers to
663     /// sized types, this has the same effect as a simple assignment.
664     ///
665     /// # Examples
666     ///
667     /// This function is primarily useful for allowing byte-wise pointer
668     /// arithmetic on potentially fat pointers:
669     ///
670     /// ```
671     /// #![feature(set_ptr_value)]
672     /// # use core::fmt::Debug;
673     /// let arr: [i32; 3] = [1, 2, 3];
674     /// let mut ptr = &arr[0] as *const dyn Debug;
675     /// let thin = ptr as *const u8;
676     /// ptr = ptr.set_ptr_value(unsafe { thin.add(8).cast() });
677     /// assert_eq!(unsafe { *(ptr as *const i32) }, 3);
678     /// ```
679     #[unstable(feature = "set_ptr_value", issue = "75091")]
680     #[inline]
681     pub fn set_ptr_value(mut self, val: *const ()) -> Self {
682         let thin = &mut self as *mut *const T as *mut *const ();
683         // SAFETY: In case of a thin pointer, this operations is identical
684         // to a simple assignment. In case of a fat pointer, with the current
685         // fat pointer layout implementation, the first field of such a
686         // pointer is always the data pointer, which is likewise assigned.
687         unsafe { *thin = val };
688         self
689     }
690
691     /// Reads the value from `self` without moving it. This leaves the
692     /// memory in `self` unchanged.
693     ///
694     /// See [`ptr::read`] for safety concerns and examples.
695     ///
696     /// [`ptr::read`]: ./ptr/fn.read.html
697     #[stable(feature = "pointer_methods", since = "1.26.0")]
698     #[inline]
699     pub unsafe fn read(self) -> T
700     where
701         T: Sized,
702     {
703         // SAFETY: the caller must uphold the safety contract for `read`.
704         unsafe { read(self) }
705     }
706
707     /// Performs a volatile read of the value from `self` without moving it. This
708     /// leaves the memory in `self` unchanged.
709     ///
710     /// Volatile operations are intended to act on I/O memory, and are guaranteed
711     /// to not be elided or reordered by the compiler across other volatile
712     /// operations.
713     ///
714     /// See [`ptr::read_volatile`] for safety concerns and examples.
715     ///
716     /// [`ptr::read_volatile`]: ./ptr/fn.read_volatile.html
717     #[stable(feature = "pointer_methods", since = "1.26.0")]
718     #[inline]
719     pub unsafe fn read_volatile(self) -> T
720     where
721         T: Sized,
722     {
723         // SAFETY: the caller must uphold the safety contract for `read_volatile`.
724         unsafe { read_volatile(self) }
725     }
726
727     /// Reads the value from `self` without moving it. This leaves the
728     /// memory in `self` unchanged.
729     ///
730     /// Unlike `read`, the pointer may be unaligned.
731     ///
732     /// See [`ptr::read_unaligned`] for safety concerns and examples.
733     ///
734     /// [`ptr::read_unaligned`]: ./ptr/fn.read_unaligned.html
735     #[stable(feature = "pointer_methods", since = "1.26.0")]
736     #[inline]
737     pub unsafe fn read_unaligned(self) -> T
738     where
739         T: Sized,
740     {
741         // SAFETY: the caller must uphold the safety contract for `read_unaligned`.
742         unsafe { read_unaligned(self) }
743     }
744
745     /// Copies `count * size_of<T>` bytes from `self` to `dest`. The source
746     /// and destination may overlap.
747     ///
748     /// NOTE: this has the *same* argument order as [`ptr::copy`].
749     ///
750     /// See [`ptr::copy`] for safety concerns and examples.
751     ///
752     /// [`ptr::copy`]: ./ptr/fn.copy.html
753     #[stable(feature = "pointer_methods", since = "1.26.0")]
754     #[inline]
755     pub unsafe fn copy_to(self, dest: *mut T, count: usize)
756     where
757         T: Sized,
758     {
759         // SAFETY: the caller must uphold the safety contract for `copy`.
760         unsafe { copy(self, dest, count) }
761     }
762
763     /// Copies `count * size_of<T>` bytes from `self` to `dest`. The source
764     /// and destination may *not* overlap.
765     ///
766     /// NOTE: this has the *same* argument order as [`ptr::copy_nonoverlapping`].
767     ///
768     /// See [`ptr::copy_nonoverlapping`] for safety concerns and examples.
769     ///
770     /// [`ptr::copy_nonoverlapping`]: ./ptr/fn.copy_nonoverlapping.html
771     #[stable(feature = "pointer_methods", since = "1.26.0")]
772     #[inline]
773     pub unsafe fn copy_to_nonoverlapping(self, dest: *mut T, count: usize)
774     where
775         T: Sized,
776     {
777         // SAFETY: the caller must uphold the safety contract for `copy_nonoverlapping`.
778         unsafe { copy_nonoverlapping(self, dest, count) }
779     }
780
781     /// Computes the offset that needs to be applied to the pointer in order to make it aligned to
782     /// `align`.
783     ///
784     /// If it is not possible to align the pointer, the implementation returns
785     /// `usize::MAX`. It is permissible for the implementation to *always*
786     /// return `usize::MAX`. Only your algorithm's performance can depend
787     /// on getting a usable offset here, not its correctness.
788     ///
789     /// The offset is expressed in number of `T` elements, and not bytes. The value returned can be
790     /// used with the `wrapping_add` method.
791     ///
792     /// There are no guarantees whatsoever that offsetting the pointer will not overflow or go
793     /// beyond the allocation that the pointer points into. It is up to the caller to ensure that
794     /// the returned offset is correct in all terms other than alignment.
795     ///
796     /// # Panics
797     ///
798     /// The function panics if `align` is not a power-of-two.
799     ///
800     /// # Examples
801     ///
802     /// Accessing adjacent `u8` as `u16`
803     ///
804     /// ```
805     /// # fn foo(n: usize) {
806     /// # use std::mem::align_of;
807     /// # unsafe {
808     /// let x = [5u8, 6u8, 7u8, 8u8, 9u8];
809     /// let ptr = &x[n] as *const u8;
810     /// let offset = ptr.align_offset(align_of::<u16>());
811     /// if offset < x.len() - n - 1 {
812     ///     let u16_ptr = ptr.add(offset) as *const u16;
813     ///     assert_ne!(*u16_ptr, 500);
814     /// } else {
815     ///     // while the pointer can be aligned via `offset`, it would point
816     ///     // outside the allocation
817     /// }
818     /// # } }
819     /// ```
820     #[stable(feature = "align_offset", since = "1.36.0")]
821     pub fn align_offset(self, align: usize) -> usize
822     where
823         T: Sized,
824     {
825         if !align.is_power_of_two() {
826             panic!("align_offset: align is not a power-of-two");
827         }
828         // SAFETY: `align` has been checked to be a power of 2 above
829         unsafe { align_offset(self, align) }
830     }
831 }
832
833 #[lang = "const_slice_ptr"]
834 impl<T> *const [T] {
835     /// Returns the length of a raw slice.
836     ///
837     /// The returned value is the number of **elements**, not the number of bytes.
838     ///
839     /// This function is safe, even when the raw slice cannot be cast to a slice
840     /// reference because the pointer is null or unaligned.
841     ///
842     /// # Examples
843     ///
844     /// ```rust
845     /// #![feature(slice_ptr_len)]
846     ///
847     /// use std::ptr;
848     ///
849     /// let slice: *const [i8] = ptr::slice_from_raw_parts(ptr::null(), 3);
850     /// assert_eq!(slice.len(), 3);
851     /// ```
852     #[inline]
853     #[unstable(feature = "slice_ptr_len", issue = "71146")]
854     #[rustc_const_unstable(feature = "const_slice_ptr_len", issue = "71146")]
855     pub const fn len(self) -> usize {
856         // SAFETY: this is safe because `*const [T]` and `FatPtr<T>` have the same layout.
857         // Only `std` can make this guarantee.
858         unsafe { Repr { rust: self }.raw }.len
859     }
860
861     /// Returns a raw pointer to the slice's buffer.
862     ///
863     /// This is equivalent to casting `self` to `*const T`, but more type-safe.
864     ///
865     /// # Examples
866     ///
867     /// ```rust
868     /// #![feature(slice_ptr_get)]
869     /// use std::ptr;
870     ///
871     /// let slice: *const [i8] = ptr::slice_from_raw_parts(ptr::null(), 3);
872     /// assert_eq!(slice.as_ptr(), 0 as *const i8);
873     /// ```
874     #[inline]
875     #[unstable(feature = "slice_ptr_get", issue = "74265")]
876     #[rustc_const_unstable(feature = "slice_ptr_get", issue = "74265")]
877     pub const fn as_ptr(self) -> *const T {
878         self as *const T
879     }
880
881     /// Returns a raw pointer to an element or subslice, without doing bounds
882     /// checking.
883     ///
884     /// Calling this method with an out-of-bounds index or when `self` is not dereferencable
885     /// is *[undefined behavior]* even if the resulting pointer is not used.
886     ///
887     /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
888     ///
889     /// # Examples
890     ///
891     /// ```
892     /// #![feature(slice_ptr_get)]
893     ///
894     /// let x = &[1, 2, 4] as *const [i32];
895     ///
896     /// unsafe {
897     ///     assert_eq!(x.get_unchecked(1), x.as_ptr().add(1));
898     /// }
899     /// ```
900     #[unstable(feature = "slice_ptr_get", issue = "74265")]
901     #[inline]
902     pub unsafe fn get_unchecked<I>(self, index: I) -> *const I::Output
903     where
904         I: SliceIndex<[T]>,
905     {
906         // SAFETY: the caller ensures that `self` is dereferencable and `index` in-bounds.
907         unsafe { index.get_unchecked(self) }
908     }
909 }
910
911 // Equality for pointers
912 #[stable(feature = "rust1", since = "1.0.0")]
913 impl<T: ?Sized> PartialEq for *const T {
914     #[inline]
915     fn eq(&self, other: &*const T) -> bool {
916         *self == *other
917     }
918 }
919
920 #[stable(feature = "rust1", since = "1.0.0")]
921 impl<T: ?Sized> Eq for *const T {}
922
923 // Comparison for pointers
924 #[stable(feature = "rust1", since = "1.0.0")]
925 impl<T: ?Sized> Ord for *const T {
926     #[inline]
927     fn cmp(&self, other: &*const T) -> Ordering {
928         if self < other {
929             Less
930         } else if self == other {
931             Equal
932         } else {
933             Greater
934         }
935     }
936 }
937
938 #[stable(feature = "rust1", since = "1.0.0")]
939 impl<T: ?Sized> PartialOrd for *const T {
940     #[inline]
941     fn partial_cmp(&self, other: &*const T) -> Option<Ordering> {
942         Some(self.cmp(other))
943     }
944
945     #[inline]
946     fn lt(&self, other: &*const T) -> bool {
947         *self < *other
948     }
949
950     #[inline]
951     fn le(&self, other: &*const T) -> bool {
952         *self <= *other
953     }
954
955     #[inline]
956     fn gt(&self, other: &*const T) -> bool {
957         *self > *other
958     }
959
960     #[inline]
961     fn ge(&self, other: &*const T) -> bool {
962         *self >= *other
963     }
964 }