1use core::any::Any;
2
3use crate::{Dyn, Instance};
4
5macro_rules! unary {
6 ($trait:ident, $method:ident, $original:ident, $doc:tt) => {
7 #[doc = $doc]
8 pub trait $trait {
9 fn $method(self: Box<Self>) -> *mut ();
10 }
11
12 impl<T: Dyn + core::ops::$trait<Output = T>> $trait for T {
13 #[inline]
14 fn $method(self: Box<Self>) -> *mut () {
15 Box::leak(Box::from((*self).$original())) as *const T as *mut ()
16 }
17 }
18
19 impl<T: core::ops::$trait<Output = T>, U> core::ops::$trait for Instance<T, U> {
20 type Output = Self;
21 #[inline]
22 fn $original(self) -> Self {
23 Self::new(self.0.$original())
24 }
25 }
26 };
27}
28
29macro_rules! binary {
30 ($trait:ident, $method:ident, $original:ident, $doc:tt) => {
31 #[doc = $doc]
32 pub trait $trait {
33 fn $method(self: Box<Self>, other: Box<dyn Any>) -> *mut ();
34 }
35
36 impl<T: Dyn + core::ops::$trait<Output = T>> $trait for T {
37 #[inline]
38 fn $method(self: Box<Self>, other: Box<dyn Any>) -> *mut () {
39 let other = other.downcast::<Self>().unwrap();
40 Box::leak(Box::from((*self).$original(*other))) as *const T as *mut ()
41 }
42 }
43
44 impl<T: core::ops::$trait<Output = T>, U> core::ops::$trait for Instance<T, U> {
45 type Output = Self;
46 #[inline]
47 fn $original(self, other: Self) -> Self {
48 Self::new(self.0.$original(other.0))
49 }
50 }
51 };
52}
53
54macro_rules! assign {
55 ($trait:ident, $method:ident, $original:ident, $doc:tt) => {
56 #[doc = $doc]
57 pub trait $trait {
58 fn $method(&mut self, other: Box<dyn Any>);
59 }
60
61 impl<T: Dyn + core::ops::$trait> $trait for T {
62 #[inline]
63 fn $method(&mut self, other: Box<dyn Any>) {
64 let other = other.downcast::<T>().unwrap();
65 self.$original(*other);
66 }
67 }
68
69 impl<T: core::ops::$trait, U> core::ops::$trait for Instance<T, U> {
70 #[inline]
71 fn $original(&mut self, other: Self) {
72 self.0.$original(other.0)
73 }
74 }
75 };
76}
77
78unary!(Neg, dyn_neg, neg, "Dynamic (object-safe) version of [`Neg`](https://doc.rust-lang.org/nightly/core/ops/trait.Neg.html)");
79unary!(Not, dyn_not, not, "Dynamic (object-safe) version of [`Not`](https://doc.rust-lang.org/nightly/core/ops/trait.Not.html)");
80
81binary!(Add, dyn_add, add, "Dynamic (object-safe) version of [`Add`](https://doc.rust-lang.org/nightly/core/ops/trait.Add.html)");
82binary!(Sub, dyn_sub, sub, "Dynamic (object-safe) version of [`Sub`](https://doc.rust-lang.org/nightly/core/ops/trait.Sub.html)");
83binary!(Mul, dyn_mul, mul, "Dynamic (object-safe) version of [`Mul`](https://doc.rust-lang.org/nightly/core/ops/trait.Mul.html)");
84binary!(Div, dyn_div, div, "Dynamic (object-safe) version of [`Div`](https://doc.rust-lang.org/nightly/core/ops/trait.Div.html)");
85binary!(Rem, dyn_rem, rem, "Dynamic (object-safe) version of [`Rem`](https://doc.rust-lang.org/nightly/core/ops/trait.Rem.html)");
86binary!(BitAnd, dyn_bitand, bitand, "Dynamic (object-safe) version of [`BitAnd`](https://doc.rust-lang.org/nightly/core/ops/trait.BitAnd.html)");
87binary!(BitOr, dyn_bitor, bitor, "Dynamic (object-safe) version of [`BitOr`](https://doc.rust-lang.org/nightly/core/ops/trait.BitOr.html)");
88binary!(BitXor, dyn_bitxor, bitxor, "Dynamic (object-safe) version of [`BitXor`](https://doc.rust-lang.org/nightly/core/ops/trait.BitXor.html)");
89binary!(Shl, dyn_shl, shl, "Dynamic (object-safe) version of [`Shl`](https://doc.rust-lang.org/nightly/core/ops/trait.Shl.html)");
90binary!(Shr, dyn_shr, shr, "Dynamic (object-safe) version of [`Shr`](https://doc.rust-lang.org/nightly/core/ops/trait.Shr.html)");
91
92assign!(AddAssign, dyn_add_assign, add_assign, "Dynamic (object-safe) version of [`AddAssign`](https://doc.rust-lang.org/nightly/core/ops/trait.AddAssign.html)");
93assign!(SubAssign, dyn_sub_assign, sub_assign, "Dynamic (object-safe) version of [`SubAssign`](https://doc.rust-lang.org/nightly/core/ops/trait.SubAssign.html)");
94assign!(MulAssign, dyn_mul_assign, mul_assign, "Dynamic (object-safe) version of [`MulAssign`](https://doc.rust-lang.org/nightly/core/ops/trait.MulAssign.html)");
95assign!(DivAssign, dyn_div_assign, div_assign, "Dynamic (object-safe) version of [`DivAssign`](https://doc.rust-lang.org/nightly/core/ops/trait.DivAssign.html)");
96assign!(RemAssign, dyn_rem_assign, rem_assign, "Dynamic (object-safe) version of [`RemAssign`](https://doc.rust-lang.org/nightly/core/ops/trait.RemAssign.html)");
97assign!(BitAndAssign, dyn_bitand_assign, bitand_assign, "Dynamic (object-safe) version of [`BitAndAssign`](https://doc.rust-lang.org/nightly/core/ops/trait.BitAndAssign.html)");
98assign!(BitOrAssign, dyn_bitor_assign, bitor_assign, "Dynamic (object-safe) version of [`BitOrAssign`](https://doc.rust-lang.org/nightly/core/ops/trait.BitOrAssign.html)");
99assign!(BitXorAssign, dyn_bitxor_assign, bitxor_assign, "Dynamic (object-safe) version of [`BitXorAssign`](https://doc.rust-lang.org/nightly/core/ops/trait.BitXorAssign.html)");
100assign!(ShlAssign, dyn_shl_assign, shl_assign, "Dynamic (object-safe) version of [`ShlAssign`](https://doc.rust-lang.org/nightly/core/ops/trait.ShlAssign.html)");
101assign!(ShrAssign, dyn_shr_assign, shr_assign, "Dynamic (object-safe) version of [`ShrAssign`](https://doc.rust-lang.org/nightly/core/ops/trait.ShrAssign.html)");