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}