# Module `0x1::bit_vector`
- [Struct `BitVector`](#0x1_bit_vector_BitVector)
- [Constants](#@Constants_0)
- [Function `new`](#0x1_bit_vector_new)
- [Function `set`](#0x1_bit_vector_set)
- [Function `unset`](#0x1_bit_vector_unset)
- [Function `shift_left`](#0x1_bit_vector_shift_left)
- [Function `is_index_set`](#0x1_bit_vector_is_index_set)
- [Function `length`](#0x1_bit_vector_length)
- [Function `longest_set_sequence_starting_at`](#0x1_bit_vector_longest_set_sequence_starting_at)
## Struct `BitVector`
struct BitVector has copy, drop, store
Fields
-
length: u64
-
-
bit_field: vector<bool>
-
## Constants
The provided index is out of bounds
const EINDEX: u64 = 131072;
An invalid length of bitvector was given
const ELENGTH: u64 = 131073;
The maximum allowed bitvector size
const MAX_SIZE: u64 = 1024;
const WORD_SIZE: u64 = 1;
## Function `new`
public fun new(length: u64): bit_vector::BitVector
Implementation
public fun new(length: u64): BitVector {
assert!(length > 0, ELENGTH);
assert!(length < MAX_SIZE, ELENGTH);
let counter = 0;
let bit_field = vector::empty();
while ({spec {
invariant counter <= length;
invariant len(bit_field) == counter;
};
(counter < length)}) {
vector::push_back(&mut bit_field, false);
counter = counter + 1;
};
spec {
assert counter == length;
assert len(bit_field) == length;
};
BitVector {
length,
bit_field,
}
}
Specification
include NewAbortsIf;
ensures result.length == length;
ensures len(result.bit_field) == length;
schema NewAbortsIf {
length: u64;
aborts_if length <= 0 with ELENGTH;
aborts_if length >= MAX_SIZE with ELENGTH;
}
## Function `set`
Set the bit at bit_index
in the bitvector
regardless of its previous state.
public fun set(bitvector: &mut bit_vector::BitVector, bit_index: u64)
Implementation
public fun set(bitvector: &mut BitVector, bit_index: u64) {
assert!(bit_index < vector::length(&bitvector.bit_field), EINDEX);
let x = vector::borrow_mut(&mut bitvector.bit_field, bit_index);
*x = true;
}
Specification
include SetAbortsIf;
ensures bitvector.bit_field[bit_index];
schema SetAbortsIf {
bitvector: BitVector;
bit_index: u64;
aborts_if bit_index >= length(bitvector) with EINDEX;
}
include UnsetAbortsIf;
ensures bitvector.bit_field[bit_index];
schema UnsetAbortsIf {
bitvector: BitVector;
bit_index: u64;
aborts_if bit_index >= length(bitvector) with EINDEX;
}
## Function `unset`
Unset the bit at bit_index
in the bitvector
regardless of its previous state.
public fun unset(bitvector: &mut bit_vector::BitVector, bit_index: u64)
Implementation
public fun unset(bitvector: &mut BitVector, bit_index: u64) {
assert!(bit_index < vector::length(&bitvector.bit_field), EINDEX);
let x = vector::borrow_mut(&mut bitvector.bit_field, bit_index);
*x = false;
}
## Function `shift_left`
Shift the bitvector
left by amount
. If amount
is greater than the
bitvector's length the bitvector will be zeroed out.
public fun shift_left(bitvector: &mut bit_vector::BitVector, amount: u64)
Implementation
public fun shift_left(bitvector: &mut BitVector, amount: u64) {
if (amount >= bitvector.length) {
let len = vector::length(&bitvector.bit_field);
let i = 0;
while (i < len) {
let elem = vector::borrow_mut(&mut bitvector.bit_field, i);
*elem = false;
i = i + 1;
};
} else {
let i = amount;
while (i < bitvector.length) {
if (is_index_set(bitvector, i)) set(bitvector, i - amount)
else unset(bitvector, i - amount);
i = i + 1;
};
i = bitvector.length - amount;
while (i < bitvector.length) {
unset(bitvector, i);
i = i + 1;
};
}
}
## Function `is_index_set`
Return the value of the bit at bit_index
in the bitvector
. true
represents "1" and false
represents a 0
public fun is_index_set(bitvector: &bit_vector::BitVector, bit_index: u64): bool
Implementation
public fun is_index_set(bitvector: &BitVector, bit_index: u64): bool {
assert!(bit_index < vector::length(&bitvector.bit_field), EINDEX);
*vector::borrow(&bitvector.bit_field, bit_index)
}
Specification
include IsIndexSetAbortsIf;
ensures result == bitvector.bit_field[bit_index];
schema IsIndexSetAbortsIf {
bitvector: BitVector;
bit_index: u64;
aborts_if bit_index >= length(bitvector) with EINDEX;
}
fun spec_is_index_set(bitvector: BitVector, bit_index: u64): bool {
if (bit_index >= length(bitvector)) {
false
} else {
bitvector.bit_field[bit_index]
}
}
## Function `length`
Return the length (number of usable bits) of this bitvector
public fun length(bitvector: &bit_vector::BitVector): u64
Implementation
public fun length(bitvector: &BitVector): u64 {
vector::length(&bitvector.bit_field)
}
## Function `longest_set_sequence_starting_at`
Returns the length of the longest sequence of set bits starting at (and
including) start_index
in the bitvector
. If there is no such
sequence, then 0
is returned.
public fun longest_set_sequence_starting_at(bitvector: &bit_vector::BitVector, start_index: u64): u64
Implementation
public fun longest_set_sequence_starting_at(bitvector: &BitVector, start_index: u64): u64 {
assert!(start_index < bitvector.length, EINDEX);
let index = start_index;
// Find the greatest index in the vector such that all indices less than it are set.
while (index < bitvector.length) {
if (!is_index_set(bitvector, index)) break;
index = index + 1;
};
index - start_index
}
[//]: # ("File containing references which can be used from documentation")