// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #pragma once namespace rh { namespace util { //--------------------------------------------------------------------------------------------- // Represents value range [a,b), and provides various convenience methods. template class Range { typedef Range THIS_T; public: //----------------------------------------------------------------------------------------- // Construction Range() : m_start(0), m_end(0) {} Range(Range const & range) : m_start(range.m_start), m_end(range.m_end) {} template static Range CreateWithEndpoint(VALUE_TYPE start, VALUE_TYPE end) { return Range(start, end); } template static Range CreateWithLength(VALUE_TYPE start, LENGTH_TYPE len) { return Range(start, start + len); } //----------------------------------------------------------------------------------------- // Operations THIS_T& operator=(THIS_T const & range) { m_start = range.m_start; m_end = range.m_end; return *this; } bool Equals(THIS_T const & range) const { return GetStart() == range.GetStart() && GetEnd() == range.GetEnd(); } bool operator==(THIS_T const & range) const { return Equals(range); } bool operator!=(THIS_T const & range) const { return !Equals(range); } VALUE_TYPE GetStart() const { return m_start; } VALUE_TYPE GetEnd() const { return m_end; } LENGTH_TYPE GetLength() const { return m_end - m_start; } bool IntersectsWith(THIS_T const &range) const { return range.GetStart() < GetEnd() && range.GetEnd() > GetStart(); } bool IntersectsWith(VALUE_TYPE start, VALUE_TYPE end) const { return IntersectsWith(THIS_T(start, end)); } bool Contains(THIS_T const &range) const { return GetStart() <= range.GetStart() && range.GetEnd() <= GetEnd(); } bool IsAdjacentTo(THIS_T const &range) const { return GetEnd() == range.GetStart() || range.GetEnd() == GetStart(); } protected: Range(VALUE_TYPE start, VALUE_TYPE end) : m_start(start), m_end(end) { ASSERT(start <= end); } VALUE_TYPE m_start; VALUE_TYPE m_end; }; //--------------------------------------------------------------------------------------------- // Represents address range [a,b), and provides various convenience methods. class MemRange : public Range { typedef Range BASE_T; public: //----------------------------------------------------------------------------------------- // Construction MemRange() : BASE_T() {} MemRange(void* pvMemStart, UIntNative cbMemLen) : BASE_T(reinterpret_cast(pvMemStart), reinterpret_cast(pvMemStart) + cbMemLen) {} MemRange(void* pvMemStart, void* pvMemEnd) : BASE_T(reinterpret_cast(pvMemStart), reinterpret_cast(pvMemEnd)) {} MemRange(MemRange const & range) : BASE_T(range) { } //----------------------------------------------------------------------------------------- // Operations MemRange& operator=(MemRange const & range) { BASE_T::operator=(range); return *this; } UIntNative GetPageCount() const { UInt8 *pCurPage = ALIGN_DOWN(GetStart(), OS_PAGE_SIZE); UInt8 *pEndPage = ALIGN_UP(GetEnd(), OS_PAGE_SIZE); return (pEndPage - pCurPage) / OS_PAGE_SIZE; } UInt8* GetStartPage() const { return ALIGN_DOWN(GetStart(), OS_PAGE_SIZE); } // The page immediately following the last page contained by this range. UInt8* GetEndPage() const { return ALIGN_UP(GetEnd(), OS_PAGE_SIZE); } MemRange GetPageRange() const { return MemRange(GetStartPage(), GetEndPage()); } }; }// namespace util }// namespace rh