8 #ifndef Sawyer_Interval_H
9 #define Sawyer_Interval_H
11 #include <Sawyer/Assert.h>
12 #include <Sawyer/Sawyer.h>
13 #include <boost/integer_traits.hpp>
14 #include <boost/iterator/iterator_facade.hpp>
15 #include <boost/range/iterator_range.hpp>
16 #include <boost/serialization/access.hpp>
17 #include <boost/serialization/nvp.hpp>
41 friend class boost::serialization::access;
44 void serialize(S &s,
const unsigned ) {
45 s & BOOST_SERIALIZATION_NVP(lo_);
46 s & BOOST_SERIALIZATION_NVP(hi_);
63 class ConstIterator:
public boost::iterator_facade<ConstIterator, const Value, boost::bidirectional_traversal_tag,
66 friend class boost::iterator_core_access;
68 T first_, cur_, last_;
71 ConstIterator(T first, T last, T cur): first_(first), cur_(cur), last_(last), atEnd_(
false) {}
90 Value dereference()
const {
91 ASSERT_forbid(
atEnd());
96 if (
atEnd() || other.atEnd())
97 return atEnd() && other.atEnd();
98 return cur_ == other.cur_;
109 ASSERT_require(cur_ == first_);
117 if (cur_ == first_) {
120 ASSERT_require(cur_ == last_);
138 #if 0 // [Robb Matzke 2014-05-14]: too much confusion with "hi" vs. "size". Use either baseSize or hull instead.
143 Interval(T lo, T hi): lo_(lo), hi_(hi) {
144 ASSERT_require(lo <= hi);
153 retval.lo_ = std::min(v1, v2);
154 retval.hi_ = std::max(v1, v2);
173 return hull(lo, boost::integer_traits<T>::const_max);
181 return hull(boost::integer_traits<T>::const_min, boost::integer_traits<T>::const_max);
203 return base + size < base;
219 bool isEmpty()
const {
return 1==lo_ && 0==hi_; }
225 bool isWhole()
const {
return lo_==boost::integer_traits<T>::const_min && hi_==boost::integer_traits<T>::const_max; }
292 return isEmpty() ? 0 : hi_ - lo_ + 1;
302 return lo_==other.lo_ && hi_==other.hi_;
305 return lo_!=other.lo_ || hi_!=other.hi_;
356 std::pair<Interval, Interval>
split(T splitPoint)
const {
359 }
else if (splitPoint <
least()) {
360 return std::make_pair(
Interval(), *
this);
361 }
else if (splitPoint <
greatest()) {
364 return std::make_pair(*
this,
Interval());
395 return hull(
least() + n, boost::integer_traits<T>::const_max);
402 typedef ConstIterator const_iterator;
403 typedef ConstIterator iterator;
423 ConstIterator
end()
const {
428 boost::iterator_range<ConstIterator>
values()
const {
429 return boost::iterator_range<ConstIterator>(
begin(),
end());
435 typedef void(
Interval::*unspecified_bool)()
const;
436 void this_type_does_not_support_comparisons()
const {}
450 operator unspecified_bool()
const {
451 return isEmpty() ? 0 : &Interval::this_type_does_not_support_comparisons;
Interval shiftRightSat(Value n) const
Shift interval upward.
std::pair< Interval, Interval > split(T splitPoint) const
Split interval in two.
Interval operator&(const Interval &other) const
Intersection.
bool isOverlapping(const Interval &other) const
True if two intervals overlap.
Value size() const
Size of interval.
Interval & operator=(const Interval &other)
Assignment from an interval.
Bidirectional forward iterator.
Interval intersection(const Interval &other) const
Intersection.
ConstIterator end() const
Iterator positioned one past the greatest value.
bool isEmpty() const
True if interval is empty.
bool isWhole() const
True if interval covers entire space.
bool isLeftAdjacent(const Interval &right) const
Adjacency predicate.
bool isSingleton() const
True if interval is a singleton.
bool isContaining(const Interval &other) const
Containment predicate.
Interval hull(T value) const
Hull.
T Value
Types of values in the interval.
Interval join(const Interval &right) const
Creates an interval by joining two adjacent intervals.
Name space for the entire library.
bool isAdjacent(const Interval &other) const
Adjacency predicate.
static Interval baseSize(T lo, T size)
Construct an interval from one endpoint and a size.
Interval(T value)
Constructs a singleton interval.
ConstIterator begin() const
Iterator positioned at the least value.
bool isLeftOf(const Interval &right) const
Relative position predicate.
bool contains(const Interval &other) const
Containment predicate.
T least() const
Returns lower limit.
static Interval whole()
Construct an interval that covers the entire domain.
static Interval hull(T v1, T v2)
Construct an interval from two endpoints.
Interval & operator=(T value)
Assignment from a scalar.
static bool baseSizeOverflows(T base, T size)
Tests whether a base and size overflows.
bool operator!=(const Interval &other) const
Equality test.
bool atEnd() const
Predicate to determine if an iterator is at one of its end positions.
boost::iterator_range< ConstIterator > values() const
Iterator range for values.
ConstIterator()
Create an empty iterator.
static Interval baseSizeSat(T lo, T size)
Construct an interval from one endpoint and size, and clip overflows.
bool overlaps(const Interval &other) const
True if two intervals overlap.
Interval hull(const Interval &other) const
Hull.
Range of values delimited by endpoints.
bool operator==(const Interval &other) const
Equality test.
T greatest() const
Returns upper limit.
Interval(const Interval &other)
Copy-constructs an interval.
bool isRightOf(const Interval &left) const
Relative position predicate.
Interval()
Constructs an empty interval.
bool isRightAdjacent(const Interval &left) const
Adjacency predicate.