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}