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}