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> 
   38#ifdef SAWYER_HAVE_BOOST_SERIALIZATION 
   40    friend class boost::serialization::access;
 
   43    void serialize(S &s, 
const unsigned ) {
 
   44        s & BOOST_SERIALIZATION_NVP(lo_);
 
   45        s & BOOST_SERIALIZATION_NVP(hi_);
 
   49#ifdef SAWYER_HAVE_CEREAL 
   51    friend class cereal::access;
 
   53    template<
class Archive>
 
   54    void CEREAL_SERIALIZE_FUNCTION_NAME(Archive &archive) {
 
   55        archive(CEREAL_NVP(lo_));
 
   56        archive(CEREAL_NVP(hi_));
 
   74    class ConstIterator: 
public boost::iterator_facade<ConstIterator, const Value, boost::bidirectional_traversal_tag,
 
   77        friend class boost::iterator_core_access;
 
   79        T first_, cur_, last_;
 
   82        ConstIterator(T first, T last, T cur): first_(first), cur_(cur), last_(last), atEnd_(
false) {}
 
  101        Value dereference()
 const {
 
  102            ASSERT_forbid(
atEnd());
 
  107            if (
atEnd() || other.atEnd())
 
  108                return atEnd() && other.atEnd();
 
  109            return cur_ == other.cur_;
 
  120                ASSERT_require(cur_ == first_);
 
  128            if (cur_ == first_) {                       
 
  131                ASSERT_require(cur_ == last_);
 
 
  154    Interval(T lo, T hi): lo_(lo), hi_(hi) {
 
  155        ASSERT_require(lo <= hi);
 
  164        retval.lo_ = std::min(v1, v2);
 
  165        retval.hi_ = std::max(v1, v2);
 
 
  174        ASSERT_forbid(baseSizeOverflows(lo, size));
 
 
  183        if (baseSizeOverflows(lo, size)) {
 
  184            return hull(lo, boost::integer_traits<T>::const_max);
 
  186            return baseSize(lo, size);
 
 
  192        return hull(boost::integer_traits<T>::const_min, boost::integer_traits<T>::const_max);
 
 
  214        return base + size < base;
 
 
  219        ASSERT_forbid(isEmpty());
 
 
  225        ASSERT_forbid(isEmpty());
 
 
  230    bool isEmpty()
 const { 
return 1==lo_ && 0==hi_; }
 
  236    bool isWhole()
 const { 
return lo_==boost::integer_traits<T>::const_min && hi_==boost::integer_traits<T>::const_max; }
 
  244        return !intersection(other).isEmpty();
 
 
  247        return overlaps(other);
 
 
  259                (!isEmpty() && least()<=other.
least() && greatest()>=other.
greatest()));
 
 
  262        return contains(other);
 
 
  273        return isEmpty() || right.
isEmpty() || (!isWhole() && greatest()+1 == right.
least());
 
 
  279        return (isEmpty() || other.
isEmpty() ||
 
  280                (!isWhole() && greatest()+1 == other.
least()) ||
 
 
  292        return isEmpty() || right.
isEmpty() || greatest() < right.
least();
 
 
  303        return isEmpty() ? 0 : hi_ - lo_ + 1;
 
 
  313        return lo_==other.lo_ && hi_==other.hi_;
 
 
  316        return lo_!=other.lo_ || hi_!=other.hi_;
 
 
  331        return intersection(other);
 
 
  357            return Interval::hull(std::min(least(), value), std::max(greatest(), value));
 
 
  367    std::pair<Interval, Interval> 
split(T splitPoint)
 const {
 
  370        } 
else if (splitPoint < least()) {
 
  371            return std::make_pair(
Interval(), *
this);
 
  372        } 
else if (splitPoint < greatest()) {
 
  375            return std::make_pair(*
this, 
Interval());
 
 
  392            ASSERT_require(greatest()+1 == right.
least() && right.
least() > greatest());
 
 
  403        if (isEmpty() || baseSizeOverflows(least(), n)) {
 
  405        } 
else if (baseSizeOverflows(greatest(), n)) {
 
  406            return hull(least() + n, boost::integer_traits<T>::const_max);
 
  408            return hull(least() + n, greatest() + n);
 
 
  413    typedef ConstIterator const_iterator;
 
  414    typedef ConstIterator iterator;
 
  439    boost::iterator_range<ConstIterator> 
values()
 const {
 
  440        return boost::iterator_range<ConstIterator>(begin(), end());
 
 
  446    typedef void(
Interval::*unspecified_bool)() const;
 
  447    void this_type_does_not_support_comparisons()
 const {}
 
  461    operator unspecified_bool()
 const {
 
  462        return isEmpty() ? 0 : &Interval::this_type_does_not_support_comparisons;
 
 
 
Bidirectional forward iterator.
 
bool atEnd() const
Predicate to determine if an iterator is at one of its end positions.
 
ConstIterator()
Create an empty iterator.
 
Range of values delimited by endpoints.
 
T greatest() const
Returns upper limit.
 
Interval hull(T value) const
Hull.
 
bool isLeftAdjacent(const Interval &right) const
Adjacency predicate.
 
static Interval baseSize(T lo, T size)
Construct an interval from one endpoint and a size.
 
bool isContaining(const Interval &other) const
Containment predicate.
 
static Interval hull(T v1, T v2)
Construct an interval from two endpoints.
 
Interval()
Constructs an empty interval.
 
ConstIterator end() const
Iterator positioned one past the greatest value.
 
ConstIterator begin() const
Iterator positioned at the least value.
 
bool isOverlapping(const Interval &other) const
True if two intervals overlap.
 
Interval & operator=(T value)
Assignment from a scalar.
 
bool isRightOf(const Interval &left) const
Relative position predicate.
 
bool isWhole() const
True if interval covers entire space.
 
static Interval baseSizeSat(T lo, T size)
Construct an interval from one endpoint and size, and clip overflows.
 
Interval shiftRightSat(Value n) const
Shift interval upward.
 
bool contains(const Interval &other) const
Containment predicate.
 
Interval & operator=(const Interval &other)
Assignment from an interval.
 
Interval(const Interval &other)
Copy-constructs an interval.
 
Value size() const
Size of interval.
 
Interval operator&(const Interval &other) const
Intersection.
 
bool isAdjacent(const Interval &other) const
Adjacency predicate.
 
Interval intersection(const Interval &other) const
Intersection.
 
bool operator!=(const Interval &other) const
Equality test.
 
bool isSingleton() const
True if interval is a singleton.
 
bool isLeftOf(const Interval &right) const
Relative position predicate.
 
bool isEmpty() const
True if interval is empty.
 
T least() const
Returns lower limit.
 
bool isRightAdjacent(const Interval &left) const
Adjacency predicate.
 
Interval join(const Interval &right) const
Creates an interval by joining two adjacent intervals.
 
bool overlaps(const Interval &other) const
True if two intervals overlap.
 
Interval hull(const Interval &other) const
Hull.
 
Interval(T value)
Constructs a singleton interval.
 
std::pair< Interval, Interval > split(T splitPoint) const
Split interval in two.
 
boost::iterator_range< ConstIterator > values() const
Iterator range for values.
 
bool operator==(const Interval &other) const
Equality test.
 
static bool baseSizeOverflows(T base, T size)
Tests whether a base and size overflows.
 
T Value
Types of values in the interval.
 
static Interval whole()
Construct an interval that covers the entire domain.