//===-- VMRange.cpp ---------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/lldb-private.h"

#include "lldb/Core/Stream.h"
#include "lldb/Core/VMRange.h"
#include <algorithm>

using namespace lldb;
using namespace lldb_private;

bool
VMRange::ContainsValue(const VMRange::collection& coll, lldb::addr_t value)
{
    ValueInRangeUnaryPredicate in_range_predicate(value);
    VMRange::const_iterator pos;
    VMRange::const_iterator end = coll.end();
    pos = std::find_if( coll.begin(), end, in_range_predicate );
    if (pos != end)
        return true;
    return false;
}

bool
VMRange::ContainsRange(const VMRange::collection& coll, const VMRange& range)
{
    RangeInRangeUnaryPredicate in_range_predicate(range);
    VMRange::const_iterator pos;
    VMRange::const_iterator end = coll.end();
    pos = std::find_if( coll.begin(), end, in_range_predicate );
    if (pos != end)
        return true;
    return false;
}

uint32_t
VMRange::FindRangeIndexThatContainsValue (const VMRange::collection& coll, lldb::addr_t value)
{
    ValueInRangeUnaryPredicate in_range_predicate(value);
    VMRange::const_iterator begin = coll.begin();
    VMRange::const_iterator end = coll.end();
    VMRange::const_iterator pos = std::find_if (begin, end, in_range_predicate);
    if (pos != end)
        return std::distance (begin, pos);
    return UINT32_MAX;
}

void
VMRange::Dump(Stream *s, lldb::addr_t offset, uint32_t addr_width) const
{
    s->AddressRange(offset + GetBaseAddress(), offset + GetEndAddress(), addr_width);
}

bool
lldb_private::operator== (const VMRange& lhs, const VMRange& rhs)
{
    return lhs.GetBaseAddress() == rhs.GetBaseAddress() && lhs.GetEndAddress() == rhs.GetEndAddress();
}

bool
lldb_private::operator!= (const VMRange& lhs, const VMRange& rhs)
{
    return lhs.GetBaseAddress() != rhs.GetBaseAddress() || lhs.GetEndAddress() != rhs.GetEndAddress();
}

bool
lldb_private::operator< (const VMRange& lhs, const VMRange& rhs)
{
    if (lhs.GetBaseAddress() < rhs.GetBaseAddress())
        return true;
    else if (lhs.GetBaseAddress() > rhs.GetBaseAddress())
        return false;
    return lhs.GetEndAddress() < rhs.GetEndAddress();
}

bool
lldb_private::operator<= (const VMRange& lhs, const VMRange& rhs)
{
    if (lhs.GetBaseAddress() < rhs.GetBaseAddress())
        return true;
    else if (lhs.GetBaseAddress() > rhs.GetBaseAddress())
        return false;
    return lhs.GetEndAddress() <= rhs.GetEndAddress();
}

bool
lldb_private::operator> (const VMRange& lhs, const VMRange& rhs)
{
    if (lhs.GetBaseAddress() > rhs.GetBaseAddress())
        return true;
    else if (lhs.GetBaseAddress() < rhs.GetBaseAddress())
        return false;
    return lhs.GetEndAddress() > rhs.GetEndAddress();
}

bool
lldb_private::operator>= (const VMRange& lhs, const VMRange& rhs)
{
    if (lhs.GetBaseAddress() > rhs.GetBaseAddress())
        return true;
    else if (lhs.GetBaseAddress() < rhs.GetBaseAddress())
        return false;
    return lhs.GetEndAddress() >= rhs.GetEndAddress();
}

