std/slice
import std/slice to use it. Source: src/std/slice.iyi at v0.18.0.
A Slice(T) is a Pointer(T) with a size and a read-only flag. While raw pointers are unchecked and unsafe, a slice enforces bounds checks on reads and writes, provides safe subslicing, in-place manipulation, and integrates with Enumerable.
Bytes is an alias for Slice(UInt8), the currency of IO, sockets, and binary protocols.
Bytesalias
pub, because an alias is part of a module's surface like anything else: an unexported one is unreachable from a consumer, which R-2 now says out loud.
pub alias Bytes = Slice(UInt8)Slice(T)struct
pub struct Slice(T)
# Returns a subslice starting *offset* elements in, extending to the end.
def +(offset : Int32) : Slice(T)
# Returns true if sizes match and all elements are equal.
#
# A slice of its own element type, as `Array#==` takes an `Array(T)`. It
# took any `Slice(U)`, and numbers that compare equal across types hash
# apart: `Slice[-1, -2]` of `Int32` was `==` to the same of `Int64` with
# hashes 204952928 and -1576659145, so a table missed one by the other.
def ==(other : Slice(T)) : Bool
def ==(other : Object) : Bool
# Returns a subslice of *count* elements starting at *start*.
def [](start : Int32, count : Int32) : Slice(T)
# Element access with bounds checking. A negative index counts from the end,
# so `s[-1]` is the last element; the message names the index as typed rather
# than the wrapped one, and words it exactly as `Array#[]` and
# `Indexable#[]` do — the same mistake reads the same way in all three.
def [](index : Int32) : T
# Returns a subslice covering *range*.
def [](range : Range(Int32, Int32)) : Slice(T)
# Element assignment with bounds checking and write-protection check.
def []=(index : Int32, value : T) : T
# Returns a subslice of *count* elements starting at *start*, or nil if out of bounds.
def []?(start : Int32, count : Int32) : Slice(T) | ::Nil
# Element access with bounds checking, returning nil if out of bounds.
def []?(index : Int32) : T | ::Nil
# Returns a subslice covering *range*, or nil if out of bounds.
#
# A range that ends before it begins is empty, not out of bounds, as the
# other library counts it: `s[3..1]` is the empty slice at 3. The count is
# taken only once the end is known to be past the start, and the
# inclusive end is added only while the count can still fit, so an end
# near the top of `Int32` answers nil instead of overflowing.
def []?(range : Range(Int32, Int32)) : Slice(T) | ::Nil
# Returns the total size in bytes of this slice's elements.
def bytesize : Int32
# Returns a copy of this slice.
def clone : Slice(T)
# Copies *count* elements from raw *source* pointer into this slice.
def copy_from(source : Pointer(T), count : Int32) : Nil
# Copies all elements from *source* slice into this slice.
def copy_from(source : Slice(T)) : Nil
# Copies *count* elements from this slice to raw *target* pointer.
def copy_to(target : Pointer(T), count : Int32) : Nil
# Copies all elements from this slice to *target* slice.
def copy_to(target : Slice(T)) : Nil
# Returns a new slice with copied contents. The copy is filled before it
# takes this slice's read-only flag: `copy_from` into a read-only copy
# refused, so a read-only slice could not be duplicated at all.
def dup : Slice(T)
# Yields each element and its index to the block.
def each_with_index(& : (T, Int32 -> Nil)) : Nil
# Returns an empty slice of size 0.
def self.empty : self
# Returns true if the slice contains no elements.
def empty? : Bool
# Fills *count* elements starting at *start* with *value*.
def fill(value : T, start : Int32, count : Int32) : self
# Fills the entire slice with *value*.
def fill(value : T) : self
# Fills the entire slice by yielding each index to the block.
def fill(& : (Int32 -> T)) : self
# Returns a lowercase hex string representation of Bytes.
def hexstring : String
# Creates a slice wrapping *pointer* bounded by *size*.
#
# `read_only` is named in this and every `Slice.new`, as in the other
# library. Positional, it took the value's place when `T` is `Bool`:
# `Slice(Bool).new(3, true)` was `Slice[false, false, false]`, read-only.
def initialize(pointer : Pointer(T), size : Int32, *, read_only : Bool = false)
def inspect : String
# Moves *count* elements from *source* pointer into this slice, safely handling overlaps.
def move_from(source : Pointer(T), count : Int32) : Nil
# Moves all elements from *source* slice into this slice, safely handling overlaps.
def move_from(source : Slice(T)) : Nil
# Moves *count* elements from this slice into *target* pointer, safely handling overlaps.
def move_to(target : Pointer(T), count : Int32) : Nil
# Moves all elements from this slice into *target* slice, safely handling overlaps.
def move_to(target : Slice(T)) : Nil
# Allocates a slice of *size* elements initialized to *value*.
#
# These three answer `Slice(T)`, not `self`, as `Array.new` does: when the
# element type is left to the value or the block, `self` is still the
# unbound `Slice(T)` while the body builds `Slice(Int32)`, so
# `Slice.new(3) { |i| i + 1 }` and `Slice.new(3, 7)` did not compile.
def self.new(size : Int32, value : T, *, read_only : Bool = false) : Slice(T)
# Allocates a slice of *size* elements on the heap.
def self.new(size : Int32, *, read_only : Bool = false) : self
# Allocates a slice of *size* elements initialized by yielding each index.
def self.new(size : Int32, & : (Int32 -> T)) : Slice(T)
def self.new(size : Int32, *, read_only : Bool, & : (Int32 -> T)) : Slice(T)
def read_only? : Bool
# Reverses the elements of the slice in-place.
def reverse : self
def reverse_in_place : self
# Returns true if this slice and *other* point to the exact same memory and have the same size.
def same?(other : Slice(T)) : Bool
def size : Int32
# Swaps elements at index *i* and index *j*.
def swap(i : Int32, j : Int32) : self
# Returns an Array containing all elements in this slice.
def to_a : Array(T)
# String representation: Bytes[...] for Slice(UInt8), Slice[...] for others.
def to_s : String
# Raw pointer to the underlying buffer.
def to_unsafe : Pointer(T)
# Raw element access without bounds checks (required for Indexable).
def unsafe_fetch(index : Int32) : T
# Raw element write without bounds checks.
def unsafe_put(index : Int32, value : T) : T
endSliceIterator(T)class
The lazy half, which Slice had no way into: std/iterator's header says a concrete collection provides its own iterator constructor and names this type twice as one that should, and then the only route from a slice to a lazy chain was fs.to_a — copying the whole sequence, which is the cost the tower exists to avoid.
A class, as ArrayIterator is (std/iterator): an adaptor keeps its source by value, and a struct source was copied into it, so it.first(2).to_a and then it.to_a gave [1, 2] and [1, 2, 3, 4] where an array's iterator gives [1, 2] and [3, 4].
pub class SliceIterator(T)
def initialize(slice : Slice(T))
def next : T | Stop
endStd::Indexable::Indexable for Slice(T) forall Timpl
impl Std::Indexable::Indexable for Slice(T) forall T
endStd::Enumerable::Enumerable for Slice(T) forall Timpl
impl Std::Enumerable::Enumerable for Slice(T) forall T
def each(& : (T -> Nil)) : Nil
endStd::Iterator::Iterator for SliceIterator(T) forall Timpl
impl Std::Iterator::Iterator for SliceIterator(T) forall T
end
Slice, a bounded pointer — SPEC.md III.