Slice(T) -

# struct Slice(T)

- Slice(T)
- Struct
- Value
- Object

## Overview

A `Slice` is a `Pointer` with an associated size.

While a pointer is unsafe because no bound checks are performed when reading from and writing to it, reading from and writing to a slice involve bound checks. In this way, a slice is a safe alternative to `Pointer`.

A Slice can be created as read-only: trying to write to it will raise. For example the slice of bytes returned by `String#to_slice` is read-only.

## Included Modules

- Indexable(T)

## Defined in:

## Constructors

- .new(ctx : YAML::ParseContext, node : YAML::Nodes::Node)
- .new(pointer : Pointer(T), size : Int, *, read_only = false)

  Creates a slice to the given pointer, bounded by the given size.

- .new(size : Int, value : T, *, read_only = false)

  Allocates `size * sizeof(T)` bytes of heap memory initialized to value and returns a slice pointing to that memory.

- .new(size : Int, *, read_only = false)

  Allocates `size * sizeof(T)` bytes of heap memory initialized to zero and returns a slice pointing to that memory.

- .new(size : Int, *, read_only = false, &block)

  Allocates `size * sizeof(T)` bytes of heap memory initialized to the value returned by the block (which is invoked once with each index in the range `0...size`) and returns a slice pointing to that memory.

## Class Method Summary

- .empty

  Creates an empty slice.

## Instance Method Summary

- #+(offset : Int)

  Returns a new slice that is offset elements apart from this slice.

- #==(other : self)
- #[](start : Int, count : Int)

  Returns a new slice that starts at start elements from this slice's start, and of count size.

- #[](range : Range)

  Returns a new slice with the elements in the given range.

- #[]=(index : Int, value : T)

  Sets the given value at the given index.

- #[]?(start : Int, count : Int)

  Returns a new slice that starts at start elements from this slice's start, and of count size.

- #[]?(range : Range)

  Returns a new slice with the elements in the given range.

- #bytesize
- #clone

  Returns a deep copy of this slice.

- #copy_from(source : self)

  Copies the contents of source into this slice.

- #copy_from(source : Pointer(T), count)
- #copy_to(target : Pointer(T), count)
- #copy_to(target : self)

  Copies the contents of this slice into target.

- #dup

  Returns a shallow copy of this slice.

- #hash(hasher)

  See `Object#hash(hasher)`

- #hexdump

  Returns a hexdump of this slice, assuming it's a `Slice(UInt8)`.

- #hexstring

  Returns a hexstring representation of this slice, assuming it's a `Slice(UInt8)`.

- #inspect(io : IO) : Nil
- #map(*, read_only = false, &block : T -> U) forall U

  Returns a new slice where elements are mapped by the given block.

- #map!(&block)

  Invokes the given block for each element of `self`, replacing the element with the value returned by the block.

- #map_with_index(*, read_only = false, &block : T, Int32 -> U) forall U

  Like `#map`, but the block gets passed both the element and its index.

- #map_with_index!(&block : T, Int32 -> T)

  Like `#map!`, but the block gets passed both the element and its index.

- #move_from(source : self)

  Moves the contents of source into this slice.

- #move_from(source : Pointer(T), count)
- #move_to(target : Pointer(T), count)
- #move_to(target : self)

  Moves the contents of this slice into target.

- #pretty_print(pp) : Nil
- #read_only? : Bool

  Returns `true` if this slice cannot be written to.

- #reverse!

  Reverses in-place all the elements of `self`.

- #shuffle!(random = Random::DEFAULT)
- #size : Int32

  Returns the size of this slice.

- #sort : Slice(T)

  Returns a new slice with all elements sorted based on the return value of their comparison method `<=>`

- #sort(&block : T, T -> U) : Slice(T) forall U

  Returns a new slice with all elements sorted based on the comparator in the given block.

- #sort! : Slice(T)

  Modifies `self` by sorting all elements based on the return value of their comparison method `<=>`

- #sort!(&block : T, T -> U) : Slice(T) forall U

  Modifies `self` by sorting all elements based on the comparator in the given block.

- #sort_by(&block : T -> UNDERSCORE) : Slice(T)

  Returns a new array with all elements sorted.

- #sort_by!(&block : T -> UNDERSCORE) : Slice(T)

  Modifies `self` by sorting all elements.

- #to_a
- #to_s(io : IO) : Nil
- #to_slice
- #to_unsafe : Pointer(T)

  Returns this slice's pointer.

