/* * Copyright (C) 2004, 2005 * Heikki Tauriainen * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "IntervalList.h" #include "StringUtil.h" /****************************************************************************** * * Function definitions for class IntervalList. * *****************************************************************************/ /* ========================================================================= */ void IntervalList::merge(unsigned long int min, unsigned long int max) /* ---------------------------------------------------------------------------- * * Description: Merges a new interval with a list of intervals. * * Arguments: min, max -- Upper and lower bound of the new interval. * * Returns: Nothing. * * ------------------------------------------------------------------------- */ { if (min > max) return; list::iterator interval; for (interval = intervals.begin(); interval != intervals.end() && interval->second + 1 < min; ++interval) ; if (interval == intervals.end()) { intervals.insert(interval, make_pair(min, max)); return; } if (interval->first <= min && max <= interval->second) return; if (max + 1 < interval->first) { intervals.insert(interval, make_pair(min, max)); return; } if (min < interval->first) interval->first = min; if (interval->second < max) { interval->second = max; list::iterator interval2 = interval; ++interval2; while (interval2 != intervals.end() && interval2->first <= interval->second + 1) { if (interval->second < interval2->second) interval->second = interval2->second; list::iterator interval_to_erase = interval2; ++interval2; intervals.erase(interval_to_erase); } } } /* ========================================================================= */ void IntervalList::remove(unsigned long int min, unsigned long int max) /* ---------------------------------------------------------------------------- * * Description: Removes a closed interval from an interval list. * * Arguments: min, max -- Bounds for the interval to remove. * * Returns: Nothing. * * ------------------------------------------------------------------------- */ { if (min > max) return; list::iterator interval; for (interval = intervals.begin(); interval != intervals.end() && interval->second < min; ++interval) ; while (interval != intervals.end()) { if (max < interval->first) /* min <= max < imin <= imax */ return; if (interval->first < min) { if (max < interval->second) /* imin < min <= max < imax */ { intervals.insert(interval, make_pair(interval->first, min - 1)); interval->first = max + 1; return; } interval->second = min - 1; /* imin < min <= imax <= max */ ++interval; } else if (max < interval->second) /* min <= imin <= max < imax */ { interval->first = max + 1; return; } else /* min <= imin <= imax <= max */ { list::iterator interval_to_erase = interval; ++interval; intervals.erase(interval_to_erase); } } } /* ========================================================================= */ bool IntervalList::covers(unsigned long int min, unsigned long int max) const /* ---------------------------------------------------------------------------- * * Description: Test whether an interval list covers a given interval. * * Arguments: min, max -- Upper and lower bound for the interval to test. * * Returns: True if the IntervalList covers the given interval. * * ------------------------------------------------------------------------- */ { if (min > max) return true; /* empty interval is always covered */ list::const_iterator interval; for (interval = intervals.begin(); interval != intervals.end() && min > interval->second; ++interval) ; if (interval == intervals.end()) return false; return (min >= interval->first && max <= interval->second); } /* ========================================================================= */ string IntervalList::toString() const /* ---------------------------------------------------------------------------- * * Description: Converts the interval list to a string. * * Arguments: None. * * Returns: A string listing the intervals in the interval list. * * ------------------------------------------------------------------------- */ { string s; for (list::const_iterator interval = intervals.begin(); interval != intervals.end(); ++interval) { if (interval != intervals.begin()) s += ','; s += StringUtil::toString(interval->first) + "..." + StringUtil::toString(interval->second); } return s; }