cpp_core/
ops_impls.rs

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}