//
// Copyright (c) 2006, Brian Frank and Andy Frank
// Licensed under the Academic Free License version 3.0
//
// History:
// 11 Dec 05 Brian Frank Creation
//
**
** Range represents a contiguous range of integers from start to
** end. Ranges may be represented as literals in Fantom source code as
** "start..end" for an inclusive end or "start..<end" for an exclusive
** range.
**
@Serializable { simple = true }
const final class Range
{
//////////////////////////////////////////////////////////////////////////
// Constructor
//////////////////////////////////////////////////////////////////////////
**
** Convenience for make(start, end, false).
**
new makeInclusive(Int start, Int end)
**
** Convenience for make(start, end, true).
**
new makeExclusive(Int start, Int end)
**
** Constructor with start, end, and exclusive flag (all must be non-null).
**
new make(Int start, Int end, Bool exclusive)
**
** Parse from string format - inclusive is "start..end", or
** exclusive is "start..<end". If invalid format then
** throw ParseErr or return null based on checked flag.
**
static new fromStr(Str s, Bool checked := true)
//////////////////////////////////////////////////////////////////////////
// Obj Overrides
//////////////////////////////////////////////////////////////////////////
**
** Return true if same start, end, and exclusive.
**
override Bool equals(Obj? obj)
**
** Return start ^ end.
**
override Int hash()
**
** If inclusive return "start..end", if exclusive return "start..<end".
**
override Str toStr()
//////////////////////////////////////////////////////////////////////////
// Methods
//////////////////////////////////////////////////////////////////////////
**
** Return start index.
**
** Example:
** (1..3).start => 1
**
Int start()
**
** Return end index.
**
** Example:
** (1..3).end => 3
**
Int end()
**
** Is the end index inclusive.
**
** Example:
** (1..3).inclusive => true
** (1..<3).inclusive => false
**
Bool inclusive()
**
** Is the end index exclusive.
**
** Example:
** (1..3).exclusive => false
** (1..<3).exclusive => true
**
Bool exclusive()
**
** Return if this range contains no integer values.
** Equivalent to 'toList.isEmpty'.
**
Bool isEmpty()
**
** Get the minimum value of the range. If range contains
** no values then return null. Equivalent to 'toList.min'.
**
Int? min()
**
** Get the maximum value of the range. If range contains
** no values then return null. Equivalent to 'toList.max'.
**
Int? max()
**
** Get the first value of the range. If range contains
** no values then return null. Equivalent to 'toList.first'.
**
Int? first()
**
** Get the last value of the range. If range contains
** no values then return null. Equivalent to 'toList.last'.
**
Int? last()
**
** Return if this range contains the specified integer.
**
** Example:
** (1..3).contains(2) => true
** (1..3).contains(4) => false
**
Bool contains(Int i)
**
** Create a new range by adding offset to this range's
** start and end values.
**
** Example:
** (3..5).offset(2) => 5..7
** (3..<5).offset(-2) => 1..<3
**
Range offset(Int offset)
**
** Call the specified function for each integer in the range.
** Also see `Int.times`.
**
** Example:
** (1..3).each |i| { echo(i) } => 1, 2, 3
** (1..<3).each |i| { echo(i) } => 1, 2
** ('a'..'z').each |Int i| { echo(i) } => 'a', 'b', ... 'z'
**
Void each(|Int i| c)
**
** Iterate every integer in the range until the function returns
** non-null. If function returns non-null, then break the iteration
** and return the resulting object. Return null if the function returns
** null for every integer in the range.
**
Obj? eachWhile(|Int i->Obj?| c)
**
** Create a new list which is the result of calling c for
** every integer in the range. The new list is typed based on
** the return type of c.
**
** Example:
** (10..15).map |i->Str| { i.toHex } => Str[a, b, c, d, e, f]
**
Obj?[] map(|Int i->Obj?| c)
**
** Convert this range into a list of Ints.
**
** Example:
** (2..4).toList => [2,3,4]
** (2..<4).toList => [2,3]
** (10..8).toList => [10,9,8]
**
Int[] toList()
**
** Convenience for [Int.random(this)]`Int.random`.
** Also see `Int.random`, `Float.random`, `List.random`,
** and `util::Random`.
**
Int random()
}