1#![no_std]
2
3extern crate alloc;
4
5use alloc::rc::Rc;
6use alloc::sync::Arc;
7use dynamic_cast::{SupportsInterfaces, impl_supports_interfaces};
8use macro_magic::export_tokens_no_emit;
9
10#[doc(hidden)]
11pub use macro_magic;
12
13pub use basic_oop_macro::class_unsafe;
14
15pub use basic_oop_macro::class_sync_unsafe;
16
17#[doc(hidden)]
18pub use alloc::rc::Rc as alloc_rc_Rc;
19#[doc(hidden)]
20pub use alloc::sync::Arc as alloc_sync_Arc;
21#[doc(hidden)]
22pub use core::mem::transmute as core_mem_transmute;
23#[doc(hidden)]
24pub use dynamic_cast::SupportsInterfaces as dynamic_cast_SupportsInterfaces;
25#[doc(hidden)]
26pub use dynamic_cast::impl_supports_interfaces as dynamic_cast_impl_supports_interfaces;
27#[doc(hidden)]
28pub use dynamic_cast::dyn_cast_rc as dynamic_cast_dyn_cast_rc;
29#[doc(hidden)]
30pub use dynamic_cast::dyn_cast_arc as dynamic_cast_dyn_cast_arc;
31
32#[export_tokens_no_emit]
33struct inherited_from_Obj { __class__: ::basic_oop::Obj }
34
35pub type Vtable = *const *const ();
36
37pub struct Obj {
38 vtable: Vtable,
39}
40
41impl Obj {
42 pub fn new() -> Rc<dyn TObj> {
43 Rc::new(unsafe { Self::new_raw(OBJ_VTABLE.as_ptr()) })
44 }
45
46 pub fn new_sync() -> Arc<dyn TObj> {
47 Arc::new(unsafe { Self::new_raw(OBJ_VTABLE.as_ptr()) })
48 }
49
50 pub unsafe fn new_raw(vtable: Vtable) -> Self {
51 Obj { vtable }
52 }
53
54 pub fn vtable(&self) -> Vtable { self.vtable }
55}
56
57pub trait TObj: SupportsInterfaces {
58 fn obj(&self) -> &Obj;
59}
60
61impl_supports_interfaces!(Obj: TObj);
62
63impl TObj for Obj {
64 fn obj(&self) -> &Obj { self }
65}
66
67#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
68#[repr(usize)]
69pub enum ObjVirtMethods {
70 VirtMethodsCount = 0usize,
71}
72
73pub struct ObjVtable(pub [*const (); ObjVirtMethods::VirtMethodsCount as usize]);
74
75impl ObjVtable {
76 pub const fn new() -> Self {
77 ObjVtable([])
78 }
79}
80
81const OBJ_VTABLE: [*const (); ObjVirtMethods::VirtMethodsCount as usize] = ObjVtable::new().0;
82
83#[repr(C)]
84pub struct VtableJoin<const A: usize, const B: usize> {
85 pub a: [*const (); A],
86 pub b: [*const (); B],
87}