22template <
typename A>
class Interval {
25 constexpr Interval() {}
26 constexpr Interval(
const A &s, std::size_t n = 1) : start_{s}, size_{n} {}
27 constexpr Interval(A &&s, std::size_t n = 1)
28 : start_{std::move(s)}, size_{n} {}
29 constexpr Interval(
const Interval &) =
default;
30 constexpr Interval(Interval &&) =
default;
31 constexpr Interval &operator=(
const Interval &) =
default;
32 constexpr Interval &operator=(Interval &&) =
default;
34 constexpr bool operator<(
const Interval &that)
const {
35 return start_ < that.start_ ||
36 (start_ == that.start_ && size_ < that.size_);
38 constexpr bool operator<=(
const Interval &that)
const {
39 return start_ < that.start_ ||
40 (start_ == that.start_ && size_ <= that.size_);
42 constexpr bool operator==(
const Interval &that)
const {
43 return start_ == that.start_ && size_ == that.size_;
45 constexpr bool operator!=(
const Interval &that)
const {
46 return !(*
this == that);
48 constexpr bool operator>=(
const Interval &that)
const {
49 return !(*
this < that);
51 constexpr bool operator>(
const Interval &that)
const {
52 return !(*
this <= that);
55 constexpr const A &start()
const {
return start_; }
56 constexpr std::size_t size()
const {
return size_; }
57 constexpr bool empty()
const {
return size_ == 0; }
59 constexpr bool Contains(
const A &x)
const {
60 return start_ <= x && x < start_ + size_;
62 constexpr bool Contains(
const Interval &that)
const {
63 return Contains(that.start_) &&
64 ((that.size_ == 0) || Contains(that.start_ + (that.size_ - 1)));
66 constexpr bool IsDisjointWith(
const Interval &that)
const {
67 return that.NextAfter() <= start_ || NextAfter() <= that.start_;
69 constexpr bool ImmediatelyPrecedes(
const Interval &that)
const {
70 return NextAfter() == that.start_;
72 void Annex(
const Interval &that) {
73 size_ = (that.start_ + that.size_) - start_;
75 bool AnnexIfPredecessor(
const Interval &that) {
76 if (ImmediatelyPrecedes(that)) {
82 void ExtendToCover(
const Interval &that) {
85 }
else if (that.size_ != 0) {
86 const auto end{std::max(NextAfter(), that.NextAfter())};
87 start_ = std::min(start_, that.start_);
92 std::size_t MemberOffset(
const A &x)
const {
96 A OffsetMember(std::size_t n)
const {
101 constexpr A Last()
const {
return start_ + (size_ - 1); }
102 constexpr A NextAfter()
const {
return start_ + size_; }
103 constexpr Interval Prefix(std::size_t n)
const {
104 return {start_, std::min(size_, n)};
106 Interval Suffix(std::size_t n)
const {
107 n = std::min(n, size_);
108 return {start_ + n, size_ - n};
111 constexpr Interval Intersection(
const Interval &that)
const {
112 if (that.NextAfter() <= start_) {
114 }
else if (that.start_ <= start_) {
115 auto skip{start_ - that.start_};
116 return {start_, std::min(size_, that.size_ - skip)};
117 }
else if (NextAfter() <= that.start_) {
120 auto skip{that.start_ - start_};
121 return {that.start_, std::min(that.size_, size_ - skip)};
127 std::size_t size_{0};