P4C
The P4 Compiler
|
#include <bitrange.h>
Public Types | |
using | FromTo = BitRange::FromTo |
using | MinToMax = BitRange::MinToMax |
using | StartLen = BitRange::StartLen |
using | ZeroToMax = BitRange::ZeroToMax |
Public Member Functions | |
HalfOpenRange (FromTo &&fromTo) | |
HalfOpenRange (int lo, int hi) | |
HalfOpenRange (MinToMax &&) | |
HalfOpenRange (StartLen &&startLen) | |
HalfOpenRange (std::pair< int, int > range) | |
HalfOpenRange (ZeroToMax &&) | |
HalfOpenRange | canonicalize () const |
bool | contains (HalfOpenRange other) const |
bool | contains (int index) const |
bool | empty () const |
int | hiByte () const |
HalfOpenRange | intersectWith (HalfOpenRange a) const |
HalfOpenRange | intersectWith (int l, int h) const |
bool | isHiAligned () const |
bool | isLoAligned () const |
int | loByte () const |
int | nextByte () const |
bool | operator!= (HalfOpenRange other) const |
HalfOpenRange | operator& (HalfOpenRange a) const |
HalfOpenRange | operator&= (HalfOpenRange a) |
bool | operator< (const HalfOpenRange &other) const |
Total ordering, first by lo, then by hi. | |
bool | operator== (HalfOpenRange other) const |
HalfOpenRange | operator| (HalfOpenRange a) const |
HalfOpenRange | operator|= (HalfOpenRange a) |
bool | overlaps (HalfOpenRange a) const |
bool | overlaps (int l, int h) const |
HalfOpenRange< RangeUnit::Bit, Order > | resizedToBits (int size) const |
HalfOpenRange | resizedToBytes (int size) const |
HalfOpenRange< RangeUnit::Bit, Order > | shiftedByBits (int offset) const |
HalfOpenRange< Unit, Order > | shiftedByBytes (int offset) const |
ssize_t | size () const |
void | toJSON (JSONGenerator &json) const |
JSON serialization/deserialization. | |
template<Endian DestOrder> | |
HalfOpenRange< Unit, DestOrder > | toOrder (int spaceSize) const |
template<RangeUnit DestUnit> | |
HalfOpenRange< DestUnit, Order > | toUnit () const |
HalfOpenRange | unionWith (HalfOpenRange a) const |
HalfOpenRange | unionWith (int l, int h) const |
Static Public Member Functions | |
static HalfOpenRange | fromJSON (JSONLoader &json) |
Public Attributes | |
int | hi |
int | lo |
Static Public Attributes | |
static constexpr Endian | order = Order |
static constexpr RangeUnit | unit = Unit |
Friends | |
size_t | hash_value (const HalfOpenRange &r) |
A half-open range of bits or bytes - [lo, hi)
- specified in terms of a specific endian order. Half-open ranges include lo
but do not include hi
, so HalfOpenRange(3, 5)
contains 3
and 4
but not 5
.
Use a half-open range when you want to allow for the possibility that the range may be empty, which may be represented by setting lo
and hi
to the same value. Using a half-open range may also make some algorithms more natural to express, and it may make working with external code easier since half-open ranges are idiomatic in C++.
Note that there are many ways to represent an empty range - (1, 1)
is empty, for example, but so is (2, 2)
. Many operations on HalfOpenRanges will canonicalize the empty range representation, so don't rely on it - just call empty()
to determine if a range is empty.
XXX: Currently, for backwards compatibility, it's possible to construct ranges where lo
is greater than hi
. We should enforce that ranges are consistent; we'll add the necessary checks after the existing code has been audited.
XXX: We should also add checks to avoid integer overflow.
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
rangeA == rangeB
does not imply that rangeA.overlaps(rangeB)
.
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
Convert this range to a range with the specified endian order.
Making this conversion requires specifying the size of the larger space that this range is embedded in. That's because the place we start numbering indices from (the origin, in other words) is changing. For example, given a space with 10 elements, a range of 3 indices within that space may be numbered in two ways as follows: Space: [o o o o o o o o o o] Big endian range: --> [2 3 4] Little endian range: [7 6 5] <-----— We couldn't switch between those numberings without knowing that the space has 10 elements.
Note that this operation may result in integer overflow when dealing with very large ranges. It's generally safe for ZeroToMax as long as the space size is not also near INT_MAX. It's never safe for MinToMax.
DestOrder | The endian order to convert to. |
spaceSize | The size of the space this range is embedded in. |
|
inline |
Convert this range to the smallest enclosing range with the specified unit.
Conversion from bytes to bits is exact, but conversion from bits to bytes is lossy and may cause the size of the range to grow if the bits aren't byte-aligned. If that would be problematic, use isLoAligned()
and isHiAligned()
to check before converting, or just check that converting the result back to bits yields the original range.
This operation will result in integer overflow when dealing with ZeroToMax or MinToMax-sized ranges.
DestUnit | The unit to convert to. |
|
inline |
int P4::HalfOpenRange< Unit, Order >::hi |
The highest numbered index in the range. For Endian::Network, this is the least significant bit or byte; for Endian::Little, it's the most significant. Because this is a half-open range, the range element this index identifies is not included in the range.
int P4::HalfOpenRange< Unit, Order >::lo |
The lowest numbered index in the range. For Endian::Network, this is the most significant bit or byte; for Endian::Little, it's the least significant.