std/core/range
std/core/src/range.trb
The three ranges the syntax writes - Range for 0..10, RangeFrom for 0.., RangeTo for ..10 - the trait
Bounds that reads any of them, and RangeIterator, what it takes to walk a range of integers.
The type says which ends there are. a..b has both, a.. has a start, ..b has an end, and no field is
optional anywhere - so for index in ..10 and (0..).length() are refused where they are written and nothing has
to panic at run time.
type Range
native type Range<Value> with Equals, Hash
0..10, 0..=10: a range with both ends. What for index in 0..list.length() counts through, and what a slice of
a known part takes (samples[0..100]).
Examples
const bounded = 0..10
print bounded.contains(5)
const inclusive = 0..=10
print inclusive.contains(10)
Related
type RangeFrom
native type RangeFrom<Value> with Equals, Hash
0..: a range with a start and no end. What a slice to the end of a value takes (text[2..]), and the one range
that iterates forever.
Examples
const fromThree = 3..
print fromThree.contains(1000)
Related
Range-0..10, the range with both ends.
field start
start: Value
The first value the range covers.
type RangeTo
native type RangeTo<Value> with Equals, Hash
..10, ..=10: a range with an end and no start. What a slice from the beginning of a value takes (items[..3]).
It is not a sequence: there is no first value to start counting at, which is why for index in ..10 is refused
where it is written.
Examples
const upToTen = ..10
print upToTen.contains(9)
Related
Range-0..10, the range with both ends.
trait Bounds
trait Bounds<Value: Compare>
What every range has in common: the two ends, each None where the range is open on that side.
This is what a receiver takes that accepts all three forms - a slice does (text[2..], items[..3],
items[1..=2]), because an open end has a meaning there: the start or the end of the value. Whoever needs a start
takes a Range or a RangeFrom instead and lets the type refuse the rest.
Examples
fn width(span: Bounds<Int>): String {
"{span.lowest()} {span.highest()} {span.includesHighest()}"
}
print width(2..=5)
print width(2..)
fn lowest
fn lowest(): Value?
The low end, or None where the range is open at the start.
fn highest
fn highest(): Value?
The high end, or None where the range is open at the end.
fn includesHighest
fn includesHighest(): Bool
Whether Bounds.highest itself lies inside. A range that has no high end answers false, which says nothing.
fn contains
fn contains(value: Value): Bool
Whether the value lies within the range's bounds. An open end never excludes anything on its side.
extend Range<Value> with Bounds<Value>
extend<Value: Compare> Range<Value> with Bounds<Value>
Both ends are there, and inclusive says whether the high one is inside.
fn lowest
fn lowest(): Value?
fn highest
fn highest(): Value?
fn includesHighest
fn includesHighest(): Bool
extend RangeFrom<Value> with Bounds<Value>
extend<Value: Compare> RangeFrom<Value> with Bounds<Value>
Open at the end, so there is no high end to include.
fn lowest
fn lowest(): Value?
fn highest
fn highest(): Value?
fn includesHighest
fn includesHighest(): Bool
extend RangeTo<Value> with Bounds<Value>
extend<Value: Compare> RangeTo<Value> with Bounds<Value>
Open at the start.
fn lowest
fn lowest(): Value?
fn highest
fn highest(): Value?
fn includesHighest
fn includesHighest(): Bool
extend Range<Int> with Iterate<Int>, Length
extend Range<Int> with Iterate<Int>, Length
A range of integers with both ends is a sequence with a length. Other ranges of integers are less: 0.. iterates
and has no length, ..10 does neither. Ranges of other types are bounds and nothing more - 'a'..'z' says what is
inside of it, but there is no "the next value after a" in general.
extend RangeFrom<Int> with Iterate<Int>
extend RangeFrom<Int> with Iterate<Int>
0.. counts on forever, which is what makes for index in 0.. and (0..).take(3) work.
fn iterate
fn iterate(): Iterator<Int>
extend Range<Value> with Show
extend<Value: Show> Range<Value> with Show
The source form, and not the fields: 0..10, 0..=10. A Show of its own rather than the derived one because a
reader writes a range that way, and because the interpreter has printed it that way all along - the two have to
agree to the character (design principle 5).
It is conditional on Value: Show, which is why it cannot be a member of the native type itself: a range of
something unshowable is still a range.
fn show
fn show(): String
extend RangeFrom<Value> with Show
extend<Value: Show> RangeFrom<Value> with Show
0.., the source form.
fn show
fn show(): String
extend RangeTo<Value> with Show
extend<Value: Show> RangeTo<Value> with Show
..10, ..=10, the source form.
fn show
fn show(): String