1c67d6573Sopenharmony_ciuse std::char;
2c67d6573Sopenharmony_ciuse std::cmp;
3c67d6573Sopenharmony_ciuse std::fmt::Debug;
4c67d6573Sopenharmony_ciuse std::slice;
5c67d6573Sopenharmony_ciuse std::u8;
6c67d6573Sopenharmony_ci
7c67d6573Sopenharmony_ciuse crate::unicode;
8c67d6573Sopenharmony_ci
9c67d6573Sopenharmony_ci// This module contains an *internal* implementation of interval sets.
10c67d6573Sopenharmony_ci//
11c67d6573Sopenharmony_ci// The primary invariant that interval sets guards is canonical ordering. That
12c67d6573Sopenharmony_ci// is, every interval set contains an ordered sequence of intervals where
13c67d6573Sopenharmony_ci// no two intervals are overlapping or adjacent. While this invariant is
14c67d6573Sopenharmony_ci// occasionally broken within the implementation, it should be impossible for
15c67d6573Sopenharmony_ci// callers to observe it.
16c67d6573Sopenharmony_ci//
17c67d6573Sopenharmony_ci// Since case folding (as implemented below) breaks that invariant, we roll
18c67d6573Sopenharmony_ci// that into this API even though it is a little out of place in an otherwise
19c67d6573Sopenharmony_ci// generic interval set. (Hence the reason why the `unicode` module is imported
20c67d6573Sopenharmony_ci// here.)
21c67d6573Sopenharmony_ci//
22c67d6573Sopenharmony_ci// Some of the implementation complexity here is a result of me wanting to
23c67d6573Sopenharmony_ci// preserve the sequential representation without using additional memory.
24c67d6573Sopenharmony_ci// In many cases, we do use linear extra memory, but it is at most 2x and it
25c67d6573Sopenharmony_ci// is amortized. If we relaxed the memory requirements, this implementation
26c67d6573Sopenharmony_ci// could become much simpler. The extra memory is honestly probably OK, but
27c67d6573Sopenharmony_ci// character classes (especially of the Unicode variety) can become quite
28c67d6573Sopenharmony_ci// large, and it would be nice to keep regex compilation snappy even in debug
29c67d6573Sopenharmony_ci// builds. (In the past, I have been careless with this area of code and it has
30c67d6573Sopenharmony_ci// caused slow regex compilations in debug mode, so this isn't entirely
31c67d6573Sopenharmony_ci// unwarranted.)
32c67d6573Sopenharmony_ci//
33c67d6573Sopenharmony_ci// Tests on this are relegated to the public API of HIR in src/hir.rs.
34c67d6573Sopenharmony_ci
35c67d6573Sopenharmony_ci#[derive(Clone, Debug, Eq, PartialEq)]
36c67d6573Sopenharmony_cipub struct IntervalSet<I> {
37c67d6573Sopenharmony_ci    ranges: Vec<I>,
38c67d6573Sopenharmony_ci}
39c67d6573Sopenharmony_ci
40c67d6573Sopenharmony_ciimpl<I: Interval> IntervalSet<I> {
41c67d6573Sopenharmony_ci    /// Create a new set from a sequence of intervals. Each interval is
42c67d6573Sopenharmony_ci    /// specified as a pair of bounds, where both bounds are inclusive.
43c67d6573Sopenharmony_ci    ///
44c67d6573Sopenharmony_ci    /// The given ranges do not need to be in any specific order, and ranges
45c67d6573Sopenharmony_ci    /// may overlap.
46c67d6573Sopenharmony_ci    pub fn new<T: IntoIterator<Item = I>>(intervals: T) -> IntervalSet<I> {
47c67d6573Sopenharmony_ci        let mut set = IntervalSet { ranges: intervals.into_iter().collect() };
48c67d6573Sopenharmony_ci        set.canonicalize();
49c67d6573Sopenharmony_ci        set
50c67d6573Sopenharmony_ci    }
51c67d6573Sopenharmony_ci
52c67d6573Sopenharmony_ci    /// Add a new interval to this set.
53c67d6573Sopenharmony_ci    pub fn push(&mut self, interval: I) {
54c67d6573Sopenharmony_ci        // TODO: This could be faster. e.g., Push the interval such that
55c67d6573Sopenharmony_ci        // it preserves canonicalization.
56c67d6573Sopenharmony_ci        self.ranges.push(interval);
57c67d6573Sopenharmony_ci        self.canonicalize();
58c67d6573Sopenharmony_ci    }
59c67d6573Sopenharmony_ci
60c67d6573Sopenharmony_ci    /// Return an iterator over all intervals in this set.
61c67d6573Sopenharmony_ci    ///
62c67d6573Sopenharmony_ci    /// The iterator yields intervals in ascending order.
63c67d6573Sopenharmony_ci    pub fn iter(&self) -> IntervalSetIter<'_, I> {
64c67d6573Sopenharmony_ci        IntervalSetIter(self.ranges.iter())
65c67d6573Sopenharmony_ci    }
66c67d6573Sopenharmony_ci
67c67d6573Sopenharmony_ci    /// Return an immutable slice of intervals in this set.
68c67d6573Sopenharmony_ci    ///
69c67d6573Sopenharmony_ci    /// The sequence returned is in canonical ordering.
70c67d6573Sopenharmony_ci    pub fn intervals(&self) -> &[I] {
71c67d6573Sopenharmony_ci        &self.ranges
72c67d6573Sopenharmony_ci    }
73c67d6573Sopenharmony_ci
74c67d6573Sopenharmony_ci    /// Expand this interval set such that it contains all case folded
75c67d6573Sopenharmony_ci    /// characters. For example, if this class consists of the range `a-z`,
76c67d6573Sopenharmony_ci    /// then applying case folding will result in the class containing both the
77c67d6573Sopenharmony_ci    /// ranges `a-z` and `A-Z`.
78c67d6573Sopenharmony_ci    ///
79c67d6573Sopenharmony_ci    /// This returns an error if the necessary case mapping data is not
80c67d6573Sopenharmony_ci    /// available.
81c67d6573Sopenharmony_ci    pub fn case_fold_simple(&mut self) -> Result<(), unicode::CaseFoldError> {
82c67d6573Sopenharmony_ci        let len = self.ranges.len();
83c67d6573Sopenharmony_ci        for i in 0..len {
84c67d6573Sopenharmony_ci            let range = self.ranges[i];
85c67d6573Sopenharmony_ci            if let Err(err) = range.case_fold_simple(&mut self.ranges) {
86c67d6573Sopenharmony_ci                self.canonicalize();
87c67d6573Sopenharmony_ci                return Err(err);
88c67d6573Sopenharmony_ci            }
89c67d6573Sopenharmony_ci        }
90c67d6573Sopenharmony_ci        self.canonicalize();
91c67d6573Sopenharmony_ci        Ok(())
92c67d6573Sopenharmony_ci    }
93c67d6573Sopenharmony_ci
94c67d6573Sopenharmony_ci    /// Union this set with the given set, in place.
95c67d6573Sopenharmony_ci    pub fn union(&mut self, other: &IntervalSet<I>) {
96c67d6573Sopenharmony_ci        // This could almost certainly be done more efficiently.
97c67d6573Sopenharmony_ci        self.ranges.extend(&other.ranges);
98c67d6573Sopenharmony_ci        self.canonicalize();
99c67d6573Sopenharmony_ci    }
100c67d6573Sopenharmony_ci
101c67d6573Sopenharmony_ci    /// Intersect this set with the given set, in place.
102c67d6573Sopenharmony_ci    pub fn intersect(&mut self, other: &IntervalSet<I>) {
103c67d6573Sopenharmony_ci        if self.ranges.is_empty() {
104c67d6573Sopenharmony_ci            return;
105c67d6573Sopenharmony_ci        }
106c67d6573Sopenharmony_ci        if other.ranges.is_empty() {
107c67d6573Sopenharmony_ci            self.ranges.clear();
108c67d6573Sopenharmony_ci            return;
109c67d6573Sopenharmony_ci        }
110c67d6573Sopenharmony_ci
111c67d6573Sopenharmony_ci        // There should be a way to do this in-place with constant memory,
112c67d6573Sopenharmony_ci        // but I couldn't figure out a simple way to do it. So just append
113c67d6573Sopenharmony_ci        // the intersection to the end of this range, and then drain it before
114c67d6573Sopenharmony_ci        // we're done.
115c67d6573Sopenharmony_ci        let drain_end = self.ranges.len();
116c67d6573Sopenharmony_ci
117c67d6573Sopenharmony_ci        let mut ita = 0..drain_end;
118c67d6573Sopenharmony_ci        let mut itb = 0..other.ranges.len();
119c67d6573Sopenharmony_ci        let mut a = ita.next().unwrap();
120c67d6573Sopenharmony_ci        let mut b = itb.next().unwrap();
121c67d6573Sopenharmony_ci        loop {
122c67d6573Sopenharmony_ci            if let Some(ab) = self.ranges[a].intersect(&other.ranges[b]) {
123c67d6573Sopenharmony_ci                self.ranges.push(ab);
124c67d6573Sopenharmony_ci            }
125c67d6573Sopenharmony_ci            let (it, aorb) =
126c67d6573Sopenharmony_ci                if self.ranges[a].upper() < other.ranges[b].upper() {
127c67d6573Sopenharmony_ci                    (&mut ita, &mut a)
128c67d6573Sopenharmony_ci                } else {
129c67d6573Sopenharmony_ci                    (&mut itb, &mut b)
130c67d6573Sopenharmony_ci                };
131c67d6573Sopenharmony_ci            match it.next() {
132c67d6573Sopenharmony_ci                Some(v) => *aorb = v,
133c67d6573Sopenharmony_ci                None => break,
134c67d6573Sopenharmony_ci            }
135c67d6573Sopenharmony_ci        }
136c67d6573Sopenharmony_ci        self.ranges.drain(..drain_end);
137c67d6573Sopenharmony_ci    }
138c67d6573Sopenharmony_ci
139c67d6573Sopenharmony_ci    /// Subtract the given set from this set, in place.
140c67d6573Sopenharmony_ci    pub fn difference(&mut self, other: &IntervalSet<I>) {
141c67d6573Sopenharmony_ci        if self.ranges.is_empty() || other.ranges.is_empty() {
142c67d6573Sopenharmony_ci            return;
143c67d6573Sopenharmony_ci        }
144c67d6573Sopenharmony_ci
145c67d6573Sopenharmony_ci        // This algorithm is (to me) surprisingly complex. A search of the
146c67d6573Sopenharmony_ci        // interwebs indicate that this is a potentially interesting problem.
147c67d6573Sopenharmony_ci        // Folks seem to suggest interval or segment trees, but I'd like to
148c67d6573Sopenharmony_ci        // avoid the overhead (both runtime and conceptual) of that.
149c67d6573Sopenharmony_ci        //
150c67d6573Sopenharmony_ci        // The following is basically my Shitty First Draft. Therefore, in
151c67d6573Sopenharmony_ci        // order to grok it, you probably need to read each line carefully.
152c67d6573Sopenharmony_ci        // Simplifications are most welcome!
153c67d6573Sopenharmony_ci        //
154c67d6573Sopenharmony_ci        // Remember, we can assume the canonical format invariant here, which
155c67d6573Sopenharmony_ci        // says that all ranges are sorted, not overlapping and not adjacent in
156c67d6573Sopenharmony_ci        // each class.
157c67d6573Sopenharmony_ci        let drain_end = self.ranges.len();
158c67d6573Sopenharmony_ci        let (mut a, mut b) = (0, 0);
159c67d6573Sopenharmony_ci        'LOOP: while a < drain_end && b < other.ranges.len() {
160c67d6573Sopenharmony_ci            // Basically, the easy cases are when neither range overlaps with
161c67d6573Sopenharmony_ci            // each other. If the `b` range is less than our current `a`
162c67d6573Sopenharmony_ci            // range, then we can skip it and move on.
163c67d6573Sopenharmony_ci            if other.ranges[b].upper() < self.ranges[a].lower() {
164c67d6573Sopenharmony_ci                b += 1;
165c67d6573Sopenharmony_ci                continue;
166c67d6573Sopenharmony_ci            }
167c67d6573Sopenharmony_ci            // ... similarly for the `a` range. If it's less than the smallest
168c67d6573Sopenharmony_ci            // `b` range, then we can add it as-is.
169c67d6573Sopenharmony_ci            if self.ranges[a].upper() < other.ranges[b].lower() {
170c67d6573Sopenharmony_ci                let range = self.ranges[a];
171c67d6573Sopenharmony_ci                self.ranges.push(range);
172c67d6573Sopenharmony_ci                a += 1;
173c67d6573Sopenharmony_ci                continue;
174c67d6573Sopenharmony_ci            }
175c67d6573Sopenharmony_ci            // Otherwise, we have overlapping ranges.
176c67d6573Sopenharmony_ci            assert!(!self.ranges[a].is_intersection_empty(&other.ranges[b]));
177c67d6573Sopenharmony_ci
178c67d6573Sopenharmony_ci            // This part is tricky and was non-obvious to me without looking
179c67d6573Sopenharmony_ci            // at explicit examples (see the tests). The trickiness stems from
180c67d6573Sopenharmony_ci            // two things: 1) subtracting a range from another range could
181c67d6573Sopenharmony_ci            // yield two ranges and 2) after subtracting a range, it's possible
182c67d6573Sopenharmony_ci            // that future ranges can have an impact. The loop below advances
183c67d6573Sopenharmony_ci            // the `b` ranges until they can't possible impact the current
184c67d6573Sopenharmony_ci            // range.
185c67d6573Sopenharmony_ci            //
186c67d6573Sopenharmony_ci            // For example, if our `a` range is `a-t` and our next three `b`
187c67d6573Sopenharmony_ci            // ranges are `a-c`, `g-i`, `r-t` and `x-z`, then we need to apply
188c67d6573Sopenharmony_ci            // subtraction three times before moving on to the next `a` range.
189c67d6573Sopenharmony_ci            let mut range = self.ranges[a];
190c67d6573Sopenharmony_ci            while b < other.ranges.len()
191c67d6573Sopenharmony_ci                && !range.is_intersection_empty(&other.ranges[b])
192c67d6573Sopenharmony_ci            {
193c67d6573Sopenharmony_ci                let old_range = range;
194c67d6573Sopenharmony_ci                range = match range.difference(&other.ranges[b]) {
195c67d6573Sopenharmony_ci                    (None, None) => {
196c67d6573Sopenharmony_ci                        // We lost the entire range, so move on to the next
197c67d6573Sopenharmony_ci                        // without adding this one.
198c67d6573Sopenharmony_ci                        a += 1;
199c67d6573Sopenharmony_ci                        continue 'LOOP;
200c67d6573Sopenharmony_ci                    }
201c67d6573Sopenharmony_ci                    (Some(range1), None) | (None, Some(range1)) => range1,
202c67d6573Sopenharmony_ci                    (Some(range1), Some(range2)) => {
203c67d6573Sopenharmony_ci                        self.ranges.push(range1);
204c67d6573Sopenharmony_ci                        range2
205c67d6573Sopenharmony_ci                    }
206c67d6573Sopenharmony_ci                };
207c67d6573Sopenharmony_ci                // It's possible that the `b` range has more to contribute
208c67d6573Sopenharmony_ci                // here. In particular, if it is greater than the original
209c67d6573Sopenharmony_ci                // range, then it might impact the next `a` range *and* it
210c67d6573Sopenharmony_ci                // has impacted the current `a` range as much as possible,
211c67d6573Sopenharmony_ci                // so we can quit. We don't bump `b` so that the next `a`
212c67d6573Sopenharmony_ci                // range can apply it.
213c67d6573Sopenharmony_ci                if other.ranges[b].upper() > old_range.upper() {
214c67d6573Sopenharmony_ci                    break;
215c67d6573Sopenharmony_ci                }
216c67d6573Sopenharmony_ci                // Otherwise, the next `b` range might apply to the current
217c67d6573Sopenharmony_ci                // `a` range.
218c67d6573Sopenharmony_ci                b += 1;
219c67d6573Sopenharmony_ci            }
220c67d6573Sopenharmony_ci            self.ranges.push(range);
221c67d6573Sopenharmony_ci            a += 1;
222c67d6573Sopenharmony_ci        }
223c67d6573Sopenharmony_ci        while a < drain_end {
224c67d6573Sopenharmony_ci            let range = self.ranges[a];
225c67d6573Sopenharmony_ci            self.ranges.push(range);
226c67d6573Sopenharmony_ci            a += 1;
227c67d6573Sopenharmony_ci        }
228c67d6573Sopenharmony_ci        self.ranges.drain(..drain_end);
229c67d6573Sopenharmony_ci    }
230c67d6573Sopenharmony_ci
231c67d6573Sopenharmony_ci    /// Compute the symmetric difference of the two sets, in place.
232c67d6573Sopenharmony_ci    ///
233c67d6573Sopenharmony_ci    /// This computes the symmetric difference of two interval sets. This
234c67d6573Sopenharmony_ci    /// removes all elements in this set that are also in the given set,
235c67d6573Sopenharmony_ci    /// but also adds all elements from the given set that aren't in this
236c67d6573Sopenharmony_ci    /// set. That is, the set will contain all elements in either set,
237c67d6573Sopenharmony_ci    /// but will not contain any elements that are in both sets.
238c67d6573Sopenharmony_ci    pub fn symmetric_difference(&mut self, other: &IntervalSet<I>) {
239c67d6573Sopenharmony_ci        // TODO(burntsushi): Fix this so that it amortizes allocation.
240c67d6573Sopenharmony_ci        let mut intersection = self.clone();
241c67d6573Sopenharmony_ci        intersection.intersect(other);
242c67d6573Sopenharmony_ci        self.union(other);
243c67d6573Sopenharmony_ci        self.difference(&intersection);
244c67d6573Sopenharmony_ci    }
245c67d6573Sopenharmony_ci
246c67d6573Sopenharmony_ci    /// Negate this interval set.
247c67d6573Sopenharmony_ci    ///
248c67d6573Sopenharmony_ci    /// For all `x` where `x` is any element, if `x` was in this set, then it
249c67d6573Sopenharmony_ci    /// will not be in this set after negation.
250c67d6573Sopenharmony_ci    pub fn negate(&mut self) {
251c67d6573Sopenharmony_ci        if self.ranges.is_empty() {
252c67d6573Sopenharmony_ci            let (min, max) = (I::Bound::min_value(), I::Bound::max_value());
253c67d6573Sopenharmony_ci            self.ranges.push(I::create(min, max));
254c67d6573Sopenharmony_ci            return;
255c67d6573Sopenharmony_ci        }
256c67d6573Sopenharmony_ci
257c67d6573Sopenharmony_ci        // There should be a way to do this in-place with constant memory,
258c67d6573Sopenharmony_ci        // but I couldn't figure out a simple way to do it. So just append
259c67d6573Sopenharmony_ci        // the negation to the end of this range, and then drain it before
260c67d6573Sopenharmony_ci        // we're done.
261c67d6573Sopenharmony_ci        let drain_end = self.ranges.len();
262c67d6573Sopenharmony_ci
263c67d6573Sopenharmony_ci        // We do checked arithmetic below because of the canonical ordering
264c67d6573Sopenharmony_ci        // invariant.
265c67d6573Sopenharmony_ci        if self.ranges[0].lower() > I::Bound::min_value() {
266c67d6573Sopenharmony_ci            let upper = self.ranges[0].lower().decrement();
267c67d6573Sopenharmony_ci            self.ranges.push(I::create(I::Bound::min_value(), upper));
268c67d6573Sopenharmony_ci        }
269c67d6573Sopenharmony_ci        for i in 1..drain_end {
270c67d6573Sopenharmony_ci            let lower = self.ranges[i - 1].upper().increment();
271c67d6573Sopenharmony_ci            let upper = self.ranges[i].lower().decrement();
272c67d6573Sopenharmony_ci            self.ranges.push(I::create(lower, upper));
273c67d6573Sopenharmony_ci        }
274c67d6573Sopenharmony_ci        if self.ranges[drain_end - 1].upper() < I::Bound::max_value() {
275c67d6573Sopenharmony_ci            let lower = self.ranges[drain_end - 1].upper().increment();
276c67d6573Sopenharmony_ci            self.ranges.push(I::create(lower, I::Bound::max_value()));
277c67d6573Sopenharmony_ci        }
278c67d6573Sopenharmony_ci        self.ranges.drain(..drain_end);
279c67d6573Sopenharmony_ci    }
280c67d6573Sopenharmony_ci
281c67d6573Sopenharmony_ci    /// Converts this set into a canonical ordering.
282c67d6573Sopenharmony_ci    fn canonicalize(&mut self) {
283c67d6573Sopenharmony_ci        if self.is_canonical() {
284c67d6573Sopenharmony_ci            return;
285c67d6573Sopenharmony_ci        }
286c67d6573Sopenharmony_ci        self.ranges.sort();
287c67d6573Sopenharmony_ci        assert!(!self.ranges.is_empty());
288c67d6573Sopenharmony_ci
289c67d6573Sopenharmony_ci        // Is there a way to do this in-place with constant memory? I couldn't
290c67d6573Sopenharmony_ci        // figure out a way to do it. So just append the canonicalization to
291c67d6573Sopenharmony_ci        // the end of this range, and then drain it before we're done.
292c67d6573Sopenharmony_ci        let drain_end = self.ranges.len();
293c67d6573Sopenharmony_ci        for oldi in 0..drain_end {
294c67d6573Sopenharmony_ci            // If we've added at least one new range, then check if we can
295c67d6573Sopenharmony_ci            // merge this range in the previously added range.
296c67d6573Sopenharmony_ci            if self.ranges.len() > drain_end {
297c67d6573Sopenharmony_ci                let (last, rest) = self.ranges.split_last_mut().unwrap();
298c67d6573Sopenharmony_ci                if let Some(union) = last.union(&rest[oldi]) {
299c67d6573Sopenharmony_ci                    *last = union;
300c67d6573Sopenharmony_ci                    continue;
301c67d6573Sopenharmony_ci                }
302c67d6573Sopenharmony_ci            }
303c67d6573Sopenharmony_ci            let range = self.ranges[oldi];
304c67d6573Sopenharmony_ci            self.ranges.push(range);
305c67d6573Sopenharmony_ci        }
306c67d6573Sopenharmony_ci        self.ranges.drain(..drain_end);
307c67d6573Sopenharmony_ci    }
308c67d6573Sopenharmony_ci
309c67d6573Sopenharmony_ci    /// Returns true if and only if this class is in a canonical ordering.
310c67d6573Sopenharmony_ci    fn is_canonical(&self) -> bool {
311c67d6573Sopenharmony_ci        for pair in self.ranges.windows(2) {
312c67d6573Sopenharmony_ci            if pair[0] >= pair[1] {
313c67d6573Sopenharmony_ci                return false;
314c67d6573Sopenharmony_ci            }
315c67d6573Sopenharmony_ci            if pair[0].is_contiguous(&pair[1]) {
316c67d6573Sopenharmony_ci                return false;
317c67d6573Sopenharmony_ci            }
318c67d6573Sopenharmony_ci        }
319c67d6573Sopenharmony_ci        true
320c67d6573Sopenharmony_ci    }
321c67d6573Sopenharmony_ci}
322c67d6573Sopenharmony_ci
323c67d6573Sopenharmony_ci/// An iterator over intervals.
324c67d6573Sopenharmony_ci#[derive(Debug)]
325c67d6573Sopenharmony_cipub struct IntervalSetIter<'a, I>(slice::Iter<'a, I>);
326c67d6573Sopenharmony_ci
327c67d6573Sopenharmony_ciimpl<'a, I> Iterator for IntervalSetIter<'a, I> {
328c67d6573Sopenharmony_ci    type Item = &'a I;
329c67d6573Sopenharmony_ci
330c67d6573Sopenharmony_ci    fn next(&mut self) -> Option<&'a I> {
331c67d6573Sopenharmony_ci        self.0.next()
332c67d6573Sopenharmony_ci    }
333c67d6573Sopenharmony_ci}
334c67d6573Sopenharmony_ci
335c67d6573Sopenharmony_cipub trait Interval:
336c67d6573Sopenharmony_ci    Clone + Copy + Debug + Default + Eq + PartialEq + PartialOrd + Ord
337c67d6573Sopenharmony_ci{
338c67d6573Sopenharmony_ci    type Bound: Bound;
339c67d6573Sopenharmony_ci
340c67d6573Sopenharmony_ci    fn lower(&self) -> Self::Bound;
341c67d6573Sopenharmony_ci    fn upper(&self) -> Self::Bound;
342c67d6573Sopenharmony_ci    fn set_lower(&mut self, bound: Self::Bound);
343c67d6573Sopenharmony_ci    fn set_upper(&mut self, bound: Self::Bound);
344c67d6573Sopenharmony_ci    fn case_fold_simple(
345c67d6573Sopenharmony_ci        &self,
346c67d6573Sopenharmony_ci        intervals: &mut Vec<Self>,
347c67d6573Sopenharmony_ci    ) -> Result<(), unicode::CaseFoldError>;
348c67d6573Sopenharmony_ci
349c67d6573Sopenharmony_ci    /// Create a new interval.
350c67d6573Sopenharmony_ci    fn create(lower: Self::Bound, upper: Self::Bound) -> Self {
351c67d6573Sopenharmony_ci        let mut int = Self::default();
352c67d6573Sopenharmony_ci        if lower <= upper {
353c67d6573Sopenharmony_ci            int.set_lower(lower);
354c67d6573Sopenharmony_ci            int.set_upper(upper);
355c67d6573Sopenharmony_ci        } else {
356c67d6573Sopenharmony_ci            int.set_lower(upper);
357c67d6573Sopenharmony_ci            int.set_upper(lower);
358c67d6573Sopenharmony_ci        }
359c67d6573Sopenharmony_ci        int
360c67d6573Sopenharmony_ci    }
361c67d6573Sopenharmony_ci
362c67d6573Sopenharmony_ci    /// Union the given overlapping range into this range.
363c67d6573Sopenharmony_ci    ///
364c67d6573Sopenharmony_ci    /// If the two ranges aren't contiguous, then this returns `None`.
365c67d6573Sopenharmony_ci    fn union(&self, other: &Self) -> Option<Self> {
366c67d6573Sopenharmony_ci        if !self.is_contiguous(other) {
367c67d6573Sopenharmony_ci            return None;
368c67d6573Sopenharmony_ci        }
369c67d6573Sopenharmony_ci        let lower = cmp::min(self.lower(), other.lower());
370c67d6573Sopenharmony_ci        let upper = cmp::max(self.upper(), other.upper());
371c67d6573Sopenharmony_ci        Some(Self::create(lower, upper))
372c67d6573Sopenharmony_ci    }
373c67d6573Sopenharmony_ci
374c67d6573Sopenharmony_ci    /// Intersect this range with the given range and return the result.
375c67d6573Sopenharmony_ci    ///
376c67d6573Sopenharmony_ci    /// If the intersection is empty, then this returns `None`.
377c67d6573Sopenharmony_ci    fn intersect(&self, other: &Self) -> Option<Self> {
378c67d6573Sopenharmony_ci        let lower = cmp::max(self.lower(), other.lower());
379c67d6573Sopenharmony_ci        let upper = cmp::min(self.upper(), other.upper());
380c67d6573Sopenharmony_ci        if lower <= upper {
381c67d6573Sopenharmony_ci            Some(Self::create(lower, upper))
382c67d6573Sopenharmony_ci        } else {
383c67d6573Sopenharmony_ci            None
384c67d6573Sopenharmony_ci        }
385c67d6573Sopenharmony_ci    }
386c67d6573Sopenharmony_ci
387c67d6573Sopenharmony_ci    /// Subtract the given range from this range and return the resulting
388c67d6573Sopenharmony_ci    /// ranges.
389c67d6573Sopenharmony_ci    ///
390c67d6573Sopenharmony_ci    /// If subtraction would result in an empty range, then no ranges are
391c67d6573Sopenharmony_ci    /// returned.
392c67d6573Sopenharmony_ci    fn difference(&self, other: &Self) -> (Option<Self>, Option<Self>) {
393c67d6573Sopenharmony_ci        if self.is_subset(other) {
394c67d6573Sopenharmony_ci            return (None, None);
395c67d6573Sopenharmony_ci        }
396c67d6573Sopenharmony_ci        if self.is_intersection_empty(other) {
397c67d6573Sopenharmony_ci            return (Some(self.clone()), None);
398c67d6573Sopenharmony_ci        }
399c67d6573Sopenharmony_ci        let add_lower = other.lower() > self.lower();
400c67d6573Sopenharmony_ci        let add_upper = other.upper() < self.upper();
401c67d6573Sopenharmony_ci        // We know this because !self.is_subset(other) and the ranges have
402c67d6573Sopenharmony_ci        // a non-empty intersection.
403c67d6573Sopenharmony_ci        assert!(add_lower || add_upper);
404c67d6573Sopenharmony_ci        let mut ret = (None, None);
405c67d6573Sopenharmony_ci        if add_lower {
406c67d6573Sopenharmony_ci            let upper = other.lower().decrement();
407c67d6573Sopenharmony_ci            ret.0 = Some(Self::create(self.lower(), upper));
408c67d6573Sopenharmony_ci        }
409c67d6573Sopenharmony_ci        if add_upper {
410c67d6573Sopenharmony_ci            let lower = other.upper().increment();
411c67d6573Sopenharmony_ci            let range = Self::create(lower, self.upper());
412c67d6573Sopenharmony_ci            if ret.0.is_none() {
413c67d6573Sopenharmony_ci                ret.0 = Some(range);
414c67d6573Sopenharmony_ci            } else {
415c67d6573Sopenharmony_ci                ret.1 = Some(range);
416c67d6573Sopenharmony_ci            }
417c67d6573Sopenharmony_ci        }
418c67d6573Sopenharmony_ci        ret
419c67d6573Sopenharmony_ci    }
420c67d6573Sopenharmony_ci
421c67d6573Sopenharmony_ci    /// Compute the symmetric difference the given range from this range. This
422c67d6573Sopenharmony_ci    /// returns the union of the two ranges minus its intersection.
423c67d6573Sopenharmony_ci    fn symmetric_difference(
424c67d6573Sopenharmony_ci        &self,
425c67d6573Sopenharmony_ci        other: &Self,
426c67d6573Sopenharmony_ci    ) -> (Option<Self>, Option<Self>) {
427c67d6573Sopenharmony_ci        let union = match self.union(other) {
428c67d6573Sopenharmony_ci            None => return (Some(self.clone()), Some(other.clone())),
429c67d6573Sopenharmony_ci            Some(union) => union,
430c67d6573Sopenharmony_ci        };
431c67d6573Sopenharmony_ci        let intersection = match self.intersect(other) {
432c67d6573Sopenharmony_ci            None => return (Some(self.clone()), Some(other.clone())),
433c67d6573Sopenharmony_ci            Some(intersection) => intersection,
434c67d6573Sopenharmony_ci        };
435c67d6573Sopenharmony_ci        union.difference(&intersection)
436c67d6573Sopenharmony_ci    }
437c67d6573Sopenharmony_ci
438c67d6573Sopenharmony_ci    /// Returns true if and only if the two ranges are contiguous. Two ranges
439c67d6573Sopenharmony_ci    /// are contiguous if and only if the ranges are either overlapping or
440c67d6573Sopenharmony_ci    /// adjacent.
441c67d6573Sopenharmony_ci    fn is_contiguous(&self, other: &Self) -> bool {
442c67d6573Sopenharmony_ci        let lower1 = self.lower().as_u32();
443c67d6573Sopenharmony_ci        let upper1 = self.upper().as_u32();
444c67d6573Sopenharmony_ci        let lower2 = other.lower().as_u32();
445c67d6573Sopenharmony_ci        let upper2 = other.upper().as_u32();
446c67d6573Sopenharmony_ci        cmp::max(lower1, lower2) <= cmp::min(upper1, upper2).saturating_add(1)
447c67d6573Sopenharmony_ci    }
448c67d6573Sopenharmony_ci
449c67d6573Sopenharmony_ci    /// Returns true if and only if the intersection of this range and the
450c67d6573Sopenharmony_ci    /// other range is empty.
451c67d6573Sopenharmony_ci    fn is_intersection_empty(&self, other: &Self) -> bool {
452c67d6573Sopenharmony_ci        let (lower1, upper1) = (self.lower(), self.upper());
453c67d6573Sopenharmony_ci        let (lower2, upper2) = (other.lower(), other.upper());
454c67d6573Sopenharmony_ci        cmp::max(lower1, lower2) > cmp::min(upper1, upper2)
455c67d6573Sopenharmony_ci    }
456c67d6573Sopenharmony_ci
457c67d6573Sopenharmony_ci    /// Returns true if and only if this range is a subset of the other range.
458c67d6573Sopenharmony_ci    fn is_subset(&self, other: &Self) -> bool {
459c67d6573Sopenharmony_ci        let (lower1, upper1) = (self.lower(), self.upper());
460c67d6573Sopenharmony_ci        let (lower2, upper2) = (other.lower(), other.upper());
461c67d6573Sopenharmony_ci        (lower2 <= lower1 && lower1 <= upper2)
462c67d6573Sopenharmony_ci            && (lower2 <= upper1 && upper1 <= upper2)
463c67d6573Sopenharmony_ci    }
464c67d6573Sopenharmony_ci}
465c67d6573Sopenharmony_ci
466c67d6573Sopenharmony_cipub trait Bound:
467c67d6573Sopenharmony_ci    Copy + Clone + Debug + Eq + PartialEq + PartialOrd + Ord
468c67d6573Sopenharmony_ci{
469c67d6573Sopenharmony_ci    fn min_value() -> Self;
470c67d6573Sopenharmony_ci    fn max_value() -> Self;
471c67d6573Sopenharmony_ci    fn as_u32(self) -> u32;
472c67d6573Sopenharmony_ci    fn increment(self) -> Self;
473c67d6573Sopenharmony_ci    fn decrement(self) -> Self;
474c67d6573Sopenharmony_ci}
475c67d6573Sopenharmony_ci
476c67d6573Sopenharmony_ciimpl Bound for u8 {
477c67d6573Sopenharmony_ci    fn min_value() -> Self {
478c67d6573Sopenharmony_ci        u8::MIN
479c67d6573Sopenharmony_ci    }
480c67d6573Sopenharmony_ci    fn max_value() -> Self {
481c67d6573Sopenharmony_ci        u8::MAX
482c67d6573Sopenharmony_ci    }
483c67d6573Sopenharmony_ci    fn as_u32(self) -> u32 {
484c67d6573Sopenharmony_ci        self as u32
485c67d6573Sopenharmony_ci    }
486c67d6573Sopenharmony_ci    fn increment(self) -> Self {
487c67d6573Sopenharmony_ci        self.checked_add(1).unwrap()
488c67d6573Sopenharmony_ci    }
489c67d6573Sopenharmony_ci    fn decrement(self) -> Self {
490c67d6573Sopenharmony_ci        self.checked_sub(1).unwrap()
491c67d6573Sopenharmony_ci    }
492c67d6573Sopenharmony_ci}
493c67d6573Sopenharmony_ci
494c67d6573Sopenharmony_ciimpl Bound for char {
495c67d6573Sopenharmony_ci    fn min_value() -> Self {
496c67d6573Sopenharmony_ci        '\x00'
497c67d6573Sopenharmony_ci    }
498c67d6573Sopenharmony_ci    fn max_value() -> Self {
499c67d6573Sopenharmony_ci        '\u{10FFFF}'
500c67d6573Sopenharmony_ci    }
501c67d6573Sopenharmony_ci    fn as_u32(self) -> u32 {
502c67d6573Sopenharmony_ci        self as u32
503c67d6573Sopenharmony_ci    }
504c67d6573Sopenharmony_ci
505c67d6573Sopenharmony_ci    fn increment(self) -> Self {
506c67d6573Sopenharmony_ci        match self {
507c67d6573Sopenharmony_ci            '\u{D7FF}' => '\u{E000}',
508c67d6573Sopenharmony_ci            c => char::from_u32((c as u32).checked_add(1).unwrap()).unwrap(),
509c67d6573Sopenharmony_ci        }
510c67d6573Sopenharmony_ci    }
511c67d6573Sopenharmony_ci
512c67d6573Sopenharmony_ci    fn decrement(self) -> Self {
513c67d6573Sopenharmony_ci        match self {
514c67d6573Sopenharmony_ci            '\u{E000}' => '\u{D7FF}',
515c67d6573Sopenharmony_ci            c => char::from_u32((c as u32).checked_sub(1).unwrap()).unwrap(),
516c67d6573Sopenharmony_ci        }
517c67d6573Sopenharmony_ci    }
518c67d6573Sopenharmony_ci}
519c67d6573Sopenharmony_ci
520c67d6573Sopenharmony_ci// Tests for interval sets are written in src/hir.rs against the public API.
521