// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_BASE_ADDRESS_REGION_H_
#define V8_BASE_ADDRESS_REGION_H_

#include <iostream>

#include "src/base/macros.h"

namespace v8 {
namespace base {

// Helper class representing an address region of certain size.
class AddressRegion {
 public:
  // Function object that compares the start address of two regions. Usable as
  // compare function on std data structures and algorithms.
  struct StartAddressLess {
    bool operator()(base::AddressRegion a, base::AddressRegion b) const {
      return a.begin() < b.begin();
    }
  };

  using Address = uintptr_t;

  constexpr AddressRegion() = default;

  constexpr AddressRegion(Address address, size_t size)
      : address_(address), size_(size) {}

  Address begin() const { return address_; }
  Address end() const { return address_ + size_; }

  size_t size() const { return size_; }
  void set_size(size_t size) { size_ = size; }

  bool is_empty() const { return size_ == 0; }

  bool contains(Address address) const {
    STATIC_ASSERT(std::is_unsigned<Address>::value);
    return (address - begin()) < size();
  }

  bool contains(Address address, size_t size) const {
    STATIC_ASSERT(std::is_unsigned<Address>::value);
    Address offset = address - begin();
    return (offset < size_) && (offset + size <= size_);
  }

  bool contains(AddressRegion region) const {
    return contains(region.address_, region.size_);
  }

  base::AddressRegion GetOverlap(AddressRegion region) const {
    Address overlap_start = std::max(begin(), region.begin());
    Address overlap_end =
        std::max(overlap_start, std::min(end(), region.end()));
    return {overlap_start, overlap_end - overlap_start};
  }

  bool operator==(AddressRegion other) const {
    return address_ == other.address_ && size_ == other.size_;
  }

  bool operator!=(AddressRegion other) const {
    return address_ != other.address_ || size_ != other.size_;
  }

 private:
  Address address_ = 0;
  size_t size_ = 0;
};
ASSERT_TRIVIALLY_COPYABLE(AddressRegion);

// Construct an AddressRegion from anything providing a {data()} and {size()}
// accessor.
template <typename Container,
          typename = decltype(std::declval<Container>().data()),
          typename = decltype(std::declval<Container>().size())>
inline constexpr AddressRegion AddressRegionOf(Container&& c) {
  return AddressRegion{reinterpret_cast<AddressRegion::Address>(c.data()),
                       sizeof(*c.data()) * c.size()};
}

inline std::ostream& operator<<(std::ostream& out, AddressRegion region) {
  return out << "[" << reinterpret_cast<void*>(region.begin()) << "+"
             << region.size() << "]";
}

}  // namespace base
}  // namespace v8

#endif  // V8_BASE_ADDRESS_REGION_H_