- #to_yaml(yaml : YAML::Nodes::Builder)
- #unsafe_fetch(index : Int)

## Macro Summary

- [](*args, read_only = false)

  Creates a new `Slice` with the given args.

### Instance methods inherited from module `Indexable(T)`

[](index : Int) [], []?(index : Int) []?, bsearch(&block : T -> Bool) bsearch, bsearch_index(&block : T, Int32 -> Bool) bsearch_index, dig(index : Int, *subindexes) dig, dig?(index : Int, *subindexes) dig?, each(*, start : Int, count : Int, &block)
each(*, within range : Range, &block)
each(&block)
each each, each_index(*, start : Int, count : Int, &block)
each_index(&block) : Nil
each_index each_index, empty? empty?, equals?(other : Indexable, &block)
equals?(other, &block) equals?, fetch(index, default)
fetch(index : Int, &block) fetch, first
first(&block) first, first? first?, hash(hasher) hash, index(object, offset : Int = 0)
index(offset : Int = 0, &block) index, join(separator = "") join, last
last(&block) last, last? last?, reverse_each(&block) : Nil
reverse_each reverse_each, rindex(offset = size - 1, &block)
rindex(value, offset = size - 1) rindex, sample(random = Random::DEFAULT) sample, size size, to_a to_a, unsafe_fetch(index : Int) unsafe_fetch, values_at(*indexes : Int) values_at

### Instance methods inherited from module `Enumerable(T)`

all?(&block)
all?(pattern)
all? all?, any?(&block)
any?(pattern)
any? any?, chunks(&block : T -> U) forall U chunks, compact_map(&block) compact_map, count(item)
count(&block) count, cycle(&block)
cycle(n, &block) cycle, each(&block : T -> UNDERSCORE) each, each_cons(count : Int, reuse = false, &block) each_cons, each_slice(count : Int, reuse = false, &block) each_slice, each_with_index(offset = 0, &block) each_with_index, each_with_object(obj, &block) each_with_object, find(if_none = nil, &block) find, first(count : Int)
first first, first? first?, flat_map(&block : T -> Array(U) | Iterator(U) | U) forall U flat_map, grep(pattern) grep, group_by(&block : T -> U) forall U group_by, in_groups_of(size : Int, filled_up_with : U = nil) forall U
in_groups_of(size : Int, filled_up_with : U = nil, reuse = false, &block) forall U in_groups_of, includes?(obj) includes?, index(&block)
index(obj) index, index_by(&block : T -> U) forall U index_by, join(separator = "", &block)
join(separator, io, &block)
join(separator, io)
join(separator = "") join, map(&block : T -> U) forall U map, map_with_index(&block : T, Int32 -> U) forall U map_with_index, max max, max? max?, max_by(&block : T -> U) forall U max_by, max_by?(&block : T -> U) forall U max_by?, max_of(&block : T -> U) forall U max_of, max_of?(&block : T -> U) forall U max_of?, min min, min? min?, min_by(&block : T -> U) forall U min_by, min_by?(&block : T -> U) forall U min_by?, min_of(&block : T -> U) forall U min_of, min_of?(&block : T -> U) forall U min_of?, minmax minmax, minmax? minmax?, minmax_by(&block : T -> U) forall U minmax_by, minmax_by?(&block : T -> U) forall U minmax_by?, minmax_of(&block : T -> U) forall U minmax_of, minmax_of?(&block : T -> U) forall U minmax_of?, none?
none?(pattern)
none?(&block) none?, one?(&block)
one?(pattern)
one? one?, partition(&block) partition, product(&block)
product(initial : Number, &block)
product
product(initial : Number) product, reduce(memo, &block)
reduce(&block) reduce, reduce?(&block) reduce?, reject(&block : T -> )
reject(type : U.class) forall U
reject(pattern) reject, select(pattern)
select(type : U.class) forall U
select(&block : T -> ) select, size size, skip(count : Int) skip, skip_while(&block) skip_while, sum(initial)
sum
sum(initial, &block)
sum(&block) sum, take_while(&block) take_while, tally : Hash(T, Int32) tally, to_a to_a, to_h
to_h(&block : T -> Tuple(K, V)) forall K, V to_h, to_set to_set, zip(*others : Indexable | Iterable | Iterator, &block)
zip(*others : Indexable | Iterable | Iterator) zip, zip?(*others : Indexable | Iterable | Iterator, &block)
zip?(*others : Indexable | Iterable | Iterator) zip?

