Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : // vim:cindent:ts=8:et:sw=4:
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : /* a set of ranges on a number-line */
8 :
9 : #include "nsIntervalSet.h"
10 : #include <new>
11 : #include <algorithm>
12 : #include "nsIPresShell.h" // for allocation
13 :
14 152 : nsIntervalSet::nsIntervalSet(nsIPresShell* aPresShell)
15 : : mList(nullptr),
16 152 : mPresShell(aPresShell)
17 : {
18 152 : }
19 :
20 304 : nsIntervalSet::~nsIntervalSet()
21 : {
22 152 : Interval *current = mList;
23 152 : while (current) {
24 0 : Interval *trash = current;
25 0 : current = current->mNext;
26 0 : FreeInterval(trash);
27 : }
28 152 : }
29 :
30 : void*
31 0 : nsIntervalSet::AllocateInterval()
32 : {
33 0 : return mPresShell->AllocateByObjectID(
34 0 : eArenaObjectID_nsIntervalSet_Interval, sizeof(Interval));
35 : }
36 :
37 0 : void nsIntervalSet::FreeInterval(nsIntervalSet::Interval *aInterval)
38 : {
39 0 : NS_ASSERTION(aInterval, "null interval");
40 :
41 : aInterval->Interval::~Interval();
42 0 : mPresShell->FreeByObjectID(eArenaObjectID_nsIntervalSet_Interval, aInterval);
43 0 : }
44 :
45 0 : void nsIntervalSet::IncludeInterval(coord_type aBegin, coord_type aEnd)
46 : {
47 0 : auto newInterval = static_cast<Interval*>(AllocateInterval());
48 0 : new(newInterval) Interval(aBegin, aEnd);
49 :
50 0 : Interval **current = &mList;
51 0 : while (*current && (*current)->mEnd < aBegin)
52 0 : current = &(*current)->mNext;
53 :
54 0 : newInterval->mNext = *current;
55 0 : *current = newInterval;
56 :
57 0 : Interval *subsumed = newInterval->mNext;
58 0 : while (subsumed && subsumed->mBegin <= aEnd) {
59 0 : newInterval->mBegin = std::min(newInterval->mBegin, subsumed->mBegin);
60 0 : newInterval->mEnd = std::max(newInterval->mEnd, subsumed->mEnd);
61 0 : newInterval->mNext = subsumed->mNext;
62 0 : FreeInterval(subsumed);
63 0 : subsumed = newInterval->mNext;
64 : }
65 0 : }
66 :
67 0 : bool nsIntervalSet::Intersects(coord_type aBegin, coord_type aEnd) const
68 : {
69 0 : Interval *current = mList;
70 0 : while (current && current->mBegin <= aEnd) {
71 0 : if (current->mEnd >= aBegin)
72 0 : return true;
73 0 : current = current->mNext;
74 : }
75 0 : return false;
76 : }
77 :
78 0 : bool nsIntervalSet::Contains(coord_type aBegin, coord_type aEnd) const
79 : {
80 0 : Interval *current = mList;
81 0 : while (current && current->mBegin <= aBegin) {
82 0 : if (current->mEnd >= aEnd)
83 0 : return true;
84 0 : current = current->mNext;
85 : }
86 0 : return false;
87 : }
|