P4C
The P4 Compiler
Loading...
Searching...
No Matches
lib/bitrange.h
1/*
2 * SPDX-FileCopyrightText: 2013 Barefoot Networks, Inc.
3 * Copyright 2013-present Barefoot Networks, Inc.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8#ifndef LIB_BITRANGE_H_
9#define LIB_BITRANGE_H_
10
11#include <algorithm>
12#include <iosfwd>
13#include <limits>
14#include <optional>
15#include <utility>
16
17#include "absl/numeric/bits.h"
18#include "bitvec.h"
19#include "cstring.h"
20#include "exceptions.h"
21#include "hash.h"
22
23namespace P4 {
24
25/* iterate over ranges of contiguous bits in a bitvector */
26class bitranges {
27 bitvec tmp;
28 const bitvec &bits;
29 struct iter {
30 bool valid = true;
32 std::pair<int, int> range;
33
34 iter &operator++() {
35 if (ptr) {
36 range.first = range.second = ptr.index();
37 while (++ptr && range.second + 1 == ptr.index()) ++range.second;
38 } else {
39 valid = false;
40 }
41 return *this;
42 }
43 std::pair<int, int> operator*() { return range; }
44 bool operator==(iter &a) const { return valid == a.valid && ptr == a.ptr; }
45 bool operator!=(iter &a) const { return !(*this == a); }
46 explicit iter(bitvec::const_bitref p) : ptr(p) { ++*this; }
47 };
48
49 public:
50 explicit bitranges(const bitvec &b) : bits(b) {}
51 explicit bitranges(bitvec &&b) : tmp(b), bits(tmp) {}
52 explicit bitranges(uintptr_t b) : tmp(b), bits(tmp) {}
53 iter begin() const { return iter(bits.begin()); }
54 iter end() const { return iter(bits.end()); }
55};
56
57class JSONGenerator;
58class JSONLoader;
59
60namespace BitRange {
61
62namespace Detail {
69constexpr inline int divideFloor(int dividend, int divisor) {
70#if defined(__GNUC__) || defined(__clang__)
71 // Code to enable compiler folding when the divisor is a power-of-two compile-time constant
72 // In this case, compiler should fold to a right-shift
73 // FIXME: Replace absl with std after moving to C++20
74 unsigned u_divisor = static_cast<unsigned>(divisor);
75 if (__builtin_constant_p(u_divisor) && absl::has_single_bit(u_divisor))
76 return dividend >> (absl::bit_width(u_divisor) - 1);
77#endif // defined(__GNUC__) || defined(__clang__)
78
79 const int quotient = dividend / divisor;
80 const int remainder = dividend % divisor;
81 if ((remainder != 0) && ((remainder < 0) != (divisor < 0))) return quotient - 1;
82 return quotient;
83}
84
92constexpr int modulo(int dividend, int divisor) {
93 return (dividend % divisor) * ((dividend < 0) != (divisor < 0) ? -1 : 1);
94}
95
109constexpr inline int moduloFloor(const int dividend, const int divisor) {
110#if defined(__GNUC__) || defined(__clang__)
111 // Code to enable compiler folding when the divisor is a power-of-two compile-time constant
112 // In this case, compiler should fold to a bitwise-and
113 // FIXME: Replace absl with std after moving to C++20
114 if (__builtin_constant_p(divisor) && absl::has_single_bit(static_cast<unsigned>(divisor)))
115 return dividend & (divisor - 1);
116#endif // defined(__GNUC__) || defined(__clang__)
117
118 const int remainder = modulo(dividend, divisor);
119 if (remainder == 0 || dividend >= 0) return remainder;
120 return divisor - remainder;
121}
122} // namespace Detail
123
133struct FromTo {
134 FromTo(int from, int to) : from(from), to(to) {}
135 FromTo(const FromTo &) = delete;
136 FromTo &operator=(const FromTo &) = delete;
137 const int from;
138 const int to;
139};
140
150struct StartLen {
151 StartLen(int start, int len) : start(start), len(len) {}
152 StartLen(const StartLen &) = delete;
153 StartLen &operator=(const StartLen &) = delete;
154 const int start;
155 const int len;
156};
157
182struct ZeroToMax {};
183
201struct MinToMax {};
202
204void rangeToJSON(JSONGenerator &json, int lo, int hi);
205std::pair<int, int> rangeFromJSON(JSONLoader &json);
206
207} // namespace BitRange
208
210enum class RangeUnit : uint8_t {
211 Bit = 0,
212 Byte = 1
213};
214
216enum class Endian : uint8_t {
217 Network = 0,
218 Little = 1,
219};
220
244template <RangeUnit Unit, Endian Order>
245struct HalfOpenRange {
246 static constexpr RangeUnit unit = Unit;
247 static constexpr Endian order = Order;
248
249 using FromTo = BitRange::FromTo;
250 using StartLen = BitRange::StartLen;
251 using ZeroToMax = BitRange::ZeroToMax;
252 using MinToMax = BitRange::MinToMax;
253
254 HalfOpenRange() : lo(0), hi(0) {}
255 HalfOpenRange(int lo, int hi) : lo(lo), hi(hi) {}
256 HalfOpenRange(FromTo &&fromTo) // NOLINT(runtime/explicit)
257 : lo(fromTo.from), hi(fromTo.to + 1) {}
258 HalfOpenRange(StartLen &&startLen) // NOLINT(runtime/explicit)
259 : lo(startLen.start), hi(startLen.start + startLen.len) {}
260 HalfOpenRange(ZeroToMax &&) // NOLINT(runtime/explicit)
261 : lo(0), hi(std::numeric_limits<int>::max()) {}
262 HalfOpenRange(MinToMax &&) // NOLINT(runtime/explicit)
263 : lo(std::numeric_limits<int>::min()), hi(std::numeric_limits<int>::max()) {}
264 explicit HalfOpenRange(std::pair<int, int> range) : lo(range.first), hi(range.second) {}
265
267 ssize_t size() const { return ssize_t(hi) - ssize_t(lo); }
268
271 HalfOpenRange canonicalize() const {
272 if (empty()) return HalfOpenRange(0, 0);
273 return *this;
274 }
275
279 HalfOpenRange<RangeUnit::Bit, Order> resizedToBits(int size) const {
280 if (empty()) return HalfOpenRange<RangeUnit::Bit, Order>(0, size);
281 auto asBits = toUnit<RangeUnit::Bit>();
282 return {asBits.lo, asBits.lo + size};
283 }
284
287 HalfOpenRange resizedToBytes(int size) const {
288 const int resizedLo = empty() ? 0 : lo;
289 if (Unit == RangeUnit::Byte) return {resizedLo, resizedLo + size};
290 return {resizedLo, resizedLo + size * 8};
291 }
292
296 HalfOpenRange<RangeUnit::Bit, Order> shiftedByBits(int offset) const {
297 if (empty()) return HalfOpenRange<RangeUnit::Bit, Order>();
298 auto asBits = toUnit<RangeUnit::Bit>();
299 return {asBits.lo + offset, asBits.hi + offset};
300 }
301
305 HalfOpenRange<Unit, Order> shiftedByBytes(int offset) const {
306 if (empty()) return HalfOpenRange();
307 if (Unit == RangeUnit::Byte) return {lo + offset, hi + offset};
308 return {lo + offset * 8, hi + offset * 8};
309 }
310
312 int loByte() const {
313 if (empty()) return 0;
314 return Unit == RangeUnit::Byte ? lo : BitRange::Detail::divideFloor(lo, 8);
315 }
316
318 int hiByte() const {
319 if (empty()) return 0;
320 return Unit == RangeUnit::Byte ? hi - 1 : BitRange::Detail::divideFloor(hi - 1, 8);
321 }
322
326 int nextByte() const { return empty() ? 0 : hiByte() + 1; }
327
330 bool isLoAligned() const {
331 return (empty() || Unit == RangeUnit::Byte) ? true
332 : BitRange::Detail::moduloFloor(lo, 8) == 0;
333 }
334
338 bool isHiAligned() const {
339 return (empty() || Unit == RangeUnit::Byte) ? true
340 : BitRange::Detail::moduloFloor(hi, 8) == 0;
341 }
342
343 bool operator==(HalfOpenRange other) const {
344 if (empty()) return other.empty();
345 return other.lo == lo && other.hi == hi;
346 }
347 bool operator!=(HalfOpenRange other) const { return !(*this == other); }
348
350 bool empty() const { return lo == hi; }
351
353 bool contains(int index) const { return index >= lo && index < hi; }
354
357 bool contains(HalfOpenRange other) const { return intersectWith(other) == other; }
358
362 bool overlaps(HalfOpenRange a) const { return !intersectWith(a).empty(); }
363 bool overlaps(int l, int h) const { return !intersectWith(l, h).empty(); }
364
368 HalfOpenRange intersectWith(HalfOpenRange a) const { return intersectWith(a.lo, a.hi); }
369 HalfOpenRange intersectWith(int l, int h) const {
370 HalfOpenRange rv = {std::max(lo, l), std::min(hi, h)};
371 if (rv.hi <= rv.lo) return {0, 0};
372 return rv;
373 }
374 HalfOpenRange operator&(HalfOpenRange a) const { return intersectWith(a); }
375 HalfOpenRange operator&=(HalfOpenRange a) {
376 *this = intersectWith(a);
377 return *this;
378 }
379
384 HalfOpenRange unionWith(HalfOpenRange a) const { return unionWith(a.lo, a.hi); }
385 HalfOpenRange unionWith(int l, int h) const {
386 if (empty()) return {l, h};
387 if (l == h) return *this;
388 return HalfOpenRange(std::min(lo, l), std::max(hi, h));
389 }
390 HalfOpenRange operator|(HalfOpenRange a) const { return unionWith(a); }
391 HalfOpenRange operator|=(HalfOpenRange a) {
392 *this = unionWith(a);
393 return *this;
394 }
395
418 template <Endian DestOrder>
419 HalfOpenRange<Unit, DestOrder> toOrder(int spaceSize) const {
420 if (DestOrder == Order) return HalfOpenRange<Unit, DestOrder>(lo, hi);
421 switch (DestOrder) {
422 case Endian::Network:
423 case Endian::Little:
424 return HalfOpenRange<Unit, DestOrder>(spaceSize - hi, spaceSize - lo);
425 }
426 BUG("Unexpected ordering");
427 }
428
444 template <RangeUnit DestUnit>
445 HalfOpenRange<DestUnit, Order> toUnit() const {
446 if (DestUnit == Unit) return HalfOpenRange<DestUnit, Order>(lo, hi);
447 if (empty()) return HalfOpenRange<DestUnit, Order>();
448 switch (DestUnit) {
449 case RangeUnit::Bit:
450 return HalfOpenRange<DestUnit, Order>(lo * 8, hi * 8);
451 case RangeUnit::Byte:
452 return HalfOpenRange<DestUnit, Order>(loByte(), nextByte());
453 }
454 BUG("Unexpected unit");
455 }
456
458 void toJSON(JSONGenerator &json) const { BitRange::rangeToJSON(json, lo, hi); }
459 static HalfOpenRange fromJSON(JSONLoader &json) {
460 return HalfOpenRange(BitRange::rangeFromJSON(json));
461 }
462
464 bool operator<(const HalfOpenRange &other) const {
465 if (lo != other.lo) return lo < other.lo;
466 return hi < other.hi;
467 }
468
469 friend size_t hash_value(const HalfOpenRange &r) { return Util::Hash{}(r.lo, r.hi); }
470
474 int lo;
475
480 int hi;
481};
482
504template <RangeUnit Unit, Endian Order>
505struct ClosedRange {
506 static constexpr RangeUnit unit = Unit;
507 static constexpr Endian order = Order;
508
509 using FromTo = BitRange::FromTo;
510 using StartLen = BitRange::StartLen;
511 using ZeroToMax = BitRange::ZeroToMax;
512 using MinToMax = BitRange::MinToMax;
513
514 ClosedRange() : lo(0), hi(0) {} // FIXME: default is [0,0]? This is just wrong ...
515 constexpr ClosedRange(int lo, int hi) : lo(lo), hi(hi) {}
516 ClosedRange(FromTo &&fromTo) // NOLINT(runtime/explicit)
517 : lo(fromTo.from), hi(fromTo.to) {}
518 ClosedRange(StartLen &&startLen) // NOLINT(runtime/explicit)
519 : lo(startLen.start), hi(startLen.start + startLen.len - 1) {}
520 ClosedRange(ZeroToMax &&) // NOLINT(runtime/explicit)
521 : lo(0), hi(std::numeric_limits<int>::max() - 1) {}
522 ClosedRange(MinToMax &&) // NOLINT(runtime/explicit)
523 : lo(std::numeric_limits<int>::min()), hi(std::numeric_limits<int>::max() - 1) {}
524 explicit ClosedRange(std::pair<int, int> range) : lo(range.first), hi(range.second) {}
525 ClosedRange(const HalfOpenRange<Unit, Order> &r) // NOLINT(runtime/explicit)
526 : lo(r.lo), hi(r.hi - 1) {
527 BUG_CHECK(!r.empty(), "can't convert empty range to Closed");
528 }
529
531 ssize_t size() const { return ssize_t(hi) - ssize_t(lo) + 1; }
532
534 ClosedRange<RangeUnit::Bit, Order> resizedToBits(int size) const {
535 BUG_CHECK(size != 0, "Resizing ClosedRange to zero size");
536 auto asBits = toUnit<RangeUnit::Bit>();
537 return {asBits.lo, asBits.lo + size - 1};
538 }
539
541 ClosedRange resizedToBytes(int size) const {
542 BUG_CHECK(size != 0, "Resizing ClosedRange to zero size");
543 if (Unit == RangeUnit::Byte) return {lo, lo + size - 1};
544 return {lo, lo + size * 8 - 1};
545 }
546
548 ClosedRange<RangeUnit::Bit, Order> shiftedByBits(int offset) const {
549 auto asBits = toUnit<RangeUnit::Bit>();
550 return {asBits.lo + offset, asBits.hi + offset};
551 }
552
554 ClosedRange shiftedByBytes(int offset) const {
555 if (Unit == RangeUnit::Byte) return {lo + offset, hi + offset};
556 return {lo + offset * 8, hi + offset * 8};
557 }
558
560 int loByte() const {
561 return Unit == RangeUnit::Byte ? lo : BitRange::Detail::divideFloor(lo, 8);
562 }
563
565 int hiByte() const {
566 return Unit == RangeUnit::Byte ? hi : BitRange::Detail::divideFloor(hi, 8);
567 }
568
570 int nextByte() const { return hiByte() + 1; }
571
573 bool isLoAligned() const {
574 return Unit == RangeUnit::Byte ? true : BitRange::Detail::moduloFloor(lo, 8) == 0;
575 }
576
578 bool isHiAligned() const {
579 return Unit == RangeUnit::Byte ? true : BitRange::Detail::moduloFloor(hi + 1, 8) == 0;
580 }
581
582 bool operator==(ClosedRange other) const { return (other.lo == lo) && (other.hi == hi); }
583 bool operator!=(ClosedRange other) const { return !(*this == other); }
584
586 bool contains(int index) const { return (index >= lo) && (index <= hi); }
587
589 bool contains(ClosedRange other) const {
590 auto intersection = intersectWith(other);
591 return intersection.lo == other.lo && intersection.size() == other.size();
592 }
593
595 bool overlaps(ClosedRange a) const { return !intersectWith(a).empty(); }
596 bool overlaps(int l, int h) const { return !intersectWith(l, h).empty(); }
597
603 return intersectWith(a.lo, a.hi);
604 }
605 HalfOpenRange<Unit, Order> intersectWith(int l, int h) const {
606 return HalfOpenRange<Unit, Order>(lo, hi + 1)
608 }
609 HalfOpenRange<Unit, Order> operator&(ClosedRange a) const { return intersectWith(a); }
610 HalfOpenRange<Unit, Order> operator&=(ClosedRange a) {
611 *this = intersectWith(a);
612 return *this;
613 }
614
616 ClosedRange unionWith(ClosedRange a) const { return unionWith(a.lo, a.hi); }
617 ClosedRange unionWith(int l, int h) const {
618 return ClosedRange(std::min(lo, l), std::max(hi, h));
619 }
620 ClosedRange operator|(ClosedRange a) const { return unionWith(a); }
621 ClosedRange operator|=(ClosedRange a) {
622 *this = unionWith(a);
623 return *this;
624 }
625
627 template <Endian DestOrder>
628 ClosedRange<Unit, DestOrder> toOrder(int spaceSize) const {
629 BUG_CHECK(spaceSize > 0, "Can't represent an empty range");
630 if (DestOrder == Order) return ClosedRange<Unit, DestOrder>(lo, hi);
631 switch (DestOrder) {
632 case Endian::Network:
633 case Endian::Little:
634 return ClosedRange<Unit, DestOrder>((spaceSize - 1) - hi, (spaceSize - 1) - lo);
635 }
636 BUG("Unexpected ordering");
637 }
638
640 template <RangeUnit DestUnit>
641 ClosedRange<DestUnit, Order> toUnit() const {
642 if (DestUnit == Unit) return ClosedRange<DestUnit, Order>(lo, hi);
643 switch (DestUnit) {
644 case RangeUnit::Bit:
645 return ClosedRange<DestUnit, Order>(lo * 8, hi * 8 + 7);
646 case RangeUnit::Byte:
647 return ClosedRange<DestUnit, Order>(loByte(), hiByte());
648 }
649 BUG("Unexpected unit");
650 }
651
653 void toJSON(JSONGenerator &json) const { BitRange::rangeToJSON(json, lo, hi); }
654 static ClosedRange fromJSON(JSONLoader &json) {
655 return ClosedRange(BitRange::rangeFromJSON(json));
656 }
657
659 bool operator<(const ClosedRange &other) const {
660 if (lo != other.lo) return lo < other.lo;
661 return hi < other.hi;
662 }
663
664 friend size_t hash_value(const ClosedRange &r) { return Util::Hash{}(r.lo, r.hi); }
665
668 cstring formatAsSlice(int spaceSize) const {
669 auto r = toOrder<Endian::Little>(spaceSize);
670 auto hi = r.hi;
671 auto lo = r.lo;
672 if (Unit == RangeUnit::Byte) {
673 lo = lo * 8;
674 hi = hi * 8 + 7;
675 } else {
676 BUG_CHECK(Unit == RangeUnit::Bit, "mismatch range units");
677 }
678 std::stringstream out;
679 out << "[" << hi << ":" << lo << "]";
680 return cstring(out.str());
681 }
682
686 int lo;
687
692 int hi;
693};
694
707template <RangeUnit Unit, Endian Order>
708std::pair<HalfOpenRange<Unit, Order>, HalfOpenRange<Unit, Order>> operator-(
710 HalfOpenRange<Unit, Order> empty = {0, 0};
711 HalfOpenRange<Unit, Order> intersect = left.intersectWith(right);
712 if (intersect.empty())
713 return left.lo < right.lo ? std::make_pair(left, empty) : std::make_pair(empty, left);
714
716 left.lo == intersect.lo ? empty : BitRange::FromTo(left.lo, intersect.lo - 1);
718 left.hi == intersect.hi ? empty : BitRange::FromTo(intersect.hi, left.hi - 1);
719
720 return {lower, upper};
721}
722
725template <RangeUnit Unit, Endian Order>
726std::pair<HalfOpenRange<Unit, Order>, HalfOpenRange<Unit, Order>> operator-(
728 return toHalfOpenRange(left) - toHalfOpenRange(right);
729}
730
733template <RangeUnit Unit, Endian Order>
735 return HalfOpenRange<Unit, Order>(closedRange.lo, closedRange.hi + 1);
736}
737
740template <RangeUnit Unit, Endian Order>
741std::optional<ClosedRange<Unit, Order>> toClosedRange(HalfOpenRange<Unit, Order> halfOpenRange) {
742 if (halfOpenRange.empty()) return std::nullopt;
743 return ClosedRange<Unit, Order>(halfOpenRange.lo, halfOpenRange.hi - 1);
744}
745
749
753
757
761
762std::ostream &toStream(std::ostream &out, RangeUnit unit, Endian order, int lo, int hi,
763 bool closed);
764
765template <RangeUnit Unit, Endian Order>
766std::ostream &operator<<(std::ostream &out, const HalfOpenRange<Unit, Order> &range) {
767 return toStream(out, Unit, Order, range.lo, range.hi, false);
768}
769
770template <RangeUnit Unit, Endian Order>
771std::ostream &operator<<(std::ostream &out, const ClosedRange<Unit, Order> &range) {
772 return toStream(out, Unit, Order, range.lo, range.hi, true);
773}
774
775} // namespace P4
776
777// Hashing specializations
778namespace std {
779template <P4::RangeUnit Unit, P4::Endian Order>
780struct hash<P4::HalfOpenRange<Unit, Order>> {
781 std::size_t operator()(const P4::HalfOpenRange<Unit, Order> &r) const {
782 return P4::Util::Hash{}(r.lo, r.hi);
783 }
784};
785
786template <P4::RangeUnit Unit, P4::Endian Order>
787struct hash<P4::ClosedRange<Unit, Order>> {
788 std::size_t operator()(const P4::ClosedRange<Unit, Order> &r) const {
789 return P4::Util::Hash{}(r.lo, r.hi);
790 }
791};
792} // namespace std
793
794namespace P4::Util {
795template <RangeUnit Unit, Endian Order>
796struct Hasher<HalfOpenRange<Unit, Order>> {
797 size_t operator()(const HalfOpenRange<Unit, Order> &r) const {
798 return Util::Hash{}(r.lo, r.hi);
799 }
800};
801
802template <RangeUnit Unit, Endian Order>
803struct Hasher<ClosedRange<Unit, Order>> {
804 size_t operator()(const ClosedRange<Unit, Order> &r) const { return Util::Hash{}(r.lo, r.hi); }
805};
806} // namespace P4::Util
807
808#endif /* LIB_BITRANGE_H_ */
Definition json_generator.h:30
Definition json_loader.h:34
Definition bitvec.h:192
Definition bitvec.h:111
Definition cstring.h:76
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:13
HalfOpenRange< RangeUnit::Byte, Endian::Network > nw_byteinterval
Convenience typedefs for half-open ranges in bytes.
Definition lib/bitrange.h:759
ClosedRange< RangeUnit::Bit, Endian::Network > nw_bitrange
Convenience typedefs for closed ranges in bits.
Definition lib/bitrange.h:747
Endian
An ordering for bits or bytes.
Definition lib/bitrange.h:216
@ Little
Most significant bit/byte first.
Definition lib/bitrange.h:218
std::optional< ClosedRange< Unit, Order > > toClosedRange(HalfOpenRange< Unit, Order > halfOpenRange)
Definition lib/bitrange.h:741
ClosedRange< RangeUnit::Byte, Endian::Network > nw_byterange
Convenience typedefs for closed ranges in bytes.
Definition lib/bitrange.h:751
HalfOpenRange< RangeUnit::Bit, Endian::Network > nw_bitinterval
Convenience typedefs for half-open ranges in bits.
Definition lib/bitrange.h:755
RangeUnit
Units in which a range can be specified.
Definition lib/bitrange.h:210
std::pair< HalfOpenRange< Unit, Order >, HalfOpenRange< Unit, Order > > operator-(HalfOpenRange< Unit, Order > left, HalfOpenRange< Unit, Order > right)
Definition lib/bitrange.h:708
HalfOpenRange< Unit, Order > toHalfOpenRange(ClosedRange< Unit, Order > closedRange)
Definition lib/bitrange.h:734
Definition bson.cpp:69
STL namespace.
Definition lib/bitrange.h:133
Definition lib/bitrange.h:201
Definition lib/bitrange.h:150
Definition lib/bitrange.h:182
Definition lib/bitrange.h:505
bool isHiAligned() const
Definition lib/bitrange.h:578
bool contains(ClosedRange other) const
Definition lib/bitrange.h:589
ClosedRange< DestUnit, Order > toUnit() const
Definition lib/bitrange.h:641
bool overlaps(ClosedRange a) const
Definition lib/bitrange.h:595
ClosedRange< Unit, DestOrder > toOrder(int spaceSize) const
Definition lib/bitrange.h:628
int loByte() const
Definition lib/bitrange.h:560
ClosedRange resizedToBytes(int size) const
Definition lib/bitrange.h:541
bool isLoAligned() const
Definition lib/bitrange.h:573
int hiByte() const
Definition lib/bitrange.h:565
HalfOpenRange< Unit, Order > intersectWith(ClosedRange a) const
Definition lib/bitrange.h:602
void toJSON(JSONGenerator &json) const
JSON serialization/deserialization.
Definition lib/bitrange.h:653
ClosedRange< RangeUnit::Bit, Order > shiftedByBits(int offset) const
Definition lib/bitrange.h:548
ClosedRange< RangeUnit::Bit, Order > resizedToBits(int size) const
Definition lib/bitrange.h:534
cstring formatAsSlice(int spaceSize) const
Definition lib/bitrange.h:668
ClosedRange shiftedByBytes(int offset) const
Definition lib/bitrange.h:554
int lo
Definition lib/bitrange.h:686
ssize_t size() const
Definition lib/bitrange.h:531
bool operator<(const ClosedRange &other) const
Definition lib/bitrange.h:659
int hi
Definition lib/bitrange.h:692
bool contains(int index) const
Definition lib/bitrange.h:586
ClosedRange unionWith(ClosedRange a) const
Definition lib/bitrange.h:616
int nextByte() const
Definition lib/bitrange.h:570
Definition lib/bitrange.h:245
bool contains(int index) const
Definition lib/bitrange.h:353
int hi
Definition lib/bitrange.h:480
bool operator<(const HalfOpenRange &other) const
Total ordering, first by lo, then by hi.
Definition lib/bitrange.h:464
int hiByte() const
Definition lib/bitrange.h:318
HalfOpenRange< Unit, DestOrder > toOrder(int spaceSize) const
Definition lib/bitrange.h:419
bool isHiAligned() const
Definition lib/bitrange.h:338
bool overlaps(HalfOpenRange a) const
Definition lib/bitrange.h:362
int nextByte() const
Definition lib/bitrange.h:326
HalfOpenRange< Unit, Order > shiftedByBytes(int offset) const
Definition lib/bitrange.h:305
bool contains(HalfOpenRange other) const
Definition lib/bitrange.h:357
bool isLoAligned() const
Definition lib/bitrange.h:330
HalfOpenRange< DestUnit, Order > toUnit() const
Definition lib/bitrange.h:445
int loByte() const
Definition lib/bitrange.h:312
ssize_t size() const
Definition lib/bitrange.h:267
void toJSON(JSONGenerator &json) const
JSON serialization/deserialization.
Definition lib/bitrange.h:458
HalfOpenRange< RangeUnit::Bit, Order > resizedToBits(int size) const
Definition lib/bitrange.h:279
bool empty() const
Definition lib/bitrange.h:350
HalfOpenRange unionWith(HalfOpenRange a) const
Definition lib/bitrange.h:384
HalfOpenRange canonicalize() const
Definition lib/bitrange.h:271
int lo
Definition lib/bitrange.h:474
HalfOpenRange< RangeUnit::Bit, Order > shiftedByBits(int offset) const
Definition lib/bitrange.h:296
HalfOpenRange resizedToBytes(int size) const
Definition lib/bitrange.h:287
HalfOpenRange intersectWith(HalfOpenRange a) const
Definition lib/bitrange.h:368
Definition hash.h:125
Definition hash.h:123