### Instance methods inherited from module `Iterable(T)`

chunk(reuse = false, &block : T -> U) forall U chunk, chunk_while(reuse : Bool | Array(T) = false, &block : T, T -> B) forall B chunk_while, cycle(n)
cycle cycle, each each, each_cons(count : Int, reuse = false) each_cons, each_slice(count : Int, reuse = false) each_slice, each_with_index(offset = 0) each_with_index, each_with_object(obj) each_with_object, slice_after(reuse : Bool | Array(T) = false, &block : T -> B) forall B
slice_after(pattern, reuse : Bool | Array(T) = false) slice_after, slice_before(reuse : Bool | Array(T) = false, &block : T -> B) forall B
slice_before(pattern, reuse : Bool | Array(T) = false) slice_before, slice_when(reuse : Bool | Array(T) = false, &block : T, T -> B) forall B slice_when

### Instance methods inherited from struct `Struct`

==(other) : Bool ==, hash(hasher) hash, inspect(io : IO) : Nil inspect, pretty_print(pp) : Nil pretty_print, to_s(io : IO) : Nil to_s

### Instance methods inherited from struct `Value`

==(other : JSON::Any)
==(other : YAML::Any)
==(other) ==, dup dup

### Instance methods inherited from class `Object`

!=(other) !=, !~(other) !~, ==(other) ==, ===(other : JSON::Any)
===(other : YAML::Any)
===(other) ===, =~(other) =~, class class, dup dup, hash(hasher)
hash hash, inspect(io : IO) : Nil
inspect : String inspect, itself itself, not_nil! not_nil!, pretty_inspect(width = 79, newline = "\n", indent = 0) : String pretty_inspect, pretty_print(pp : PrettyPrint) : Nil pretty_print, tap(&block) tap, to_json(io : IO)
to_json to_json, to_pretty_json(indent : String = " ")
to_pretty_json(io : IO, indent : String = " ") to_pretty_json, to_s : String
to_s(io : IO) : Nil to_s, to_yaml(io : IO)
to_yaml to_yaml, try(&block) try, unsafe_as(type : T.class) forall T unsafe_as

### Constructor methods inherited from class `Object`

from_json(string_or_io, root : String) : self
from_json(string_or_io) : self from_json, from_yaml(string_or_io : String | IO) : self from_yaml

## Constructor Detail

def self.new(ctx : YAML::ParseContext, node : YAML::Nodes::Node) #
def self.new(pointer : Pointer(T), size : Int, *, read_only = false) #

Creates a slice to the given pointer, bounded by the given size. This method does not allocate heap memory.

    ptr = Pointer.malloc(9) { |i| ('a'.ord + i).to_u8 }

    slice = Slice.new(ptr, 3)
    slice.size # => 3
    slice      # => Bytes[97, 98, 99]

    String.new(slice) # => "abc"

def self.new(size : Int, value : T, *, read_only = false) #

Allocates `size * sizeof(T)` bytes of heap memory initialized to value and returns a slice pointing to that memory.

The memory is allocated by the `GC`, so when there are no pointers to this memory, it will be automatically freed.

    slice = Slice.new(3, 10)
    slice # => Slice[10, 10, 10]

def self.new(size : Int, *, read_only = false) #

Allocates `size * sizeof(T)` bytes of heap memory initialized to zero and returns a slice pointing to that memory.

The memory is allocated by the `GC`, so when there are no pointers to this memory, it will be automatically freed.

Only works for primitive integers and floats (`UInt8`, `Int32`, `Float64`, etc.)

    slice = Slice(UInt8).new(3)
    slice # => Bytes[0, 0, 0]

def self.new(size : Int, *, read_only = false, &block) #

Allocates `size * sizeof(T)` bytes of heap memory initialized to the value returned by the block (which is invoked once with each index in the range `0...size`) and returns a slice pointing to that memory.

The memory is allocated by the `GC`, so when there are no pointers to this memory, it will be automatically freed.

    slice = Slice.new(3) { |i| i + 10 }
    slice # => Slice[10, 11, 12]

## Class Method Detail

def self.empty #

Creates an empty slice.

    slice = Slice(UInt8).empty
    slice.size # => 0

## Instance Method Detail

def +(offset : Int) #

