.. index:: pair: address range; design .. _design-range: Ranges of addresses =================== .. mps:prefix:: design.mps.range Introduction ------------ :mps:tag:`intro` This is the design of the Range module, which implements objects representing address ranges. :mps:tag:`readership` This document is intended for any MPS developer. Requirements ------------ :mps:tag:`req.range` A range object must be able to represent an arbitrary range of addresses that neither starts at :c:macro:`NULL` nor includes the top grain of the address space. :mps:tag:`req.empty` A range object must be able to represent the empty range. :mps:tag:`req.stack-alloc` It must be possible to allocate range objects on the stack: that is, they do not require any heap resource. Interface --------- .. c:type:: RangeStruct *Range :c:type:`Range` is the type of a range. It is an alias for ``RangeStruct *``. :c:type:`RangeStruct` is defined in the header so that it can be inlined in client structures or allocated on the stack. Clients must not depend on its implementation details. .. c:function:: void RangeInit(Range range, Addr base, Addr limit) Initialize a range object to represent the half-open address range between ``base`` (inclusive) and ``limit`` (exclusive). It must be the case that ``base <= limit``. If ``base == limit`` then the range is empty. .. c:function:: void RangeCopy(Range dest, Range src) Initialize ``dest`` to be a copy of ``src``. .. c:function:: void RangeInitSize(Range range, Addr base, Size size) Initialize a range object to represent the half-open address range between ``base`` (inclusive) and ``base + size`` (exclusive). If ``size == 0`` then the range is empty. .. c:function:: void RangeFinish(Range range) Finish a range object. Because a range object uses no heap resources (:mps:ref:`.req.stack-alloc`) it is not necessary to call this. However, clients may wish to do so in order to ensure that the range object is invalid. .. c:function:: Addr RangeBase(Range range) Return the base of the range. (This is implemented as a macro, but there is a function too.) .. c:function:: Addr RangeLimit(Range range) Return the limit of the range. (This is implemented as a macro, but there is a function too.) .. c:function:: Size RangeSize(Range range) Return the size of the range. (This is implemented as a macro, but there is a function too. The macro evaluates its argument twice.) .. c:function:: Bool RangeContains(Range range, Addr addr) Return :c:macro:`TRUE` if ``addr`` belongs to the range, or :c:macro:`FALSE` if it does not. (This is implemented as a macro, but there is a function too. The macro evaluates its arguments twice.) .. c:function:: Bool RangeIsEmpty(Range range) Return :c:macro:`TRUE` if the range is empty (contains no addresses), :c:macro:`FALSE` otherwise. (This is implemented as a macro, but there is a function too. The macro evaluates its argument twice.) .. c:function:: Bool RangeIsAligned(Range range, Align alignment) Return :c:macro:`TRUE` if the base and limit of the range are both aligned to the given alignment, or :c:macro:`FALSE` if either is not. .. c:function:: Bool RangesOverlap(Range range1, Range range2) Return :c:macro:`TRUE` if the two ranges overlap (have at least one address in common), or :c:macro:`FALSE` if they do not. Note that ranges [*A*, *B*) and [*B*, *C*) do not overlap. .. c:function:: Bool RangesNest(Range outer, Range inner) Return :c:macro:`TRUE` if all addresses in ``inner`` are also in ``outer``, or :c:macro:`FALSE` otherwise.