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 "exceptions.h"
20#include "hash.h"
21
22namespace P4 {
23
24/* iterate over ranges of contiguous bits in a bitvector */
25class bitranges {
26 bitvec tmp;
27 const bitvec &bits;
28 struct iter {
29 bool valid = true;
31 std::pair<int, int> range;
32
33 iter &operator++() {
34 if (ptr) {
35 range.first = range.second = ptr.index();
36 while (++ptr && range.second + 1 == ptr.index()) ++range.second;
37 } else {
38 valid = false;
39 }
40 return *this;
41 }
42 std::pair<int, int> operator*() { return range; }
43 bool operator==(iter &a) const { return valid == a.valid && ptr == a.ptr; }
44 bool operator!=(iter &a) const { return !(*this == a); }
45 explicit iter(bitvec::const_bitref p) : ptr(p) { ++*this; }
46 };
47
48 public:
49 explicit bitranges(const bitvec &b) : bits(b) {}
50 explicit bitranges(bitvec &&b) : tmp(b), bits(tmp) {}
51 explicit bitranges(uintptr_t b) : tmp(b), bits(tmp) {}
52 iter begin() const { return iter(bits.begin()); }
53 iter end() const { return iter(bits.end()); }
54};
55
56class JSONGenerator;
57class JSONLoader;
58
59namespace BitRange {
60
61namespace Detail {
68constexpr inline int divideFloor(int dividend, int divisor) {
69#if defined(__GNUC__) || defined(__clang__)
70 // Code to enable compiler folding when the divisor is a power-of-two compile-time constant
71 // In this case, compiler should fold to a right-shift
72 // FIXME: Replace absl with std after moving to C++20
73 unsigned u_divisor = static_cast<unsigned>(divisor);
74 if (__builtin_constant_p(u_divisor) && absl::has_single_bit(u_divisor))
75 return dividend >> (absl::bit_width(u_divisor) - 1);
76#endif // defined(__GNUC__) || defined(__clang__)
77
78 const int quotient = dividend / divisor;
79 const int remainder = dividend % divisor;
80 if ((remainder != 0) && ((remainder < 0) != (divisor < 0))) return quotient - 1;
81 return quotient;
82}
83
91constexpr int modulo(int dividend, int divisor) {
92 return (dividend % divisor) * ((dividend < 0) != (divisor < 0) ? -1 : 1);
93}
94
108constexpr inline int moduloFloor(const int dividend, const int divisor) {
109#if defined(__GNUC__) || defined(__clang__)
110 // Code to enable compiler folding when the divisor is a power-of-two compile-time constant
111 // In this case, compiler should fold to a bitwise-and
112 // FIXME: Replace absl with std after moving to C++20
113 if (__builtin_constant_p(divisor) && absl::has_single_bit(static_cast<unsigned>(divisor)))
114 return dividend & (divisor - 1);
115#endif // defined(__GNUC__) || defined(__clang__)
116
117 const int remainder = modulo(dividend, divisor);
118 if (remainder == 0 || dividend >= 0) return remainder;
119 return divisor - remainder;
120}
121} // namespace Detail
122
132struct FromTo {
133 FromTo(int from, int to) : from(from), to(to) {}
134 FromTo(const FromTo &) = delete;
135 FromTo &operator=(const FromTo &) = delete;
136 const int from;
137 const int to;
138};
139
149struct StartLen {
150 StartLen(int start, int len) : start(start), len(len) {}
151 StartLen(const StartLen &) = delete;
152 StartLen &operator=(const StartLen &) = delete;
153 const int start;
154 const int len;
155};
156
181struct ZeroToMax {};
182
200struct MinToMax {};
201
203void rangeToJSON(JSONGenerator &json, int lo, int hi);
204std::pair<int, int> rangeFromJSON(JSONLoader &json);
205
206} // namespace BitRange
207
209enum class RangeUnit : uint8_t {
210 Bit = 0,
211 Byte = 1
212};
213
215enum class Endian : uint8_t {
216 Network = 0,
217 Little = 1,
218};
219
243template <RangeUnit Unit, Endian Order>
244struct HalfOpenRange {
245 static constexpr RangeUnit unit = Unit;
246 static constexpr Endian order = Order;
247
248 using FromTo = BitRange::FromTo;
249 using StartLen = BitRange::StartLen;
250 using ZeroToMax = BitRange::ZeroToMax;
251 using MinToMax = BitRange::MinToMax;
252
253 HalfOpenRange() : lo(0), hi(0) {}
254 HalfOpenRange(int lo, int hi) : lo(lo), hi(hi) {}
255 HalfOpenRange(FromTo &&fromTo) // NOLINT(runtime/explicit)
256 : lo(fromTo.from), hi(fromTo.to + 1) {}
257 HalfOpenRange(StartLen &&startLen) // NOLINT(runtime/explicit)
258 : lo(startLen.start), hi(startLen.start + startLen.len) {}
259 HalfOpenRange(ZeroToMax &&) // NOLINT(runtime/explicit)
260 : lo(0), hi(std::numeric_limits<int>::max()) {}
261 HalfOpenRange(MinToMax &&) // NOLINT(runtime/explicit)
262 : lo(std::numeric_limits<int>::min()), hi(std::numeric_limits<int>::max()) {}
263 explicit HalfOpenRange(std::pair<int, int> range) : lo(range.first), hi(range.second) {}
264
266 ssize_t size() const { return ssize_t(hi) - ssize_t(lo); }
267
270 HalfOpenRange canonicalize() const {
271 if (empty()) return HalfOpenRange(0, 0);
272 return *this;
273 }
274
278 HalfOpenRange<RangeUnit::Bit, Order> resizedToBits(int size) const {
279 if (empty()) return HalfOpenRange<RangeUnit::Bit, Order>(0, size);
280 auto asBits = toUnit<RangeUnit::Bit>();
281 return {asBits.lo, asBits.lo + size};
282 }
283
286 HalfOpenRange resizedToBytes(int size) const {
287 const int resizedLo = empty() ? 0 : lo;
288 if (Unit == RangeUnit::Byte) return {resizedLo, resizedLo + size};
289 return {resizedLo, resizedLo + size * 8};
290 }
291
295 HalfOpenRange<RangeUnit::Bit, Order> shiftedByBits(int offset) const {
296 if (empty()) return HalfOpenRange<RangeUnit::Bit, Order>();
297 auto asBits = toUnit<RangeUnit::Bit>();
298 return {asBits.lo + offset, asBits.hi + offset};
299 }
300
304 HalfOpenRange<Unit, Order> shiftedByBytes(int offset) const {
305 if (empty()) return HalfOpenRange();
306 if (Unit == RangeUnit::Byte) return {lo + offset, hi + offset};
307 return {lo + offset * 8, hi + offset * 8};
308 }
309
311 int loByte() const {
312 if (empty()) return 0;
313 return Unit == RangeUnit::Byte ? lo : BitRange::Detail::divideFloor(lo, 8);
314 }
315
317 int hiByte() const {
318 if (empty()) return 0;
319 return Unit == RangeUnit::Byte ? hi - 1 : BitRange::Detail::divideFloor(hi - 1, 8);
320 }
321
325 int nextByte() const { return empty() ? 0 : hiByte() + 1; }
326
329 bool isLoAligned() const {
330 return (empty() || Unit == RangeUnit::Byte) ? true
331 : BitRange::Detail::moduloFloor(lo, 8) == 0;
332 }
333
337 bool isHiAligned() const {
338 return (empty() || Unit == RangeUnit::Byte) ? true
339 : BitRange::Detail::moduloFloor(hi, 8) == 0;
340 }
341
342 bool operator==(HalfOpenRange other) const {
343 if (empty()) return other.empty();
344 return other.lo == lo && other.hi == hi;
345 }
346 bool operator!=(HalfOpenRange other) const { return !(*this == other); }
347
349 bool empty() const { return lo == hi; }
350
352 bool contains(int index) const { return index >= lo && index < hi; }
353
356 bool contains(HalfOpenRange other) const { return intersectWith(other) == other; }
357
361 bool overlaps(HalfOpenRange a) const { return !intersectWith(a).empty(); }
362 bool overlaps(int l, int h) const { return !intersectWith(l, h).empty(); }
363
367 HalfOpenRange intersectWith(HalfOpenRange a) const { return intersectWith(a.lo, a.hi); }
368 HalfOpenRange intersectWith(int l, int h) const {
369 HalfOpenRange rv = {std::max(lo, l), std::min(hi, h)};
370 if (rv.hi <= rv.lo) return {0, 0};
371 return rv;
372 }
373 HalfOpenRange operator&(HalfOpenRange a) const { return intersectWith(a); }
374 HalfOpenRange operator&=(HalfOpenRange a) {
375 *this = intersectWith(a);
376 return *this;
377 }
378
383 HalfOpenRange unionWith(HalfOpenRange a) const { return unionWith(a.lo, a.hi); }
384 HalfOpenRange unionWith(int l, int h) const {
385 if (empty()) return {l, h};
386 if (l == h) return *this;
387 return HalfOpenRange(std::min(lo, l), std::max(hi, h));
388 }
389 HalfOpenRange operator|(HalfOpenRange a) const { return unionWith(a); }
390 HalfOpenRange operator|=(HalfOpenRange a) {
391 *this = unionWith(a);
392 return *this;
393 }
394
417 template <Endian DestOrder>
418 HalfOpenRange<Unit, DestOrder> toOrder(int spaceSize) const {
419 if (DestOrder == Order) return HalfOpenRange<Unit, DestOrder>(lo, hi);
420 switch (DestOrder) {
421 case Endian::Network:
422 case Endian::Little:
423 return HalfOpenRange<Unit, DestOrder>(spaceSize - hi, spaceSize - lo);
424 }
425 BUG("Unexpected ordering");
426 }
427
443 template <RangeUnit DestUnit>
444 HalfOpenRange<DestUnit, Order> toUnit() const {
445 if (DestUnit == Unit) return HalfOpenRange<DestUnit, Order>(lo, hi);
446 if (empty()) return HalfOpenRange<DestUnit, Order>();
447 switch (DestUnit) {
448 case RangeUnit::Bit:
449 return HalfOpenRange<DestUnit, Order>(lo * 8, hi * 8);
450 case RangeUnit::Byte:
451 return HalfOpenRange<DestUnit, Order>(loByte(), nextByte());
452 }
453 BUG("Unexpected unit");
454 }
455
457 void toJSON(JSONGenerator &json) const { BitRange::rangeToJSON(json, lo, hi); }
458 static HalfOpenRange fromJSON(JSONLoader &json) {
459 return HalfOpenRange(BitRange::rangeFromJSON(json));
460 }
461
463 bool operator<(const HalfOpenRange &other) const {
464 if (lo != other.lo) return lo < other.lo;
465 return hi < other.hi;
466 }
467
468 friend size_t hash_value(const HalfOpenRange &r) { return Util::Hash{}(r.lo, r.hi); }
469
473 int lo;
474
479 int hi;
480};
481
503template <RangeUnit Unit, Endian Order>
504struct ClosedRange {
505 static constexpr RangeUnit unit = Unit;
506 static constexpr Endian order = Order;
507
508 using FromTo = BitRange::FromTo;
509 using StartLen = BitRange::StartLen;
510 using ZeroToMax = BitRange::ZeroToMax;
511 using MinToMax = BitRange::MinToMax;
512
513 ClosedRange() : lo(0), hi(0) {} // FIXME: default is [0,0]? This is just wrong ...
514 constexpr ClosedRange(int lo, int hi) : lo(lo), hi(hi) {}
515 ClosedRange(FromTo &&fromTo) // NOLINT(runtime/explicit)
516 : lo(fromTo.from), hi(fromTo.to) {}
517 ClosedRange(StartLen &&startLen) // NOLINT(runtime/explicit)
518 : lo(startLen.start), hi(startLen.start + startLen.len - 1) {}
519 ClosedRange(ZeroToMax &&) // NOLINT(runtime/explicit)
520 : lo(0), hi(std::numeric_limits<int>::max() - 1) {}
521 ClosedRange(MinToMax &&) // NOLINT(runtime/explicit)
522 : lo(std::numeric_limits<int>::min()), hi(std::numeric_limits<int>::max() - 1) {}
523 explicit ClosedRange(std::pair<int, int> range) : lo(range.first), hi(range.second) {}
524 ClosedRange(const HalfOpenRange<Unit, Order> &r) // NOLINT(runtime/explicit)
525 : lo(r.lo), hi(r.hi - 1) {
526 BUG_CHECK(!r.empty(), "can't convert empty range to Closed");
527 }
528
530 ssize_t size() const { return ssize_t(hi) - ssize_t(lo) + 1; }
531
533 ClosedRange<RangeUnit::Bit, Order> resizedToBits(int size) const {
534 BUG_CHECK(size != 0, "Resizing ClosedRange to zero size");
535 auto asBits = toUnit<RangeUnit::Bit>();
536 return {asBits.lo, asBits.lo + size - 1};
537 }
538
540 ClosedRange resizedToBytes(int size) const {
541 BUG_CHECK(size != 0, "Resizing ClosedRange to zero size");
542 if (Unit == RangeUnit::Byte) return {lo, lo + size - 1};
543 return {lo, lo + size * 8 - 1};
544 }
545
547 ClosedRange<RangeUnit::Bit, Order> shiftedByBits(int offset) const {
548 auto asBits = toUnit<RangeUnit::Bit>();
549 return {asBits.lo + offset, asBits.hi + offset};
550 }
551
553 ClosedRange shiftedByBytes(int offset) const {
554 if (Unit == RangeUnit::Byte) return {lo + offset, hi + offset};
555 return {lo + offset * 8, hi + offset * 8};
556 }
557
559 int loByte() const {
560 return Unit == RangeUnit::Byte ? lo : BitRange::Detail::divideFloor(lo, 8);
561 }
562
564 int hiByte() const {
565 return Unit == RangeUnit::Byte ? hi : BitRange::Detail::divideFloor(hi, 8);
566 }
567
569 int nextByte() const { return hiByte() + 1; }
570
572 bool isLoAligned() const {
573 return Unit == RangeUnit::Byte ? true : BitRange::Detail::moduloFloor(lo, 8) == 0;
574 }
575
577 bool isHiAligned() const {
578 return Unit == RangeUnit::Byte ? true : BitRange::Detail::moduloFloor(hi + 1, 8) == 0;
579 }
580
581 bool operator==(ClosedRange other) const { return (other.lo == lo) && (other.hi == hi); }
582 bool operator!=(ClosedRange other) const { return !(*this == other); }
583
585 bool contains(int index) const { return (index >= lo) && (index <= hi); }
586
588 bool contains(ClosedRange other) const {
589 auto intersection = intersectWith(other);
590 return intersection.lo == other.lo && intersection.size() == other.size();
591 }
592
594 bool overlaps(ClosedRange a) const { return !intersectWith(a).empty(); }
595 bool overlaps(int l, int h) const { return !intersectWith(l, h).empty(); }
596
602 return intersectWith(a.lo, a.hi);
603 }
604 HalfOpenRange<Unit, Order> intersectWith(int l, int h) const {
605 return HalfOpenRange<Unit, Order>(lo, hi + 1)
607 }
608 HalfOpenRange<Unit, Order> operator&(ClosedRange a) const { return intersectWith(a); }
609 HalfOpenRange<Unit, Order> operator&=(ClosedRange a) {
610 *this = intersectWith(a);
611 return *this;
612 }
613
615 ClosedRange unionWith(ClosedRange a) const { return unionWith(a.lo, a.hi); }
616 ClosedRange unionWith(int l, int h) const {
617 return ClosedRange(std::min(lo, l), std::max(hi, h));
618 }
619 ClosedRange operator|(ClosedRange a) const { return unionWith(a); }
620 ClosedRange operator|=(ClosedRange a) {
621 *this = unionWith(a);
622 return *this;
623 }
624
626 template <Endian DestOrder>
627 ClosedRange<Unit, DestOrder> toOrder(int spaceSize) const {
628 BUG_CHECK(spaceSize > 0, "Can't represent an empty range");
629 if (DestOrder == Order) return ClosedRange<Unit, DestOrder>(lo, hi);
630 switch (DestOrder) {
631 case Endian::Network:
632 case Endian::Little:
633 return ClosedRange<Unit, DestOrder>((spaceSize - 1) - hi, (spaceSize - 1) - lo);
634 }
635 BUG("Unexpected ordering");
636 }
637
639 template <RangeUnit DestUnit>
640 ClosedRange<DestUnit, Order> toUnit() const {
641 if (DestUnit == Unit) return ClosedRange<DestUnit, Order>(lo, hi);
642 switch (DestUnit) {
643 case RangeUnit::Bit:
644 return ClosedRange<DestUnit, Order>(lo * 8, hi * 8 + 7);
645 case RangeUnit::Byte:
646 return ClosedRange<DestUnit, Order>(loByte(), hiByte());
647 }
648 BUG("Unexpected unit");
649 }
650
652 void toJSON(JSONGenerator &json) const { BitRange::rangeToJSON(json, lo, hi); }
653 static ClosedRange fromJSON(JSONLoader &json) {
654 return ClosedRange(BitRange::rangeFromJSON(json));
655 }
656
658 bool operator<(const ClosedRange &other) const {
659 if (lo != other.lo) return lo < other.lo;
660 return hi < other.hi;
661 }
662
663 friend size_t hash_value(const ClosedRange &r) { return Util::Hash{}(r.lo, r.hi); }
664
667 cstring formatAsSlice(int spaceSize) const {
668 auto r = toOrder<Endian::Little>(spaceSize);
669 auto hi = r.hi;
670 auto lo = r.lo;
671 if (Unit == RangeUnit::Byte) {
672 lo = lo * 8;
673 hi = hi * 8 + 7;
674 } else {
675 BUG_CHECK(Unit == RangeUnit::Bit, "mismatch range units");
676 }
677 std::stringstream out;
678 out << "[" << hi << ":" << lo << "]";
679 return cstring(out.str());
680 }
681
685 int lo;
686
691 int hi;
692};
693
706template <RangeUnit Unit, Endian Order>
707std::pair<HalfOpenRange<Unit, Order>, HalfOpenRange<Unit, Order>> operator-(
709 HalfOpenRange<Unit, Order> empty = {0, 0};
710 HalfOpenRange<Unit, Order> intersect = left.intersectWith(right);
711 if (intersect.empty())
712 return left.lo < right.lo ? std::make_pair(left, empty) : std::make_pair(empty, left);
713
715 left.lo == intersect.lo ? empty : BitRange::FromTo(left.lo, intersect.lo - 1);
717 left.hi == intersect.hi ? empty : BitRange::FromTo(intersect.hi, left.hi - 1);
718
719 return {lower, upper};
720}
721
724template <RangeUnit Unit, Endian Order>
725std::pair<HalfOpenRange<Unit, Order>, HalfOpenRange<Unit, Order>> operator-(
727 return toHalfOpenRange(left) - toHalfOpenRange(right);
728}
729
732template <RangeUnit Unit, Endian Order>
734 return HalfOpenRange<Unit, Order>(closedRange.lo, closedRange.hi + 1);
735}
736
739template <RangeUnit Unit, Endian Order>
740std::optional<ClosedRange<Unit, Order>> toClosedRange(HalfOpenRange<Unit, Order> halfOpenRange) {
741 if (halfOpenRange.empty()) return std::nullopt;
742 return ClosedRange<Unit, Order>(halfOpenRange.lo, halfOpenRange.hi - 1);
743}
744
748
752
756
760
761std::ostream &toStream(std::ostream &out, RangeUnit unit, Endian order, int lo, int hi,
762 bool closed);
763
764template <RangeUnit Unit, Endian Order>
765std::ostream &operator<<(std::ostream &out, const HalfOpenRange<Unit, Order> &range) {
766 return toStream(out, Unit, Order, range.lo, range.hi, false);
767}
768
769template <RangeUnit Unit, Endian Order>
770std::ostream &operator<<(std::ostream &out, const ClosedRange<Unit, Order> &range) {
771 return toStream(out, Unit, Order, range.lo, range.hi, true);
772}
773
774} // namespace P4
775
776// Hashing specializations
777namespace std {
778template <P4::RangeUnit Unit, P4::Endian Order>
779struct hash<P4::HalfOpenRange<Unit, Order>> {
780 std::size_t operator()(const P4::HalfOpenRange<Unit, Order> &r) const {
781 return P4::Util::Hash{}(r.lo, r.hi);
782 }
783};
784
785template <P4::RangeUnit Unit, P4::Endian Order>
786struct hash<P4::ClosedRange<Unit, Order>> {
787 std::size_t operator()(const P4::ClosedRange<Unit, Order> &r) const {
788 return P4::Util::Hash{}(r.lo, r.hi);
789 }
790};
791} // namespace std
792
793namespace P4::Util {
794template <RangeUnit Unit, Endian Order>
795struct Hasher<HalfOpenRange<Unit, Order>> {
796 size_t operator()(const HalfOpenRange<Unit, Order> &r) const {
797 return Util::Hash{}(r.lo, r.hi);
798 }
799};
800
801template <RangeUnit Unit, Endian Order>
802struct Hasher<ClosedRange<Unit, Order>> {
803 size_t operator()(const ClosedRange<Unit, Order> &r) const { return Util::Hash{}(r.lo, r.hi); }
804};
805} // namespace P4::Util
806
807#endif /* LIB_BITRANGE_H_ */
Definition json_generator.h:30
Definition json_loader.h:32
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:758
ClosedRange< RangeUnit::Bit, Endian::Network > nw_bitrange
Convenience typedefs for closed ranges in bits.
Definition lib/bitrange.h:746
Endian
An ordering for bits or bytes.
Definition lib/bitrange.h:215
@ Little
Most significant bit/byte first.
Definition lib/bitrange.h:217
std::optional< ClosedRange< Unit, Order > > toClosedRange(HalfOpenRange< Unit, Order > halfOpenRange)
Definition lib/bitrange.h:740
ClosedRange< RangeUnit::Byte, Endian::Network > nw_byterange
Convenience typedefs for closed ranges in bytes.
Definition lib/bitrange.h:750
HalfOpenRange< RangeUnit::Bit, Endian::Network > nw_bitinterval
Convenience typedefs for half-open ranges in bits.
Definition lib/bitrange.h:754
RangeUnit
Units in which a range can be specified.
Definition lib/bitrange.h:209
std::pair< HalfOpenRange< Unit, Order >, HalfOpenRange< Unit, Order > > operator-(HalfOpenRange< Unit, Order > left, HalfOpenRange< Unit, Order > right)
Definition lib/bitrange.h:707
HalfOpenRange< Unit, Order > toHalfOpenRange(ClosedRange< Unit, Order > closedRange)
Definition lib/bitrange.h:733
Definition bson.cpp:69
STL namespace.
Definition lib/bitrange.h:132
Definition lib/bitrange.h:200
Definition lib/bitrange.h:149
Definition lib/bitrange.h:181
Definition lib/bitrange.h:504
bool isHiAligned() const
Definition lib/bitrange.h:577
bool contains(ClosedRange other) const
Definition lib/bitrange.h:588
ClosedRange< DestUnit, Order > toUnit() const
Definition lib/bitrange.h:640
bool overlaps(ClosedRange a) const
Definition lib/bitrange.h:594
ClosedRange< Unit, DestOrder > toOrder(int spaceSize) const
Definition lib/bitrange.h:627
int loByte() const
Definition lib/bitrange.h:559
ClosedRange resizedToBytes(int size) const
Definition lib/bitrange.h:540
bool isLoAligned() const
Definition lib/bitrange.h:572
int hiByte() const
Definition lib/bitrange.h:564
HalfOpenRange< Unit, Order > intersectWith(ClosedRange a) const
Definition lib/bitrange.h:601
void toJSON(JSONGenerator &json) const
JSON serialization/deserialization.
Definition lib/bitrange.h:652
ClosedRange< RangeUnit::Bit, Order > shiftedByBits(int offset) const
Definition lib/bitrange.h:547
ClosedRange< RangeUnit::Bit, Order > resizedToBits(int size) const
Definition lib/bitrange.h:533
cstring formatAsSlice(int spaceSize) const
Definition lib/bitrange.h:667
ClosedRange shiftedByBytes(int offset) const
Definition lib/bitrange.h:553
int lo
Definition lib/bitrange.h:685
ssize_t size() const
Definition lib/bitrange.h:530
bool operator<(const ClosedRange &other) const
Definition lib/bitrange.h:658
int hi
Definition lib/bitrange.h:691
bool contains(int index) const
Definition lib/bitrange.h:585
ClosedRange unionWith(ClosedRange a) const
Definition lib/bitrange.h:615
int nextByte() const
Definition lib/bitrange.h:569
Definition lib/bitrange.h:244
bool contains(int index) const
Definition lib/bitrange.h:352
int hi
Definition lib/bitrange.h:479
bool operator<(const HalfOpenRange &other) const
Total ordering, first by lo, then by hi.
Definition lib/bitrange.h:463
int hiByte() const
Definition lib/bitrange.h:317
HalfOpenRange< Unit, DestOrder > toOrder(int spaceSize) const
Definition lib/bitrange.h:418
bool isHiAligned() const
Definition lib/bitrange.h:337
bool overlaps(HalfOpenRange a) const
Definition lib/bitrange.h:361
int nextByte() const
Definition lib/bitrange.h:325
HalfOpenRange< Unit, Order > shiftedByBytes(int offset) const
Definition lib/bitrange.h:304
bool contains(HalfOpenRange other) const
Definition lib/bitrange.h:356
bool isLoAligned() const
Definition lib/bitrange.h:329
HalfOpenRange< DestUnit, Order > toUnit() const
Definition lib/bitrange.h:444
int loByte() const
Definition lib/bitrange.h:311
ssize_t size() const
Definition lib/bitrange.h:266
void toJSON(JSONGenerator &json) const
JSON serialization/deserialization.
Definition lib/bitrange.h:457
HalfOpenRange< RangeUnit::Bit, Order > resizedToBits(int size) const
Definition lib/bitrange.h:278
bool empty() const
Definition lib/bitrange.h:349
HalfOpenRange unionWith(HalfOpenRange a) const
Definition lib/bitrange.h:383
HalfOpenRange canonicalize() const
Definition lib/bitrange.h:270
int lo
Definition lib/bitrange.h:473
HalfOpenRange< RangeUnit::Bit, Order > shiftedByBits(int offset) const
Definition lib/bitrange.h:295
HalfOpenRange resizedToBytes(int size) const
Definition lib/bitrange.h:286
HalfOpenRange intersectWith(HalfOpenRange a) const
Definition lib/bitrange.h:367
Definition hash.h:125
Definition hash.h:123