1use crate::{
2 cmp::{Ge, Gt, Le, Lt},
3 CppBox, CppDeletable, MutPtr, MutRef, Ptr, Ref,
4};
5use std::cmp::{Ordering, PartialEq, PartialOrd};
6use std::ops::{
7 Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
8 Mul, MulAssign, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
9};
10
11macro_rules! define_op {
12 ($trait1:ident, $func:ident) => {
13 impl<'a, T: CppDeletable, U> $trait1<U> for &'a CppBox<T>
14 where
15 &'a T: $trait1<U>,
16 {
17 type Output = <&'a T as $trait1<U>>::Output;
18
19 fn $func(self, rhs: U) -> Self::Output {
20 (**self).$func(rhs)
21 }
22 }
23
24 impl<T: 'static, U> $trait1<U> for Ptr<T>
25 where
26 &'static T: $trait1<U>,
27 {
28 type Output = <&'static T as $trait1<U>>::Output;
29
30 fn $func(self, rhs: U) -> Self::Output {
31 unsafe { (*self.as_raw_ptr()).$func(rhs) }
32 }
33 }
34
35 impl<T: 'static, U> $trait1<U> for MutPtr<T>
36 where
37 &'static T: $trait1<U>,
38 {
39 type Output = <&'static T as $trait1<U>>::Output;
40
41 fn $func(self, rhs: U) -> Self::Output {
42 unsafe { (*self.as_raw_ptr()).$func(rhs) }
43 }
44 }
45
46 impl<T: 'static, U> $trait1<U> for Ref<T>
47 where
48 &'static T: $trait1<U>,
49 {
50 type Output = <&'static T as $trait1<U>>::Output;
51
52 fn $func(self, rhs: U) -> Self::Output {
53 unsafe { (*self.as_raw_ptr()).$func(rhs) }
54 }
55 }
56
57 impl<T: 'static, U> $trait1<U> for MutRef<T>
58 where
59 &'static T: $trait1<U>,
60 {
61 type Output = <&'static T as $trait1<U>>::Output;
62
63 fn $func(self, rhs: U) -> Self::Output {
64 unsafe { (*self.as_raw_ptr()).$func(rhs) }
65 }
66 }
67 };
68}
69
70define_op!(Add, add);
71define_op!(Sub, sub);
72define_op!(Mul, mul);
73define_op!(Div, div);
74define_op!(Rem, rem);
75define_op!(BitAnd, bitand);
76define_op!(BitOr, bitor);
77define_op!(BitXor, bitxor);
78define_op!(Shl, shl);
79define_op!(Shr, shr);
80
81macro_rules! define_assign_op {
82 ($trait1:ident, $func:ident) => {
83 impl<T: CppDeletable, U> $trait1<U> for CppBox<T>
84 where
85 T: $trait1<U>,
86 {
87 fn $func(&mut self, rhs: U) {
88 (**self).$func(rhs);
89 }
90 }
91
92 impl<T: 'static, U> $trait1<U> for MutPtr<T>
93 where
94 T: $trait1<U>,
95 {
96 fn $func(&mut self, rhs: U) {
97 unsafe { (&mut *self.as_mut_raw_ptr()).$func(rhs) };
98 }
99 }
100
101 impl<T: 'static, U> $trait1<U> for MutRef<T>
102 where
103 T: $trait1<U>,
104 {
105 fn $func(&mut self, rhs: U) {
106 unsafe { (&mut *self.as_mut_raw_ptr()).$func(rhs) };
107 }
108 }
109 };
110}
111
112define_assign_op!(AddAssign, add_assign);
113define_assign_op!(SubAssign, sub_assign);
114define_assign_op!(MulAssign, mul_assign);
115define_assign_op!(DivAssign, div_assign);
116define_assign_op!(RemAssign, rem_assign);
117define_assign_op!(BitAndAssign, bitand_assign);
118define_assign_op!(BitOrAssign, bitor_assign);
119define_assign_op!(BitXorAssign, bitxor_assign);
120define_assign_op!(ShlAssign, shl_assign);
121define_assign_op!(ShrAssign, shr_assign);
122
123macro_rules! define_comparison_op {
124 ($container:ident) => {
125 impl<T, U> PartialEq<U> for $container<T>
126 where
127 T: PartialEq<U>,
128 {
129 fn eq(&self, rhs: &U) -> bool {
130 &**self == rhs
131 }
132 }
133
134 impl<T, U> PartialOrd<U> for $container<T>
135 where
136 T: Lt<U> + Le<U> + Gt<U> + Ge<U> + PartialEq<U>,
137 {
138 fn partial_cmp(&self, other: &U) -> Option<Ordering> {
139 if &**self == other {
140 Some(Ordering::Equal)
141 } else if (**self).lt(other) {
142 Some(Ordering::Less)
143 } else if (**self).gt(other) {
144 Some(Ordering::Greater)
145 } else {
146 None
147 }
148 }
149
150 fn lt(&self, other: &U) -> bool {
151 (**self).lt(other)
152 }
153
154 fn le(&self, other: &U) -> bool {
155 (**self).le(other)
156 }
157
158 fn gt(&self, other: &U) -> bool {
159 (**self).gt(other)
160 }
161
162 fn ge(&self, other: &U) -> bool {
163 (**self).ge(other)
164 }
165 }
166 };
167}
168
169define_comparison_op!(Ptr);
170define_comparison_op!(MutPtr);
171define_comparison_op!(Ref);
172define_comparison_op!(MutRef);
173
174impl<T: CppDeletable, U> PartialEq<U> for CppBox<T>
175where
176 T: PartialEq<U>,
177{
178 fn eq(&self, rhs: &U) -> bool {
179 &**self == rhs
180 }
181}
182
183impl<T: CppDeletable, U> PartialOrd<U> for CppBox<T>
184where
185 T: Lt<U> + Le<U> + Gt<U> + Ge<U> + PartialEq<U>,
186{
187 fn partial_cmp(&self, other: &U) -> Option<Ordering> {
188 if &**self == other {
189 Some(Ordering::Equal)
190 } else if (**self).lt(other) {
191 Some(Ordering::Less)
192 } else if (**self).gt(other) {
193 Some(Ordering::Greater)
194 } else {
195 None
196 }
197 }
198
199 fn lt(&self, other: &U) -> bool {
200 (**self).lt(other)
201 }
202
203 fn le(&self, other: &U) -> bool {
204 (**self).le(other)
205 }
206
207 fn gt(&self, other: &U) -> bool {
208 (**self).gt(other)
209 }
210
211 fn ge(&self, other: &U) -> bool {
212 (**self).ge(other)
213 }
214}