lib.rs (25732B)
1 //! [![git]](https://git.philomathiclife.com/zfc/log.html) [![crates-io]](https://crates.io/crates/zfc) [![docs-rs]](crate) 2 //! 3 //! [git]: https://git.philomathiclife.com/git_badge.svg 4 //! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust 5 //! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs 6 //! 7 //! `zfc` is a library for sets according to 8 //! [Zermelo–Fraenkel set theory with the axiom of choice (ZFC)](https://en.wikipedia.org/wiki/Zermelo%E2%80%93Fraenkel_set_theory). 9 #![expect( 10 clippy::doc_paragraphs_missing_punctuation, 11 reason = "false positive for crate documentation having image links" 12 )] 13 #![cfg_attr(docsrs, feature(doc_cfg))] 14 #![no_std] 15 extern crate alloc; 16 use alloc::{collections::BTreeSet, vec::Vec}; 17 use core::{ 18 borrow::Borrow, 19 cmp::Ordering, 20 error::Error, 21 fmt::{self, Display, Formatter}, 22 ops::{Range, RangeInclusive, Sub}, 23 }; 24 pub use num_bigint; 25 use num_bigint::BigUint; 26 /// Represents the quantity of elements in a [`Set`]. 27 #[derive(Clone, Eq, Hash, Ord, PartialEq, PartialOrd)] 28 pub enum Cardinality { 29 /// The contained `BigUint` represents the quantity of elements in a finite `Set`. 30 Finite(BigUint), 31 /// The contained `BigUint` represents the [aleph number](https://en.wikipedia.org/wiki/Aleph_number) of a transfinite `Set`. 32 Transfinite(BigUint), 33 } 34 impl Cardinality { 35 /// Returns a reference to the contained `BigUint`. 36 #[inline] 37 #[must_use] 38 pub const fn as_biguint(&self) -> &BigUint { 39 match *self { 40 Self::Finite(ref val) | Self::Transfinite(ref val) => val, 41 } 42 } 43 /// Creates a `Cardinality::Finite` containing `value`. 44 #[inline] 45 #[must_use] 46 pub const fn from_biguint(value: BigUint) -> Self { 47 Self::Finite(value) 48 } 49 /// `Cardinality::Transfinite` is always greater. 50 /// For `Cardinality::Finite` the contained `BigUint` 51 /// is compared to `value`. 52 #[inline] 53 #[must_use] 54 pub fn cmp_u8(&self, value: &u8) -> Ordering { 55 match *self { 56 Self::Finite(ref card) => card.cmp(&(*value).into()), 57 Self::Transfinite(_) => Ordering::Greater, 58 } 59 } 60 /// `Cardinality::Transfinite` is always greater. 61 /// For `Cardinality::Finite` the contained `BigUint` 62 /// is compared to `value`. 63 #[inline] 64 #[must_use] 65 pub fn cmp_u16(&self, value: &u16) -> Ordering { 66 match *self { 67 Self::Finite(ref card) => card.cmp(&(*value).into()), 68 Self::Transfinite(_) => Ordering::Greater, 69 } 70 } 71 /// `Cardinality::Transfinite` is always greater. 72 /// For `Cardinality::Finite` the contained `BigUint` 73 /// is compared to `value`. 74 #[inline] 75 #[must_use] 76 pub fn cmp_u32(&self, value: &u32) -> Ordering { 77 match *self { 78 Self::Finite(ref card) => card.cmp(&(*value).into()), 79 Self::Transfinite(_) => Ordering::Greater, 80 } 81 } 82 /// `Cardinality::Transfinite` is always greater. 83 /// For `Cardinality::Finite` the contained `BigUint` 84 /// is compared to `value`. 85 #[inline] 86 #[must_use] 87 pub fn cmp_u64(&self, value: &u64) -> Ordering { 88 match *self { 89 Self::Finite(ref card) => card.cmp(&(*value).into()), 90 Self::Transfinite(_) => Ordering::Greater, 91 } 92 } 93 /// `Cardinality::Transfinite` is always greater. 94 /// For `Cardinality::Finite` the contained `BigUint` 95 /// is compared to `value`. 96 #[inline] 97 #[must_use] 98 pub fn cmp_u128(&self, value: &u128) -> Ordering { 99 match *self { 100 Self::Finite(ref card) => card.cmp(&(*value).into()), 101 Self::Transfinite(_) => Ordering::Greater, 102 } 103 } 104 /// `Cardinality::Transfinite` is always greater. 105 /// For `Cardinality::Finite` the contained `BigUint` 106 /// is compared to `value`. 107 #[inline] 108 #[must_use] 109 pub fn cmp_usize(&self, value: &usize) -> Ordering { 110 match *self { 111 Self::Finite(ref card) => card.cmp(&(*value).into()), 112 Self::Transfinite(_) => Ordering::Greater, 113 } 114 } 115 /// `Cardinality::Transfinite` is always greater. 116 /// For `Cardinality::Finite` the contained `BigUint` 117 /// is compared to `value`. 118 #[inline] 119 #[must_use] 120 pub fn cmp_biguint(&self, value: &BigUint) -> Ordering { 121 match *self { 122 Self::Finite(ref card) => card.cmp(value), 123 Self::Transfinite(_) => Ordering::Greater, 124 } 125 } 126 } 127 impl Display for Cardinality { 128 #[inline] 129 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 130 match *self { 131 Self::Finite(ref val) => val.fmt(f), 132 Self::Transfinite(ref val) => write!(f, "\u{2135}_{val}"), 133 } 134 } 135 } 136 impl fmt::Debug for Cardinality { 137 #[inline] 138 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 139 <Self as Display>::fmt(self, f) 140 } 141 } 142 impl From<BigUint> for Cardinality { 143 #[inline] 144 fn from(value: BigUint) -> Self { 145 Self::from_biguint(value) 146 } 147 } 148 impl TryFrom<BoundedCardinality> for Cardinality { 149 type Error = CardinalityErr; 150 #[inline] 151 fn try_from(value: BoundedCardinality) -> Result<Self, Self::Error> { 152 if value.lower == value.upper { 153 Ok(value.lower) 154 } else { 155 Err(CardinalityErr) 156 } 157 } 158 } 159 impl From<Cardinality> for BigUint { 160 #[inline] 161 fn from(value: Cardinality) -> Self { 162 match value { 163 Cardinality::Finite(val) | Cardinality::Transfinite(val) => val, 164 } 165 } 166 } 167 impl PartialEq<u8> for Cardinality { 168 #[inline] 169 fn eq(&self, other: &u8) -> bool { 170 match *self { 171 Self::Finite(ref card) => *card == BigUint::from(*other), 172 Self::Transfinite(_) => false, 173 } 174 } 175 } 176 impl PartialEq<u16> for Cardinality { 177 #[inline] 178 fn eq(&self, other: &u16) -> bool { 179 match *self { 180 Self::Finite(ref card) => *card == BigUint::from(*other), 181 Self::Transfinite(_) => false, 182 } 183 } 184 } 185 impl PartialEq<u32> for Cardinality { 186 #[inline] 187 fn eq(&self, other: &u32) -> bool { 188 match *self { 189 Self::Finite(ref card) => *card == BigUint::from(*other), 190 Self::Transfinite(_) => false, 191 } 192 } 193 } 194 impl PartialEq<u64> for Cardinality { 195 #[inline] 196 fn eq(&self, other: &u64) -> bool { 197 match *self { 198 Self::Finite(ref card) => *card == BigUint::from(*other), 199 Self::Transfinite(_) => false, 200 } 201 } 202 } 203 impl PartialEq<u128> for Cardinality { 204 #[inline] 205 fn eq(&self, other: &u128) -> bool { 206 match *self { 207 Self::Finite(ref card) => *card == BigUint::from(*other), 208 Self::Transfinite(_) => false, 209 } 210 } 211 } 212 impl PartialEq<usize> for Cardinality { 213 #[inline] 214 fn eq(&self, other: &usize) -> bool { 215 match *self { 216 Self::Finite(ref card) => *card == BigUint::from(*other), 217 Self::Transfinite(_) => false, 218 } 219 } 220 } 221 impl PartialEq<BigUint> for Cardinality { 222 #[inline] 223 fn eq(&self, other: &BigUint) -> bool { 224 match *self { 225 Self::Finite(ref card) => card == other, 226 Self::Transfinite(_) => false, 227 } 228 } 229 } 230 impl PartialOrd<u8> for Cardinality { 231 #[inline] 232 fn partial_cmp(&self, other: &u8) -> Option<Ordering> { 233 Some(self.cmp_u8(other)) 234 } 235 } 236 impl PartialOrd<u16> for Cardinality { 237 #[inline] 238 fn partial_cmp(&self, other: &u16) -> Option<Ordering> { 239 Some(self.cmp_u16(other)) 240 } 241 } 242 impl PartialOrd<u32> for Cardinality { 243 #[inline] 244 fn partial_cmp(&self, other: &u32) -> Option<Ordering> { 245 Some(self.cmp_u32(other)) 246 } 247 } 248 impl PartialOrd<u64> for Cardinality { 249 #[inline] 250 fn partial_cmp(&self, other: &u64) -> Option<Ordering> { 251 Some(self.cmp_u64(other)) 252 } 253 } 254 impl PartialOrd<u128> for Cardinality { 255 #[inline] 256 fn partial_cmp(&self, other: &u128) -> Option<Ordering> { 257 Some(self.cmp_u128(other)) 258 } 259 } 260 impl PartialOrd<usize> for Cardinality { 261 #[inline] 262 fn partial_cmp(&self, other: &usize) -> Option<Ordering> { 263 Some(self.cmp_usize(other)) 264 } 265 } 266 impl PartialOrd<BigUint> for Cardinality { 267 #[inline] 268 fn partial_cmp(&self, other: &BigUint) -> Option<Ordering> { 269 Some(self.cmp_biguint(other)) 270 } 271 } 272 /// Error returned when attempting to create a [`BoundedCardinality`] from a pair of [`BigUint`]s 273 /// or [`Cardinality`]s such that the upper bound is strictly less than the lower bound. 274 #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] 275 pub struct BoundedErr; 276 impl Display for BoundedErr { 277 #[inline] 278 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 279 f.write_str("upper bound is greater than lower bound") 280 } 281 } 282 impl Error for BoundedErr {} 283 /// Error returned when attempting to create a [`Cardinality`] from a [`BoundedCardinality`] such that 284 /// the lower bound is less than the upper bound. 285 #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] 286 pub struct CardinalityErr; 287 impl Display for CardinalityErr { 288 #[inline] 289 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 290 f.write_str("lower bound of the BoundedCardinality is less than the upper bound") 291 } 292 } 293 impl Error for CardinalityErr {} 294 /// Contains a lower and upper bound [`Cardinality`] used to bound the cardinality of a [`Set`]. 295 #[derive(Clone, Eq, Hash, Ord, PartialEq, PartialOrd)] 296 pub struct BoundedCardinality { 297 /// Lower bound. 298 lower: Cardinality, 299 /// Upper bound. 300 upper: Cardinality, 301 } 302 impl BoundedCardinality { 303 /// Creates an instance of `BoundedCardinality`. 304 /// 305 /// Returns `None` iff `lower > upper`. 306 #[inline] 307 #[must_use] 308 pub fn new(lower: Cardinality, upper: Cardinality) -> Option<Self> { 309 if lower > upper { 310 None 311 } else { 312 Some(Self { lower, upper }) 313 } 314 } 315 /// Creates an instance of `BoundedCardinality` with the lower and upper bounds both set to `exact`. 316 #[inline] 317 #[must_use] 318 pub fn new_exact(exact: Cardinality) -> Self { 319 Self { 320 lower: exact.clone(), 321 upper: exact, 322 } 323 } 324 /// Creates an instance of `BoundedCardinality` with the lower and upper bounds as `Cardinality::Finite` 325 /// of their respective values. 326 /// 327 /// Returns `None` iff `lower > upper`. 328 #[inline] 329 #[must_use] 330 pub fn from_biguint(lower: BigUint, upper: BigUint) -> Option<Self> { 331 if lower > upper { 332 None 333 } else { 334 Some(Self { 335 lower: Cardinality::Finite(lower), 336 upper: Cardinality::Finite(upper), 337 }) 338 } 339 } 340 /// Creates an instance of `BoundedCardinality` with the lower and upper bounds as `Cardinality::Finite(exact)`. 341 #[inline] 342 #[must_use] 343 pub fn from_biguint_exact(exact: BigUint) -> Self { 344 Self { 345 lower: Cardinality::Finite(exact.clone()), 346 upper: Cardinality::Finite(exact), 347 } 348 } 349 /// Creates an instance of `BoundedCardinality` without verifying `lower <= upper`. 350 /// 351 /// # Safety 352 /// 353 /// `lower <= upper`. 354 #[expect( 355 unsafe_code, 356 reason = "when literal values are used, code can reasonably bypass checks" 357 )] 358 #[inline] 359 #[must_use] 360 pub const unsafe fn new_unsafe(lower: Cardinality, upper: Cardinality) -> Self { 361 Self { lower, upper } 362 } 363 /// Creates an instance of `BoundedCardinality` with the lower and upper bounds as `Cardinality::Finite` 364 /// of their respective values without verifying `lower <= upper`. 365 /// 366 /// # Safety 367 /// 368 /// `lower <= upper`. 369 #[expect( 370 unsafe_code, 371 reason = "when literal values are used, code can reasonably bypass checks" 372 )] 373 #[inline] 374 #[must_use] 375 pub const unsafe fn from_biguint_unsafe(lower: BigUint, upper: BigUint) -> Self { 376 Self { 377 lower: Cardinality::Finite(lower), 378 upper: Cardinality::Finite(upper), 379 } 380 } 381 /// Returns a reference to the lower bound. 382 #[inline] 383 #[must_use] 384 pub const fn lower(&self) -> &Cardinality { 385 &self.lower 386 } 387 /// Returns the lower bound. 388 #[inline] 389 #[must_use] 390 pub fn to_lower(self) -> Cardinality { 391 self.lower 392 } 393 /// Returns a reference to the upper bound. 394 #[inline] 395 #[must_use] 396 pub const fn upper(&self) -> &Cardinality { 397 &self.upper 398 } 399 /// Returns the upper bound. 400 #[inline] 401 #[must_use] 402 pub fn to_upper(self) -> Cardinality { 403 self.upper 404 } 405 /// Returns a tuple containing the references to the lower and upper bounds respectively. 406 #[inline] 407 #[must_use] 408 pub const fn lower_upper(&self) -> (&Cardinality, &Cardinality) { 409 (&self.lower, &self.upper) 410 } 411 /// Returns a reference to the contained `BigUint` of `self.lower()`. 412 #[inline] 413 #[must_use] 414 pub const fn lower_biguint(&self) -> &BigUint { 415 self.lower.as_biguint() 416 } 417 /// Returns the lower bound as a `BigUint`. 418 #[inline] 419 #[must_use] 420 pub fn to_lower_biguint(self) -> BigUint { 421 self.lower.into() 422 } 423 /// Returns a reference to the contained `BigUint` of `self.upper()`. 424 #[inline] 425 #[must_use] 426 pub const fn upper_biguint(&self) -> &BigUint { 427 self.upper.as_biguint() 428 } 429 /// Returns the upper bound as a `BigUint`. 430 #[inline] 431 #[must_use] 432 pub fn to_upper_biguint(self) -> BigUint { 433 self.upper.into() 434 } 435 /// Returns a tuple of references to the contained `BigUint`s of `self.lower()` and `self.upper()` respectively. 436 #[inline] 437 #[must_use] 438 pub const fn lower_upper_biguint(&self) -> (&BigUint, &BigUint) { 439 (self.lower_biguint(), self.upper_biguint()) 440 } 441 } 442 impl Display for BoundedCardinality { 443 #[inline] 444 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 445 write!(f, "({}, {})", self.lower, self.upper) 446 } 447 } 448 impl fmt::Debug for BoundedCardinality { 449 #[inline] 450 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 451 <Self as Display>::fmt(self, f) 452 } 453 } 454 impl From<BigUint> for BoundedCardinality { 455 #[inline] 456 fn from(value: BigUint) -> Self { 457 Self::from_biguint_exact(value) 458 } 459 } 460 impl From<Cardinality> for BoundedCardinality { 461 #[inline] 462 fn from(value: Cardinality) -> Self { 463 Self { 464 lower: value.clone(), 465 upper: value, 466 } 467 } 468 } 469 impl TryFrom<(Cardinality, Cardinality)> for BoundedCardinality { 470 type Error = BoundedErr; 471 #[inline] 472 fn try_from(value: (Cardinality, Cardinality)) -> Result<Self, Self::Error> { 473 Self::new(value.0, value.1).ok_or(BoundedErr) 474 } 475 } 476 impl TryFrom<(BigUint, BigUint)> for BoundedCardinality { 477 type Error = BoundedErr; 478 #[inline] 479 fn try_from(value: (BigUint, BigUint)) -> Result<Self, Self::Error> { 480 Self::from_biguint(value.0, value.1).ok_or(BoundedErr) 481 } 482 } 483 impl From<BoundedCardinality> for (Cardinality, Cardinality) { 484 #[inline] 485 fn from(value: BoundedCardinality) -> Self { 486 (value.lower, value.upper) 487 } 488 } 489 impl From<BoundedCardinality> for (BigUint, BigUint) { 490 #[inline] 491 fn from(value: BoundedCardinality) -> Self { 492 (value.lower.into(), value.upper.into()) 493 } 494 } 495 /// Represents a set according to 496 /// [Zermelo–Fraenkel set theory with the axiom of choice (ZFC)](https://en.wikipedia.org/wiki/Zermelo%E2%80%93Fraenkel_set_theory). 497 /// 498 /// Note that elements in a `Set` must not be distinguishable by order or frequency, so care must be taken in its 499 /// implementation if the implementing type exposes an API that distinguishes between the order or frequency of 500 /// `Elem` (e.g., [`Vec<T>`](https://doc.rust-lang.org/alloc/vec/struct.Vec.html) where `Elem` = `T`). 501 pub trait Set { 502 /// The elements that make up the set. 503 /// 504 /// Per ZFC, this must not be the same type as `Self` nor a recursive type based on `Self`. 505 type Elem: Eq + ?Sized; 506 /// Returns the cardinality of `self` if it is known exactly. 507 /// 508 /// The following property must be true: 509 /// * `self.cardinality().unwrap() == self.bounded_cardinality().lower()` ⇔ `self.bounded_cardinality().lower() == self.bounded_cardinality().upper()`. 510 #[inline] 511 fn cardinality(&self) -> Option<Cardinality> { 512 let bound = self.bounded_cardinality(); 513 if bound.lower < bound.upper { 514 None 515 } else { 516 Some(bound.lower) 517 } 518 } 519 /// Returns the bounded cardinality of `self`. 520 fn bounded_cardinality(&self) -> BoundedCardinality; 521 /// Returns `true` iff `Self` contains `elem`. 522 fn contains<Q>(&self, elem: &Q) -> bool 523 where 524 Q: Borrow<Self::Elem> + Eq + ?Sized; 525 /// Must conform to the following properties: 526 /// * Irreflexivity. 527 /// * Antisymmetry. 528 /// * Transitivity. 529 /// * ∀`a`, `b`: `Self`, `a.is_proper_subset(b)`⇒ ∀`e`: `Elem` | `a.contains(e)`, `b.contains(e)` ∧ ∃`f`: `Elem`, `b.contains(f) && !a.contains(f)`. 530 /// * ∀`a`, `b`: `Self`, `a.is_proper_subset(b)` ⇒ `a.is_subset(b)`. 531 /// * ∀`a`, `b`: `Self`, `a.is_proper_subset(b)` ⇔ `b.is_proper_superset(a)`. 532 fn is_proper_subset(&self, val: &Self) -> bool; 533 /// Must conform to the following properties: 534 /// * Reflexivity. 535 /// * Antisymmetry. 536 /// * Transitivity. 537 /// * ∀`a`, `b`: `Self`, `a.is_subset(b)`⇒ ∀`e`: `Elem` | `a.contains(e)`, `b.contains(e)`. 538 /// * ∀`a`, `b`: `Self`, `a.is_subset(b)` ⇔ `b.is_superset(a)`. 539 fn is_subset(&self, val: &Self) -> bool; 540 /// Must conform to the following properties: 541 /// * Irreflexivity. 542 /// * Antisymmetry. 543 /// * Transitivity. 544 /// * ∀`a`, `b`: `Self`, `a.is_proper_superset(b)` ⇒ `a.is_superset(b)`. 545 #[inline] 546 fn is_proper_superset(&self, val: &Self) -> bool { 547 val.is_proper_subset(self) 548 } 549 /// Must conform to the following properties: 550 /// * Reflexivity. 551 /// * Antisymmetry. 552 /// * Transitivity. 553 #[inline] 554 fn is_superset(&self, val: &Self) -> bool { 555 val.is_subset(self) 556 } 557 /// Read [`Set::is_proper_subset`]. 558 #[inline] 559 fn is_proper_subset_iter<T>(&self, val: &T) -> bool 560 where 561 Self::Elem: Borrow<T::Elem> + PartialEq<T::Elem>, 562 for<'a> &'a Self: IntoIterator<Item = &'a Self::Elem>, 563 T: Set + ?Sized, 564 T::Elem: PartialEq<Self::Elem>, 565 { 566 self.cardinality() < val.cardinality() 567 && self 568 .into_iter() 569 .try_fold( 570 (), 571 |(), elem| { 572 if val.contains(elem) { Ok(()) } else { Err(()) } 573 }, 574 ) 575 .is_ok_and(|()| true) 576 } 577 /// Read [`Set::is_subset`]. 578 #[inline] 579 fn is_subset_iter<T>(&self, val: &T) -> bool 580 where 581 Self::Elem: Borrow<T::Elem> + PartialEq<T::Elem>, 582 for<'a> &'a Self: IntoIterator<Item = &'a Self::Elem>, 583 T: Set + ?Sized, 584 T::Elem: PartialEq<Self::Elem>, 585 { 586 self.cardinality() <= val.cardinality() 587 && self 588 .into_iter() 589 .try_fold( 590 (), 591 |(), elem| { 592 if val.contains(elem) { Ok(()) } else { Err(()) } 593 }, 594 ) 595 .is_ok_and(|()| true) 596 } 597 /// Read [`Set::is_proper_superset`]. 598 #[inline] 599 fn is_proper_superset_iter<T>(&self, val: &T) -> bool 600 where 601 Self::Elem: PartialEq<T::Elem>, 602 T: Set + ?Sized, 603 for<'a> &'a T: IntoIterator<Item = &'a T::Elem>, 604 T::Elem: Borrow<Self::Elem> + PartialEq<Self::Elem>, 605 { 606 val.is_proper_subset_iter(self) 607 } 608 /// Read [`Set::is_superset`]. 609 #[inline] 610 fn is_superset_iter<T>(&self, val: &T) -> bool 611 where 612 Self::Elem: PartialEq<T::Elem>, 613 T: Set + ?Sized, 614 for<'a> &'a T: IntoIterator<Item = &'a T::Elem>, 615 T::Elem: Borrow<Self::Elem> + PartialEq<Self::Elem>, 616 { 617 val.is_subset_iter(self) 618 } 619 } 620 impl<T> Set for BTreeSet<T> 621 where 622 T: Ord, 623 { 624 type Elem = T; 625 #[inline] 626 fn cardinality(&self) -> Option<Cardinality> { 627 Some(Cardinality::Finite(self.len().into())) 628 } 629 #[inline] 630 fn bounded_cardinality(&self) -> BoundedCardinality { 631 let card = Cardinality::from_biguint(self.len().into()); 632 BoundedCardinality { 633 lower: card.clone(), 634 upper: card, 635 } 636 } 637 #[inline] 638 fn contains<Q>(&self, elem: &Q) -> bool 639 where 640 Q: Borrow<Self::Elem> + Eq + ?Sized, 641 { 642 self.contains(elem.borrow()) 643 } 644 #[inline] 645 fn is_proper_subset(&self, val: &Self) -> bool { 646 self.len() < val.len() && self.intersection(val).count() == val.len() 647 } 648 #[inline] 649 fn is_subset(&self, val: &Self) -> bool { 650 self.len() <= val.len() && self.intersection(val).count() == val.len() 651 } 652 } 653 impl<T> Set for Range<T> 654 where 655 T: Ord, 656 for<'a, 'b> &'a T: Sub<&'b T>, 657 for<'a, 'b> <&'a T as Sub<&'b T>>::Output: Into<BigUint>, 658 { 659 type Elem = T; 660 #[expect( 661 clippy::arithmetic_side_effects, 662 reason = "we need to calculate the cardinality, and we avoid underflow" 663 )] 664 #[inline] 665 fn cardinality(&self) -> Option<Cardinality> { 666 Some(Cardinality::Finite(if self.end >= self.start { 667 (&self.end - &self.start).into() 668 } else { 669 BigUint::new(Vec::new()) 670 })) 671 } 672 #[expect( 673 clippy::arithmetic_side_effects, 674 reason = "we need to calculate the cardinality, and we avoid underflow" 675 )] 676 #[inline] 677 fn bounded_cardinality(&self) -> BoundedCardinality { 678 let card = Cardinality::Finite(if self.end >= self.start { 679 (&self.end - &self.start).into() 680 } else { 681 BigUint::new(Vec::new()) 682 }); 683 BoundedCardinality { 684 lower: card.clone(), 685 upper: card, 686 } 687 } 688 #[inline] 689 fn contains<Q>(&self, elem: &Q) -> bool 690 where 691 Q: Borrow<Self::Elem> + Eq + ?Sized, 692 { 693 self.contains(elem.borrow()) 694 } 695 #[inline] 696 fn is_proper_subset(&self, val: &Self) -> bool { 697 match self.start.cmp(&val.start) { 698 Ordering::Less => false, 699 Ordering::Equal => self.end < val.end, 700 Ordering::Greater => self.end <= val.end, 701 } 702 } 703 #[inline] 704 fn is_subset(&self, val: &Self) -> bool { 705 self.start >= val.start && self.end <= val.end 706 } 707 } 708 impl<T> Set for RangeInclusive<T> 709 where 710 T: Ord, 711 for<'a, 'b> &'a T: Sub<&'b T>, 712 for<'a, 'b> <&'a T as Sub<&'b T>>::Output: Into<BigUint>, 713 { 714 type Elem = T; 715 #[expect( 716 clippy::arithmetic_side_effects, 717 reason = "we need to calculate the cardinality, and we avoid underflow. Overflow is no worry since we use BigUint." 718 )] 719 #[inline] 720 fn cardinality(&self) -> Option<Cardinality> { 721 Some(Cardinality::Finite(if self.end() >= self.start() { 722 (self.end() - self.start()).into() + BigUint::new(alloc::vec![1]) 723 } else { 724 BigUint::new(Vec::new()) 725 })) 726 } 727 #[expect( 728 clippy::arithmetic_side_effects, 729 reason = "we need to calculate the cardinality, and we avoid underflow. Overflow is no worry since we use BigUint." 730 )] 731 #[inline] 732 fn bounded_cardinality(&self) -> BoundedCardinality { 733 let card = Cardinality::Finite(if self.end() >= self.start() { 734 (self.end() - self.start()).into() + BigUint::new(alloc::vec![1]) 735 } else { 736 BigUint::new(Vec::new()) 737 }); 738 BoundedCardinality { 739 lower: card.clone(), 740 upper: card, 741 } 742 } 743 #[inline] 744 fn contains<Q>(&self, elem: &Q) -> bool 745 where 746 Q: Borrow<Self::Elem> + Eq + ?Sized, 747 { 748 self.contains(elem.borrow()) 749 } 750 #[inline] 751 fn is_proper_subset(&self, val: &Self) -> bool { 752 match self.start().cmp(val.start()) { 753 Ordering::Less => false, 754 Ordering::Equal => self.end() < val.end(), 755 Ordering::Greater => self.end() <= val.end(), 756 } 757 } 758 #[inline] 759 fn is_subset(&self, val: &Self) -> bool { 760 self.start() >= val.start() && self.end() <= val.end() 761 } 762 } 763 #[cfg(feature = "std")] 764 extern crate std; 765 #[cfg(feature = "std")] 766 use core::hash::{BuildHasher, Hash}; 767 #[cfg(feature = "std")] 768 use std::collections::HashSet; 769 #[cfg(feature = "std")] 770 impl<T, S> Set for HashSet<T, S> 771 where 772 T: Eq + Hash, 773 S: BuildHasher, 774 { 775 type Elem = T; 776 #[inline] 777 fn cardinality(&self) -> Option<Cardinality> { 778 Some(Cardinality::Finite(self.len().into())) 779 } 780 #[inline] 781 fn bounded_cardinality(&self) -> BoundedCardinality { 782 let card = Cardinality::Finite(self.len().into()); 783 BoundedCardinality { 784 lower: card.clone(), 785 upper: card, 786 } 787 } 788 #[inline] 789 fn contains<Q>(&self, elem: &Q) -> bool 790 where 791 Q: Borrow<Self::Elem> + Eq + ?Sized, 792 { 793 self.contains(elem.borrow()) 794 } 795 #[inline] 796 fn is_proper_subset(&self, val: &Self) -> bool { 797 self.len() < val.len() && self.intersection(val).count() == val.len() 798 } 799 #[inline] 800 fn is_subset(&self, val: &Self) -> bool { 801 self.len() <= val.len() && self.intersection(val).count() == val.len() 802 } 803 }