struct Slice(T)

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.

Included Modules

Defined in:

slice.cr

Class Method Summary

Instance Method Summary

Macro Summary

Instance methods inherited from module Indexable({"T", T})

[](index : Int) [], []?(index : Int) []?, at(index : Int, &block)
at(index : Int)
at
, bsearch(&block) bsearch, bsearch_index(&block) bsearch_index, each(&block)
each
each
, each_index(&block)
each_index
each_index
, empty? empty?, equals?(other, &block) equals?, first(&block)
first
first
, first? first?, hash hash, index(object, offset : Int = 0)
index(offset : Int = 0, &block)
index
, last
last(&block)
last
, last? last?, reverse_each(&block)
reverse_each
reverse_each
, rindex(offset = size - 1, &block)
rindex(value, offset = size - 1)
rindex
, sample(random = Random::DEFAULT) sample, size size, unsafe_at(index : Int) unsafe_at, values_at(*indexes : Int) values_at

Instance methods inherited from module Iterable({"T", T})

chunk(&block : T -> U) forall U chunk, cycle(n)
cycle
cycle
, each each, each_cons(count : Int) each_cons, each_slice(count : Int) each_slice, each_with_index(offset = 0) each_with_index, each_with_object(obj) each_with_object

Instance methods inherited from module Enumerable({"T", T})

all?(&block)
all?
all?
, any?(&block)
any?
any?
, chunks(&block : T -> U) chunks, compact_map(&block) compact_map, count(&block)
count(item)
count
, cycle(n, &block)
cycle(&block)
cycle
, each(&block : T -> _) each, each_cons(count : Int, &block) each_cons, each_slice(count : Int, &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) | 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, &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, io)
join(separator = "")
join(separator, io, &block)
join(separator = "", &block)
join
, map(&block : T -> U) forall U map, map_with_index(&block : T, Int32 -> 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?(&block)
none?
none?
, one?(&block) one?, partition(&block) partition, product(&block)
product(initial : Number, &block)
product
product(initial : Number)
product
, reduce(&block)
reduce(memo, &block)
reduce
, reject(&block : T -> ) reject, 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, to_a to_a, to_h to_h, to_set to_set

Instance methods inherited from struct Struct

==(other : self) : Bool ==, hash : Int32 hash, inspect(io : IO) : Nil inspect, to_s(io) to_s

Instance methods inherited from struct Value

==(other) ==, dup dup

Instance methods inherited from class Object

!=(other) !=, !~(other) !~, ==(other) ==, ===(other : JSON::Any)
===(other : YAML::Any)
===(other)
===
, =~(other) =~, class class, crystal_type_id crystal_type_id, dup dup, hash hash, inspect(io : IO)
inspect
inspect
, itself itself, not_nil! not_nil!, tap(&block) tap, to_json to_json, to_pretty_json(indent : String = " ")
to_pretty_json(io : IO, indent : String = " ")
to_pretty_json
, to_s
to_s(io : IO)
to_s
, to_yaml(io : IO)
to_yaml
to_yaml
, try(&block) try

Class methods inherited from class Object

==(other : Class) ==, ===(other) ===, cast(other) : self cast, clone clone, dup dup, from_json(string_or_io, root : String) : self
from_json(string_or_io) : self
from_json
, from_yaml(string : String) : self from_yaml, hash hash, inspect(io) inspect, name : String name, nilable? nilable?, to_s(io) to_s, |(other : U.class) forall U |

Class Method Detail

def self.new(pointer : Pointer(T), size : Int) #

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      # => [97, 98, 99]

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

[View source]
def self.new(size : Int, value : T) #

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 # => [10, 10, 10]

[View source]
def self.new(size : Int) #

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.

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

[View source]
def self.new(size : Int, &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 # => [10, 11, 12]

[View source]

Instance Method Detail

def +(offset : Int) #

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

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

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

[View source]
def ==(other : self) #

[View source]
def [](start, count) #

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 # => [10, 11, 12, 13, 14]

slice2 = slice[1, 3]
slice2 # => [11, 12, 13]

[View source]
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 # => [20, 11, 12, 13, 30]

slice[4] = 1 # => IndexError

[View source]
def bytesize #

[View source]
def copy_from(source : self) #

Copies the contents of source into this slice.

Truncates if the other slice doesn't fit. The same as source.copy_to(self).


[View source]
def copy_from(source : Pointer(T), count) #

[View source]
def copy_to(target : self) #

Copies the contents of this slice into target.

Raises 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 # => IndexError

[View source]
def copy_to(target : Pointer(T), count) #

[View source]
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>?.."

[View source]
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 # => "61626308ff"

[View source]
def inspect(io) #

[View source]
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.

Truncates if the other slice doesn't fit. The same as source.move_to(self).


[View source]
def move_from(source : Pointer(T), count) #

[View source]
def move_to(target : Pointer(T), count) #

[View source]
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 if the desination slice cannot fit the data being transferred e.g. dest.size < self.size.

See Pointer#move_to

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 # => IndexError

[View source]
def pointer(size) #

[View source]
def reverse! #

Reverses in-place all the elements of self.


[View source]
def shuffle!(random = Random::DEFAULT) #

[View source]
def size : Int32 #

Returns the size of this slice.

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

[View source]
def to_a #

[View source]
def to_s(io) #

[View source]
def to_slice #

[View source]
def to_unsafe : Pointer(T) #

Returns this slice's pointer.

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

[View source]
def unsafe_at(index : Int) #

[View source]

Macro Detail

macro [](*args) #

Create 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.


[View source]