memapi2/data/marker.rs
1/// Unsafe marker trait for types that can be copied, including unsized types such as slices.
2///
3/// # Safety
4///
5/// Implementing `UnsizedCopy` indicates the type's memory representation can be duplicated without
6/// violating soundness or causing double frees.
7pub unsafe trait UnsizedCopy {}
8
9// SAFETY: Any `T` which is `Copy` is also `UnsizedCopy`.
10unsafe impl<T: Copy> UnsizedCopy for T {}
11// SAFETY: And so are slices containing copyable T.
12unsafe impl<T: Copy> UnsizedCopy for [T] {}
13// SAFETY: `str == [u8]` and `u8: Copy`.
14unsafe impl UnsizedCopy for str {}
15#[cfg(feature = "c_str")]
16// SAFETY: `CStr == [u8]`
17unsafe impl UnsizedCopy for core::ffi::CStr {}
18#[cfg(feature = "std")]
19// SAFETY: `OsStr == [u8]`
20unsafe impl UnsizedCopy for std::ffi::OsStr {}
21#[cfg(feature = "std")]
22// SAFETY: `Path == OsStr == [u8]`
23unsafe impl UnsizedCopy for std::path::Path {}
24
25#[cfg(all(not(feature = "metadata"), not(feature = "sized_hierarchy")))]
26/// Trait indicating that a type has no metadata.
27///
28/// This usually means `Self: Sized` or `Self` is `extern`.
29///
30/// # Safety
31///
32/// Implementors must ensure this type has no metadata (`<Self as Pointee>::Metadata = ()`).
33///
34/// # Example
35///
36/// ```
37/// # use memapi2::data::{
38/// # marker::Thin,
39/// # type_props::SizedProps
40/// # };
41///
42/// fn never_panics<T: Thin>() {
43/// assert_eq!(<&T>::SZ, usize::SZ)
44/// }
45/// ```
46pub unsafe trait Thin {}
47
48#[cfg(all(feature = "metadata", not(feature = "sized_hierarchy")))]
49/// Trait indicating that a type has no metadata.
50///
51/// This usually means `Self: Sized` or `Self` is `extern`.
52///
53/// # Safety
54///
55/// This is safe to implement in this configuration; however, because the actually unsafe
56/// version exists when both `metadata` and `sized_hierarchy` are disabled, this trait
57/// must still be marked `unsafe` for consistency across configurations.
58///
59/// # Example
60///
61/// ```
62/// # use memapi2::{data::type_props::SizedProps, data::marker::Thin};
63///
64/// fn never_panics<T: Thin>() {
65/// assert_eq!(<&T>::SZ, usize::SZ)
66/// }
67/// ```
68pub unsafe trait Thin: core::ptr::Pointee<Metadata = ()> {}
69
70#[cfg(all(feature = "metadata", feature = "sized_hierarchy"))]
71/// Trait indicating that a type has no metadata and may or may not have a size.
72///
73/// # Safety
74///
75/// This is safe to implement in this configuration; however, because the actually unsafe
76/// version exists when both `metadata` and `sized_hierarchy` are disabled, this trait
77/// must still be marked `unsafe` for consistency across configurations.
78///
79/// # Example
80///
81/// ```
82/// # use memapi2::{data::type_props::SizedProps, data::marker::Thin};
83///
84/// fn never_panics<T: Thin>() {
85/// assert_eq!(<&T>::SZ, usize::SZ)
86/// }
87/// ```
88pub unsafe trait Thin:
89 core::ptr::Pointee<Metadata = ()> + core::marker::PointeeSized
90{
91}
92
93#[cfg(all(not(feature = "metadata"), not(feature = "sized_hierarchy")))]
94/// Trait indicating that a type has `usize` metadata.
95///
96/// # Safety
97///
98/// Implementors must ensure this type has `usize` metadata (`<Self as Pointee>::Metadata = usize`).
99///
100/// # Example
101///
102/// ```
103/// # use memapi2::{data::type_props::SizedProps, data::marker::SizeMeta};
104///
105/// fn never_panics<T: SizeMeta>() {
106/// assert_eq!(<&T>::SZ, usize::SZ * 2)
107/// }
108/// ```
109pub unsafe trait SizeMeta {}
110
111#[cfg(all(not(feature = "metadata"), feature = "sized_hierarchy"))]
112/// Trait indicating that a type has `usize` metadata.
113///
114/// # Safety
115///
116/// Implementors must ensure this type has `usize` metadata (`<Self as Pointee>::Metadata = usize`).
117///
118/// # Example
119///
120/// ```
121/// # use memapi2::{data::type_props::SizedProps, data::marker::SizeMeta};
122///
123/// fn never_panics<T: SizeMeta>() {
124/// assert_eq!(<&T>::SZ, usize::SZ * 2)
125/// }
126/// ```
127pub unsafe trait SizeMeta: core::marker::MetaSized {}
128
129#[cfg(all(feature = "metadata", not(feature = "sized_hierarchy")))]
130/// Trait indicating that a type has `usize` metadata.
131///
132/// # Safety
133///
134/// This is safe to implement in this configuration; however, because the actually unsafe version
135/// exists when `metadata` is disabled, this trait must still be marked `unsafe` for consistency
136/// across configurations.
137///
138/// # Example
139///
140/// ```
141/// # use memapi2::{data::type_props::SizedProps, data::marker::SizeMeta};
142///
143/// fn never_panics<T: SizeMeta>() {
144/// assert_eq!(<&T>::SZ, usize::SZ * 2)
145/// }
146/// ```
147pub unsafe trait SizeMeta: core::ptr::Pointee<Metadata = usize> {}
148
149#[cfg(all(feature = "metadata", feature = "sized_hierarchy"))]
150/// Trait indicating that a type has `usize` metadata.
151///
152/// # Safety
153///
154/// This is safe to implement in this configuration; however, because the actually unsafe version
155/// exists when `metadata` is disabled, this trait must still be marked `unsafe` for consistency
156/// across configurations.
157///
158/// # Example
159///
160/// ```
161/// # use memapi2::{data::type_props::SizedProps, data::marker::SizeMeta};
162///
163/// fn never_panics<T: SizeMeta>() {
164/// assert_eq!(<&T>::SZ, usize::SZ * 2)
165/// }
166/// ```
167pub unsafe trait SizeMeta:
168 core::ptr::Pointee<Metadata = usize> + core::marker::MetaSized
169{
170}
171
172#[cfg(feature = "metadata")]
173// SAFETY: `P: Pointee<Metadata = ()>`
174unsafe impl<P: core::ptr::Pointee<Metadata = ()> + ?Sized> Thin for P {}
175
176#[cfg(feature = "metadata")]
177// SAFETY: `P: Pointee<Metadata = usize>`
178unsafe impl<P: core::ptr::Pointee<Metadata = usize> + ?Sized> SizeMeta for P {}