This repository was archived by the owner on May 28, 2025. It is now read-only.
File tree Expand file tree Collapse file tree 3 files changed +85
-0
lines changed Expand file tree Collapse file tree 3 files changed +85
-0
lines changed Original file line number Diff line number Diff line change @@ -66,6 +66,34 @@ impl<T: ?Sized> *const T {
6666 self as _
6767 }
6868
69+ /// Try to cast to a pointer of another type by checking aligment.
70+ ///
71+ /// If the pointer is properly aligned to the target type, it will be
72+ /// cast to the target type. Otherwise, `None` is returned.
73+ ///
74+ /// # Examples
75+ ///
76+ /// ```rust
77+ /// #![feature(pointer_try_cast_aligned)]
78+ ///
79+ /// let aligned: *const u8 = 0x1000 as _;
80+ ///
81+ /// // i32 has at most 4-byte alignment, so this will succeed
82+ /// assert!(aligned.try_cast_aligned::<i32>().is_some());
83+ ///
84+ /// let unaligned: *const u8 = 0x1001 as _;
85+ ///
86+ /// // i32 has at least 2-byte alignment, so this will fail
87+ /// assert!(unaligned.try_cast_aligned::<i32>().is_none());
88+ /// ```
89+ #[ unstable( feature = "pointer_try_cast_aligned" , issue = "141221" ) ]
90+ #[ must_use = "this returns the result of the operation, \
91+ without modifying the original"]
92+ #[ inline]
93+ pub fn try_cast_aligned < U > ( self ) -> Option < * const U > {
94+ if self . is_aligned_to ( align_of :: < U > ( ) ) { Some ( self . cast ( ) ) } else { None }
95+ }
96+
6997 /// Uses the address value in a new pointer of another type.
7098 ///
7199 /// This operation will ignore the address part of its `meta` operand and discard existing
Original file line number Diff line number Diff line change @@ -48,6 +48,34 @@ impl<T: ?Sized> *mut T {
4848 self as _
4949 }
5050
51+ /// Try to cast to a pointer of another type by checking aligment.
52+ ///
53+ /// If the pointer is properly aligned to the target type, it will be
54+ /// cast to the target type. Otherwise, `None` is returned.
55+ ///
56+ /// # Examples
57+ ///
58+ /// ```rust
59+ /// #![feature(pointer_try_cast_aligned)]
60+ ///
61+ /// let aligned: *mut u8 = 0x1000 as _;
62+ ///
63+ /// // i32 has at most 4-byte alignment, so this will succeed
64+ /// assert!(aligned.try_cast_aligned::<i32>().is_some());
65+ ///
66+ /// let unaligned: *mut u8 = 0x1001 as _;
67+ ///
68+ /// // i32 has at least 2-byte alignment, so this will fail
69+ /// assert!(unaligned.try_cast_aligned::<i32>().is_none());
70+ /// ```
71+ #[ unstable( feature = "pointer_try_cast_aligned" , issue = "141221" ) ]
72+ #[ must_use = "this returns the result of the operation, \
73+ without modifying the original"]
74+ #[ inline]
75+ pub fn try_cast_aligned < U > ( self ) -> Option < * mut U > {
76+ if self . is_aligned_to ( align_of :: < U > ( ) ) { Some ( self . cast ( ) ) } else { None }
77+ }
78+
5179 /// Uses the address value in a new pointer of another type.
5280 ///
5381 /// This operation will ignore the address part of its `meta` operand and discard existing
Original file line number Diff line number Diff line change @@ -490,6 +490,35 @@ impl<T: ?Sized> NonNull<T> {
490490 unsafe { NonNull { pointer : self . as_ptr ( ) as * mut U } }
491491 }
492492
493+ /// Try to cast to a pointer of another type by checking aligment.
494+ ///
495+ /// If the pointer is properly aligned to the target type, it will be
496+ /// cast to the target type. Otherwise, `None` is returned.
497+ ///
498+ /// # Examples
499+ ///
500+ /// ```rust
501+ /// #![feature(pointer_try_cast_aligned)]
502+ /// use std::ptr::NonNull;
503+ ///
504+ /// let aligned: NonNull<u8> = NonNull::new(0x1000 as _).unwrap();
505+ ///
506+ /// // i32 has at most 4-byte alignment, so this will succeed
507+ /// assert!(aligned.try_cast_aligned::<i32>().is_some());
508+ ///
509+ /// let unaligned: NonNull<u8> = NonNull::new(0x1001 as _).unwrap();
510+ ///
511+ /// // i32 has at least 2-byte alignment, so this will fail
512+ /// assert!(unaligned.try_cast_aligned::<i32>().is_none());
513+ /// ```
514+ #[ unstable( feature = "pointer_try_cast_aligned" , issue = "141221" ) ]
515+ #[ must_use = "this returns the result of the operation, \
516+ without modifying the original"]
517+ #[ inline]
518+ pub fn try_cast_aligned < U > ( self ) -> Option < NonNull < U > > {
519+ if self . is_aligned_to ( align_of :: < U > ( ) ) { Some ( self . cast ( ) ) } else { None }
520+ }
521+
493522 /// Adds an offset to a pointer.
494523 ///
495524 /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
You can’t perform that action at this time.
0 commit comments