nsIntervalSet.cpp (2429B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 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 11 #include <algorithm> 12 #include <new> 13 14 #include "mozilla/PresShell.h" // for allocation 15 16 using namespace mozilla; 17 18 nsIntervalSet::nsIntervalSet(PresShell* aPresShell) 19 : mList(nullptr), mPresShell(aPresShell) {} 20 21 nsIntervalSet::~nsIntervalSet() { 22 Interval* current = mList; 23 while (current) { 24 Interval* trash = current; 25 current = current->mNext; 26 FreeInterval(trash); 27 } 28 } 29 30 void* nsIntervalSet::AllocateInterval() { 31 return mPresShell->AllocateByObjectID(eArenaObjectID_nsIntervalSet_Interval, 32 sizeof(Interval)); 33 } 34 35 void nsIntervalSet::FreeInterval(nsIntervalSet::Interval* aInterval) { 36 NS_ASSERTION(aInterval, "null interval"); 37 38 aInterval->Interval::~Interval(); 39 mPresShell->FreeByObjectID(eArenaObjectID_nsIntervalSet_Interval, aInterval); 40 } 41 42 void nsIntervalSet::IncludeInterval(coord_type aBegin, coord_type aEnd) { 43 auto newInterval = static_cast<Interval*>(AllocateInterval()); 44 new (newInterval) Interval(aBegin, aEnd); 45 46 Interval** current = &mList; 47 while (*current && (*current)->mEnd < aBegin) { 48 current = &(*current)->mNext; 49 } 50 51 newInterval->mNext = *current; 52 *current = newInterval; 53 54 Interval* subsumed = newInterval->mNext; 55 while (subsumed && subsumed->mBegin <= aEnd) { 56 newInterval->mBegin = std::min(newInterval->mBegin, subsumed->mBegin); 57 newInterval->mEnd = std::max(newInterval->mEnd, subsumed->mEnd); 58 newInterval->mNext = subsumed->mNext; 59 FreeInterval(subsumed); 60 subsumed = newInterval->mNext; 61 } 62 } 63 64 bool nsIntervalSet::Intersects(coord_type aBegin, coord_type aEnd) const { 65 Interval* current = mList; 66 while (current && current->mBegin <= aEnd) { 67 if (current->mEnd >= aBegin) { 68 return true; 69 } 70 current = current->mNext; 71 } 72 return false; 73 } 74 75 bool nsIntervalSet::Contains(coord_type aBegin, coord_type aEnd) const { 76 Interval* current = mList; 77 while (current && current->mBegin <= aBegin) { 78 if (current->mEnd >= aEnd) { 79 return true; 80 } 81 current = current->mNext; 82 } 83 return false; 84 }