basic_oop/
lib.rs

1#![feature(macro_metavar_expr_concat)]
2
3#![no_std]
4
5extern crate alloc;
6
7#[doc(hidden)]
8pub use macro_magic;
9
10pub use basic_oop_macro::class_unsafe;
11
12pub use basic_oop_macro::class_sync_unsafe;
13
14#[doc(hidden)]
15pub use alloc::rc::Rc as alloc_rc_Rc;
16#[doc(hidden)]
17pub use alloc::sync::Arc as alloc_sync_Arc;
18#[doc(hidden)]
19pub use core::mem::transmute as core_mem_transmute;
20#[doc(hidden)]
21pub use dynamic_cast::SupportsInterfaces as dynamic_cast_SupportsInterfaces;
22#[doc(hidden)]
23pub use dynamic_cast::impl_supports_interfaces as dynamic_cast_impl_supports_interfaces;
24#[doc(hidden)]
25pub use dynamic_cast::dyn_cast_rc as dynamic_cast_dyn_cast_rc;
26#[doc(hidden)]
27pub use dynamic_cast::dyn_cast_arc as dynamic_cast_dyn_cast_arc;
28
29pub type Vtable = *const *const ();
30
31#[repr(C)]
32pub struct VtableJoin<const A: usize, const B: usize> {
33    pub a: [*const (); A],
34    pub b: [*const (); B],
35}
36
37#[macro_export]
38macro_rules! import {
39    ($vis:vis $class:ident : use $([$base:ident $($path:tt)*])+ ; $($custom_uses:tt)*) => {
40        $vis mod ${concat($class, _types)} {
41            $(
42                #[allow(unused_imports)]
43                pub use $($path)*::*;
44                #[allow(unused_imports)]
45                pub use $($path)*:: ${concat($base, _types)} ::*;
46            )+
47            $($custom_uses)*
48        }
49        use ${concat($class, _types)} ::*;
50    };
51}
52
53pub mod obj {
54    use alloc::rc::Rc;
55    use alloc::sync::Arc;
56    use dynamic_cast::{SupportsInterfaces, impl_supports_interfaces};
57    use macro_magic::export_tokens_no_emit;
58    use crate::Vtable;
59
60    pub mod obj_types { }
61
62    #[export_tokens_no_emit]
63    struct inherits_Obj { __class__: Obj }
64
65    #[derive(Debug, Clone)]
66    pub struct Obj {
67        vtable: Vtable,
68    }
69
70    unsafe impl Send for Obj { }
71
72    unsafe impl Sync for Obj { }
73
74    impl Obj {
75        pub fn new() -> Rc<dyn TObj> {
76            Rc::new(unsafe { Self::new_raw(OBJ_VTABLE.as_ptr()) })
77        }
78
79        pub fn new_sync() -> Arc<dyn TObj> {
80            Arc::new(unsafe { Self::new_raw(OBJ_VTABLE.as_ptr()) })
81        }
82
83        pub unsafe fn new_raw(vtable: Vtable) -> Self {
84            Obj { vtable }
85        }
86
87        pub fn vtable(&self) -> Vtable { self.vtable }
88    }
89
90    pub trait TObj: SupportsInterfaces {
91        fn obj(&self) -> &Obj;
92    }
93
94    impl_supports_interfaces!(Obj: TObj);
95
96    impl TObj for Obj {
97        fn obj(&self) -> &Obj { self }
98    }
99
100    #[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
101    #[repr(usize)]
102    pub enum ObjVirtMethods {
103        VirtMethodsCount = 0usize,
104    }
105
106    pub struct ObjVtable(pub [*const (); ObjVirtMethods::VirtMethodsCount as usize]);
107
108    impl ObjVtable {
109        pub const fn new() -> Self {
110            ObjVtable([])
111        }
112    }
113
114    const OBJ_VTABLE: [*const (); ObjVirtMethods::VirtMethodsCount as usize] = ObjVtable::new().0;
115}