| // Copyright 2015 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 | // | 
 | // An Interval<T> is a data structure used to represent a contiguous, mutable | 
 | // range over an ordered type T. Supported operations include testing a value to | 
 | // see whether it is included in the interval, comparing two intervals, and | 
 | // performing their union, intersection, and difference. For the purposes of | 
 | // this library, an "ordered type" is any type that induces a total order on its | 
 | // values via its less-than operator (operator<()). Examples of such types are | 
 | // basic arithmetic types like int and double as well as class types like | 
 | // string. | 
 | // | 
 | // An Interval<T> is represented using the usual C++ STL convention, namely as | 
 | // the half-open interval [min, max). A point p is considered to be contained in | 
 | // the interval iff p >= min && p < max. One consequence of this definition is | 
 | // that for any non-empty interval, min is contained in the interval but max is | 
 | // not. There is no canonical representation for the empty interval; rather, any | 
 | // interval where max <= min is regarded as empty. As a consequence, two empty | 
 | // intervals will still compare as equal despite possibly having different | 
 | // underlying min() or max() values. Also beware of the terminology used here: | 
 | // the library uses the terms "min" and "max" rather than "begin" and "end" as | 
 | // is conventional for the STL. | 
 | // | 
 | // T is required to be default- and copy-constructable, to have an assignment | 
 | // operator, and the full complement of comparison operators (<, <=, ==, !=, >=, | 
 | // >).  A difference operator (operator-()) is required if Interval<T>::Length | 
 | // is used. | 
 | // | 
 | // For equality comparisons, Interval<T> supports an Equals() method and an | 
 | // operator==() which delegates to it. Two intervals are considered equal if | 
 | // either they are both empty or if their corresponding min and max fields | 
 | // compare equal. For ordered comparisons, Interval<T> also provides the | 
 | // comparator Interval<T>::Less and an operator<() which delegates to it. | 
 | // Unfortunately this comparator is currently buggy because its behavior is | 
 | // inconsistent with Equals(): two empty ranges with different representations | 
 | // may be regarded as equivalent by Equals() but regarded as different by | 
 | // the comparator. Bug 9240050 has been created to address this. | 
 | // | 
 | // This class is thread-compatible if T is thread-compatible. (See | 
 | // go/thread-compatible). | 
 | // | 
 | // Examples: | 
 | //   Interval<int> r1(0, 100);  // The interval [0, 100). | 
 | //   EXPECT_TRUE(r1.Contains(0)); | 
 | //   EXPECT_TRUE(r1.Contains(50)); | 
 | //   EXPECT_FALSE(r1.Contains(100));  // 100 is just outside the interval. | 
 | // | 
 | //   Interval<int> r2(50, 150);  // The interval [50, 150). | 
 | //   EXPECT_TRUE(r1.Intersects(r2)); | 
 | //   EXPECT_FALSE(r1.Contains(r2)); | 
 | //   EXPECT_TRUE(r1.IntersectWith(r2));  // Mutates r1. | 
 | //   EXPECT_EQ(Interval<int>(50, 100), r1);  // r1 is now [50, 100). | 
 | // | 
 | //   Interval<int> r3(1000, 2000);  // The interval [1000, 2000). | 
 | //   EXPECT_TRUE(r1.IntersectWith(r3));  // Mutates r1. | 
 | //   EXPECT_TRUE(r1.Empty());  // Now r1 is empty. | 
 | //   EXPECT_FALSE(r1.Contains(r1.min()));  // e.g. doesn't contain its own min. | 
 |  | 
 | #ifndef NET_QUIC_INTERVAL_H_ | 
 | #define NET_QUIC_INTERVAL_H_ | 
 |  | 
 | #include <stddef.h> | 
 |  | 
 | #include <algorithm> | 
 | #include <functional> | 
 | #include <ostream> | 
 | #include <string> | 
 | #include <utility> | 
 | #include <vector> | 
 |  | 
 | namespace net { | 
 |  | 
 | template <typename T> | 
 | class Interval { | 
 |  private: | 
 | // TODO(rtenneti): Implement after suupport for std::decay. | 
 | #if 0 | 
 |   // Type trait for deriving the return type for Interval::Length.  If | 
 |   // operator-() is not defined for T, then the return type is void.  This makes | 
 |   // the signature for Length compile so that the class can be used for such T, | 
 |   // but code that calls Length would still generate a compilation error. | 
 |   template <typename U> | 
 |   class DiffTypeOrVoid { | 
 |    private: | 
 |     template <typename V> | 
 |     static auto f(const V* v) -> decltype(*v - *v); | 
 |     template <typename V> | 
 |     static void f(...); | 
 |  | 
 |    public: | 
 |     using type = typename std::decay<decltype(f<U>(0))>::type; | 
 |   }; | 
 | #endif | 
 |  | 
 |  public: | 
 |   // Compatibility alias. | 
 |   using Less = std::less<Interval>; | 
 |  | 
 |   // Construct an Interval representing an empty interval. | 
 |   Interval() : min_(), max_() {} | 
 |  | 
 |   // Construct an Interval representing the interval [min, max). If min < max, | 
 |   // the constructed object will represent the non-empty interval containing all | 
 |   // values from min up to (but not including) max. On the other hand, if min >= | 
 |   // max, the constructed object will represent the empty interval. | 
 |   Interval(const T& min, const T& max) : min_(min), max_(max) {} | 
 |  | 
 |   const T& min() const { return min_; } | 
 |   const T& max() const { return max_; } | 
 |   void SetMin(const T& t) { min_ = t; } | 
 |   void SetMax(const T& t) { max_ = t; } | 
 |  | 
 |   void Set(const T& min, const T& max) { | 
 |     SetMin(min); | 
 |     SetMax(max); | 
 |   } | 
 |  | 
 |   void Clear() { *this = {}; } | 
 |   void CopyFrom(const Interval& i) { *this = i; } | 
 |   bool Equals(const Interval& i) const { return *this == i; } | 
 |   bool Empty() const { return min() >= max(); } | 
 |  | 
 |   // Returns the length of this interval. The value returned is zero if | 
 |   // IsEmpty() is true; otherwise the value returned is max() - min(). | 
 |   const T Length() const { return (min_ >= max_ ? min_ : max_) - min_; } | 
 |  | 
 |   // Returns true iff t >= min() && t < max(). | 
 |   bool Contains(const T& t) const { return min() <= t && max() > t; } | 
 |  | 
 |   // Returns true iff *this and i are non-empty, and *this includes i. "*this | 
 |   // includes i" means that for all t, if i.Contains(t) then this->Contains(t). | 
 |   // Note the unintuitive consequence of this definition: this method always | 
 |   // returns false when i is the empty interval. | 
 |   bool Contains(const Interval& i) const { | 
 |     return !Empty() && !i.Empty() && min() <= i.min() && max() >= i.max(); | 
 |   } | 
 |  | 
 |   // Returns true iff there exists some point t for which this->Contains(t) && | 
 |   // i.Contains(t) evaluates to true, i.e. if the intersection is non-empty. | 
 |   bool Intersects(const Interval& i) const { | 
 |     return !Empty() && !i.Empty() && min() < i.max() && max() > i.min(); | 
 |   } | 
 |  | 
 |   // Returns true iff there exists some point t for which this->Contains(t) && | 
 |   // i.Contains(t) evaluates to true, i.e. if the intersection is non-empty. | 
 |   // Furthermore, if the intersection is non-empty and the intersection pointer | 
 |   // is not null, this method stores the calculated intersection in | 
 |   // *intersection. | 
 |   bool Intersects(const Interval& i, Interval* out) const; | 
 |  | 
 |   // Sets *this to be the intersection of itself with i. Returns true iff | 
 |   // *this was modified. | 
 |   bool IntersectWith(const Interval& i); | 
 |  | 
 |   // Calculates the smallest interval containing both *this i, and updates *this | 
 |   // to represent that interval, and returns true iff *this was modified. | 
 |   bool SpanningUnion(const Interval& i); | 
 |  | 
 |   // Determines the difference between two intervals by finding all points that | 
 |   // are contained in *this but not in i, coalesces those points into the | 
 |   // largest possible contiguous intervals, and appends those intervals to the | 
 |   // *difference vector. Intuitively this can be thought of as "erasing" i from | 
 |   // *this. This will either completely erase *this (leaving nothing behind), | 
 |   // partially erase some of *this from the left or right side (leaving some | 
 |   // residual behind), or erase a hole in the middle of *this (leaving behind an | 
 |   // interval on either side). Therefore, 0, 1, or 2 intervals will be appended | 
 |   // to *difference. The method returns true iff the intersection of *this and i | 
 |   // is non-empty. The caller owns the vector and the Interval* pointers | 
 |   // inside it. The difference vector is required to be non-null. | 
 |   bool Difference(const Interval& i, std::vector<Interval*>* difference) const; | 
 |  | 
 |   // Determines the difference between two intervals as in | 
 |   // Difference(Interval&, vector*), but stores the results directly in out | 
 |   // parameters rather than dynamically allocating an Interval* and appending | 
 |   // it to a vector. If two results are generated, the one with the smaller | 
 |   // value of min() will be stored in *lo and the other in *hi. Otherwise (if | 
 |   // fewer than two results are generated), unused arguments will be set to the | 
 |   // empty interval (it is possible that *lo will be empty and *hi non-empty). | 
 |   // The method returns true iff the intersection of *this and i is non-empty. | 
 |   bool Difference(const Interval& i, Interval* lo, Interval* hi) const; | 
 |  | 
 |   friend bool operator==(const Interval& a, const Interval& b) { | 
 |     bool ae = a.Empty(); | 
 |     bool be = b.Empty(); | 
 |     if (ae && be) | 
 |       return true;  // All empties are equal. | 
 |     if (ae != be) | 
 |       return false;  // Empty cannot equal nonempty. | 
 |     return a.min() == b.min() && a.max() == b.max(); | 
 |   } | 
 |  | 
 |   friend bool operator!=(const Interval& a, const Interval& b) { | 
 |     return !(a == b); | 
 |   } | 
 |  | 
 |   // Defines a comparator which can be used to induce an order on Intervals, so | 
 |   // that, for example, they can be stored in an ordered container such as | 
 |   // std::set. The ordering is arbitrary, but does provide the guarantee that, | 
 |   // for non-empty intervals X and Y, if X contains Y, then X <= Y. | 
 |   // TODO(kosak): The current implementation of this comparator has a problem | 
 |   // because the ordering it induces is inconsistent with that of Equals(). In | 
 |   // particular, this comparator does not properly consider all empty intervals | 
 |   // equivalent. Bug b/9240050 has been created to track this. | 
 |   friend bool operator<(const Interval& a, const Interval& b) { | 
 |     return a.min() < b.min() || (a.min() == b.min() && a.max() > b.max()); | 
 |   } | 
 |  | 
 |   friend std::ostream& operator<<(std::ostream& out, const Interval& i) { | 
 |     return out << "[" << i.min() << ", " << i.max() << ")"; | 
 |   } | 
 |  | 
 |  private: | 
 |   T min_;  // Inclusive lower bound. | 
 |   T max_;  // Exclusive upper bound. | 
 | }; | 
 |  | 
 | //============================================================================== | 
 | // Implementation details: Clients can stop reading here. | 
 |  | 
 | template <typename T> | 
 | bool Interval<T>::Intersects(const Interval& i, Interval* out) const { | 
 |   if (!Intersects(i)) | 
 |     return false; | 
 |   if (out != nullptr) { | 
 |     *out = Interval(std::max(min(), i.min()), std::min(max(), i.max())); | 
 |   } | 
 |   return true; | 
 | } | 
 |  | 
 | template <typename T> | 
 | bool Interval<T>::IntersectWith(const Interval& i) { | 
 |   if (Empty()) | 
 |     return false; | 
 |   bool modified = false; | 
 |   if (i.min() > min()) { | 
 |     SetMin(i.min()); | 
 |     modified = true; | 
 |   } | 
 |   if (i.max() < max()) { | 
 |     SetMax(i.max()); | 
 |     modified = true; | 
 |   } | 
 |   return modified; | 
 | } | 
 |  | 
 | template <typename T> | 
 | bool Interval<T>::SpanningUnion(const Interval& i) { | 
 |   if (i.Empty()) | 
 |     return false; | 
 |   if (Empty()) { | 
 |     *this = i; | 
 |     return true; | 
 |   } | 
 |   bool modified = false; | 
 |   if (i.min() < min()) { | 
 |     SetMin(i.min()); | 
 |     modified = true; | 
 |   } | 
 |   if (i.max() > max()) { | 
 |     SetMax(i.max()); | 
 |     modified = true; | 
 |   } | 
 |   return modified; | 
 | } | 
 |  | 
 | template <typename T> | 
 | bool Interval<T>::Difference(const Interval& i, | 
 |                              std::vector<Interval*>* difference) const { | 
 |   if (Empty()) { | 
 |     // <empty> - <i> = <empty> | 
 |     return false; | 
 |   } | 
 |   if (i.Empty()) { | 
 |     // <this> - <empty> = <this> | 
 |     difference->push_back(new Interval(*this)); | 
 |     return false; | 
 |   } | 
 |   if (min() < i.max() && min() >= i.min() && max() > i.max()) { | 
 |     //            [------ this ------) | 
 |     // [------ i ------) | 
 |     //                 [-- result ---) | 
 |     difference->push_back(new Interval(i.max(), max())); | 
 |     return true; | 
 |   } | 
 |   if (max() > i.min() && max() <= i.max() && min() < i.min()) { | 
 |     // [------ this ------) | 
 |     //            [------ i ------) | 
 |     // [- result -) | 
 |     difference->push_back(new Interval(min(), i.min())); | 
 |     return true; | 
 |   } | 
 |   if (min() < i.min() && max() > i.max()) { | 
 |     // [------- this --------) | 
 |     //      [---- i ----) | 
 |     // [ R1 )           [ R2 ) | 
 |     // There are two results: R1 and R2. | 
 |     difference->push_back(new Interval(min(), i.min())); | 
 |     difference->push_back(new Interval(i.max(), max())); | 
 |     return true; | 
 |   } | 
 |   if (min() >= i.min() && max() <= i.max()) { | 
 |     //   [--- this ---) | 
 |     // [------ i --------) | 
 |     // Intersection is <this>, so difference yields the empty interval. | 
 |     // Nothing is appended to *difference. | 
 |     return true; | 
 |   } | 
 |   // No intersection. Append <this>. | 
 |   difference->push_back(new Interval(*this)); | 
 |   return false; | 
 | } | 
 |  | 
 | template <typename T> | 
 | bool Interval<T>::Difference(const Interval& i, | 
 |                              Interval* lo, | 
 |                              Interval* hi) const { | 
 |   // Initialize *lo and *hi to empty | 
 |   *lo = {}; | 
 |   *hi = {}; | 
 |   if (Empty()) | 
 |     return false; | 
 |   if (i.Empty()) { | 
 |     *lo = *this; | 
 |     return false; | 
 |   } | 
 |   if (min() < i.max() && min() >= i.min() && max() > i.max()) { | 
 |     //            [------ this ------) | 
 |     // [------ i ------) | 
 |     //                 [-- result ---) | 
 |     *hi = Interval(i.max(), max()); | 
 |     return true; | 
 |   } | 
 |   if (max() > i.min() && max() <= i.max() && min() < i.min()) { | 
 |     // [------ this ------) | 
 |     //            [------ i ------) | 
 |     // [- result -) | 
 |     *lo = Interval(min(), i.min()); | 
 |     return true; | 
 |   } | 
 |   if (min() < i.min() && max() > i.max()) { | 
 |     // [------- this --------) | 
 |     //      [---- i ----) | 
 |     // [ R1 )           [ R2 ) | 
 |     // There are two results: R1 and R2. | 
 |     *lo = Interval(min(), i.min()); | 
 |     *hi = Interval(i.max(), max()); | 
 |     return true; | 
 |   } | 
 |   if (min() >= i.min() && max() <= i.max()) { | 
 |     //   [--- this ---) | 
 |     // [------ i --------) | 
 |     // Intersection is <this>, so difference yields the empty interval. | 
 |     return true; | 
 |   } | 
 |   *lo = *this;  // No intersection. | 
 |   return false; | 
 | } | 
 |  | 
 | }  // namespace net | 
 |  | 
 | #endif  // NET_QUIC_INTERVAL_H_ |