# struct BitArray

- BitArray
- Struct
- Value
- Object

##
Overview

`BitArray` is an array data structure that compactly stores bits.

Bits externally represented as `Bool`s are stored internally as `UInt32`s. The total number of bits stored is set at creation and is immutable.

###
Example

    require "bit_array"

    ba = BitArray.new(12) # => "BitArray[000000000000]"
    ba[2]                 # => false
    0.upto(5) { |i| ba[i * 2] = true }
    ba    # => "BitArray[101010101010]"
    ba[2] # => true

##
Included Modules

- Indexable(Bool)

##
Defined in:

##
Constructors

- .new(size, initial : Bool = false)

  Creates a new `BitArray` of size bits.

##
Instance Method Summary

- #==(other : BitArray)
- #==(other)

  Returns `true` if this struct is equal to other.

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

  Returns count or less (if there aren't enough) elements starting at the given start index.

- #[](range : Range)

  Returns all elements that are within the given range.

- #[]=(index, value : Bool)

  Sets the bit at the given index.

- #hash(hasher)

  See `Object#hash(hasher)`

- #inspect(io : IO) : Nil

  Creates a string representation of self.

- #invert

  Inverts all bits in the array.

- #size : Int32

  The number of bits the BitArray stores

- #to_s(io : IO) : Nil

  Creates a string representation of self.

- #to_slice : Bytes

  Returns a `Bytes` able to read and write bytes from a buffer.

- #toggle(index)

  Toggles the bit at the given index.

- #unsafe_fetch(index : Int)

  Returns the element at the given index, without doing any bounds check.

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

[](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(Bool)`

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(Bool)`

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) =~, __crystal_pseudo_! : Bool __crystal_pseudo_!, __crystal_pseudo_as(type : Class) __crystal_pseudo_as, __crystal_pseudo_as?(type : Class) __crystal_pseudo_as?, __crystal_pseudo_is_a?(type : Class) : Bool __crystal_pseudo_is_a?, __crystal_pseudo_nil? : Bool __crystal_pseudo_nil?, __crystal_pseudo_responds_to?(name : Symbol) : Bool __crystal_pseudo_responds_to?, class class, dup dup, hash(hasher)
hash hash, inspect : String
inspect(io : IO) : Nil 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(&) 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

def self.new(size, initial : Bool = false) #

Creates a new `BitArray` of size bits.

initial optionally sets the starting value, `true` or `false`, for all bits in the array.

##
Instance Method Detail

def ==(other : BitArray) #
def ==(other) #
Description copied from struct Struct

Returns `true` if this struct is equal to other.

Both structs's instance vars are compared to each other. Thus, two structs are considered equal if each of their instance variables are equal. Subclasses should override this method to provide specific equality semantics.

    struct Point
      def initialize(@x : Int32, @y : Int32)
      end
    end

    p1 = Point.new 1, 2
    p2 = Point.new 1, 2
    p3 = Point.new 3, 4

    p1 == p2 # => true
    p1 == p3 # => false

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

Returns count or less (if there aren't enough) elements starting at the given start index.

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

Raises `IndexError` if the starting index is out of range.

    require "bit_array"

    ba = BitArray.new(5)
    ba[0] = true; ba[2] = true; ba[4] = true
    ba # => BitArray[10101]

    ba[-3, 3] # => BitArray[101]
    ba[6, 1]  # raise indexError
    ba[1, 2]  # => BitArray[01]
    ba[5, 1]  # => BitArray[]

def [](range : Range) #

Returns all elements that are within the given range.

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

Raises `IndexError` if the starting index is out of range.

    require "bit_array"

    ba = BitArray.new(5)
    ba[0] = true; ba[2] = true; ba[4] = true
    ba # => BitArray[10101]

    ba[1..3]    # => BitArray[010]
    ba[4..7]    # => BitArray[1]
    ba[6..10]   # raise IndexError
    ba[5..10]   # => BitArray[]
    ba[-2...-1] # => BitArray[0]

def []=(index, value : Bool) #

Sets the bit at the given index. Negative indices can be used to start counting from the end of the array. Raises `IndexError` if trying to access a bit outside the array's range.

    require "bit_array"

    ba = BitArray.new(5)
    ba[3] = true

def hash(hasher) #

See `Object#hash(hasher)`

def inspect(io : IO) : Nil #

Creates a string representation of self.

    require "bit_array"

    ba = BitArray.new(5)
    ba.to_s # => "BitArray[00000]"

def invert #

Inverts all bits in the array. Falses become `true` and vice versa.

    require "bit_array"

    ba = BitArray.new(5)
    ba[2] = true; ba[3] = true
    ba # => BitArray[00110]
    ba.invert
    ba # => BitArray[11001]

def size : Int32 #

The number of bits the BitArray stores

def to_s(io : IO) : Nil #

Creates a string representation of self.

    require "bit_array"

    ba = BitArray.new(5)
    ba.to_s # => "BitArray[00000]"

def to_slice : Bytes #

Returns a `Bytes` able to read and write bytes from a buffer. The slice will be long enough to hold all the bits groups in bytes despite the `UInt32` internal representation. It's useful for reading and writing a bit array from a byte buffer directly.

def toggle(index) #

Toggles the bit at the given index. A false bit becomes a `true` bit, and vice versa. Negative indices can be used to start counting from the end of the array. Raises `IndexError` if trying to access a bit outside the array's range.

    require "bit_array"

    ba = BitArray.new(5)
    ba[3] # => false
    ba.toggle(3)
    ba[3] # => true

def unsafe_fetch(index : Int) #
Description copied from module Indexable(Bool)

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.