intuicio_data/
lib.rs

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
pub mod data_stack;
pub mod lifetime;
pub mod managed;
pub mod managed_box;
pub mod shared;
pub mod type_hash;

pub mod prelude {
    pub use crate::{
        data_stack::*, lifetime::*, managed::*, managed_box::*, shared::*, type_hash::*, Finalize,
        Initialize,
    };
}

pub trait Initialize: Sized {
    fn initialize() -> Self;

    /// # Safety
    unsafe fn initialize_raw(data: *mut ()) {
        data.cast::<Self>().write(Self::initialize());
    }
}

impl<T> Initialize for T
where
    T: Default,
{
    fn initialize() -> Self {
        Self::default()
    }
}

pub trait Finalize: Sized {
    /// # Safety
    unsafe fn finalize_raw(data: *mut ()) {
        data.cast::<Self>().read_unaligned();
    }
}

impl<T> Finalize for T {}

#[inline]
pub fn pointer_alignment_padding(pointer: *const u8, alignment: usize) -> usize {
    let mut result = (pointer as usize) % alignment;
    if result > 0 {
        result = alignment - result;
    }
    result
}

macro_rules! does_implement_trait {
    ($trait:path => $identifier:ident < $type:ident >) => {
        pub fn $identifier<$type>() -> bool {
            struct ImplementsTrait<'a, $type> {
                implements: &'a std::cell::Cell<bool>,
                _marker: std::marker::PhantomData<$type>,
            }

            #[allow(clippy::non_canonical_clone_impl)]
            impl<$type> Clone for ImplementsTrait<'_, $type> {
                fn clone(&self) -> Self {
                    self.implements.set(false);
                    ImplementsTrait {
                        implements: self.implements,
                        _marker: std::marker::PhantomData,
                    }
                }
            }

            impl<$type: $trait> Copy for ImplementsTrait<'_, $type> {}

            let implements = std::cell::Cell::new(true);
            let _ = [ImplementsTrait::<$type> {
                implements: &implements,
                _marker: std::marker::PhantomData,
            }]
            .clone();
            implements.get()
        }
    };
}

does_implement_trait!(Send => is_send<T>);
does_implement_trait!(Sync => is_sync<T>);
does_implement_trait!(Copy => is_copy<T>);
does_implement_trait!(Clone => is_clone<T>);
does_implement_trait!(Sized => is_sized<T>);
does_implement_trait!(Unpin => is_unpin<T>);
does_implement_trait!(ToString => is_to_string<T>);

#[cfg(test)]
mod tests {
    use super::*;
    use std::{marker::PhantomPinned, rc::Rc};

    struct Foo;

    #[test]
    fn test_does_implement_trait() {
        assert!(is_send::<i32>());
        assert!(!is_send::<Rc<i32>>());

        assert!(is_sync::<i32>());
        assert!(!is_sync::<Rc<i32>>());

        assert!(is_copy::<i32>());
        assert!(!is_copy::<Foo>());

        assert!(is_clone::<i32>());
        assert!(!is_clone::<Foo>());

        assert!(is_sized::<[i32; 1]>());

        assert!(is_unpin::<&i32>());
        assert!(!is_unpin::<PhantomPinned>());

        assert!(is_to_string::<i32>());
        assert!(!is_to_string::<Foo>());
    }
}