Returns a new slice that is offset elements apart from this slice.

    slice = Slice.new(5) { |i| i + 10 }
    slice # => Slice[10, 11, 12, 13, 14]

    slice2 = slice + 2
    slice2 # => Slice[12, 13, 14]

def ==(other : self) #
def [](start : Int, count : Int) #

Returns a new slice that starts at start elements from this slice's start, and of count size.

Raises `IndexError` if the new slice falls outside this slice.

    slice = Slice.new(5) { |i| i + 10 }
    slice # => Slice[10, 11, 12, 13, 14]

    slice[1, 3]  # => Slice[11, 12, 13]
    slice[1, 33] # raises IndexError

def [](range : Range) #

Returns a new slice with the elements in the given range.

Negative indices count backward from the end of the slice (`-1` is the last element). Additionally, an empty slice is returned when the starting index for an element range is at the end of the slice.

Raises `IndexError` if the new slice falls outside this slice.

    slice = Slice.new(5) { |i| i + 10 }
    slice # => Slice[10, 11, 12, 13, 14]

    slice[1..3]  # => Slice[11, 12, 13]
    slice[1..33] # raises IndexError

def []=(index : Int, value : T) #

Sets the given value at the given index.

Negative indices can be used to start counting from the end of the slice. Raises `IndexError` if trying to set an element outside the slice's range.

    slice = Slice.new(5) { |i| i + 10 }
    slice[0] = 20
    slice[-1] = 30
    slice # => Slice[20, 11, 12, 13, 30]

    slice[10] = 1 # raises IndexError

def []?(start : Int, count : Int) #

Returns a new slice that starts at start elements from this slice's start, and of count size.

Returns `nil` if the new slice falls outside this slice.

    slice = Slice.new(5) { |i| i + 10 }
    slice # => Slice[10, 11, 12, 13, 14]

    slice[1, 3]?  # => Slice[11, 12, 13]
    slice[1, 33]? # => nil

def []?(range : Range) #

Returns a new slice with the elements in the given range.

Negative indices count backward from the end of the slice (`-1` is the last element). Additionally, an empty slice is returned when the starting index for an element range is at the end of the slice.

Returns `nil` if the new slice falls outside this slice.

    slice = Slice.new(5) { |i| i + 10 }
    slice # => Slice[10, 11, 12, 13, 14]

    slice[1..3]?  # => Slice[11, 12, 13]
    slice[1..33]? # => nil

def bytesize #
def clone #

Returns a deep copy of this slice.

This method allocates memory for the slice copy and stores the return values from calling `#clone` on each item.

def copy_from(source : self) #

Copies the contents of source into this slice.

Raises `IndexError` if the desination slice cannot fit the data being transferred.

def copy_from(source : Pointer(T), count) #
def copy_to(target : Pointer(T), count) #
def copy_to(target : self) #

Copies the contents of this slice into target.

Raises `IndexError` if the desination slice cannot fit the data being transferred e.g. dest.size < self.size.

    src = Slice['a', 'a', 'a']
    dst = Slice['b', 'b', 'b', 'b', 'b']
    src.copy_to dst
    dst             # => Slice['a', 'a', 'a', 'b', 'b']
    dst.copy_to src # raises IndexError

def dup #

Returns a shallow copy of this slice.

This method allocates memory for the slice copy and duplicates the values.

def hash(hasher) #

See `Object#hash(hasher)`

def hexdump #

Returns a hexdump of this slice, assuming it's a `Slice(UInt8)`. This method is specially useful for debugging binary data and incoming/outgoing data in protocols.

    slice = UInt8.slice(97, 62, 63, 8, 255)
    slice.hexdump # => "00000000  61 3e 3f 08 ff                                    a>?.."

def hexstring #

Returns a hexstring representation of this slice, assuming it's a `Slice(UInt8)`.

    slice = UInt8.slice(97, 62, 63, 8, 255)
    slice.hexstring # => "613e3f08ff"

def inspect(io : IO) : Nil #
def map(*, read_only = false, &block : T -> U) forall U #

Returns a new slice where elements are mapped by the given block.

    slice = Slice[1, 2.5, "a"]
    slice.map &.to_s # => Slice["1", "2.5", "a"]

def map!(&block) #

Invokes the given block for each element of `self`, replacing the element with the value returned by the block. Returns `self`.

    slice = Slice[1, 2, 3]
    slice.map! { |x| x * x }
    slice # => Slice[1, 4, 9]

