1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#![forbid(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(feature = "nightly", feature(core_intrinsics, coerce_unsized, unsize, maybe_uninit))]
#[cfg(not(feature = "std"))]
extern crate core as std;
#[cfg(test)]
mod tests;
#[cfg(feature = "nightly")]
use std::mem::MaybeUninit;
use std::marker::PhantomData as PD;
#[derive(Debug)]
#[repr(transparent)]
pub struct Out<'a, T: ?Sized>(*mut T, PD<&'a mut T>);
impl<'a, T> Out<'a, T> {
#[cfg(feature = "nightly")]
pub fn from_maybe_uninit(maybe_uninit: &mut MaybeUninit<T>) -> Out<'_, T> {
Out(maybe_uninit.as_mut_ptr(), PD)
}
}
impl<'a, T: ?Sized> Out<'a, T> {
pub fn from_raw(ptr: *mut T) -> Out<'a, T> {
if ptr.is_null() {
panic!("Tried to create a Out reference from a raw pointer")
}
Out(ptr, PD)
}
pub unsafe fn from_raw_unchecked(ptr: *mut T) -> Out<'a, T> {
Out(ptr, PD)
}
pub fn borrow(&mut self) -> Out<'_, T> { Out(self.0, PD) }
pub fn into_raw(self) -> *mut T { self.0 }
}
impl<'a, T> Out<'a, T> {
pub fn set(&mut self, value: T) { unsafe { std::ptr::write(self.0, value) } }
}
pub trait OutMethod {
#[inline(always)]
fn out(&mut self) -> Out<'_, Self> { Out(self, PD) }
#[inline(always)]
#[cfg(any(feature = "std", feature = "nightly"))]
fn linear_out(&mut self) -> LinearOut<'_, Self> { OutMethod::out(self).into_linear() }
}
impl<T: ?Sized> OutMethod for T {}
impl<'a, T: ?Sized> From<&'a mut T> for Out<'a, T> {
fn from(ptr: &'a mut T) -> Self {
Out(ptr, PD)
}
}
#[cfg(any(feature = "std", feature = "nightly"))]
pub use self::linear::*;
#[cfg(any(feature = "std", feature = "nightly"))]
mod linear {
use super::*;
pub struct LinearOut<'a, T: ?Sized>(Out<'a, T>);
impl<'a, T> LinearOut<'a, T> {
pub fn set(mut self, value: T) {
self.0.set(value);
std::mem::forget(self)
}
}
impl<'a, T: ?Sized> Drop for LinearOut<'a, T> {
fn drop(&mut self) {
#[cfg(feature = "std")]
std::process::abort();
#[cfg(all(
feature = "nightly",
not(feature = "std")
))]
unsafe { std::intrinsics::abort(); }
}
}
impl<'a, T: ?Sized> Out<'a, T> {
pub fn into_linear(self) -> LinearOut<'a, T> {
LinearOut(self)
}
}
#[cfg(feature = "nightly")]
pub use self::nightly::*;
#[cfg(feature = "nightly")]
mod nightly {
use std::ops::CoerceUnsized;
use std::marker::Unsize;
use super::*;
impl<'a, T: Unsize<U>, U: ?Sized> CoerceUnsized<Out<'a, U>> for Out<'a, T> {}
}
}