1use crate::{
2 cmp::{Ge, Gt, Le, Lt},
3 CppBox, CppDeletable, Ptr, Ref,
4};
5use std::cmp::{Ordering, PartialEq, PartialOrd};
6use std::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Rem, Shl, Shr, Sub};
7
8macro_rules! define_op {
9 ($trait1:ident, $func:ident) => {
10 impl<'a, T: CppDeletable, U> $trait1<U> for &'a CppBox<T>
11 where
12 &'a T: $trait1<U>,
13 {
14 type Output = <&'a T as $trait1<U>>::Output;
15
16 fn $func(self, rhs: U) -> Self::Output {
17 (**self).$func(rhs)
18 }
19 }
20
21 impl<T: 'static, U> $trait1<U> for Ptr<T>
22 where
23 &'static T: $trait1<U>,
24 {
25 type Output = <&'static T as $trait1<U>>::Output;
26
27 fn $func(self, rhs: U) -> Self::Output {
28 unsafe { (*self.as_raw_ptr()).$func(rhs) }
29 }
30 }
31
32 impl<T: 'static, U> $trait1<U> for Ref<T>
33 where
34 &'static T: $trait1<U>,
35 {
36 type Output = <&'static T as $trait1<U>>::Output;
37
38 fn $func(self, rhs: U) -> Self::Output {
39 unsafe { (*self.as_raw_ptr()).$func(rhs) }
40 }
41 }
42 };
43}
44
45define_op!(Add, add);
46define_op!(Sub, sub);
47define_op!(Mul, mul);
48define_op!(Div, div);
49define_op!(Rem, rem);
50define_op!(BitAnd, bitand);
51define_op!(BitOr, bitor);
52define_op!(BitXor, bitxor);
53define_op!(Shl, shl);
54define_op!(Shr, shr);
55
56macro_rules! define_comparison_op {
57 ($container:ident) => {
58 impl<T, U> PartialEq<U> for $container<T>
59 where
60 T: PartialEq<U>,
61 {
62 fn eq(&self, rhs: &U) -> bool {
63 &**self == rhs
64 }
65 }
66
67 impl<T, U> PartialOrd<U> for $container<T>
68 where
69 T: Lt<U> + Le<U> + Gt<U> + Ge<U> + PartialEq<U>,
70 {
71 fn partial_cmp(&self, other: &U) -> Option<Ordering> {
72 unsafe {
73 if &**self == other {
74 Some(Ordering::Equal)
75 } else if (**self).lt(other) {
76 Some(Ordering::Less)
77 } else if (**self).gt(other) {
78 Some(Ordering::Greater)
79 } else {
80 None
81 }
82 }
83 }
84
85 fn lt(&self, other: &U) -> bool {
86 unsafe { (**self).lt(other) }
87 }
88
89 fn le(&self, other: &U) -> bool {
90 unsafe { (**self).le(other) }
91 }
92
93 fn gt(&self, other: &U) -> bool {
94 unsafe { (**self).gt(other) }
95 }
96
97 fn ge(&self, other: &U) -> bool {
98 unsafe { (**self).ge(other) }
99 }
100 }
101 };
102}
103
104define_comparison_op!(Ptr);
105define_comparison_op!(Ref);
106
107impl<T: CppDeletable, U> PartialEq<U> for CppBox<T>
108where
109 T: PartialEq<U>,
110{
111 fn eq(&self, rhs: &U) -> bool {
112 &**self == rhs
113 }
114}
115
116impl<T: CppDeletable, U> PartialOrd<U> for CppBox<T>
117where
118 T: Lt<U> + Le<U> + Gt<U> + Ge<U> + PartialEq<U>,
119{
120 fn partial_cmp(&self, other: &U) -> Option<Ordering> {
121 unsafe {
122 if &**self == other {
123 Some(Ordering::Equal)
124 } else if (**self).lt(other) {
125 Some(Ordering::Less)
126 } else if (**self).gt(other) {
127 Some(Ordering::Greater)
128 } else {
129 None
130 }
131 }
132 }
133
134 fn lt(&self, other: &U) -> bool {
135 unsafe { (**self).lt(other) }
136 }
137
138 fn le(&self, other: &U) -> bool {
139 unsafe { (**self).le(other) }
140 }
141
142 fn gt(&self, other: &U) -> bool {
143 unsafe { (**self).gt(other) }
144 }
145
146 fn ge(&self, other: &U) -> bool {
147 unsafe { (**self).ge(other) }
148 }
149}