start = \$start; \$this->stop = \$stop; } public static function invalid() : self { static \$invalid; return \$invalid ?? \$invalid = new Interval(-1, -2); } public function contains(int \$item) : bool { return \$item >= \$this->start && \$item <= \$this->stop; } public function getLength() : int { return \$this->stop - \$this->start + 1; } public function equals(object \$other) : bool { if (\$this === \$other) { return true; } return \$other instanceof self && \$this->start === \$other->start && \$this->stop === \$other->stop; } /** * Does this start completely before other? Disjoint. */ public function startsBeforeDisjoint(Interval \$other) : bool { return \$this->start < \$other->start && \$this->stop < \$other->start; } /** * Does this start at or before other? Nondisjoint. */ public function startsBeforeNonDisjoint(Interval \$other) : bool { return \$this->start <= \$other->start && \$this->stop >= \$other->start; } /** * Does this.a start after other.b? May or may not be disjoint. */ public function startsAfter(Interval \$other) : bool { return \$this->start > \$other->start; } /** * Does this start completely after other? Disjoint. */ public function startsAfterDisjoint(Interval \$other) : bool { return \$this->start > \$other->stop; } /** * Does this start after other? NonDisjoint */ public function startsAfterNonDisjoint(Interval \$other) : bool { // this.b >= other.b implied return \$this->start > \$other->start && \$this->start <= \$other->stop; } /** * Are both ranges disjoint? I.e., no overlap? */ public function disjoint(Interval \$other) : bool { return \$this->startsBeforeDisjoint(\$other) || \$this->startsAfterDisjoint(\$other); } /** * Are two intervals adjacent such as 0..41 and 42..42? */ public function adjacent(Interval \$other) : bool { return \$this->start === \$other->stop + 1 || \$this->stop === \$other->start - 1; } /** * Return the interval computed from combining this and other */ public function union(Interval \$other) : self { return new self(\min(\$this->start, \$other->start), \max(\$this->stop, \$other->stop)); } /** * Return the interval in common between this and o */ public function intersection(Interval \$other) : self { return new self(\max(\$this->start, \$other->start), \min(\$this->stop, \$other->stop)); } public function __toString() : string { if (\$this->start === \$this->stop) { return (string) \$this->start; } return \$this->start . '..' . \$this->stop; } }