pub struct CharRange { /* private fields */ }Expand description
A range of characters SmtChars defined by a start and an end character.
Every range covers all characters between the start and the end character, including the start and the end character themselves.
If the start character is greater than the end character, the range is empty, otherwise it spans exactly end - start + 1 characters.
§Ordering
Ranges are ordered lexicographically.
That is, if [s1, e1] and [s2, e2] are two ranges, then [s1, e1] < [s2, e2] precisely if
s1 < s2,- or
s1 == s2ande1 < e2.
§Example
The range ['a', 'k'] is less than the range ['a', 'z'] which is less than the range ['b', 'z'].
use smt_str::alphabet::CharRange;
assert!(CharRange::new('a', 'k') < CharRange::new('a', 'z'));
assert!(CharRange::new('a', 'z') < CharRange::new('b', 'z'));§Set operations
CharRange supports several common set-theoretic operations:
- Intersection: The intersection of two ranges is the range that contains all characters that are in both ranges (see intersect).
- Complement: The complement of a range is the range(s) containing all characters (in the SMT-LIB alphabet) that are not in the original range (see complement).
- Difference: The difference of two ranges is the range(s) containing all characters that are in the first range but not in the second range (see subtract).
- Subset check: Check if a range is a subset of another range (see covers).
All above operations are performed in O(1) time. Unions of ranges are not directly supported by the CharRange type but are represented by the Alphabet type.
Implementations§
Source§impl CharRange
impl CharRange
Sourcepub fn new(start: impl Into<SmtChar>, end: impl Into<SmtChar>) -> Self
pub fn new(start: impl Into<SmtChar>, end: impl Into<SmtChar>) -> Self
Create a new range of characters between two characters start and end (inclusive), where start and end can be any type that can be converted into a SmtChar.
If start > end, the range is empty.
If start == end, the range contains a single character.
§Example
use smt_str::alphabet::CharRange;
use smt_str::SmtChar;
let range = CharRange::new('a', 'z');
assert_eq!(range.len(), 26);
let empty = CharRange::new('z', 'a');
assert!(empty.is_empty());
let single = CharRange::new('a', 'a');
assert_eq!(single.is_singleton(), Some('a'.into()));Sourcepub fn empty() -> Self
pub fn empty() -> Self
Creates an empty range that contains no characters.
§Example
use smt_str::alphabet::CharRange;
let range = CharRange::empty();
assert!(range.is_empty());Sourcepub fn singleton(c: impl Into<SmtChar>) -> Self
pub fn singleton(c: impl Into<SmtChar>) -> Self
Create a range that contains a single character.
§Example
use smt_str::alphabet::CharRange;
let range = CharRange::singleton('a');
assert_eq!(range.len(), 1);
assert!(range.contains('a'));Sourcepub fn all() -> Self
pub fn all() -> Self
Create a range that covers all characters in the SMT-LIB alphabet, i.e., all characters in the range [0, 0x2FFFF].
§Example
use smt_str::alphabet::CharRange;
use smt_str::SmtChar;
let range = CharRange::all();
assert_eq!(range.len(), 0x2FFFF + 1);
assert!(range.contains(0));
assert!(range.contains(SmtChar::MAX));Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Return the number of characters in the range.
§Example
use smt_str::alphabet::CharRange;
use smt_str::SmtChar;
assert_eq!(CharRange::new('a', 'z').len(), 26);
assert_eq!(CharRange::singleton('a').len(), 1);
assert_eq!(CharRange::new('z', 'a').len(), 0);Sourcepub fn iter(&self) -> impl Iterator<Item = SmtChar>
pub fn iter(&self) -> impl Iterator<Item = SmtChar>
Returns an iterator over all characters in the range. The iterator returns all characters in the range, including the start and the end character. If the range is empty, the iterator returns no characters.
§Example
use smt_str::alphabet::CharRange;
use smt_str::SmtChar;
let range = CharRange::new('a', 'c');
let mut iter = range.iter();
assert_eq!(iter.next(), Some('a'.into()));
assert_eq!(iter.next(), Some('b'.into()));
assert_eq!(iter.next(), Some('c'.into()));
assert_eq!(iter.next(), None);Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Check if the range is empty. The range is empty if the start character is greater than the end character.
§Example
use smt_str::alphabet::CharRange;
use smt_str::SmtChar;
assert!(CharRange::empty().is_empty());
assert!(!CharRange::new('a', 'z').is_empty());
assert!(!CharRange::singleton('a').is_empty());
assert!(CharRange::new('z', 'a').is_empty());Sourcepub fn start(&self) -> SmtChar
pub fn start(&self) -> SmtChar
Returns the lower bound of the range.
§Example
use smt_str::alphabet::CharRange;
use smt_str::SmtChar;
let range = CharRange::new('a', 'z');
assert_eq!(range.start(), 'a'.into());
// Does not check for empty range
let empty = CharRange::new('z', 'a');
assert_eq!(empty.start(), 'z'.into());Sourcepub fn end(&self) -> SmtChar
pub fn end(&self) -> SmtChar
Returns the upper bound of the range.
§Example
use smt_str::alphabet::CharRange;
use smt_str::SmtChar;
let range = CharRange::new('a', 'z');
assert_eq!(range.end(), 'z'.into());
// Does not check for empty range
let empty = CharRange::new('z', 'a');
assert_eq!(empty.end(), 'a'.into());Sourcepub fn choose(&self) -> Option<SmtChar>
pub fn choose(&self) -> Option<SmtChar>
Returns a character from the range.
If the range is empty, returns None.
§Example
use smt_str::alphabet::CharRange;
use smt_str::SmtChar;
let range = CharRange::new('a', 'z');
assert!(range.choose().is_some());
assert_eq!(CharRange::empty().choose(), None);Sourcepub fn is_singleton(&self) -> Option<SmtChar>
pub fn is_singleton(&self) -> Option<SmtChar>
Check if the range contains a single character.
§Example
use smt_str::alphabet::CharRange;
use smt_str::SmtChar;
assert!(CharRange::singleton('a').is_singleton().is_some());
assert!(CharRange::new('a', 'z').is_singleton().is_none());
assert!(CharRange::empty().is_singleton().is_none());Sourcepub fn is_full(&self) -> bool
pub fn is_full(&self) -> bool
Check if the range contains all characters in the SMT-LIB alphabet.
§Example
use smt_str::alphabet::CharRange;
use smt_str::SmtChar;
assert!(CharRange::all().is_full());
assert!(CharRange::new(SmtChar::MIN, SmtChar::MAX).is_full());
assert!(!CharRange::empty().is_full());
assert!(!CharRange::new('a', 'z').is_full());Sourcepub fn contains(&self, c: impl Into<SmtChar>) -> bool
pub fn contains(&self, c: impl Into<SmtChar>) -> bool
Check if a character is in the range. Returns true if the character is in the range, false otherwise.
§Example
use smt_str::alphabet::CharRange;
use smt_str::SmtChar;
let range = CharRange::new('a', 'z');
assert!(range.contains('a'));
assert!(range.contains('z'));
assert!(range.contains('m'));
assert!(range.contains(98)); // 'a'
assert!(!range.contains('A'));
assert!(!range.contains('0'));Sourcepub fn covers(&self, other: &Self) -> bool
pub fn covers(&self, other: &Self) -> bool
Checks if this range is a superset of another range. Returns true if this range contains all characters in the other range.
§Example
use smt_str::alphabet::CharRange;
use smt_str::SmtChar;
let r1 = CharRange::new('a', 'c');
let r2 = CharRange::new('a', 'b');
let r3 = CharRange::new('b', 'f');
assert!(r1.covers(&r2));
assert!(!r1.covers(&r3));
assert!(r1.covers(&r1));Sourcepub fn intersect(&self, other: &Self) -> Self
pub fn intersect(&self, other: &Self) -> Self
Return the intersection of two ranges. The intersection of two ranges is the range that contains all characters that are in both ranges. If the two ranges do not overlap, the intersection is empty.
§Example
use smt_str::alphabet::CharRange;
use smt_str::SmtChar;
let r1 = CharRange::new('a', 'm');
let r2 = CharRange::new('a', 'z');
let r3 = CharRange::singleton('a');
let r4 = CharRange::new('y', 'z');
assert_eq!(r1.intersect(&r2), CharRange::new('a', 'm'));
assert_eq!(r1.intersect(&r3), CharRange::singleton('a'));
assert!(r1.intersect(&r4).is_empty());Sourcepub fn complement(&self) -> Vec<CharRange>
pub fn complement(&self) -> Vec<CharRange>
Returns the complement of the SMT-LIB alphabet w.r.t. this range.
If this range is [a, b], the complement is a union of ranges containing
[0, a-1]ifa > 0,- and
[b+1, MAX]ifb < MAX.
Thus, the complement of an empty range is the full alphabet and the complement of the full alphabet is empty.
§Example
use smt_str::alphabet::CharRange;
use smt_str::SmtChar;
let range = CharRange::new('a', 'd');
let complement = range.complement();
let mut iter = complement.into_iter();
assert_eq!(iter.next(), Some(CharRange::new(SmtChar::from(0), SmtChar::from('a').saturating_prev())));
assert_eq!(iter.next(), Some(CharRange::new(SmtChar::from('d').saturating_next(), SmtChar::MAX)));
assert_eq!(iter.next(), None);
assert_eq!(CharRange::empty().complement(), vec![CharRange::all()]);
assert_eq!(CharRange::all().complement(), vec![]);Sourcepub fn subtract(&self, other: &Self) -> Vec<CharRange>
pub fn subtract(&self, other: &Self) -> Vec<CharRange>
Subtracts the other range from this ranges. Returns the difference of two ranges. The difference of two ranges is the range that contains all characters that are in the first range but not in the second range. If the two ranges do not overlap, the difference is the first range itself. If the first range is a subset of the second range, the difference is empty. If the second range is a subset of the first range, the difference is the two ranges that are not overlapping. If the two ranges are equal, the difference is empty.
§Example
use smt_str::alphabet::CharRange;
use smt_str::SmtChar;
let r1 = CharRange::new('a', 'z');
let r2 = CharRange::new('a', 'm');
let r3 = CharRange::new('m', 'z');
let r4 = CharRange::singleton('c');
assert_eq!(r1.subtract(&r2), vec![CharRange::new('n', 'z')]);
assert_eq!(r1.subtract(&r3), vec![CharRange::new('a', 'l')]);
assert_eq!(r2.subtract(&r3), vec![CharRange::new('a', 'l')]);
assert_eq!(r1.subtract(&r4), vec![CharRange::new('a', 'b'), CharRange::new('d', 'z')]);
assert_eq!(r2.subtract(&r2), vec![]);Trait Implementations§
Source§impl FromIterator<CharRange> for Alphabet
impl FromIterator<CharRange> for Alphabet
Source§impl Ord for CharRange
impl Ord for CharRange
Source§impl PartialOrd for CharRange
impl PartialOrd for CharRange
impl Copy for CharRange
impl Eq for CharRange
impl StructuralPartialEq for CharRange
Auto Trait Implementations§
impl Freeze for CharRange
impl RefUnwindSafe for CharRange
impl Send for CharRange
impl Sync for CharRange
impl Unpin for CharRange
impl UnwindSafe for CharRange
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Comparable<K> for Q
impl<Q, K> Comparable<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more