cpp_utils/
ops_impls.rs

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}