aligned_ptr/ptr.rs
1//! A module containing functions defined in [`core::ptr`] with null and alignment checks.
2
3use crate::return_error_on_null_or_misaligned;
4use crate::Result;
5use crate::ERR_MSG;
6
7/// The wrapper of `*p` which panics if `p` is either null or not aligned.
8///
9/// # Safety
10///
11/// The caller must follow the safety rules listed at [`core::ptr`] except the alignment and null
12/// rules.
13///
14/// # Panics
15///
16/// This function panics if `p` is either null or not aligned correctly.
17///
18/// # Examples
19///
20/// ```rust
21/// use aligned_ptr::ptr;
22///
23/// let b = Box::new(3);
24/// let p = Box::into_raw(b);
25///
26/// assert_eq!(unsafe { ptr::get(p) }, 3);
27/// ```
28pub unsafe fn get<T: Copy>(p: *const T) -> T {
29 // SAFETY: The caller must uphold the all safety rules.
30 unsafe { try_get(p).expect(ERR_MSG) }
31}
32
33/// The wrapper of `*p` which returns an error if the pointer is either null or not aligned.
34///
35/// # Safety
36///
37/// The caller must follow the safety rules listed at [`core::ptr`] except the alignment and null
38/// rules.
39///
40/// # Errors
41///
42/// This function may return an error:
43///
44/// - [`crate::Error::Null`] - `p` is null.
45/// - [`crate::Error::NotAligned`] - `p` is not aligned correctly.
46///
47/// # Examples
48///
49/// ```rust
50/// use aligned_ptr::ptr;
51/// use aligned_ptr::Error;
52///
53/// let b = Box::new(3);
54/// let p = Box::into_raw(b);
55/// assert_eq!(unsafe { ptr::try_get(p) }, Ok(3));
56///
57/// let p: *const i32 = core::ptr::null();
58/// assert_eq!(unsafe { ptr::try_get(p) }, Err(Error::Null));
59///
60/// let p = 0x1001 as *const i32;
61/// assert_eq!(unsafe { ptr::try_get(p) }, Err(Error::NotAligned));
62/// ```
63pub unsafe fn try_get<T: Copy>(p: *const T) -> Result<T> {
64 return_error_on_null_or_misaligned(p)?;
65
66 // SAFETY: The caller must uphold the all safety rules.
67 Ok(unsafe { *p })
68}
69
70/// The wrapper of `&mut *p` which panics if `p` is either null or not aligned.
71///
72/// # Safety
73///
74/// The caller must follow the safety rules listed at [`core::ptr`] except the alignment and null
75/// rules.
76///
77/// # Panics
78///
79/// This function panics if `p` is either null or not aligned correctly.
80///
81/// # Examples
82///
83/// ```rust
84/// use aligned_ptr::ptr;
85///
86/// let mut x = 3;
87/// let p = &mut x as *mut i32;
88/// let r = unsafe { ptr::as_mut(p) };
89/// *r = 4;
90/// assert_eq!(x, 4);
91/// ```
92pub unsafe fn as_mut<'a, T>(p: *mut T) -> &'a mut T {
93 // SAFETY: The caller must uphold the all safety notes.
94 unsafe { try_as_mut(p).expect(ERR_MSG) }
95}
96
97/// The wrapper of `&mut *p` which may return an error if `p` is either null or not aligned.
98///
99/// # Safety
100///
101/// The caller must follow the safety rules listed at [`core::ptr`] except the alignment and null
102/// rules.
103///
104/// # Errors
105///
106/// This function may return an error:
107///
108/// - [`crate::Error::Null`] - `p` is null.
109/// - [`crate::Error::NotAligned`] - `p` is not aligned correctly.
110///
111/// # Examples
112///
113/// ```rust
114/// use aligned_ptr::ptr;
115/// use aligned_ptr::Error;
116///
117/// let mut x = 3;
118/// let p = &mut x as *mut i32;
119/// let r = unsafe { ptr::try_as_mut(p) };
120///
121/// if let Ok(r) = r {
122/// *r = 4;
123/// assert_eq!(x, 4);
124/// } else {
125/// unreachable!();
126/// }
127///
128/// let mut p: *mut i32 = core::ptr::null_mut();
129/// let r = unsafe { ptr::try_as_mut(p) };
130/// assert_eq!(r, Err(Error::Null));
131///
132/// let mut p = 0x1001 as *mut i32;
133/// let r = unsafe { ptr::try_as_mut(p) };
134/// assert_eq!(r, Err(Error::NotAligned));
135/// ```
136pub unsafe fn try_as_mut<'a, T>(p: *mut T) -> Result<&'a mut T> {
137 return_error_on_null_or_misaligned(p)?;
138
139 // SAFETY: The caller must uphold the all safety rules.
140 Ok(unsafe { &mut *p })
141}
142
143/// The wrapper of `&*p` which panics if `p` is either null or not aligned.
144///
145/// # Safety
146///
147/// The caller must follow the safety rules listed at [`core::ptr`] except the alignment and null
148/// rules.
149///
150/// # Panics
151///
152/// This function panics if `p` is either null or not aligned correctly.
153///
154/// # Examples
155///
156/// ```rust
157/// use aligned_ptr::ptr;
158///
159/// let x = 3;
160/// let p = &x as *const i32;
161/// let r = unsafe { ptr::as_ref(p) };
162/// assert_eq!(*r, 3);
163/// ```
164pub unsafe fn as_ref<'a, T>(p: *const T) -> &'a T {
165 // SAFETY: The caller must uphold the all safety rules.
166 unsafe { try_as_ref(p).expect(ERR_MSG) }
167}
168
169/// The wrapper of `&*p` which may return an error if `p` is either null or not aligned.
170///
171/// # Safety
172///
173/// The caller must follow the safety rules listed at [`core::ptr`] except the alignment and null
174/// rules.
175///
176/// # Errors
177///
178/// This function may return an error:
179///
180/// - [`crate::Error::Null`] - `p` is null.
181/// - [`crate::Error::NotAligned`] - `p` is not aligned correctly.
182///
183/// # Examples
184///
185/// ```rust
186/// use aligned_ptr::ptr;
187/// use aligned_ptr::Error;
188///
189/// let x = 3;
190/// let p = &x as *const i32;
191/// let r = unsafe { ptr::try_as_ref(p) };
192///
193/// assert_eq!(r, Ok(&3));
194///
195/// let p: *const i32 = core::ptr::null();
196/// let r = unsafe { ptr::try_as_ref(p) };
197/// assert_eq!(r, Err(Error::Null));
198///
199/// let mut p = 0x1001 as *const i32;
200/// let r = unsafe { ptr::try_as_ref(p) };
201/// assert_eq!(r, Err(Error::NotAligned));
202/// ```
203pub unsafe fn try_as_ref<'a, T>(p: *const T) -> Result<&'a T> {
204 return_error_on_null_or_misaligned(p)?;
205
206 // SAFETY: The caller must uphold the all safety rules.
207 Ok(unsafe { &*p })
208}
209
210/// The wrapper of [`core::ptr::read`] which panics if the passed pointer is either null or not
211/// aligned.
212///
213/// # Safety
214///
215/// The caller must follow the safety rules required by [`core::ptr::read`] except the alignment and null
216/// rules.
217///
218/// # Panics
219///
220/// This function panics if `p` is either null or not aligned correctly.
221///
222/// # Examples
223///
224/// ```rust
225/// use aligned_ptr::ptr;
226///
227/// let x = 3;
228/// let p = &x as *const _;
229///
230/// assert_eq!(unsafe { ptr::read(p) }, 3);
231/// ```
232pub unsafe fn read<T>(p: *const T) -> T {
233 // SAFETY: The caller must uphold the all safety rules.
234 unsafe { try_read(p).expect(ERR_MSG) }
235}
236
237/// The wrapper of [`core::ptr::read`] which may return an error if the passed pointer is either
238/// null or not null.
239///
240/// # Safety
241///
242/// The caller must follow the safety rules required by [`core::ptr::read`] except the alignment
243/// and null rules.
244///
245/// # Errors
246///
247/// This function may return an error:
248///
249/// - [`crate::Error::Null`] - `p` is null.
250/// - [`crate::Error::NotAligned`] - `p` is not aligned correctly.
251///
252/// # Examples
253///
254/// ```rust
255/// use aligned_ptr::ptr;
256/// use aligned_ptr::Error;
257///
258/// let x = 3;
259/// let p = &x as *const _;
260///
261/// assert_eq!(unsafe { ptr::try_read(p) }, Ok(3));
262///
263/// let p: *const i32 = core::ptr::null();
264/// assert_eq!(unsafe { ptr::try_read(p) }, Err(Error::Null));
265///
266/// let p = 0x1001 as *const i32;
267/// assert_eq!(unsafe { ptr::try_read(p) }, Err(Error::NotAligned));
268/// ```
269pub unsafe fn try_read<T>(p: *const T) -> Result<T> {
270 return_error_on_null_or_misaligned(p)?;
271
272 Ok(unsafe { p.read() })
273}
274
275/// The wrapper of [`core::ptr::read_volatile`] which panics if the passed pointer is either null
276/// or not aligned.
277///
278/// # Safety
279///
280/// The caller must follow the safety rules required by [`core::ptr::read_volatile`] except the
281/// alignment and null rules.
282///
283/// # Examples
284///
285/// ```rust
286/// use aligned_ptr::ptr;
287///
288/// let x = 3;
289/// let p = &x as *const _;
290///
291/// assert_eq!(unsafe { ptr::read_volatile(p) }, 3);
292/// ```
293pub unsafe fn read_volatile<T>(p: *const T) -> T {
294 // SAFETY: The caller must uphold the all safety rules.
295 unsafe { try_read_volatile(p).expect(ERR_MSG) }
296}
297
298/// The wrapper of [`core::ptr::read_volatile`] which returns an error if the passed pointer is
299/// either null or not aligned.
300///
301/// # Safety
302///
303/// The caller must follow the safety rules required by [`core::ptr::read_volatile`] except the
304/// alignment and null rules.
305///
306/// # Errors
307///
308/// This function may return an error:
309///
310/// - [`crate::Error::Null`] - `p` is null.
311/// - [`crate::Error::NotAligned`] - `p` is not aligned correctly.
312///
313/// # Examples
314///
315/// ```rust
316/// use aligned_ptr::ptr;
317/// use aligned_ptr::Error;
318///
319/// let x = 3;
320/// let p = &x as *const _;
321///
322/// assert_eq!(unsafe { ptr::try_read_volatile(p) }, Ok(3));
323///
324/// let p: *const i32 = core::ptr::null();
325/// assert_eq!(unsafe { ptr::try_read_volatile(p) }, Err(Error::Null));
326///
327/// let p = 0x1001 as *const i32;
328/// assert_eq!(unsafe { ptr::try_read_volatile(p) }, Err(Error::NotAligned));
329/// ```
330pub unsafe fn try_read_volatile<T>(p: *const T) -> Result<T> {
331 return_error_on_null_or_misaligned(p)?;
332
333 // SAFETY: The caller must uphold the all safety rules.
334 Ok(unsafe { p.read_volatile() })
335}
336
337/// The wrapper of [`core::ptr::write`] which panics if the passed pointer is either null or not
338/// aligned.
339///
340/// # Safety
341///
342/// The caller must follow the safety rules required by [`core::ptr::write`] except the alignment
343/// and null rules.
344///
345/// # Panics
346///
347/// This function panics if `p` is either null or not aligned correctly.
348///
349/// # Examples
350///
351/// ```rust
352/// use aligned_ptr::ptr;
353/// use aligned_ptr::Error;
354///
355/// let mut x = 3;
356/// let p = &mut x as *mut i32;
357///
358/// unsafe { ptr::write(p, 4) };
359///
360/// assert_eq!(x, 4);
361/// ```
362pub unsafe fn write<T>(p: *mut T, v: T) {
363 // SAFETY: The caller must uphold the all safety rules.
364 unsafe { try_write(p, v).expect(ERR_MSG) }
365}
366
367/// The wrapper of [`core::ptr::write`] which may return an error if the passed pointer is either
368/// null or not aligned.
369///
370/// # Safety
371///
372/// The caller must follow the safety rules required by [`core::ptr::write`] except the alignment
373/// and null rules.
374///
375/// # Errors
376///
377/// This function may return an error:
378///
379/// - [`crate::Error::Null`] - `p` is null.
380/// - [`crate::Error::NotAligned`] - `p` is not aligned correctly.
381///
382/// # Examples
383///
384/// ```rust
385/// use aligned_ptr::ptr;
386/// use aligned_ptr::Error;
387///
388/// let mut x = 3;
389/// let p = &mut x as *mut i32;
390///
391/// let r = unsafe { ptr::try_write(p, 4) };
392/// assert!(r.is_ok());
393/// assert_eq!(x, 4);
394///
395/// let p: *mut i32 = core::ptr::null_mut();
396/// let r = unsafe { ptr::try_write(p, 4) };
397/// assert_eq!(r, Err(Error::Null));
398///
399/// let p = 0x1001 as *mut i32;
400/// let r = unsafe { ptr::try_write(p, 4) };
401/// assert_eq!(r, Err(Error::NotAligned));
402/// ```
403pub unsafe fn try_write<T>(p: *mut T, v: T) -> Result<()> {
404 return_error_on_null_or_misaligned(p)?;
405
406 // SAFETY: The caller must uphold the all safety rules.
407 unsafe { p.write(v) };
408 Ok(())
409}
410
411/// The wrapper of [`core::ptr::write_bytes`] which panics if the passed pointer is null or not
412/// aligned.
413///
414/// # Safety
415///
416/// The caller must follow the safety rules required by [`core::ptr::write_bytes`] except the
417/// alignment and null rules.
418///
419/// # Examples
420///
421/// ```rust
422/// use aligned_ptr::ptr;
423///
424/// let mut slice = [0_u8; 4];
425/// unsafe { ptr::write_bytes(slice.as_mut_ptr(), 0xff, 4) };
426///
427/// assert_eq!(slice, [0xff, 0xff, 0xff, 0xff]);
428/// ```
429pub unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
430 // SAFETY: The caller must uphold the safety requirements.
431 unsafe { try_write_bytes(dst, val, count).expect(ERR_MSG) }
432}
433
434/// The wrapper of [`core::ptr::write_bytes`] which returns an error if the passed pointer is null or not
435/// aligned.
436///
437/// # Safety
438///
439/// The caller must follow the safety rules required by [`core::ptr::write_bytes`] except the
440/// alignment and null rules.
441///
442/// # Errors
443///
444/// This function returns an error:
445///
446/// - [`crate::Error::Null`] - `dst` is null.
447/// - [`crate::Error::NotAligned`] - `dst` is not aligned.
448///
449/// # Examples
450///
451/// ```rust
452/// use aligned_ptr::ptr;
453/// use aligned_ptr::Error;
454///
455/// let mut slice = [0_u8; 4];
456///
457/// let r = unsafe { ptr::try_write_bytes(slice.as_mut_ptr(), 0xff, 4) };
458/// assert!(r.is_ok());
459/// assert_eq!(slice, [0xff, 0xff, 0xff, 0xff]);
460///
461/// let p: *mut i32 = core::ptr::null_mut();
462/// let r = unsafe { ptr::try_write_bytes(p, 0xff, 4) };
463/// assert_eq!(r, Err(Error::Null));
464///
465/// let p = 0x1001 as *mut i32;
466/// let r = unsafe { ptr::try_write_bytes(p, 0xff, 4) };
467/// assert_eq!(r, Err(Error::NotAligned));
468/// ```
469#[allow(clippy::shadow_unrelated)]
470pub unsafe fn try_write_bytes<T>(dst: *mut T, val: u8, count: usize) -> Result<()> {
471 return_error_on_null_or_misaligned(dst)?;
472
473 // SAFETY: The caller must uphold the safety requirements.
474 unsafe { core::ptr::write_bytes(dst, val, count) };
475
476 Ok(())
477}
478
479/// The wrapper of [`core::ptr::write_volatile`] which panics if the passed pionter is either null
480/// or not aligned.
481///
482/// # Safety
483///
484/// The caller must follow the safety rules required by [`core::ptr::write_volatile`] except the
485/// null and alignment requirements.
486///
487/// # Examples
488///
489/// ```rust
490/// use aligned_ptr::ptr;
491/// use aligned_ptr::Error;
492///
493/// let mut x = 0;
494///
495/// let r = unsafe { ptr::try_write_volatile(&mut x, 3) };
496/// assert!(r.is_ok());
497/// assert_eq!(x, 3);
498/// ```
499pub unsafe fn write_volatile<T>(dst: *mut T, src: T) {
500 // SAFETY: The caller must uphold the safety requirements.
501 unsafe { try_write_volatile(dst, src).expect(ERR_MSG) }
502}
503
504/// The wrapper of [`core::ptr::write_volatile`] which returns an error if the passed pointer is
505/// either null or not aligned.
506///
507/// # Safety
508///
509/// The caller must follow the safety rules required by [`core::ptr::write_volatile`] except the
510/// alignment and null requirements.
511///
512/// # Errors
513///
514/// This function may return an error:
515///
516/// - [`crate::Error::Null`] - `dst` is null.
517/// - [`crate::Error::NotAligned`] - `dst` is not aligned correctly.
518///
519/// # Examples
520///
521/// ```rust
522/// use aligned_ptr::ptr;
523/// use aligned_ptr::Error;
524///
525/// let mut x = 0;
526///
527/// let r = unsafe { ptr::try_write_volatile(&mut x, 3) };
528/// assert!(r.is_ok());
529/// assert_eq!(x, 3);
530///
531/// let p: *mut i32 = core::ptr::null_mut();
532/// let r = unsafe { ptr::try_write_volatile(p, 3) };
533/// assert_eq!(r, Err(Error::Null));
534///
535/// let p = 0x1001 as *mut i32;
536/// let r = unsafe { ptr::try_write_volatile(p, 3) };
537/// assert_eq!(r, Err(Error::NotAligned));
538/// ```
539pub unsafe fn try_write_volatile<T>(dst: *mut T, src: T) -> Result<()> {
540 return_error_on_null_or_misaligned(dst)?;
541
542 // SAFETY: The caller must uphold the safety requirements.
543 unsafe { dst.write_volatile(src) };
544
545 Ok(())
546}
547
548/// The wrapper of [`core::ptr::copy`] which panics unless the passed pointers are aligned and not
549/// null.
550///
551/// # Safety
552///
553/// The caller must follow the safety rules required by [`core::ptr::copy`] except the alignment
554/// and null rules.
555///
556/// # Examples
557///
558/// ```rust
559/// use aligned_ptr::ptr;
560/// use core::mem::MaybeUninit;
561///
562/// let x = 3;
563/// let src = &x as *const i32;
564/// let mut y = MaybeUninit::uninit();
565/// let dst = y.as_mut_ptr();
566///
567/// unsafe { ptr::copy(src, dst, 1) };
568/// let y = unsafe { y.assume_init() };
569/// assert_eq!(y, 3);
570/// ```
571pub unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
572 // SAFETY: The caller must uphold the all safety rules.
573 unsafe { try_copy(src, dst, count).expect(ERR_MSG) }
574}
575
576/// The wrapper of [`core::ptr::copy`] which may return an error unless the passed pointers are
577/// aligned and not null.
578///
579/// # Safety
580///
581/// The caller must follow the safety rules required by [`core::ptr::copy`] except the alignment
582/// and null rules.
583///
584/// # Errors
585///
586/// This function may return an error:
587///
588/// - [`crate::Error::Null`] - Either `src` or `dst` is null.
589/// - [`crate::Error::NotAligned`] - Either `src` or `dst` is not aligned correctly.
590///
591/// # Examples
592///
593/// ```rust
594/// use aligned_ptr::ptr;
595/// use aligned_ptr::Error;
596/// use core::mem::MaybeUninit;
597///
598/// let x = 3;
599/// let src = &x as *const i32;
600/// let mut y = MaybeUninit::uninit();
601/// let dst = y.as_mut_ptr();
602///
603/// let r = unsafe { ptr::try_copy(src, dst, 1) };
604/// assert!(r.is_ok());
605/// let y = unsafe { y.assume_init() };
606/// assert_eq!(y, 3);
607///
608/// let dst = core::ptr::null_mut();
609/// let r = unsafe { ptr::try_copy(src, dst, 1) };
610/// assert_eq!(r, Err(Error::Null));
611///
612/// let dst = 0x1001 as *mut i32;
613/// let r = unsafe { ptr::try_copy(src, dst, 1) };
614/// assert_eq!(r, Err(Error::NotAligned));
615/// ```
616pub unsafe fn try_copy<T>(src: *const T, dst: *mut T, count: usize) -> Result<()> {
617 return_error_on_null_or_misaligned(src)?;
618 return_error_on_null_or_misaligned(dst)?;
619
620 // SAFETY: The caller must uphold the all safety rules.
621 unsafe { core::ptr::copy(src, dst, count) };
622 Ok(())
623}
624
625/// The wrapper of [`core::ptr::copy_nonoverlapping`] which panics unless the passed pointers are aligned and not
626/// null.
627///
628/// # Safety
629///
630/// The caller must follow the safety rules required by [`core::ptr::copy_nonoverlapping`] except the alignment
631/// and null rules.
632///
633/// # Examples
634///
635/// ```rust
636/// use aligned_ptr::ptr;
637/// use core::mem::MaybeUninit;
638///
639/// let x = 3;
640/// let src = &x as *const i32;
641/// let mut y = MaybeUninit::uninit();
642/// let dst = y.as_mut_ptr();
643///
644/// unsafe { ptr::copy_nonoverlapping(src, dst, 1) };
645/// let y = unsafe { y.assume_init() };
646/// assert_eq!(y, 3);
647/// ```
648pub unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {
649 // SAFETY: The caller must uphold the all safety rules.
650 unsafe { try_copy_nonoverlapping(src, dst, count).expect(ERR_MSG) }
651}
652
653/// The wrapper of [`core::ptr::copy_nonoverlapping`] which returns an error unless the passed
654/// pointers are aligned and not null.
655///
656/// # Safety
657///
658/// The caller must follow the safety rules required by [`core::ptr::copy_nonoverlapping`] except
659/// the alignment and null rules.
660///
661/// # Errors
662///
663/// This function may return an error:
664///
665/// - [`crate::Error::Null`] - Either `src` or `dst` is null.
666/// - [`crate::Error::NotAligned`] - Either `src` or `dst` is not aligned.
667///
668/// # Examples
669///
670/// ```rust
671/// use aligned_ptr::ptr;
672/// use aligned_ptr::Error;
673/// use core::mem::MaybeUninit;
674///
675/// let x = 3;
676/// let src = &x as *const i32;
677/// let mut y = MaybeUninit::uninit();
678/// let dst = y.as_mut_ptr();
679///
680/// let r = unsafe { ptr::try_copy_nonoverlapping(src, dst, 1) };
681/// assert!(r.is_ok());
682/// let y = unsafe { y.assume_init() };
683/// assert_eq!(y, 3);
684///
685/// let dst = core::ptr::null_mut();
686/// let r = unsafe { ptr::try_copy_nonoverlapping(src, dst, 1) };
687/// assert_eq!(r, Err(Error::Null));
688///
689/// let dst = 0x1001 as *mut i32;
690/// let r = unsafe { ptr::try_copy_nonoverlapping(src, dst, 1) };
691/// assert_eq!(r, Err(Error::NotAligned));
692/// ```
693pub unsafe fn try_copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) -> Result<()> {
694 return_error_on_null_or_misaligned(src)?;
695 return_error_on_null_or_misaligned(dst)?;
696
697 // SAFETY: The caller must uphold the all safety rules.
698 unsafe { core::ptr::copy_nonoverlapping(src, dst, count) };
699
700 Ok(())
701}
702
703/// The wrapper of [`core::ptr::drop_in_place`] which panics if the passed pointer is null or not
704/// aligned.
705///
706/// Note that the original function accepts types which are not [`Sized`]. However, this function
707/// only accepts types which are [`Sized`].
708///
709/// # Safety
710///
711/// The caller must follow the safety rules required by [`core::ptr::drop_in_place`] except the
712/// alignment and null rules.
713///
714/// # Examples
715///
716/// ```rust
717/// use aligned_ptr::ptr;
718/// use aligned_ptr::Error;
719///
720/// let b = Box::new(3);
721/// let p = Box::into_raw(b);
722/// unsafe { ptr::drop_in_place(p) };
723/// ```
724pub unsafe fn drop_in_place<T>(to_drop: *mut T) {
725 // SAFETY: The caller must uphold the all safety rules.
726 unsafe { try_drop_in_place(to_drop).expect(ERR_MSG) }
727}
728
729/// The wraper of [`core::ptr::drop_in_place`] which returns an error if the passed pointer is null
730/// or not aligned.
731///
732/// Note that the original function accepts types which are not [`Sized`]. However, this function
733/// only accepts types which are [`Sized`].
734///
735/// # Safety
736///
737/// The caller must follow the safety rules required by [`core::ptr::drop_in_place`] except the
738/// alignment and null rules.
739///
740/// # Errors
741///
742/// This function may return an error:
743///
744/// - [`crate::Error::Null`] - `to_drop` is null.
745/// - [`crate::Error::NotAligned`] - `to_drop` is not aligned.
746///
747/// # Examples
748///
749/// ```rust
750/// use aligned_ptr::ptr;
751/// use aligned_ptr::Error;
752///
753/// let b = Box::new(3);
754/// let p = Box::into_raw(b);
755/// let r = unsafe { ptr::try_drop_in_place(p) };
756/// assert!(r.is_ok());
757///
758/// let p: *mut i32 = core::ptr::null_mut();
759/// let r = unsafe { ptr::try_drop_in_place(p) };
760/// assert_eq!(r, Err(Error::Null));
761///
762/// let p = 0x1001 as *mut i32;
763/// let r = unsafe { ptr::try_drop_in_place(p) };
764/// assert_eq!(r, Err(Error::NotAligned));
765/// ```
766pub unsafe fn try_drop_in_place<T>(to_drop: *mut T) -> Result<()> {
767 return_error_on_null_or_misaligned(to_drop)?;
768
769 // SAFETY: The caller must uphold the all safety rules.
770 unsafe { core::ptr::drop_in_place(to_drop) };
771 Ok(())
772}
773
774/// The wrapper of [`core::ptr::replace`] which panics if the passed pointer is either null or not
775/// aligned.
776///
777/// # Safety
778///
779/// The caller must follow the safety rules required by [`core::ptr::replace`] except the alignment
780/// and null rules.
781///
782/// # Examples
783///
784/// ```rust
785/// use aligned_ptr::ptr;
786/// use aligned_ptr::Error;
787///
788/// let mut x = 3;
789///
790/// let r = unsafe { ptr::replace(&mut x, 4) };
791/// assert_eq!(x, 4);
792/// assert_eq!(r, 3);
793/// ```
794pub unsafe fn replace<T>(dst: *mut T, src: T) -> T {
795 // SAFETY: The caller must uphold the safety requirements.
796 unsafe { try_replace(dst, src).expect(ERR_MSG) }
797}
798
799/// The wrapper of [`core::ptr::replace`] which returns an error if the passed pointer is
800/// null or not aligned.
801///
802/// # Safety
803///
804/// The caller must follow the safety rules required by [`core::ptr::replace`] except the alignment
805/// and null rules.
806///
807/// # Errors
808///
809/// This function may return an error:
810///
811/// - [`crate::Error::Null`] - `dst` is null.
812/// - [`crate::Error::NotAligned`] - `dst` is not aligned correctly.
813///
814/// # Examples
815///
816/// ```rust
817/// use aligned_ptr::ptr;
818/// use aligned_ptr::Error;
819///
820/// let mut x = 3;
821///
822/// let r = unsafe { ptr::try_replace(&mut x, 4) };
823/// assert_eq!(x, 4);
824/// assert_eq!(r, Ok(3));
825///
826/// let dst: *mut i32 = core::ptr::null_mut();
827///
828/// let r = unsafe { ptr::try_replace(dst, 4) };
829/// assert_eq!(r, Err(Error::Null));
830///
831/// let dst = 0x1001 as *mut i32;
832///
833/// let r = unsafe { ptr::try_replace(dst, 4) };
834/// assert_eq!(r, Err(Error::NotAligned));
835/// ```
836pub unsafe fn try_replace<T>(dst: *mut T, src: T) -> Result<T> {
837 return_error_on_null_or_misaligned(dst)?;
838
839 // SAFETY: The caller must uphold the safety rules.
840 Ok(unsafe { core::ptr::replace(dst, src) })
841}
842
843/// The wrapper of [`core::ptr::swap`] which panics unless the passed pointers are aligned and not
844/// null.
845///
846/// # Safety
847///
848/// The caller must follow the safety rules required by [`core::ptr::replace`] except the alignment
849/// and null rules.
850///
851/// # Examples
852///
853/// ```rust
854/// use aligned_ptr::ptr;
855/// use aligned_ptr::Error;
856///
857/// let mut x = 3;
858/// let mut y = 4;
859/// unsafe { ptr::swap(&mut x, &mut y) };
860/// assert_eq!(x, 4);
861/// assert_eq!(y, 3);
862/// ```
863pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
864 // SAFETY: The caller must uphold the safety requirements.
865 unsafe { try_swap(x, y).expect(ERR_MSG) }
866}
867
868/// The wrapper of [`core::ptr::swap`] which returns an error unless the passed pointers are
869/// aligned and not null.
870///
871/// # Safety
872///
873/// The caller must follow the safety rules required by [`core::ptr::replace`] except the alignment
874/// and null rules.
875///
876/// # Errors
877///
878/// This function may return an error:
879///
880/// - [`crate::Error::Null`] - Either `x` or `y` is null.
881/// - [`crate::Error::NotAligned`] - Either `x` or `y` is not aligned correctly.
882///
883/// # Examples
884///
885/// ```rust
886/// use aligned_ptr::ptr;
887/// use aligned_ptr::Error;
888///
889/// let mut x = 3;
890/// let mut y = 4;
891/// let r = unsafe { ptr::try_swap(&mut x, &mut y) };
892/// assert!(r.is_ok());
893/// assert_eq!(x, 4);
894/// assert_eq!(y, 3);
895///
896/// let r = unsafe { ptr::try_swap(&mut x, core::ptr::null_mut()) };
897/// assert_eq!(r, Err(Error::Null));
898///
899/// let z = 0x1001 as *mut i32;
900/// let r = unsafe { ptr::try_swap(&mut x, z) };
901/// assert_eq!(r, Err(Error::NotAligned));
902/// ```
903pub unsafe fn try_swap<T>(x: *mut T, y: *mut T) -> Result<()> {
904 return_error_on_null_or_misaligned(x)?;
905 return_error_on_null_or_misaligned(y)?;
906
907 // SAFETY: The caller must uphold the safety requirements.
908 unsafe { core::ptr::swap(x, y) };
909 Ok(())
910}
911
912/// The wrapper of [`core::ptr::swap_nonoverlapping`] which panics unless the passed pointers are
913/// aligned and not null.
914///
915/// # Safety
916///
917/// The caller must follow the safety rules required by [`core::ptr::swap_nonoverlapping`] except
918/// the alignment and null rules.
919///
920/// # Examples
921///
922/// ```rust
923/// use aligned_ptr::ptr;
924///
925/// let mut x = [1, 2, 3];
926/// let mut y = [4, 5, 6];
927///
928/// unsafe { ptr::swap_nonoverlapping(x.as_mut_ptr(), y.as_mut_ptr(), 3) };
929/// assert_eq!(x, [4, 5, 6]);
930/// assert_eq!(y, [1, 2, 3]);
931/// ```
932pub unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
933 // SAFETY: The caller must uphold the safety requirements.
934 unsafe { try_swap_nonoverlapping(x, y, count).expect(ERR_MSG) }
935}
936
937/// The wrapper of [`core::ptr::swap_nonoverlapping`] which returns an error unless the passed
938/// pointers are aligned and not null.
939///
940/// # Safety
941///
942/// The caller must follow the safety rules required by [`core::ptr::swap_nonoverlapping`] excpet
943/// the alignment and null rules.
944///
945/// # Errors
946///
947/// This function may return an error:
948///
949/// - [`crate::Error::Null`] - Either `x` or `y` is null.
950/// - [`crate::Error::NotAligned`] - Either `x` or `y` is not aligned correctly.
951///
952/// # Examples
953///
954/// ```rust
955/// use aligned_ptr::ptr;
956/// use aligned_ptr::Error;
957///
958/// let mut x = [1, 2, 3];
959/// let mut y = [4, 5, 6];
960///
961/// let r = unsafe { ptr::try_swap_nonoverlapping(x.as_mut_ptr(), y.as_mut_ptr(), 3) };
962/// assert!(r.is_ok());
963/// assert_eq!(x, [4, 5, 6]);
964/// assert_eq!(y, [1, 2, 3]);
965///
966/// let z: *mut i32 = core::ptr::null_mut();
967/// let r = unsafe { ptr::try_swap_nonoverlapping(x.as_mut_ptr(), z, 3) };
968/// assert_eq!(r, Err(Error::Null));
969///
970/// let z = 0x1001 as *mut i32;
971/// let r = unsafe { ptr::try_swap_nonoverlapping(x.as_mut_ptr(), z, 3) };
972/// assert_eq!(r, Err(Error::NotAligned));
973/// ```
974pub unsafe fn try_swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) -> Result<()> {
975 return_error_on_null_or_misaligned(x)?;
976 return_error_on_null_or_misaligned(y)?;
977
978 // SAFETY: The caller must uphold the safety requirements.
979 unsafe { core::ptr::swap_nonoverlapping(x, y, count) };
980 Ok(())
981}