1#![no_std]
2
3use core::{
4 marker::PhantomData,
5 mem::MaybeUninit,
6 ops::{Deref, DerefMut},
7};
8pub struct In<'a, T> {
9 pub ptr: *mut T,
10 _private: PhantomData<&'a ()>,
11}
12pub struct Out<'a, T> {
13 pub ptr: *mut T,
14 _private: PhantomData<&'a ()>,
15}
16impl<'a, T> In<'a, T> {
17 pub fn fill(self, value: T) -> Out<'a, T> {
18 unsafe {
19 self.ptr.write(value);
20 }
21 Out {
22 ptr: self.ptr,
23 _private: self._private,
24 }
25 }
26 pub unsafe fn raw<F>(raw: *mut T, f: F) -> Out<'a, T>
27 where
28 F: FnOnce(In<T>) -> Out<T>,
29 {
30 f(In {
31 ptr: raw,
32 _private: PhantomData,
33 })
34 }
35}
36impl<'a, T> Deref for Out<'a, T> {
37 type Target = T;
38
39 fn deref(&self) -> &Self::Target {
40 unsafe { &*self.ptr }
41 }
42}
43impl<'a, T> DerefMut for Out<'a, T> {
44 fn deref_mut(&mut self) -> &mut Self::Target {
45 unsafe { &mut *self.ptr }
46 }
47}
48impl<'a, T> Out<'a, T> {
49 pub unsafe fn from_raw(a: *mut T) -> Self {
50 Self {
51 ptr: a,
52 _private: PhantomData,
53 }
54 }
55}
56pub fn stack<T, E>(
57 f: impl for<'a> FnOnce(In<'a, T>) -> Result<Out<'a, T>, (In<'a, T>, E)>,
58) -> Result<T, E> {
59 let mut x = MaybeUninit::uninit();
60 match f(In {
61 ptr: x.as_mut_ptr(),
62 _private: PhantomData,
63 }) {
64 Err((_, e)) => return Err(e),
65 Ok(o) => {
66 return Ok(unsafe { o.ptr.read() });
67 }
68 }
69}
70#[macro_export]
71macro_rules! init {
72 ($p:ident.$field:ident @ $then:expr) => {
73 $crate::In::raw(
74 $crate::__::core::ptr::addr_of_mut!((*$p).$field),
75 move |$p| $then,
76 )
77 };
78 ($p:ident.$field:ident = $val:expr) => {
79 $crate::In::raw($crate::__::core::ptr::addr_of_mut!((*$p).$field), |$p| {
80 $p.fill($val)
81 })
82 };
83}
84#[doc(hidden)]
85pub mod __ {
86 pub use core;
87}