mirror of
https://github.com/gechandesu/ranges.git
synced 2026-10-05 00:46:48 +03:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ceed23ceed |
@@ -37,7 +37,15 @@ pub fn (r Range[T]) bounds() (T, T, T) {
|
|||||||
return r.start, r.end, r.step
|
return r.start, r.end, r.step
|
||||||
}
|
}
|
||||||
|
|
||||||
// with_step returns copy of the range with new step value.
|
// capacity returns the calculated number of elements in range.
|
||||||
|
pub fn (r Range[T]) capacity() int {
|
||||||
|
if !r.is_valid() {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return r.capacity_no_valid_check()
|
||||||
|
}
|
||||||
|
|
||||||
|
// with_step returns copy of the range with updated step value.
|
||||||
pub fn (r Range[T]) with_step[T](step T) Range[T] {
|
pub fn (r Range[T]) with_step[T](step T) Range[T] {
|
||||||
return Range[T]{
|
return Range[T]{
|
||||||
...r
|
...r
|
||||||
@@ -46,20 +54,14 @@ pub fn (r Range[T]) with_step[T](step T) Range[T] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// to_array returns an array of elements from the range.
|
// to_array returns an array of elements from the range. This method is slightly
|
||||||
|
// faster than simply filling an array with elements in a loop, because the
|
||||||
|
// memory for the array is pre-allocated.
|
||||||
pub fn (r Range[T]) to_array() []T {
|
pub fn (r Range[T]) to_array() []T {
|
||||||
if r.is_empty() {
|
if !r.is_valid() {
|
||||||
return []T{}
|
return []T{}
|
||||||
}
|
}
|
||||||
|
cap := r.capacity_no_valid_check()
|
||||||
mut cap := 0
|
|
||||||
|
|
||||||
$if T is $int || T is $float {
|
|
||||||
cap = int((r.end - r.start) / r.step + T(1))
|
|
||||||
} $else $if T is big.Integer {
|
|
||||||
cap = ((r.end - r.start) / r.step + big.one_int).int()
|
|
||||||
}
|
|
||||||
|
|
||||||
mut arr := []T{cap: cap}
|
mut arr := []T{cap: cap}
|
||||||
for el in r {
|
for el in r {
|
||||||
arr << el
|
arr << el
|
||||||
@@ -67,10 +69,30 @@ pub fn (r Range[T]) to_array() []T {
|
|||||||
return arr
|
return arr
|
||||||
}
|
}
|
||||||
|
|
||||||
// is_empty reports is the range instance empty (has no values).
|
// is_valid reports is the range valid.
|
||||||
pub fn (r Range[T]) is_empty() bool {
|
pub fn (r Range[T]) is_valid() bool {
|
||||||
empty := $zero(Range[T])
|
zero := T{}
|
||||||
return r == empty
|
if r.step == zero {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if r.step > zero && r.start > r.end {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if r.step < zero && r.start <= r.end {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
@[inline]
|
||||||
|
fn (r Range[T]) capacity_no_valid_check() int {
|
||||||
|
mut cap := 0
|
||||||
|
$if T is $int || T is $float {
|
||||||
|
cap = int((r.end - r.start) / r.step + T(1))
|
||||||
|
} $else $if T is big.Integer {
|
||||||
|
cap = ((r.end - r.start) / r.step + big.one_int).int()
|
||||||
|
}
|
||||||
|
return cap
|
||||||
}
|
}
|
||||||
|
|
||||||
// range creates new Range iterator with given start, end and step values.
|
// range creates new Range iterator with given start, end and step values.
|
||||||
@@ -81,7 +103,8 @@ pub fn (r Range[T]) is_empty() bool {
|
|||||||
//
|
//
|
||||||
// The range includes the end value.
|
// The range includes the end value.
|
||||||
//
|
//
|
||||||
// Note: If range cannot be created the empty range will be returned. See also `new()`.
|
// Note: If range cannot be created the empty range will be returned.
|
||||||
|
// Is it recommended to check range with `is_valid()`. See also `new()`.
|
||||||
pub fn range[T](start T, end T, step T) Range[T] {
|
pub fn range[T](start T, end T, step T) Range[T] {
|
||||||
return new(start, end, step) or { Range[T]{} }
|
return new(start, end, step) or { Range[T]{} }
|
||||||
}
|
}
|
||||||
@@ -200,8 +223,7 @@ pub fn from_string_custom[T](s string, conv StringConvertFn[T], config RangeFrom
|
|||||||
fn split_string(s string, sep string) ![]string {
|
fn split_string(s string, sep string) ![]string {
|
||||||
parts := s.split(sep)
|
parts := s.split(sep)
|
||||||
if parts.any(|x| x.is_blank()) || parts.len !in [1, 2, 3] {
|
if parts.any(|x| x.is_blank()) || parts.len !in [1, 2, 3] {
|
||||||
return error('`start${sep}end` or `start[:step]:end`' +
|
return error('`start${sep}end` or `start[:step]:end`' + "formatted string expected, not '${s}'")
|
||||||
"formatted string expected, not '${s}'")
|
|
||||||
}
|
}
|
||||||
if parts.len == 1 {
|
if parts.len == 1 {
|
||||||
return [parts[0], parts[0], '1']
|
return [parts[0], parts[0], '1']
|
||||||
@@ -216,8 +238,7 @@ fn split_string(s string, sep string) ![]string {
|
|||||||
if sep == ':' && parts.len == 3 {
|
if sep == ':' && parts.len == 3 {
|
||||||
return [parts[0], parts[2], parts[1]]
|
return [parts[0], parts[2], parts[1]]
|
||||||
}
|
}
|
||||||
return error('invalid range string: expected `start[${sep}step]${sep}end` ' +
|
return error('invalid range string: expected `start[${sep}step]${sep}end` ' + 'or `start${sep}end[/step]` format, got `${s}`')
|
||||||
'or `start${sep}end[/step]` format, got `${s}`')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_string[T](s string) !T {
|
fn convert_string[T](s string) !T {
|
||||||
|
|||||||
+12
-2
@@ -240,9 +240,9 @@ fn test_range_empty_bigint() {
|
|||||||
assert r.to_array() == []
|
assert r.to_array() == []
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_range_is_empty() {
|
fn test_range_is_valid() {
|
||||||
r := ranges.range(0, 0, -9000)
|
r := ranges.range(0, 0, -9000)
|
||||||
assert r.is_empty()
|
assert !r.is_valid()
|
||||||
assert r.to_array() == []
|
assert r.to_array() == []
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,3 +306,13 @@ fn test_new_error_negative_step_start_eq_end() {
|
|||||||
assert err.msg() == 'step is negative, but start value is lesser than or equals end value'
|
assert err.msg() == 'step is negative, but start value is lesser than or equals end value'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_range_capacity() {
|
||||||
|
r := ranges.range(0, 9, 1)
|
||||||
|
assert r.capacity() == 10
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_range_capacity_non_one_step() {
|
||||||
|
r := ranges.range(0, 9, 2)
|
||||||
|
assert r.capacity() == 5
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user