sel4_abstract_ptr/abstract_ptr/
operations.rs
1use core::{marker::PhantomData, ptr::NonNull};
9
10use crate::{
11 access::{Access, ReadOnly, ReadWrite, Readable, RestrictAccess, Writable, WriteOnly},
12 memory_type::UnitaryOps,
13 AbstractPtr,
14};
15
16impl<'a, M, T> AbstractPtr<'a, M, T>
18where
19 T: ?Sized,
20{
21 pub unsafe fn new(pointer: NonNull<T>) -> AbstractPtr<'a, M, T, ReadWrite> {
22 unsafe { AbstractPtr::new_restricted(ReadWrite, pointer) }
23 }
24
25 pub const unsafe fn new_read_only(pointer: NonNull<T>) -> AbstractPtr<'a, M, T, ReadOnly> {
26 unsafe { Self::new_restricted(ReadOnly, pointer) }
27 }
28
29 pub const unsafe fn new_restricted<A>(
30 access: A,
31 pointer: NonNull<T>,
32 ) -> AbstractPtr<'a, M, T, A>
33 where
34 A: Access,
35 {
36 let _ = access;
37 unsafe { Self::new_generic(pointer) }
38 }
39
40 pub(super) const unsafe fn new_generic<A>(pointer: NonNull<T>) -> AbstractPtr<'a, M, T, A> {
41 AbstractPtr {
42 pointer,
43 memory_type: PhantomData,
44 reference: PhantomData,
45 access: PhantomData,
46 }
47 }
48}
49
50impl<'a, M, T, A> AbstractPtr<'a, M, T, A>
51where
52 T: ?Sized,
53{
54 #[must_use]
55 pub fn read(self) -> T
56 where
57 M: UnitaryOps<T>,
58 T: Sized,
59 A: Readable,
60 {
61 unsafe { M::read(self.pointer.as_ptr()) }
62 }
63
64 pub fn write(self, value: T)
65 where
66 M: UnitaryOps<T>,
67 T: Sized,
68 A: Writable,
69 {
70 unsafe { M::write(self.pointer.as_ptr(), value) };
71 }
72
73 pub fn update<F>(self, f: F)
74 where
75 M: UnitaryOps<T>,
76 T: Sized,
77 A: Readable + Writable,
78 F: FnOnce(T) -> T,
79 {
80 let new = f(self.read());
81 self.write(new);
82 }
83
84 #[must_use]
85 pub fn as_raw_ptr(self) -> NonNull<T> {
86 self.pointer
87 }
88
89 pub unsafe fn map<F, U>(self, f: F) -> AbstractPtr<'a, M, U, A>
90 where
91 F: FnOnce(NonNull<T>) -> NonNull<U>,
92 A: Access,
93 U: ?Sized,
94 {
95 unsafe { AbstractPtr::new_restricted(A::default(), f(self.pointer)) }
96 }
97}
98
99impl<'a, M, T, A> AbstractPtr<'a, M, T, A>
101where
102 T: ?Sized,
103{
104 pub fn restrict<To>(self) -> AbstractPtr<'a, M, T, A::Restricted>
105 where
106 A: RestrictAccess<To>,
107 {
108 unsafe { AbstractPtr::new_restricted(Default::default(), self.pointer) }
109 }
110}
111
112impl<'a, M, T> AbstractPtr<'a, M, T, ReadWrite>
114where
115 T: ?Sized,
116{
117 pub fn read_only(self) -> AbstractPtr<'a, M, T, ReadOnly> {
118 self.restrict()
119 }
120
121 pub fn write_only(self) -> AbstractPtr<'a, M, T, WriteOnly> {
122 self.restrict()
123 }
124}