def map_with_index(*, read_only = false, &block : T, Int32 -> U) forall U #

Like `#map`, but the block gets passed both the element and its index.

def map_with_index!(&block : T, Int32 -> T) #

Like `#map!`, but the block gets passed both the element and its index.

def move_from(source : self) #

Moves the contents of source into this slice. source and `self` may overlap; the copy is always done in a non-destructive manner.

Raises `IndexError` if the desination slice cannot fit the data being transferred.

def move_from(source : Pointer(T), count) #
def move_to(target : Pointer(T), count) #
def move_to(target : self) #

Moves the contents of this slice into target. target and `self` may overlap; the copy is always done in a non-destructive manner.

Raises `IndexError` if the desination slice cannot fit the data being transferred e.g. `dest.size < self.size`.

    src = Slice['a', 'a', 'a']
    dst = Slice['b', 'b', 'b', 'b', 'b']
    src.move_to dst
    dst             # => Slice['a', 'a', 'a', 'b', 'b']
    dst.move_to src # raises IndexError

See also: `Pointer#move_to`.

def pretty_print(pp) : Nil #
def read_only? : Bool #

Returns `true` if this slice cannot be written to.

def reverse! #

Reverses in-place all the elements of `self`.

def shuffle!(random = Random::DEFAULT) #
def size : Int32 #

Returns the size of this slice.

    Slice(UInt8).new(3).size # => 3

def sort : Slice(T) #

Returns a new slice with all elements sorted based on the return value of their comparison method `<=>`

    a = Slice[3, 1, 2]
    a.sort # => Slice[1, 2, 3]
    a      # => Slice[3, 1, 2]

def sort(&block : T, T -> U) : Slice(T) forall U #

Returns a new slice with all elements sorted based on the comparator in the given block.

The block must implement a comparison between two elements a and b, where `a < b` returns `-1`, `a == b` returns `0`, and `a > b` returns `1`. The comparison operator `<=>` can be used for this.

    a = Slice[3, 1, 2]
    b = a.sort { |a, b| b <=> a }

    b # => Slice[3, 2, 1]
    a # => Slice[3, 1, 2]

def sort! : Slice(T) #

Modifies `self` by sorting all elements based on the return value of their comparison method `<=>`

    a = Slice[3, 1, 2]
    a.sort!
    a # => Slice[1, 2, 3]

def sort!(&block : T, T -> U) : Slice(T) forall U #

Modifies `self` by sorting all elements based on the comparator in the given block.

The given block must implement a comparison between two elements a and b, where `a < b` returns `-1`, `a == b` returns `0`, and `a > b` returns `1`. The comparison operator `<=>` can be used for this.

    a = Slice[3, 1, 2]
    a.sort! { |a, b| b <=> a }
    a # => Slice[3, 2, 1]

def sort_by(&block : T -> UNDERSCORE) : Slice(T) #

Returns a new array with all elements sorted. The given block is called for each element, then the comparison method `<=>` is called on the object returned from the block to determine sort order.

    a = Slice["apple", "pear", "fig"]
    b = a.sort_by { |word| word.size }
    b # => Slice["fig", "pear", "apple"]
    a # => Slice["apple", "pear", "fig"]

def sort_by!(&block : T -> UNDERSCORE) : Slice(T) #

Modifies `self` by sorting all elements. The given block is called for each element, then the comparison method `<=>` is called on the object returned from the block to determine sort order.

    a = Slice["apple", "pear", "fig"]
    a.sort_by! { |word| word.size }
    a # => Slice["fig", "pear", "apple"]

def to_a #
def to_s(io : IO) : Nil #
def to_slice #
def to_unsafe : Pointer(T) #

Returns this slice's pointer.

    slice = Slice.new(3, 10)
    slice.to_unsafe[0] # => 10

def to_yaml(yaml : YAML::Nodes::Builder) #
def unsafe_fetch(index : Int) #

## Macro Detail

macro [](*args, read_only = false) #

Creates a new `Slice` with the given args. The type of the slice will be the union of the type of the given args.

The slice is allocated on the heap.

    slice = Slice[1, 'a']
    slice[0]    # => 1
    slice[1]    # => 'a'
    slice.class # => Slice(Char | Int32)

If `T` is a `Number` then this is equivalent to `Number.slice` (numbers will be coerced to the type `T`)

See also: `Number.slice`.