| // 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_ |