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    (
40        $vis:vis $class:ident :
41        use $([$base:ident $($path:tt)*])+ ;
42        $($custom_use:tt)*
43    ) => {
44        $vis mod ${concat($class, _types)} {
45            $(
46                #[allow(unused_imports)]
47                pub use $($path)*::*;
48                #[allow(unused_imports)]
49                pub use $($path)*:: ${concat($base, _types)} ::*;
50            )+
51            $crate::import_impl! { @split [] [$($custom_use)*] }
52        }
53        use ${concat($class, _types)} ::*;
54    };
55}
56
57#[doc(hidden)]
58#[macro_export]
59macro_rules! import_impl {
60    (
61        @split [$($t:tt)*] [ ; $($custom_use:tt)*]
62    ) => {
63        $crate::import_impl! { @use [$($t)* ; ] }
64        $crate::import_impl! { @split [] [$($custom_use)*] }
65    };
66    (
67        @split [$($t:tt)*] [$x:tt $($custom_use:tt)*]
68    ) => {
69        $crate::import_impl! { @split [$($t)* $x] [$($custom_use)*] }
70    };
71    (
72        @split [] []
73    ) => {
74    };
75    (
76        @split [$($t:tt)+] []
77    ) => {
78        $crate::import_impl! { @use [$($t)+] }
79    };
80    (
81        @use [use $($list:tt)*]
82    ) => {
83        pub use $($list)*
84    };
85}
86
87pub mod obj {
88    use alloc::rc::Rc;
89    use alloc::sync::Arc;
90    use dynamic_cast::{SupportsInterfaces, impl_supports_interfaces};
91    use macro_magic::export_tokens_no_emit;
92    use crate::Vtable;
93
94    pub mod obj_types { }
95
96    #[export_tokens_no_emit]
97    struct inherits_Obj { __class__: Obj }
98
99    #[derive(Debug, Clone)]
100    pub struct Obj {
101        vtable: Vtable,
102    }
103
104    unsafe impl Send for Obj { }
105
106    unsafe impl Sync for Obj { }
107
108    impl Obj {
109        pub fn new() -> Rc<dyn TObj> {
110            Rc::new(unsafe { Self::new_raw(OBJ_VTABLE.as_ptr()) })
111        }
112
113        pub fn new_sync() -> Arc<dyn TObj> {
114            Arc::new(unsafe { Self::new_raw(OBJ_VTABLE.as_ptr()) })
115        }
116
117        pub unsafe fn new_raw(vtable: Vtable) -> Self {
118            Obj { vtable }
119        }
120
121        pub fn vtable(&self) -> Vtable { self.vtable }
122    }
123
124    pub trait TObj: SupportsInterfaces {
125        fn obj(&self) -> &Obj;
126    }
127
128    impl_supports_interfaces!(Obj: TObj);
129
130    impl TObj for Obj {
131        fn obj(&self) -> &Obj { self }
132    }
133
134    #[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
135    #[repr(usize)]
136    pub enum ObjVirtMethods {
137        VirtMethodsCount = 0usize,
138    }
139
140    pub struct ObjVtable(pub [*const (); ObjVirtMethods::VirtMethodsCount as usize]);
141
142    impl ObjVtable {
143        pub const fn new() -> Self {
144            ObjVtable([])
145        }
146    }
147
148    const OBJ_VTABLE: [*const (); ObjVirtMethods::VirtMethodsCount as usize] = ObjVtable::new().0;
149}