package gs.std.v0.core /** Opaque type for collection sizes. Values are guaranteed to be 0 or greater. */ opaque type Size = Int /** Opaque type for collection sizes. Values are guaranteed to be 0 or greater. */ object Size: sealed trait Invalid object Invalid extends Invalid /** The size 0. */ final val Zero: Size = 0 /** The size 1. */ final val One: Size = 1 /** Express the given integer as a size. * * Throws an `IllegalArgumentException` if a negative value is given as * input. * * @param value * The input integer. * @return * The [[Size]] instance. */ def apply(value: Int): Size = if value >= 0 then value else throw new IllegalArgumentException("Size values must be 0 or greater.") def validate(value: Int): Either[Invalid, Size] = if value >= 0 then Right(value) else Left(Invalid) /** Express the size of any collection. * * @param iter * The collection. * @return * The size of the collection. */ def of(iter: Iterable[?]): Size = iter.size /** Express the size of any array. * * @param arr * The array. * @return * The size of the array. */ def of(arr: Array[?]): Size = arr.length given CanEqual[Size, Size] = CanEqual.derived given Ordering[Size] with /** @inheritDocs */ def compare( x: Size, y: Size ): Int = x - y extension (size: Size) /** @return * The underlying integer. */ def unwrap(): Int = size /** @return * The next value. */ def next(): Size = size + 1 /** @return * The next value. */ def increment(): Size = size + 1 /** Add some size to this one. * * @param that * The number to add. * @return * The sum of the numbers. */ def +(that: Size): Size = size + that /** Multiply this size by some other size. * * @param that * The number to multiply by. * @return * The product of the numbers. */ def *(that: Size): Size = size * that end Size