Skip to content

Add each_with_index and each_set_index methods #13

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Jeweler::Tasks.new do |gem|
end
Jeweler::RubygemsDotOrgTasks.new

require 'rake/rdoctask'
require 'rdoc/task'
Rake::RDocTask.new do |rdoc|
version = File.exist?('VERSION') ? File.read('VERSION') : ""

Expand Down
40 changes: 36 additions & 4 deletions ext/bitset/bitset.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,37 @@ static VALUE rb_bitset_each(VALUE self) {
return self;
}

static VALUE rb_bitset_marshall_dump(VALUE self) {
static VALUE rb_bitset_each_with_index(VALUE self) {
Bitset * bs = get_bitset(self);
int i;

for(i = 0; i < bs->len; i++) {
rb_yield_values(2, get_bit(bs, i) > 0 ? Qtrue : Qfalse, INT2NUM(i));
}

return self;
}

static VALUE rb_bitset_each_set_index(VALUE self) {
Bitset * bs = get_bitset(self);
int i, n = INTS(bs);

for(i = 0; i < n; i++) {
uint64_t bits = bs->data[i];
int j = 0;
while (bits) {
if (bits & 1) {
rb_yield(INT2NUM((i << 6) + j));
}
bits >>= 1;
j++;
}
}

return self;
}

static VALUE rb_bitset_marshal_dump(VALUE self) {
Bitset * bs = get_bitset(self);
VALUE hash = rb_hash_new();
VALUE data = rb_str_new(bs->data, BYTES(bs));
Expand All @@ -321,7 +351,7 @@ static VALUE rb_bitset_marshall_dump(VALUE self) {
return hash;
}

static VALUE rb_bitset_marshall_load(VALUE self, VALUE hash) {
static VALUE rb_bitset_marshal_load(VALUE self, VALUE hash) {
Bitset * bs = get_bitset(self);
int len = NUM2INT(rb_hash_aref(hash, ID2SYM(rb_intern("len"))));

Expand Down Expand Up @@ -361,8 +391,10 @@ void Init_bitset() {
rb_define_alias(cBitset, "~", "not");
rb_define_method(cBitset, "hamming", rb_bitset_hamming, 1);
rb_define_method(cBitset, "each", rb_bitset_each, 0);
rb_define_method(cBitset, "each_with_index", rb_bitset_each_with_index, 0);
rb_define_method(cBitset, "each_set_index", rb_bitset_each_set_index, 0);
rb_define_method(cBitset, "to_s", rb_bitset_to_s, 0);
rb_define_singleton_method(cBitset, "from_s", rb_bitset_from_s, 1);
rb_define_method(cBitset, "marshal_dump", rb_bitset_marshall_dump, 0);
rb_define_method(cBitset, "marshal_load", rb_bitset_marshall_load, 1);
rb_define_method(cBitset, "marshal_dump", rb_bitset_marshal_dump, 0);
rb_define_method(cBitset, "marshal_load", rb_bitset_marshal_load, 1);
}
28 changes: 28 additions & 0 deletions spec/bitset_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,34 @@
end
end

describe :each_with_index do
it 'iterates over the bits in the Bitset and provides index' do
bs = Bitset.new(4)
bs.set 0, 2

i = 0
bs.each_with_index do |bit, idx|
bit.should == bs[i]
idx.should == i
i += 1
end
i.should == 4
end
end

describe :each_set_index do
it 'iterates over the set bits in the Bitset by index' do
bs = Bitset.new(100)
bs.set 0, 2, 8, 13, 17, 55, 88, 98

a = []
bs.each_set_index do |idx|
a << idx
end
a.should == [0, 2, 8, 13, 17, 55, 88, 98]
end
end

describe :to_s do
it 'correctly prints out a binary string' do
bs = Bitset.new(4)
Expand Down