1
use std::cmp::Ordering;
2
use std::fmt;
3
use std::marker::PhantomData;
4
use std::slice::Iter;
5

            
6
use itertools::Itertools;
7

            
8
use crate::vec_difference::Difference;
9

            
10
#[macro_export]
11
macro_rules! vecbag {
12
    () => {
13
        $crate::VecBag::new()
14
    };
15
    ($elem:expr; $n:expr) => {
16
        $crate::VecBag::from_vec(vec![$elem; $n])
17
    };
18
    ($($x:expr),+ $(,)?) => {{
19
        let mut __bag = $crate::VecBag::new();
20
        $( __bag.insert($x); )*
21
        __bag
22
    }};
23
}
24

            
25
///
26
/// A bag (multiset) that is internally represented by a sorted vector.
27
/// Mostly useful for a compact representation of bags that are not changed often.
28
///
29
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
30
pub struct VecBag<T: Ord> {
31
    /// The internal storage with the invariant that the array is sorted.
32
    sorted_array: Vec<T>,
33
}
34

            
35
impl<T: Ord> VecBag<T> {
36
    /// Creates a new, empty VecBag.
37
5311
    pub fn new() -> Self {
38
5311
        Self {
39
5311
            sorted_array: Vec::new(),
40
5311
        }
41
5311
    }
42

            
43
    /// Creates a VecBag from the given vector without assuming anything of the given vector.
44
206
    pub fn from_vec(mut vec: Vec<T>) -> Self {
45
206
        vec.sort_unstable();
46
206
        Self { sorted_array: vec }
47
206
    }
48

            
49
    /// Returns the capacity of the bag.
50
    pub fn capacity(&self) -> usize {
51
        self.sorted_array.capacity()
52
    }
53

            
54
    /// Returns true iff the bag contains at least one occurrence of the given element.
55
    pub fn contains(&self, element: &T) -> bool {
56
        self.sorted_array.binary_search(element).is_ok()
57
    }
58

            
59
    /// Clears the bag, removing all elements.
60
    pub fn clear(&mut self) {
61
        self.sorted_array.clear();
62
    }
63

            
64
    /// Retains only the elements specified by the predicate.
65
    pub fn retain<F>(&mut self, mut f: F)
66
    where
67
        F: FnMut(&T) -> bool,
68
    {
69
        // Removing elements does not change the order.
70
        self.sorted_array.retain(|e| f(e));
71
    }
72

            
73
    /// Returns true iff this bag is a subbag of the other bag.
74
    pub fn is_subset(&self, other: &VecBag<T>) -> bool {
75
        let mut self_iter = self.sorted_array.iter();
76
        let mut other_iter = other.sorted_array.iter();
77

            
78
        // Traverse both bags in order, checking multiplicity as well.
79
        let mut self_next = self_iter.next();
80
        let mut other_next = other_iter.next();
81

            
82
        while let Some(self_val) = self_next {
83
            match other_next {
84
                Some(other_val) => match self_val.cmp(other_val) {
85
                    Ordering::Equal => {
86
                        self_next = self_iter.next();
87
                        other_next = other_iter.next();
88
                    }
89
                    Ordering::Greater => other_next = other_iter.next(),
90
                    Ordering::Less => return false,
91
                },
92
                None => return false,
93
            }
94
        }
95

            
96
        true
97
    }
98

            
99
    /// Returns a new bag only containing the given element.
100
2200
    pub fn singleton(element: T) -> Self {
101
2200
        Self {
102
2200
            sorted_array: vec![element],
103
2200
        }
104
2200
    }
105

            
106
    /// Returns true iff the bag is empty.
107
33675
    pub fn is_empty(&self) -> bool {
108
33675
        self.sorted_array.is_empty()
109
33675
    }
110

            
111
    /// Returns the difference of this bag and the other bag.
112
100
    pub fn difference<'a>(&'a self, other: &'a VecBag<T>) -> impl Iterator<Item = &'a T> {
113
100
        Difference::<'a, T, _> {
114
100
            self_iter: self.sorted_array.iter(),
115
100
            other_iter: other.sorted_array.iter(),
116
100
            other_next: None,
117
100
            marker: PhantomData,
118
100
        }
119
100
    }
