File tree 3 files changed +85
-0
lines changed
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 {
66
66
self as _
67
67
}
68
68
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
+
69
97
/// Uses the address value in a new pointer of another type.
70
98
///
71
99
/// 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 {
48
48
self as _
49
49
}
50
50
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
+
51
79
/// Uses the address value in a new pointer of another type.
52
80
///
53
81
/// 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> {
490
490
unsafe { NonNull { pointer : self . as_ptr ( ) as * mut U } }
491
491
}
492
492
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
+
493
522
/// Adds an offset to a pointer.
494
523
///
495
524
/// `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