sudoku_variants/
util.rs

1//! This module contains utility functionality needed for this crate. Most
2//! prominently, it contains the definition of the [USizeSet] used for storing
3//! cell options for strategies.
4
5use std::mem;
6use std::ops::{
7    BitAnd,
8    BitAndAssign,
9    BitOr,
10    BitOrAssign,
11    BitXor,
12    BitXorAssign,
13    Sub,
14    SubAssign
15};
16use std::slice::Iter;
17
18/// A set of `usize` that is implemented as a bit vector. Each `usize` that is
19/// in the range of possible elements is represented by one bit in a vector of
20/// numbers. This generally has better performance than a `HashSet`.
21#[derive(Clone, Debug, Eq, PartialEq)]
22pub struct USizeSet {
23    min: usize,
24    max: usize,
25    len: usize,
26    content: Vec<u64>
27}
28
29/// An enumeration of the errors that can happen when using a [USizeSet].
30#[derive(Debug, Eq, PartialEq)]
31pub enum USizeSetError {
32
33    /// Indicates that the bounds provided in the constructor are invalid, that
34    /// is, the minimum is greater than the maximum.
35    InvalidBounds,
36
37    /// Indicates that an operation was performed on two or more `USizeSet`s
38    /// with different bounds.
39    DifferentBounds,
40
41    /// Indicates that a number that was queried to be inserted or removed is
42    /// out of the bounds of the `USizeSet` in question.
43    OutOfBounds
44}
45
46/// Syntactic sugar for `Result<V, USizeSetError>`.
47pub type USizeSetResult<V> = Result<V, USizeSetError>;
48
49struct BitIterator {
50    bit_index: usize,
51    value: u64
52}
53
54impl BitIterator {
55    fn new(value: u64) -> BitIterator {
56        BitIterator {
57            bit_index: 0,
58            value
59        }
60    }
61
62    fn progress(&mut self) {
63        let diff = self.value.trailing_zeros() as usize;
64        self.value >>= diff;
65        self.bit_index += diff;
66    }
67}
68
69impl Iterator for BitIterator {
70    type Item = usize;
71
72    fn next(&mut self) -> Option<usize> {
73        if self.value != 0 && (self.value & 1) == 0 {
74            self.progress();
75        }
76
77        let result = if self.value == 0 { None } else { Some(self.bit_index) };
78        self.value &= 0xfffffffffffffffe;
79        result
80    }
81}
82
83/// An iterator over the content of a [USizeSet].
84pub struct USizeSetIter<'a> {
85    offset: usize,
86    current: BitIterator,
87    content: Iter<'a, u64>
88}
89
90impl<'a> USizeSetIter<'a> {
91    fn new(set: &'a USizeSet) -> USizeSetIter<'a> {
92        let mut iter = set.content.iter();
93        let first_bit_iterator = if let Some(&first) = iter.next() {
94            BitIterator::new(first)
95        }
96        else {
97            BitIterator::new(0)
98        };
99
100        USizeSetIter {
101            offset: set.min,
102            current: first_bit_iterator,
103            content: iter
104        }
105    }
106}
107
108const USIZE_BIT_SIZE: usize = mem::size_of::<usize>() * 8;
109
110impl<'a> Iterator for USizeSetIter<'a> {
111    type Item = usize;
112
113    fn next(&mut self) -> Option<usize> {
114        loop {
115            if let Some(bit_index) = self.current.next() {
116                return Some(self.offset + bit_index);
117            }
118
119            if let Some(&next_content) = self.content.next() {
120                self.current = BitIterator::new(next_content);
121                self.offset += USIZE_BIT_SIZE;
122            }
123            else {
124                return None;
125            }
126        }
127    }
128}
129
130impl USizeSet {
131
132    /// Creates a new, empty `USizeSet` with the given (inclusive) bounds.
133    ///
134    /// # Arguments
135    ///
136    /// * `min`: The minimum value that can be contained in the created set.
137    /// Any values lower than that will yield a `USizeSetError::OutOfBounds` if
138    /// inserted or removed. Must be less than or equal to `max`.
139    /// * `max`: The maximum value that can be contained in the created set.
140    /// Any values higher than that will yield a `USizeSetError::OutOfBounds`
141    /// if inserted or removed. Must be greater than or equal to `min`.
142    ///
143    /// # Errors
144    ///
145    /// If `min > max`. In that case, a `USizeSetError::InvalidBounds` is
146    /// returned.
147    pub fn new(min: usize, max: usize) -> USizeSetResult<USizeSet> {
148        if min > max {
149            Err(USizeSetError::InvalidBounds)
150        }
151        else {
152            let required_words = (max - min + 64) >> 6;
153
154            Ok(USizeSet {
155                min,
156                max,
157                len: 0,
158                content: vec![0u64; required_words]
159            })
160        }
161    }
162
163    /// Creates a new singleton `USizeSet` with the given (inclusive) bounds.
164    /// The set contains one element, which is specified by `content`.
165    ///
166    /// # Arguments
167    ///
168    /// * `min`: The minimum value that can be contained in the created set.
169    /// Any values lower than that will yield a `USizeSetError::OutOfBounds` if
170    /// inserted or removed. Must be less than or equal to `max`.
171    /// * `max`: The maximum value that can be contained in the created set.
172    /// Any values higher than that will yield a `USizeSetError::OutOfBounds`
173    /// if inserted or removed. Must be greater than or equal to `min`.
174    /// * `content`: The only element contained by the created set. Must be
175    /// within the bounds.
176    ///
177    /// # Errors
178    ///
179    /// * `USizeSetError::InvalidBounds`: If `min > max`.
180    /// * `USizeSetError::OutOfBounds`: If `content < min` or `content > max`.
181    pub fn singleton(min: usize, max: usize, content: usize)
182            -> USizeSetResult<USizeSet> {
183        let mut result = USizeSet::new(min, max)?;
184        result.insert(content)?;
185        Ok(result)
186    }
187
188    /// Creates a new `USizeSet` that includes all numbers in the given
189    /// (inclusive) bounds. Note that these bounds also apply later.
190    ///
191    /// # Arguments
192    ///
193    /// * `min`: The minimum value contained in the created set, which is also
194    /// the minimum that can be contained. Any values lower than this will
195    /// yield a `USizeSetError::OutOfBounds` if inserted or removed. Must be
196    /// less than or equal to `max`.
197    /// * `max`: The maximum value contained in the created set, which is also
198    /// the maximum value that can be contained. Any values higher than this
199    /// will yield a `USizeSetError::OutOfBounds` if inserted or removed. Must
200    /// be greater than or equal to `min`.
201    ///
202    /// # Errors
203    ///
204    /// If `min > max`. In that case, a `USizeSetError::InvalidBounds` is
205    /// returned.
206    pub fn range(min: usize, max: usize) -> USizeSetResult<USizeSet> {
207        if min > max {
208            Err(USizeSetError::InvalidBounds)
209        }
210        else {
211            let mut content = Vec::new();
212            let ones = max - min + 1;
213            let ones_words = ones >> 6;
214
215            for _ in 1..ones_words {
216                content.push(!0);
217            }
218
219            let remaining_ones = ones - (ones_words << 6);
220
221            if remaining_ones > 0 {
222                content.push((1 << remaining_ones) - 1);
223            }
224
225            Ok(USizeSet {
226                min,
227                max,
228                len: ones,
229                content
230            })
231        }
232    }
233
234    fn compute_index(&self, number: usize) -> USizeSetResult<(usize, u64)> {
235        if number < self.min || number > self.max {
236            Err(USizeSetError::OutOfBounds)
237        }
238        else {
239            let index = number - self.min;
240            let word_index = index >> 6;
241            let sub_word_index = index & 63;
242            let mask = 1u64 << sub_word_index;
243            Ok((word_index, mask))
244        }
245    }
246
247    /// Returns the minimum value that this set can contain (inclusive).
248    pub fn min(&self) -> usize {
249        self.min
250    }
251
252    /// Returns the maximum value that this set can contain (inclusive).
253    pub fn max(&self) -> usize {
254        self.max
255    }
256
257    /// Indicates whether this set contains the given number, in which case
258    /// this method returns `true`. If it is not contained or outside the
259    /// bounds, `false` will be returned.
260    pub fn contains(&self, number: usize) -> bool {
261        if let Ok((word_index, mask)) = self.compute_index(number) {
262            (self.content[word_index] & mask) > 0
263        }
264        else {
265            false
266        }
267    }
268
269    /// Inserts the given number into this set, such that [USizeSet::contains]
270    /// returns `true` for this number afterwards. Note that it must be within
271    /// the bounds provided at construction time.
272    ///
273    /// This method returns `true` if the set has changed (i.e. the number was
274    /// not present before) and `false` otherwise.
275    ///
276    /// # Errors
277    ///
278    /// If `number` is less than [USizeSet::min] or greater than
279    /// [USizeSet::max]. In that case, `USizeSetError::OutOfBounds` is
280    /// returned.
281    pub fn insert(&mut self, number: usize) -> USizeSetResult<bool> {
282        let (word_index, mask) = self.compute_index(number)?;
283        let word = &mut self.content[word_index];
284
285        if *word & mask == 0 {
286            self.len += 1;
287            *word |= mask;
288            Ok(true)
289        }
290        else {
291            Ok(false)
292        }
293    }
294
295    /// Removes the given number from this set, such that [USizeSet::contains]
296    /// returns `false` for this number afterwards. Note that it must be within
297    /// the bounds provided at construction time.
298    ///
299    /// This method returns `true` if the set has changed (i.e. the number was
300    /// present before) and `false` otherwise.
301    ///
302    /// # Errors
303    ///
304    /// If `number` is less than [USizeSet::min] or greater than
305    /// [USizeSet::max]. In that case, `USizeSetError::OutOfBounds` is
306    /// returned.
307    pub fn remove(&mut self, number: usize) -> USizeSetResult<bool> {
308        let (word_index, mask) = self.compute_index(number)?;
309        let word = &mut self.content[word_index];
310
311        if *word & mask > 0 {
312            *word &= !mask;
313            self.len -= 1;
314            Ok(true)
315        }
316        else {
317            Ok(false)
318        }
319    }
320
321    /// Removes all numbers from this set, such that [USizeSet::contains] will
322    /// return `false` for all inputs and [USizeSet::is_empty] will return
323    /// `true`.
324    pub fn clear(&mut self) {
325        for i in 0..self.content.len() {
326            self.content[i] = 0;
327        }
328
329        self.len = 0;
330    }
331
332    /// Returns an iterator over the numbers contained in this set in ascending
333    /// order.
334    pub fn iter(&self) -> USizeSetIter<'_> {
335        USizeSetIter::new(self)
336    }
337
338    /// Indicates whether this set is empty, i.e. contains no numbers. If this
339    /// method returns `true`, [USizeSet::contains] will return `false` for all
340    /// inputs.
341    pub fn is_empty(&self) -> bool {
342        self.len == 0
343    }
344
345    /// Returns the number of elements contained in this set.
346    pub fn len(&self) -> usize {
347        self.len
348    }
349
350    fn count(&self) -> usize {
351        self.content.iter()
352            .map(|c| c.count_ones() as usize)
353            .sum()
354    }
355
356    fn op_assign(&mut self, other: &USizeSet, op: impl Fn(u64, u64) -> u64)
357            -> USizeSetResult<bool> {
358        if self.min() != other.min() || self.max() != other.max() {
359            Err(USizeSetError::DifferentBounds)
360        }
361        else {
362            let contents = self.content.iter_mut().zip(other.content.iter());
363            let mut changed = false;
364
365            for (self_u64, &other_u64) in contents {
366                let self_before = *self_u64;
367                *self_u64 = op(self_before, other_u64);
368                changed |= self_before != *self_u64;
369            }
370
371            self.len = self.count();
372            Ok(changed)
373        }
374    }
375
376    fn op(&self, other: &USizeSet,
377            op_assign: impl Fn(&mut USizeSet, &USizeSet) -> USizeSetResult<bool>)
378            -> USizeSetResult<USizeSet> {
379        let mut clone = self.clone();
380        op_assign(&mut clone, other)?;
381        Ok(clone)
382    }
383
384    /// Computes the set union between this and the given set and stores the
385    /// result in this set. The bounds of this set and `other` must be equal.
386    ///
387    /// `USizeSet` implements [BitOrAssign] as syntactic sugar for this
388    /// operation. Note that that implementation panics instead of returning
389    /// potential errors.
390    ///
391    /// # Returns
392    ///
393    /// True, if and only if this set changed as a result of the operation.
394    ///
395    /// # Errors
396    ///
397    /// If either the minimum or maximum of this set and `other` are different.
398    /// In that case, `USizeError::DifferentBounds` is returned.
399    pub fn union_assign(&mut self, other: &USizeSet) -> USizeSetResult<bool> {
400        self.op_assign(other, u64::bitor)
401    }
402
403    /// Computes the set union between this and the given set and stores the
404    /// result in a new set which is returned. The bounds of this set and
405    /// `other` must be equal.
406    ///
407    /// `USizeSet` implements [BitOr] as syntactic sugar for this operation.
408    /// Note that that implementation  panics instead of returning potential
409    /// errors.
410    ///
411    /// # Errors
412    ///
413    /// If the minimum or maximum of this set and `other` are different. In
414    /// that case, `USizeError::DifferentBounds` is returned.
415    pub fn union(&self, other: &USizeSet) -> USizeSetResult<USizeSet> {
416        self.op(other, USizeSet::union_assign)
417    }
418
419    /// Computes the set intersection between this and the given set and stores
420    /// the result in this set. The bounds of this set and `other` must be
421    /// equal.
422    ///
423    /// `USizeSet` implements [BitAndAssign] as syntactic sugar for this
424    /// operation. Note that that implementation panics instead of returning
425    /// potential errors.
426    ///
427    /// # Returns
428    ///
429    /// True, if and only if this set changed as a result of the operation.
430    ///
431    /// # Errors
432    ///
433    /// If the minimum or maximum of this set and `other` are different. In
434    /// that case, `USizeError::DifferentBounds` is returned.
435    pub fn intersect_assign(&mut self, other: &USizeSet)
436            -> USizeSetResult<bool> {
437        self.op_assign(other, u64::bitand)
438    }
439
440    /// Computes the set intersection between this and the given set and stores
441    /// the result in a new set which is returned. The bounds of this set and
442    /// `other` must be equal.
443    ///
444    /// `USizeSet` implements [BitAnd] as syntactic sugar for this operation.
445    /// Note that that implementation panics instead of returning potential
446    /// errors.
447    ///
448    /// # Errors
449    ///
450    /// If the minimum or maximum of this set and `other` are different. In
451    /// that case, `USizeError::DifferentBounds` is returned.
452    pub fn intersect(&self, other: &USizeSet) -> USizeSetResult<USizeSet> {
453        self.op(other, USizeSet::intersect_assign)
454    }
455
456    /// Computes the set difference between this and the given set and stores
457    /// the result in this set. The bounds of this set and `other` must be
458    /// equal. `other` acts as the right-hand-side, meaning its elements are
459    /// removed from the result.
460    ///
461    /// `USizeSet` implements [SubAssign] as syntactic sugar for this
462    /// operation. Note that that implementation panics instead of returning
463    /// potential errors.
464    ///
465    /// # Returns
466    ///
467    /// True, if and only if this set changed as a result of the operation.
468    ///
469    /// # Errors
470    ///
471    /// If the minimum or maximum of this set and `other` are different. In
472    /// that case, `USizeError::DifferentBounds` is returned.
473    pub fn difference_assign(&mut self, other: &USizeSet)
474            -> USizeSetResult<bool> {
475        self.op_assign(other, |a, b| a & !b)
476    }
477
478    /// Computes the set difference between this and the given set and stores
479    /// the result in a new set which is returned. The bounds of this set and
480    /// `other` must be equal.
481    ///
482    /// `USizeSet` implements [Sub] as syntactic sugar for this operation. Note
483    /// that that implementation panics instead of returning potential errors.
484    ///
485    /// # Errors
486    ///
487    /// If the minimum or maximum of this set and `other` are different. In
488    /// that case, `USizeError::DifferentBounds` is returned.
489    pub fn difference(&self, other: &USizeSet) -> USizeSetResult<USizeSet> {
490        self.op(other, USizeSet::difference_assign)
491    }
492
493    /// Computes the symmetric set difference between this and the given set
494    /// and stores the result in this set. The bounds of this set and `other`
495    /// must be equal.
496    ///
497    /// `USizeSet` implements [BitXorAssign] as syntactic sugar for this
498    /// operation. Note that that implementation panics instead of returning
499    /// potential errors.
500    ///
501    /// # Returns
502    ///
503    /// True, if and only if this set changed as a result of the operation.
504    ///
505    /// # Errors
506    ///
507    /// If the minimum or maximum of this set and `other` are different. In
508    /// that case, `USizeError::DifferentBounds` is returned.
509    pub fn symmetric_difference_assign(&mut self, other: &USizeSet)
510            -> USizeSetResult<bool> {
511        self.op_assign(other, u64::bitxor)
512    }
513
514    /// Computes the symmetric set difference between this and the given set
515    /// and stores the result in a new set which is returned. The bounds of
516    /// this set and `other` must be equal.
517    ///
518    /// `USizeSet` implements [BitXor] as syntactic sugar for this operation.
519    /// Note that that implementation panics instead of returning potential
520    /// errors.
521    ///
522    /// # Errors
523    ///
524    /// If the minimum or maximum of this set and `other` are different. In
525    /// that case, `USizeError::DifferentBounds` is returned.
526    pub fn symmetric_difference(&self, other: &USizeSet)
527            -> USizeSetResult<USizeSet> {
528        self.op(other, USizeSet::symmetric_difference_assign)
529    }
530}
531
532/// Creates a new [USizeSet] that contains the specified elements. First, the
533/// minimum and maximum values must be specified. Then, after a semicolon, a
534/// comma-separated list of the contained values must be provided. For empty
535/// sets, [USizeSet.new()] can be used.
536///
537/// An example usage of this macro looks as follows:
538///
539/// ```
540/// use sudoku_variants::set;
541/// use sudoku_variants::util::USizeSet;
542///
543/// let set = set!(1, 5; 2, 4);
544/// assert_eq!(1, set.min());
545/// assert_eq!(5, set.max());
546/// assert!(set.contains(2));
547/// assert!(!set.contains(3));
548/// ```
549#[macro_export]
550macro_rules! set {
551    ($set:expr; $e:expr) => {
552        ($set).insert($e).unwrap()
553    };
554
555    ($set:expr; $e:expr, $($es:expr),+) => {
556        set!($set; $e);
557        set!($set; $($es),+)
558    };
559
560    ($min:expr, $max:expr; $($es:expr),+) => {
561        {
562            let mut set = USizeSet::new($min, $max).unwrap();
563            set!(set; $($es),+);
564            set
565        }
566    };
567}
568
569impl BitAnd<&USizeSet> for USizeSet {
570    type Output = USizeSet;
571
572    fn bitand(mut self, rhs: &USizeSet) -> USizeSet {
573        self.intersect_assign(rhs).unwrap();
574        self
575    }
576}
577
578impl BitOr<&USizeSet> for USizeSet {
579    type Output = USizeSet;
580
581    fn bitor(mut self, rhs: &USizeSet) -> USizeSet {
582        self.union_assign(rhs).unwrap();
583        self
584    }
585}
586
587impl Sub<&USizeSet> for USizeSet {
588    type Output = USizeSet;
589
590    fn sub(mut self, rhs: &USizeSet) -> USizeSet {
591        self.difference_assign(rhs).unwrap();
592        self
593    }
594}
595
596impl BitXor<&USizeSet> for USizeSet {
597    type Output = USizeSet;
598
599    fn bitxor(mut self, rhs: &USizeSet) -> USizeSet {
600        self.symmetric_difference_assign(rhs).unwrap();
601        self
602    }
603}
604
605impl BitAnd for &USizeSet {
606    type Output = USizeSet;
607
608    fn bitand(self, rhs: &USizeSet) -> USizeSet {
609        self.intersect(rhs).unwrap()
610    }
611}
612
613impl BitOr for &USizeSet {
614    type Output = USizeSet;
615
616    fn bitor(self, rhs: &USizeSet) -> USizeSet {
617        self.union(rhs).unwrap()
618    }
619}
620
621impl Sub for &USizeSet {
622    type Output = USizeSet;
623
624    fn sub(self, rhs: &USizeSet) -> USizeSet {
625        self.difference(rhs).unwrap()
626    }
627}
628
629impl BitXor for &USizeSet {
630    type Output = USizeSet;
631
632    fn bitxor(self, rhs: &USizeSet) -> USizeSet {
633        self.symmetric_difference(rhs).unwrap()
634    }
635}
636
637impl BitAndAssign<&USizeSet> for USizeSet {
638    fn bitand_assign(&mut self, rhs: &USizeSet) {
639        self.intersect_assign(rhs).unwrap();
640    }
641}
642
643impl BitOrAssign<&USizeSet> for USizeSet {
644    fn bitor_assign(&mut self, rhs: &USizeSet) {
645        self.union_assign(rhs).unwrap();
646    }
647}
648
649impl SubAssign<&USizeSet> for USizeSet {
650    fn sub_assign(&mut self, rhs: &USizeSet) {
651        self.difference_assign(rhs).unwrap();
652    }
653}
654
655impl BitXorAssign<&USizeSet> for USizeSet {
656    fn bitxor_assign(&mut self, rhs: &USizeSet) {
657        self.symmetric_difference_assign(rhs).unwrap();
658    }
659}
660
661impl BitAndAssign<&USizeSet> for &mut USizeSet {
662    fn bitand_assign(&mut self, rhs: &USizeSet) {
663        self.intersect_assign(rhs).unwrap();
664    }
665}
666
667impl BitOrAssign<&USizeSet> for &mut USizeSet {
668    fn bitor_assign(&mut self, rhs: &USizeSet) {
669        self.union_assign(rhs).unwrap();
670    }
671}
672
673impl SubAssign<&USizeSet> for &mut USizeSet {
674    fn sub_assign(&mut self, rhs: &USizeSet) {
675        self.difference_assign(rhs).unwrap();
676    }
677}
678
679impl BitXorAssign<&USizeSet> for &mut USizeSet {
680    fn bitxor_assign(&mut self, rhs: &USizeSet) {
681        self.symmetric_difference_assign(rhs).unwrap();
682    }
683}
684
685#[cfg(test)]
686mod tests {
687
688    use super::*;
689
690    #[test]
691    fn new_set_is_empty() {
692        let set = USizeSet::new(1, 9).unwrap();
693        assert!(set.is_empty());
694        assert!(!set.contains(1));
695        assert!(!set.contains(3));
696        assert!(!set.contains(9));
697        assert_eq!(0, set.len());
698    }
699
700    #[test]
701    fn range_set_is_full() {
702        let set = USizeSet::range(1, 9).unwrap();
703        assert!(!set.is_empty());
704        assert!(set.contains(1));
705        assert!(set.contains(3));
706        assert!(set.contains(9));
707        assert_eq!(9, set.len());
708    }
709
710    #[test]
711    fn singleton_set_contains_only_given_element() {
712        let set = USizeSet::singleton(1, 9, 3).unwrap();
713        assert!(!set.is_empty());
714        assert!(!set.contains(1));
715        assert!(set.contains(3));
716        assert!(!set.contains(9));
717        assert_eq!(1, set.len());
718    }
719
720    #[test]
721    fn set_macro_has_specified_range() {
722        let set = set!(2, 5; 3);
723        assert_eq!(2, set.min());
724        assert_eq!(5, set.max());
725    }
726
727    #[test]
728    fn set_macro_contains_specified_elements() {
729        let set = set!(2, 8; 3, 7, 8);
730        assert_eq!(3, set.len());
731        assert!(set.contains(3));
732        assert!(set.contains(7));
733        assert!(set.contains(8));
734        assert!(!set.contains(5));
735    }
736
737    #[test]
738    fn set_creation_error() {
739        assert_eq!(Err(USizeSetError::InvalidBounds), USizeSet::new(1, 0));
740        assert_eq!(Err(USizeSetError::InvalidBounds), USizeSet::new(5, 3));
741    }
742
743    #[test]
744    fn set_insertion_error() {
745        let mut set = USizeSet::new(1, 5).unwrap();
746        assert_eq!(Err(USizeSetError::OutOfBounds), set.insert(0));
747        assert_eq!(Err(USizeSetError::OutOfBounds), set.insert(6));
748    }
749
750    #[test]
751    fn set_operation_error() {
752        let set_1 = USizeSet::new(1, 9).unwrap();
753        let set_2 = USizeSet::new(1, 6).unwrap();
754        assert_eq!(Err(USizeSetError::DifferentBounds), set_1.union(&set_2));
755        assert_eq!(Err(USizeSetError::DifferentBounds),
756            set_2.intersect(&set_1));
757    }
758
759    #[test]
760    fn manipulation() {
761        let mut set = USizeSet::new(1, 9).unwrap();
762        set.insert(2).unwrap();
763        set.insert(4).unwrap();
764        set.insert(6).unwrap();
765
766        assert!(!set.is_empty());
767        assert!(set.contains(2));
768        assert!(set.contains(4));
769        assert!(set.contains(6));
770        assert_eq!(3, set.len());
771
772        set.remove(4).unwrap();
773
774        assert!(!set.is_empty());
775        assert!(set.contains(2));
776        assert!(!set.contains(4));
777        assert!(set.contains(6));
778        assert_eq!(2, set.len());
779
780        set.clear();
781
782        assert!(set.is_empty());
783        assert!(!set.contains(2));
784        assert!(!set.contains(4));
785        assert!(!set.contains(6));
786        assert_eq!(0, set.len());
787    }
788
789    #[test]
790    fn iteration() {
791        let mut set = USizeSet::new(1, 100).unwrap();
792        set.insert(1).unwrap();
793        set.insert(12).unwrap();
794        set.insert(23).unwrap();
795        set.insert(36).unwrap();
796        set.insert(42).unwrap();
797        set.insert(64).unwrap();
798        set.insert(65).unwrap();
799        set.insert(97).unwrap();
800        set.insert(100).unwrap();
801
802        let mut iter = set.iter();
803
804        assert_eq!(Some(1), iter.next());
805        assert_eq!(Some(12), iter.next());
806        assert_eq!(Some(23), iter.next());
807        assert_eq!(Some(36), iter.next());
808        assert_eq!(Some(42), iter.next());
809        assert_eq!(Some(64), iter.next());
810        assert_eq!(Some(65), iter.next());
811        assert_eq!(Some(97), iter.next());
812        assert_eq!(Some(100), iter.next());
813        assert_eq!(None, iter.next());
814    }
815
816    #[test]
817    fn double_insert() {
818        let mut set = USizeSet::new(1, 9).unwrap();
819        assert!(set.insert(3).unwrap());
820        assert!(set.insert(4).unwrap());
821        assert!(!set.insert(3).unwrap());
822
823        assert!(set.contains(3));
824        assert_eq!(2, set.len());
825    }
826
827    #[test]
828    fn double_remove() {
829        let mut set = USizeSet::range(1, 9).unwrap();
830        assert!(set.remove(3).unwrap());
831        assert!(set.remove(5).unwrap());
832        assert!(!set.remove(3).unwrap());
833
834        assert!(!set.contains(3));
835        assert_eq!(7, set.len());
836    }
837
838    fn op_test_lhs() -> USizeSet {
839        set!(1, 4; 2, 4)
840    }
841
842    fn op_test_rhs() -> USizeSet {
843        set!(1, 4; 3, 4)
844    }
845
846    #[test]
847    fn union() {
848        let result = op_test_lhs() | &op_test_rhs();
849        let expected = set!(1, 4; 2, 3, 4);
850        assert_eq!(expected, result);
851    }
852
853    #[test]
854    fn intersection() {
855        let result = op_test_lhs() & &op_test_rhs();
856        let expected = set!(1, 4; 4);
857        assert_eq!(expected, result);
858    }
859
860    #[test]
861    fn difference() {
862        let result = op_test_lhs() - &op_test_rhs();
863        let expected = set!(1, 4; 2);
864        assert_eq!(expected, result);
865    }
866
867    #[test]
868    fn symmetric_difference() {
869        let result = op_test_lhs() ^ &op_test_rhs();
870        let expected = set!(1, 4; 2, 3);
871        assert_eq!(expected, result);
872    }
873}