#ifndef theplu_yat_utility_segment #define theplu_yat_utility_segment // $Id$ /* Copyright (C) 2010 Peter Johansson This file is part of the yat library, http://dev.thep.lu.se/yat The yat library 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 3 of the License, or (at your option) any later version. The yat library 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 yat. If not, see . */ #include "yat_assert.h" #include #include namespace theplu { namespace yat { namespace utility { /** \brief a class for a Segment or Interval A Segment is defined by its \a begin and \a end. The end is not included in the Segment, i.e., you could write the Segment as [begin, end). Type T must be comparable, optionally with a comparator Compare, which should implement Strict Weak Ordering.. \since new in yat 0.7 */ template > class Segment { public: /** type the Segment holds */ typedef T value_type; /** \brief default constructor */ Segment(void) {} /** \brief Constructor Creates a segment [begin, end) */ Segment(const T& begin, const T& end) : begin_(begin), end_(end) {} /** \return reference to first element in Segment */ T& begin(void) { return begin_; } /** \return const reference to first element in Segment */ const T& begin(void) const { return begin_; } /** \return reference to first element greater than Segment */ T& end(void) { return end_; } /** \return const reference to first element greater than Segment */ const T& end(void) const { return end_; } private: T begin_; T end_; // using compiler generated copying //Segment(const Segment&); //Segment& operator=(const Segment&); }; /** This function takes two Segment and compare them with comparator Compare. If all elements in \a lhs is less than all elements in \a rhs, \c true is returned. In other words, \c false is returned if \a rhs.begin() is less than \a lhs.end(). The exception is if both \a lhs and \a rhs are empty Segment (i.e. begin equals end) and their begins and ends are equal, in which case \c false is returned. This exception implies that compare(x,x) always returns false. \relates Segment \since new in yat 0.7 */ template bool compare(const Segment& lhs, const Segment& rhs) { Compare c; // begin <= end YAT_ASSERT(!c(lhs.end(), lhs.begin())); YAT_ASSERT(!c(rhs.end(), rhs.begin())); // take care of case when both sides are zero segments if (!c(lhs.begin(), lhs.end()) && !c(rhs.begin(), rhs.end())) { return c(lhs.begin(), rhs.begin()); } return ! c(rhs.begin(), lhs.end()); } /** \return -1 if compare(lhs, rhs) is \c true, +1 if compare(rhs, lhs) is \c true, and 0 otherwise \relates Segment \see compare(const Segment&, const Segment&) \since new in yat 0.7 */ template int compare_3way(const Segment& lhs, const Segment& rhs) { if (compare(lhs, rhs)) return -1; if (compare(rhs, lhs)) return 1; return 0; } /** \return -1 if \a element is less than all elements in \a segment, 0 if \a element overlaps with \a segment, and 1 otherwise. \relates Segment \since new in yat 0.7 */ template int compare_3way(const T& element, const Segment& segment) { Compare comp; if (comp(element, segment.begin())) return -1; if (comp(element, segment.end())) return 0; return 1; } /** \return intersection of \a a and \a b. If \a a and \a b do not overlap an empty Section is returned (begin==end), but the exact value of begin is undefined. \relates Segment \since new in yat 0.7 */ template Segment intersection(const Segment& a, const Segment& b) { Compare comp; Segment result; result.begin() = std::max(a.begin(), b.begin(), comp); // the first max is needed in case a and b don't overlap result.end() = std::max(result.begin(), std::min(a.end(), b.end(), comp), comp); return result; } /** \brief functor using compare */ template struct SegmentCompare : public std::binary_function, Segment, bool> { /** \see compare(const Segment&, const Segment&) */ bool operator()(const Segment& lhs, const Segment& rhs) const { return compare(lhs, rhs); } }; }}} #endif