| // Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file | 
 | // for details. All rights reserved. Use of this source code is governed by a | 
 | // BSD-style license that can be found in the LICENSE file. | 
 |  | 
 | #ifndef RUNTIME_VM_COMPILER_FFI_RANGE_H_ | 
 | #define RUNTIME_VM_COMPILER_FFI_RANGE_H_ | 
 |  | 
 | #include "platform/assert.h" | 
 | #include "platform/utils.h" | 
 | #include "vm/allocation.h" | 
 |  | 
 | namespace dart { | 
 |  | 
 | namespace compiler { | 
 |  | 
 | namespace ffi { | 
 |  | 
 | // A non-empty range. | 
 | // | 
 | // Ranges are positive and non-empty. | 
 | // | 
 | // The end is exclusive. | 
 | class Range { | 
 |  public: | 
 |   // Constructs a Range from start (inclusive) and length. | 
 |   // | 
 |   // The resulting range is `[start_inclusive, start_inclusive + length)`. | 
 |   static Range StartAndLength(intptr_t start_inclusive, intptr_t length) { | 
 |     return Range(start_inclusive, start_inclusive + length); | 
 |   } | 
 |  | 
 |   // Constructs a Range from start (inclusive) and end (exclusive). | 
 |   // | 
 |   // The resulting range is `[start_inclusive, end_exclusive)`. | 
 |   static Range StartAndEnd(intptr_t start_inclusive, intptr_t end_exclusive) { | 
 |     return Range(start_inclusive, end_exclusive); | 
 |   } | 
 |  | 
 |   intptr_t start() const { return start_; } | 
 |   intptr_t end_exclusive() const { return end_exclusive_; } | 
 |   intptr_t end_inclusive() const { return end_exclusive_ - 1; } | 
 |  | 
 |   intptr_t Length() const { return end_exclusive_ - start_; } | 
 |  | 
 |   // Returns true iff number is in this range. | 
 |   bool Contains(intptr_t number) const { | 
 |     return start_ <= number && number < end_exclusive_; | 
 |   } | 
 |  | 
 |   // Returns true iff [this] contains [other] completely. | 
 |   bool Contains(const Range& other) const { | 
 |     return Contains(other.start_) && Contains(other.end_inclusive()); | 
 |   } | 
 |  | 
 |   // Returns true iff [this] is completely after [other]. | 
 |   bool After(const Range& other) const { | 
 |     return other.end_exclusive_ <= start_; | 
 |   } | 
 |  | 
 |   // Returns true iff [this] contains some numbers of [other]. | 
 |   bool Overlaps(const Range& other) const { | 
 |     return !this->After(other) && !other.After(*this); | 
 |   } | 
 |  | 
 |   // Returns the intersection of [this] with [other]. | 
 |   // | 
 |   // Requires [this] and [other] to overlap. | 
 |   const Range Intersect(const Range& other) const { | 
 |     ASSERT(Overlaps(other)); | 
 |     return Range(Utils::Maximum(start_, other.start_), | 
 |                  Utils::Minimum(end_exclusive_, other.end_exclusive_)); | 
 |   } | 
 |  | 
 |   // Returns a range moved by [delta]. | 
 |   // | 
 |   // `this.start() - delta` must be positive. | 
 |   const Range Translate(intptr_t delta) const { | 
 |     return Range(start_ + delta, end_exclusive_ + delta); | 
 |   } | 
 |  | 
 |  private: | 
 |   Range(intptr_t start_inclusive, intptr_t end_exclusive) | 
 |       : start_(start_inclusive), end_exclusive_(end_exclusive) { | 
 |     ASSERT(start_ < end_exclusive_); | 
 |   } | 
 |  | 
 |   const intptr_t start_; | 
 |   const intptr_t end_exclusive_; | 
 | }; | 
 |  | 
 | }  // namespace ffi | 
 |  | 
 | }  // namespace compiler | 
 |  | 
 | }  // namespace dart | 
 |  | 
 | #endif  // RUNTIME_VM_COMPILER_FFI_RANGE_H_ |