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
.
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
Defined in:
slice/sort.crslice.cr
yaml/from_yaml.cr
yaml/to_yaml.cr
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, &)
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 range0...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 : Slice(U)) forall U
Combined comparison operator.
-
#==(other : Slice(U)) : Bool forall U
Returns
true
ifself
and other have the same size and all their elements are equal,false
otherwise. -
#[](range : Range)
Returns a new slice with the elements in the given range.
-
#[](start : Int, count : Int)
Returns a new slice that starts at start elements from this slice's start, and of count size.
-
#[]=(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 : Pointer(T), count)
-
#copy_from(source : self)
Copies the contents of source into this slice.
- #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)
- #hexdump
- #hexstring
-
#inspect(io : IO) : Nil
Appends this struct's name and instance variables names and values to the given IO.
-
#map(*, read_only = false, &block : T -> U) forall U
Returns a new slice where elements are mapped by the given block.
-
#map!(&)
Invokes the given block for each element of
self
, replacing the element with the value returned by the block. -
#map_with_index(offset = 0, *, 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!(offset = 0, &block : T, Int32 -> T)
Like
#map!
, but the block gets passed both the element and its index. - #move_from(source : Pointer(T), count)
-
#move_from(source : self)
Moves the contents of source into this slice.
- #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 -> _) : Slice(T)
Returns a new array with all elements sorted.
-
#sort_by!(&block : T -> _) : Slice(T)
Modifies
self
by sorting all elements. -
#to_a
Returns an
Array
with all the elements in the collection. -
#to_s(io : IO) : Nil
Same as
#inspect(io)
. - #to_slice
-
#to_unsafe : Pointer(T)
Returns this slice's pointer.
- #to_yaml(yaml : YAML::Nodes::Builder)
-
#unsafe_fetch(index : Int)
Returns the element at the given index, without doing any bounds check.
Macro Summary
-
[](*args, read_only = false)
Creates a new
Slice
with the given args.
Instance methods inherited from module Comparable(Slice(T))
<(other : T)
<,
<=(other : T)
<=,
<=>(other : T)
<=>,
==(other : T)
==,
>(other : T)
>,
>=(other : T)
>=,
clamp(min, max)clamp(range : Range) clamp
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, &)each(*, within range : Range, &)
each(&)
each each, each_index(*, start : Int, count : Int, &)
each_index(&) : Nil
each_index each_index, empty? empty?, equals?(other : Indexable, &)
equals?(other, &) equals?, fetch(index, default)
fetch(index : Int, &) fetch, first
first(&) first, first? first?, hash(hasher) hash, index(object, offset : Int = 0)
index(offset : Int = 0, &) index, join(separator = "") join, last
last(&) last, last? last?, reverse_each(&) : Nil
reverse_each reverse_each, rindex(offset = size - 1, &)
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?(&)all?(pattern)
all? all?, any?(&)
any?(pattern)
any? any?, chunks(&block : T -> U) forall U chunks, compact_map(&) compact_map, count(&)
count(item) count, cycle(n, &)
cycle(&) cycle, each(&block : T -> _) each, each_cons(count : Int, reuse = false, &) each_cons, each_cons_pair(& : T, T -> _) : Nil each_cons_pair, each_slice(count : Int, reuse = false, &) each_slice, each_with_index(offset = 0, &) each_with_index, each_with_object(obj, &) each_with_object, find(if_none = nil, &) 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, &) forall U in_groups_of, includes?(obj) includes?, index(&)
index(obj) index, index_by(&block : T -> U) forall U index_by, join(separator = "", &)
join(separator, io, &)
join(separator, io)
join(separator = "") join, map(&block : T -> U) forall U map, map_with_index(offset = 0, &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?(&) none?, one?(&)
one?(pattern)
one? one?, partition(&) partition, product(&)
product(initial : Number, &)
product
product(initial : Number) product, reduce(memo, &)
reduce(&) reduce, reduce?(&) 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(&) skip_while, sum(initial)
sum
sum(initial, &)
sum(&) sum, take_while(&) 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, &)
zip(*others : Indexable | Iterable | Iterator) zip, zip?(*others : Indexable | Iterable | Iterator, &)
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
! : Bool
!,
!=(other)
!=,
!~(other)
!~,
==(other)
==,
===(other : JSON::Any)===(other : YAML::Any)
===(other) ===, =~(other) =~, as(type : Class) as, as?(type : Class) as?, class class, dup dup, hash
hash(hasher) hash, inspect(io : IO) : Nil
inspect : String inspect, is_a?(type : Class) : Bool is_a?, itself itself, nil? : Bool nil?, not_nil! not_nil!, pretty_inspect(width = 79, newline = "\n", indent = 0) : String pretty_inspect, pretty_print(pp : PrettyPrint) : Nil pretty_print, responds_to?(name : Symbol) : Bool responds_to?, tap(&) 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(&) try, unsafe_as(type : T.class) forall T unsafe_as
Class methods inherited from class Object
from_json(string_or_io, root : String)from_json(string_or_io) from_json, from_yaml(string_or_io : String | IO) from_yaml
Constructor Detail
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"
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]
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]
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
Instance Method Detail
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]
Combined comparison operator.
Returns a negative number, 0
, or a positive number depending on
whether self
is less than other, equals other.
It compares the elements of both slices in the same position using the
#<=>
operator. As soon as one of such comparisons returns a non-zero
value, that result is the return value of the comparison.
If all elements are equal, the comparison is based on the size of the arrays.
Bytes[8] <=> Bytes[1, 2, 3] # => 7
Bytes[2] <=> Bytes[4, 2, 3] # => -2
Bytes[1, 2] <=> Bytes[1, 2] # => 0
Returns true
if self
and other have the same size and all their
elements are equal, false
otherwise.
Bytes[1, 2] == Bytes[1, 2] # => true
Bytes[1, 3] == Bytes[1, 2] # => false
Bytes[1, 2] == Bytes[1, 2, 3] # => false
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
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
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
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
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
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.
Copies the contents of source into this slice.
Raises IndexError
if the desination slice cannot fit the data being transferred.
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
Returns a shallow copy of this slice.
This method allocates memory for the slice copy and duplicates the values.
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>?.."
Returns a hexstring representation of this slice, assuming it's
a Slice(UInt8)
.
slice = UInt8.slice(97, 62, 63, 8, 255)
slice.hexstring # => "613e3f08ff"
Appends this struct's name and instance variables names and values to the given IO.
struct Point
def initialize(@x : Int32, @y : Int32)
end
end
p1 = Point.new 1, 2
p1.to_s # "Point(@x=1, @y=2)"
p1.inspect # "Point(@x=1, @y=2)"
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"]
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]
Like #map
, but the block gets passed both the element and its index.
Accepts an optional offset parameter, which tells it to start counting from there.
Like #map!
, but the block gets passed both the element and its index.
Accepts an optional offset parameter, which tells it to start counting from there.
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.
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
.
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]
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]
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]
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]
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"]
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"]
Returns an Array
with all the elements in the collection.
{1, 2, 3}.to_a # => [1, 2, 3]
Returns this slice's pointer.
slice = Slice.new(3, 10)
slice.to_unsafe[0] # => 10
Returns the element at the given index, without doing any bounds check.
Indexable
makes sure to invoke this method with index in 0...size
,
so converting negative indices to positive ones is not needed here.
Clients never invoke this method directly. Instead, they access
elements with #[](index)
and #[]?(index)
.
This method should only be directly invoked if you are absolutely sure the index is in bounds, to avoid a bounds check for a small boost of performance.
Macro Detail
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
.