Category talk:Wren-seq: Difference between revisions

→‎Source code: Numerous changes to View class.
(→‎Source code: Added View class.)
(→‎Source code: Numerous changes to View class.)
Line 497:
from the underlying list may invalidate the view bounds and insertions may 'move' it.
As in the case of the List class, views support negative indices.
 
There is inevitably a performance penalty when indexing the elements of the View compared
to indexing the elements of the underlying list directly. To mitigate this penalty,
unsafe get, set and switch methods are provided which do not check their arguments.
*/
class View is Sequence {
Line 515 ⟶ 519:
Fiber.abort("'end' cannot be before 'start'.")
}
_lst = lst
_start = start
_end = end
_count = end - start + 1
}
 
// Private constructor which does not check the arguments.
construct new_(lst, start, end) {
_lst = lst
_start = start
Line 531 ⟶ 543:
 
// Gets or sets the value at index 'i' of the view (zero based).
[i] {
[i] { (i >= 0) ?_lst[i + _start] : _lst[_count + i + _start] }
if (i < 0) i = _count + i
if (i < 0 || i > _count) Fiber.abort("Index is out of range.")
return _lst[i + _start]
}
 
[i]=(v) {
if (i >=< 0) _lst[i + _start] = v else _lst[_count + i + _start] = v
if (i < 0 || i > _count) Fiber.abort("Index is out of range.")
_lst[i + _start] = v
}
 
// Unsafe versions of the above indexers which are much quicker as the index is
// not adjusted if negative nor checked to be within the view's bounds before
// being passed (after adding _start) to the underlying list.
// Only use when certain this adjustment/check is unnecessary.
get(i) { _lst[i + _start] }
 
set(i, v) {
_lst[i + _start] = v
}
 
// Returns a new View which is a slice of this one.
slice(start, end) {
if (start < 0) start = _count + start
if (start < 0 || start > _count) Fiber.abort("'start' is out of range.")
if (end < 0) end = _count + end
if (end < start || end > _count) Fiber.abort("'end' is out of range.")
return View.new_(_lst, start + _start, end + _start)
}
 
// Copies this to a new otherwise identical View.
copy() { View.new_(_lst, _start, _end) }
 
// Returns the index of 'v' in the view or -1 if it does not exist.
Line 559 ⟶ 599:
swap(i, j) {
if (i < 0) i = _count + i
if (i < 0 || i > _count) Fiber.abort("First index is out of range.")
if (j < 0) j = _count + j
if (j < 0 || j > _count) Fiber.abort("Second index is out of range.")
_lst.swap(i + _start, j + _start)
}
 
// Unsafe version of 'swap' above which is much quicker as the indices are
// not adjusted if negative nor checked to be within the view's bounds before
// being passed (after adding _start) to the underlying list.
// Only use when certain these adjustments/checks are unnecessary.
switch(i, j) {
[i] { (i >= 0) ?_lst[.swap(i + _start], : _lst[_count + ij + _start] })
}
 
9,476

edits