def leftClosedRightOpen[T: Ordering]()

in algebird-core/src/main/scala/com/twitter/algebird/Interval.scala [95:166]


  def leftClosedRightOpen[T: Ordering](lower: T, upper: T): MaybeEmpty[T, InLowExUp] =
    if (Ordering[T].lt(lower, upper))
      MaybeEmpty.NotSoEmpty[T, InLowExUp](Intersection(InclusiveLower(lower), ExclusiveUpper(upper)))
    else MaybeEmpty.SoEmpty[T, InLowExUp]()

  def leftOpenRightClosed[T: Ordering](lower: T, upper: T): MaybeEmpty[T, ExLowInUp] =
    if (Ordering[T].lt(lower, upper))
      MaybeEmpty.NotSoEmpty[T, ExLowInUp](Intersection(ExclusiveLower(lower), InclusiveUpper(upper)))
    else MaybeEmpty.SoEmpty[T, ExLowInUp]()

  def closed[T: Ordering](lower: T, upper: T): MaybeEmpty[T, InLowInUp] =
    if (Ordering[T].lteq(lower, upper))
      MaybeEmpty.NotSoEmpty[T, InLowInUp](Intersection(InclusiveLower(lower), InclusiveUpper(upper)))
    else MaybeEmpty.SoEmpty[T, InLowInUp]()

  def open[T: Ordering](lower: T, upper: T): MaybeEmpty[T, ExLowExUp] =
    if (Ordering[T].lt(lower, upper))
      MaybeEmpty.NotSoEmpty[T, ExLowExUp](Intersection(ExclusiveLower(lower), ExclusiveUpper(upper)))
    else MaybeEmpty.SoEmpty[T, ExLowExUp]()

  /**
   * This is here for binary compatibility reasons. These methods should be moved to Interval, which should
   * also be an abstract class for better binary compatibility at the next incompatible change
   */
  implicit final class IntervalMethods[T](val intr: Interval[T]) extends AnyVal {
    def isEmpty(implicit succ: Successible[T], pred: Predecessible[T]): Boolean = intr match {
      case Empty()    => true
      case Universe() => false
      case Intersection(InclusiveLower(l), ExclusiveUpper(u)) =>
        !succ.ordering.lt(l, u)
      case Intersection(InclusiveLower(l), InclusiveUpper(u)) =>
        !succ.ordering.lteq(l, u)
      case Intersection(ExclusiveLower(l), ExclusiveUpper(u)) =>
        !succ.next(l).exists(succ.ordering.lt(_, u))
      case Intersection(ExclusiveLower(l), InclusiveUpper(u)) =>
        !succ.next(l).exists(succ.ordering.lteq(_, u))
      case InclusiveLower(_) => false // we at least have l
      case InclusiveUpper(_) => false // false // we at least have u
      case ExclusiveLower(l) =>
        succ.next(l).isEmpty
      case ExclusiveUpper(u) =>
        pred.prev(u).isEmpty
    }

    /**
     * If this returns Some(t), then intr.contains(t) and there is no s less than t such that intr.contains(s)
     *
     * if this returns None, it may be Empty, Upper or Universe
     */
    def boundedLeast(implicit succ: Successible[T]): Option[T] = intr match {
      case Empty()                => None
      case Universe()             => None
      case _: Upper[_]            => None
      case i @ Intersection(_, _) => i.least
      case l: Lower[_]            => l.least
    }

    /**
     * If this returns Some(t), then intr.contains(t) and there is no s greater than t such that
     * intr.contains(s)
     *
     * if this returns None, it may be Empty, Lower, or Universe
     */
    def boundedGreatest(implicit pred: Predecessible[T]): Option[T] =
      intr match {
        case Empty()                => None
        case Universe()             => None
        case _: Lower[_]            => None
        case i @ Intersection(_, _) => i.greatest
        case u: Upper[_]            => u.greatest
      }
  }