croaring/bitmap64/
ops.rs

1use crate::{Bitmap, Bitmap64};
2use core::fmt;
3use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Sub, SubAssign};
4use ffi::roaring64_bitmap_copy;
5
6impl fmt::Debug for Bitmap64 {
7    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8        if self.cardinality() < 32 {
9            write!(f, "Bitmap64<[")?;
10            let mut first = true;
11            for value in self.iter() {
12                let prefix = if first {
13                    first = false;
14                    ""
15                } else {
16                    ", "
17                };
18                write!(f, "{prefix}{value}")?;
19            }
20            write!(f, "]>")?;
21            Ok(())
22        } else {
23            write!(
24                f,
25                "Bitmap64<{:?} values between {:?} and {:?}>",
26                self.cardinality(),
27                self.minimum().unwrap(),
28                self.maximum().unwrap()
29            )
30        }
31    }
32}
33
34impl Default for Bitmap64 {
35    fn default() -> Self {
36        Self::new()
37    }
38}
39
40impl From<&'_ [u64]> for Bitmap64 {
41    #[inline]
42    #[doc(alias = "roaring64_bitmap_of_ptr")]
43    fn from(slice: &[u64]) -> Self {
44        Self::of(slice)
45    }
46}
47
48impl From<Bitmap> for Bitmap64 {
49    fn from(mut value: Bitmap) -> Self {
50        unsafe { Self::take_heap(ffi::roaring64_bitmap_move_from_roaring32(&mut value.bitmap)) }
51    }
52}
53
54impl<const N: usize> From<[u64; N]> for Bitmap64 {
55    #[inline]
56    #[doc(alias = "roaring64_bitmap_of_ptr")]
57    fn from(slice: [u64; N]) -> Self {
58        Self::of(&slice)
59    }
60}
61
62impl PartialEq for Bitmap64 {
63    #[inline]
64    #[doc(alias = "roaring64_bitmap_equals")]
65    fn eq(&self, other: &Self) -> bool {
66        unsafe { ffi::roaring64_bitmap_equals(self.raw.as_ptr(), other.raw.as_ptr()) }
67    }
68}
69
70impl Eq for Bitmap64 {}
71
72impl Clone for Bitmap64 {
73    #[inline]
74    #[doc(alias = "roaring64_bitmap_copy")]
75    fn clone(&self) -> Self {
76        unsafe {
77            let raw = roaring64_bitmap_copy(self.raw.as_ptr());
78            Self::take_heap(raw)
79        }
80    }
81}
82
83impl Drop for Bitmap64 {
84    fn drop(&mut self) {
85        unsafe {
86            ffi::roaring64_bitmap_free(self.raw.as_ptr());
87        }
88    }
89}
90
91macro_rules! impl_binop {
92    (
93        impl $trait_name:ident {
94            $(type $type_name:ident = $type_value:ty;)*
95
96            $(#[$($attr:tt)*])*
97            fn $fn_name:ident -> $ret_ty:ty as $alias:ident
98        }
99    ) => {
100        impl_binop!{
101            impl $trait_name {
102                $(type $type_name = $type_value;)*
103
104                $(#[$($attr)*])*
105                fn $fn_name(self, other) -> $ret_ty {
106                    self.$alias(&other)
107                }
108            }
109        }
110    };
111    (
112        impl $trait_name:ident {
113            $(type $type_name:ident = $type_value:ty;)*
114
115            $(#[$($attr:tt)*])*
116            fn $fn_name:ident($self_ident:ident, $other_ident:ident) -> $ret_ty:ty
117            $body:block
118        }
119    ) => {
120        impl $trait_name for Bitmap64 {
121            $(type $type_name = $type_value;)*
122
123            $(#[$($attr)*])*
124            fn $fn_name($self_ident, $other_ident: Bitmap64) -> $ret_ty
125            $body
126        }
127
128        impl $trait_name<&Bitmap64> for Bitmap64 {
129            $(type $type_name = $type_value;)*
130
131            $(#[$($attr)*])*
132            fn $fn_name($self_ident, $other_ident: &Bitmap64) -> $ret_ty
133            $body
134        }
135
136        impl $trait_name<Bitmap64> for &Bitmap64 {
137            $(type $type_name = $type_value;)*
138
139            $(#[$($attr)*])*
140            fn $fn_name($self_ident, $other_ident: Bitmap64) -> $ret_ty
141            $body
142        }
143
144        impl $trait_name<&Bitmap64> for &Bitmap64 {
145            $(type $type_name = $type_value;)*
146
147            $(#[$($attr)*])*
148            fn $fn_name($self_ident, $other_ident: &Bitmap64) -> $ret_ty
149            $body
150        }
151    };
152}
153
154macro_rules! impl_binop_assign {
155    (
156        impl $trait_name:ident {
157            $(#[$($attr:tt)*])*
158            fn $fn_name:ident as $alias:ident
159        }
160    ) => {
161        impl $trait_name for Bitmap64 {
162            $(#[$($attr)*])*
163            fn $fn_name(&mut self, other: Bitmap64) {
164                self.$alias(&other)
165            }
166        }
167
168        impl $trait_name<&'_ Bitmap64> for Bitmap64 {
169            $(#[$($attr)*])*
170            fn $fn_name(&mut self, other: &Bitmap64) {
171                self.$alias(other)
172            }
173        }
174    };
175}
176
177impl_binop! {
178    impl BitAnd {
179        type Output = Bitmap64;
180
181        /// Syntactic sugar for `.and`
182        ///
183        /// # Examples
184        ///
185        /// ```
186        /// use croaring::Bitmap64;
187        ///
188        /// let mut bitmap1 = Bitmap64::new();
189        /// bitmap1.add(1);
190        ///
191        /// let mut bitmap2 = Bitmap64::new();
192        /// bitmap2.add(1);
193        /// bitmap2.add(2);
194        ///
195        /// let bitmap3 = bitmap1 & bitmap2;
196        ///
197        /// assert!(bitmap3.contains(1));
198        /// assert!(!bitmap3.contains(2));
199        /// ```
200        #[inline]
201        #[doc(alias = "roaring64_bitmap_and")]
202        fn bitand -> Bitmap64 as and
203    }
204}
205
206impl_binop! {
207    impl BitOr {
208        type Output = Bitmap64;
209
210        /// Syntatic sugar for `.or`
211        ///
212        /// # Examples
213        ///
214        /// ```
215        /// use croaring::Bitmap64;
216        ///
217        /// let bitmap1 = Bitmap64::of(&[15]);
218        /// let bitmap2 = Bitmap64::of(&[25]);
219        ///
220        /// let bitmap3 = bitmap1 | bitmap2;
221        ///
222        /// assert!(bitmap3.cardinality() == 2);
223        /// assert!(bitmap3.contains(15));
224        /// assert!(bitmap3.contains(25));
225        /// ```
226        #[inline]
227        #[doc(alias = "roaring64_bitmap_or")]
228        fn bitor -> Bitmap64 as or
229    }
230}
231
232impl_binop! {
233    impl BitXor {
234        type Output = Bitmap64;
235
236        /// Syntatic sugar for `.xor`
237        ///
238        /// # Examples
239        ///
240        /// ```
241        /// use croaring::Bitmap64;
242        ///
243        /// let bitmap1 = Bitmap64::of(&[15, 25]);
244        /// let bitmap2 = Bitmap64::of(&[25, 35]);
245        ///
246        /// let bitmap3 = bitmap1 ^ bitmap2;
247        ///
248        /// assert!(bitmap3.cardinality() == 2);
249        /// assert!(bitmap3.contains(15));
250        /// assert!(!bitmap3.contains(25));
251        /// assert!(bitmap3.contains(35));
252        /// ```
253        #[inline]
254        #[doc(alias = "roaring64_bitmap_xor")]
255        fn bitxor -> Bitmap64 as xor
256    }
257}
258
259impl_binop! {
260    impl Sub {
261        type Output = Bitmap64;
262
263        /// Syntatic sugar for `.andnot`
264        ///
265        /// # Examples
266        ///
267        /// ```
268        /// use croaring::Bitmap64;
269        ///
270        /// let bitmap1 = Bitmap64::of(&[15, 25]);
271        /// let bitmap2 = Bitmap64::of(&[25, 35]);
272        ///
273        /// let bitmap3 = bitmap1 - bitmap2;
274        ///
275        /// assert_eq!(bitmap3.cardinality(), 1);
276        /// assert!(bitmap3.contains(15));
277        /// assert!(!bitmap3.contains(25));
278        /// assert!(!bitmap3.contains(35));
279        /// ```
280        #[inline]
281        #[doc(alias = "andnot")]
282        #[doc(alias = "roaring64_bitmap_andnot")]
283        fn sub -> Bitmap64 as andnot
284    }
285}
286
287impl_binop_assign! {
288    impl BitAndAssign {
289        /// Syntactic sugar for `.and_inplace`
290        ///
291        /// # Examples
292        ///
293        /// ```
294        /// use croaring::Bitmap64;
295        ///
296        /// let mut bitmap1 = Bitmap64::of(&[15]);
297        /// let bitmap2 = Bitmap64::of(&[25]);
298        /// let mut bitmap3 = Bitmap64::of(&[15]);
299        /// let bitmap4 = Bitmap64::of(&[15, 25]);
300        ///
301        /// bitmap1 &= bitmap2;
302        ///
303        /// assert!(bitmap1.cardinality() == 0);
304        /// assert!(!bitmap1.contains(15));
305        /// assert!(!bitmap1.contains(25));
306        ///
307        /// bitmap3 &= bitmap4;
308        ///
309        /// assert!(bitmap3.cardinality() == 1);
310        /// assert!(bitmap3.contains(15));
311        /// assert!(!bitmap3.contains(25));
312        /// ```
313        #[inline]
314        #[doc(alias = "roaring64_bitmap_and_inplace")]
315        fn bitand_assign as and_inplace
316    }
317}
318
319impl_binop_assign! {
320    impl BitOrAssign {
321        /// Syntatic sugar for `.or_inplace`
322        ///
323        /// # Examples
324        ///
325        /// ```
326        /// use croaring::Bitmap64;
327        ///
328        /// let mut bitmap1 = Bitmap64::of(&[15]);
329        /// let bitmap2 = Bitmap64::of(&[25]);
330        ///
331        /// bitmap1 |= bitmap2;
332        ///
333        /// assert!(bitmap1.cardinality() == 2);
334        /// assert!(bitmap1.contains(15));
335        /// assert!(bitmap1.contains(25));
336        /// ```
337        #[inline]
338        #[doc(alias = "roaring64_bitmap_or_inplace")]
339        fn bitor_assign as or_inplace
340    }
341}
342
343impl_binop_assign! {
344    impl BitXorAssign {
345        /// Syntatic sugar for `.xor_inplace`
346        ///
347        /// # Examples
348        ///
349        /// ```
350        /// use croaring::Bitmap64;
351        ///
352        /// let mut bitmap1 = Bitmap64::of(&[15, 25]);
353        /// let bitmap2 = Bitmap64::of(&[25, 35]);
354        ///
355        /// bitmap1 ^= bitmap2;
356        ///
357        /// assert!(bitmap1.cardinality() == 2);
358        /// assert!(bitmap1.contains(15));
359        /// assert!(!bitmap1.contains(25));
360        /// assert!(bitmap1.contains(35));
361        /// ```
362        #[inline]
363        #[doc(alias = "roaring64_bitmap_xor_inplace")]
364        fn bitxor_assign as xor_inplace
365    }
366}
367
368impl_binop_assign! {
369    impl SubAssign {
370        /// Syntatic sugar for `.andnot_inplace`
371        ///
372        /// # Examples
373        ///
374        /// ```
375        /// use croaring::Bitmap64;
376        ///
377        /// let mut bitmap1 = Bitmap64::of(&[15, 25]);
378        /// let bitmap2 = Bitmap64::of(&[25, 35]);
379        ///
380        /// bitmap1 -= bitmap2;
381        ///
382        /// assert_eq!(bitmap1.cardinality(), 1);
383        /// assert!(bitmap1.contains(15));
384        /// assert!(!bitmap1.contains(25));
385        /// assert!(!bitmap1.contains(35));
386        /// ```
387        #[inline]
388        #[doc(alias = "andnot_inplace")]
389        #[doc(alias = "roaring64_bitmap_andnot_inplace")]
390        fn sub_assign as andnot_inplace
391    }
392}