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