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