120

            
121
    /// Inserts one occurrence of the given element into the bag.
122
4895
    pub fn insert(&mut self, element: T) {
123
        // Finds the location where to insert the element to keep the array sorted.
124
4895
        let position = match self.sorted_array.binary_search(&element) {
125
4895
            Ok(position) | Err(position) => position,
126
        };
127

            
128
4895
        self.sorted_array.insert(position, element);
129
4895
    }
130

            
131
    /// Extends this bag with the elements from the given iterator.
132
    pub fn extend<'a, I: IntoIterator<Item = &'a T>>(&mut self, iter: I)
133
    where
134
        T: Clone + 'a,
135
    {
136
        for element in iter {
137
            self.insert(element.clone());
138
        }
139
    }
140

            
141
    /// Returns an iterator over the elements in the bag, they are yielded in sorted order.
142
33392
    pub fn iter(&self) -> impl Iterator<Item = &T> {
143
33392
        self.sorted_array.iter()
144
33392
    }
145

            
146
    /// Returns the number of elements in the bag.
147
5
    pub fn len(&self) -> usize {
148
5
        self.sorted_array.len()
149
5
    }
150

            
151
    /// Consumes the bag and returns a vector with the elements in sorted order.
152
    pub fn to_vec(self) -> Vec<T> {
153
        self.sorted_array
154
    }
155
}
156

            
157
impl<T: Ord> FromIterator<T> for VecBag<T> {
158
    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
159
        Self::from_vec(iter.into_iter().collect())
160
    }
161
}
162

            
163
impl<T: Ord> Default for VecBag<T> {
164
    fn default() -> Self {
165
        Self::new()
166
    }
167
}
168

            
169
impl<'a, T: Ord> IntoIterator for &'a VecBag<T> {
170
    type Item = &'a T;
171
    type IntoIter = Iter<'a, T>;
172

            
173
    fn into_iter(self) -> Self::IntoIter {
174
        self.sorted_array.iter()
175
    }
176
}
177

            
178
impl<T: Ord + fmt::Debug> fmt::Debug for VecBag<T> {
179
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
180
        write!(f, "{{{:?}}}", self.sorted_array.iter().format(", "))
181
    }
182
}
183

            
184
#[cfg(test)]
185
mod tests {
186
    use rand::RngExt;
187

            
188
    use merc_utilities::random_test;
189

            
190
    use crate::VecBag;
191

            
192
    #[test]
193
1
    fn test_random_vecbag_difference() {
194
100
        random_test(100, |rng| {
195
100
            let size = rng.random_range(0..20);
196
100
            let size2 = rng.random_range(0..20);
197
947
            let vec1: Vec<u32> = (0..size).map(|_| rng.random_range(0..10)).collect();
198
939
            let vec2: Vec<u32> = (0..size2).map(|_| rng.random_range(0..10)).collect();
199

            
200
100
            let bag1 = VecBag::from_vec(vec1.clone());
201
100
            let bag2 = VecBag::from_vec(vec2.clone());
202

            
203
100
            let difference: Vec<u32> = bag1.difference(&bag2).cloned().collect();
204

            
205
100
            let mut expected_difference = vec1;
206
100
            expected_difference.sort_unstable();
207

            
208
100
            let mut sorted_vec2 = vec2;
209
100
            sorted_vec2.sort_unstable();
210

            
211
939
            for value in sorted_vec2 {
212
939
                if let Ok(index) = expected_difference.binary_search(&value) {
213
390
                    expected_difference.remove(index);
214
549
                }
215
            }
216

            
217
100
            assert_eq!(difference, expected_difference);
218
100
        })
219
1
    }
220
}