bitset 0.1.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 67a16f9ffaa21475905ca59bde6734954735e3c7
4
+ data.tar.gz: c734af4e2b220c01b760f1e93fd05940ca79569d
5
+ SHA512:
6
+ metadata.gz: 6603741fd0c7f3a5e348e3db792695fdfc5926062567d401e49b2c66f8ae7e44dc8e1eed66fc8d69859305dc265a3abe2377dad5486ee234da872fa427a9119b
7
+ data.tar.gz: 50f4c82523b31f15d176d7dc26a47be1610135bd4b826f2633abe960394c3fea407d67b7b624dc27148004374f1035968880fb007753c7efd2e440166d429431
@@ -0,0 +1,158 @@
1
+ Bitset
2
+ ======
3
+
4
+ A fast Bitset implementation for Ruby. Available as the 'bitset' gem.
5
+
6
+
7
+ Installation
8
+ ------------
9
+
10
+ Usually you want to do this:
11
+
12
+ gem install bitset
13
+
14
+ But if you want the latest patches or want to work on it yourself, you may want
15
+ to do this:
16
+
17
+ git clone git://github.com/ericboesch/bitset.git
18
+ cd bitset
19
+ rake build
20
+ gem install pkg/bitset-<version>.gem
21
+
22
+
23
+ Usage
24
+ -----
25
+
26
+ You create a bitset like this:
27
+
28
+ >> Bitset.new(8)
29
+ => 00000000
30
+
31
+ Here we created an 8-bit bitset. All bits are initialized to 0.
32
+
33
+ We can also create a bitset based on a string of ones and zeros.
34
+
35
+ >> Bitset.from_s('00010001')
36
+ => 00010001
37
+
38
+ Obviously you can also set and clear bits...
39
+
40
+ >> bitset = Bitset.new(8)
41
+ => 00000000
42
+
43
+ >> bitset[3] = true
44
+ => 00010000
45
+
46
+ >> bitset[3] = false
47
+ => 00000000
48
+
49
+ >> bitset.set(1, 3, 5, 7)
50
+ => 01010101
51
+
52
+ >> bitset.clear(1, 5)
53
+ => 00010001
54
+
55
+ The point of a bitset is to be, effectively, an array of single bits. It should
56
+ support basic set and bitwise operations. So, let's look at a few of those.
57
+
58
+ >> a = Bitset.from_s('00001111')
59
+ => 00001111
60
+
61
+ >> b = Bitset.from_s('01010101')
62
+ => 01010101
63
+
64
+ >> a & b
65
+ => 00000101
66
+
67
+ >> a | b
68
+ => 01011111
69
+
70
+ >> b - a
71
+ => 01010000
72
+
73
+ >> a ^ b
74
+ => 01011010
75
+
76
+ >> ~a
77
+ => 11110000
78
+
79
+ >> a.hamming(b)
80
+ => 4
81
+
82
+ >> a.cardinality
83
+ => 4
84
+
85
+ >> a.reverse
86
+ => 11110000
87
+
88
+ # Tell whether all of the given bit numbers are set
89
+ >> a.set? 6
90
+ => true
91
+
92
+ # Return a new Bitset composed of bits #1, #3, #5, #4, and #1 again
93
+ >> a.select_bits [1,3,5,4,1]
94
+ => 00110
95
+
96
+ # Tell whether all of the given bit numbers are clear
97
+ >> a.clear? 1,3,5
98
+ => false
99
+
100
+ # Tell whether all bits are clear
101
+ >> a.empty?
102
+ => false
103
+
104
+ # Pass all bits to the block
105
+ >> b.each { |v| puts v }
106
+ => false
107
+ true
108
+ false
109
+ ...
110
+
111
+ # Pass the positions of all set bits to the block
112
+ >> b.each_set { |bit| puts bit }
113
+ => 1
114
+ 3
115
+ 5
116
+ 7
117
+
118
+ # Return an array of the positions of all set bits
119
+ >> b.each_set
120
+ => [1, 3, 5, 7]
121
+
122
+ # The following methods modify a Bitset in place very quickly:
123
+ >> a.intersect!(b) # like a &= b
124
+ >> a.union!(b) # like a |= b
125
+ >> a.difference!(b) # like a -= b
126
+ >> a.xor!(b) # alias a.symmetric_difference!(b), like a ^= b
127
+ >> a.reset!
128
+
129
+ # Above, "like" does not mean "identical to." a |= b creates a new
130
+ # Bitset object. a.union!(b) changes an existing object which
131
+ # affects all variables that point to the same object.
132
+
133
+ # Attempting to apply bitwise binary operators or their in-place
134
+ # equivalents between bitsets of different sizes will raise an
135
+ # ArgumentError.
136
+
137
+ # b.dup and b.clone are also available.
138
+
139
+ # Marshal.dump and Marshal.load are also supported. If you want to
140
+ # save a few bytes and don't need Marshal.load to work, you can
141
+ # use #pack and Bitset.unpack instead.
142
+
143
+ Contributing
144
+ ------------
145
+
146
+ The best way to contribute is to fork the project on GitHub, make your changes,
147
+ and send a pull request. This is always much appreciated. If you want to mess
148
+ around with the version numbers, gemspec, or anything like that feel free... But
149
+ do it in separate commits so I can easily ignore them.
150
+
151
+
152
+ License
153
+ -------
154
+
155
+ See LICENSE.txt.
156
+
157
+
158
+ ### Thanks for using Bitset!
data/Rakefile CHANGED
@@ -12,17 +12,17 @@ task :default => :spec
12
12
  require 'jeweler'
13
13
  Jeweler::Tasks.new do |gem|
14
14
  gem.name = "bitset"
15
- gem.homepage = "http://github.com/tyler/bitset"
15
+ gem.homepage = "http://github.com/ericboesch/bitset"
16
16
  gem.license = "MIT"
17
17
  gem.summary = 'Bitset implementation.'
18
18
  gem.description = 'A fast C-based Bitset. It supports the standard set operations as well as operations you may expect on bit arrays. (popcount, for instance)'
19
- gem.email = "tbmcmullen@gmail.com"
19
+ gem.email = "eric.boesch@nist.gov"
20
20
  gem.authors = ["Tyler McMullen"]
21
21
  end
22
22
  Jeweler::RubygemsDotOrgTasks.new
23
23
 
24
- require 'rake/rdoctask'
25
- Rake::RDocTask.new do |rdoc|
24
+ require 'rdoc/task'
25
+ RDoc::Task.new do |rdoc|
26
26
  version = File.exist?('VERSION') ? File.read('VERSION') : ""
27
27
 
28
28
  rdoc.rdoc_dir = 'rdoc'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 1.0.0
@@ -5,13 +5,13 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{bitset}
8
- s.version = "0.1.0"
8
+ s.version = "0.3.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Tyler McMullen"]
12
- s.date = %q{2011-03-03}
11
+ s.authors = ["Tyler McMullen", "Eric Boesch"]
12
+ s.date = %q{2016-02-22}
13
13
  s.description = %q{A fast C-based Bitset. It supports the standard set operations as well as operations you may expect on bit arrays. (popcount, for instance)}
14
- s.email = %q{tbmcmullen@gmail.com}
14
+ s.email = %q{ericboesch@gmail.com}
15
15
  s.extensions = ["ext/bitset/extconf.rb"]
16
16
  s.extra_rdoc_files = [
17
17
  "LICENSE.txt",
@@ -25,9 +25,10 @@ Gem::Specification.new do |s|
25
25
  "bitset.gemspec",
26
26
  "ext/bitset/bitset.c",
27
27
  "ext/bitset/extconf.rb",
28
+ "lib/bitset/bitset.rb",
28
29
  "spec/bitset_spec.rb"
29
30
  ]
30
- s.homepage = %q{http://github.com/tyler/bitset}
31
+ s.homepage = %q{http://github.com/ericboesch/bitset}
31
32
  s.licenses = ["MIT"]
32
33
  s.require_paths = ["lib"]
33
34
  s.rubygems_version = %q{1.3.7}
@@ -11,16 +11,18 @@ typedef struct {
11
11
  uint64_t * data;
12
12
  } Bitset;
13
13
 
14
- #define BYTES(_bs) (((_bs->len-1) >> 3) + 1)
15
- #define INTS(_bs) (((_bs->len-1) >> 6) + 1)
14
+ // Avoid using (len-1), just in case len == 0.
15
+ #define BYTES(_bs) (((_bs)->len+7) >> 3)
16
+ #define INTS(_bs) (((_bs)->len+63) >> 6)
17
+ // 2^6=64
16
18
 
17
19
  Bitset * bitset_new() {
18
- return (Bitset *) malloc(sizeof(Bitset));
20
+ return (Bitset *) calloc(1, sizeof(Bitset));
19
21
  }
20
22
 
21
23
  void bitset_setup(Bitset * bs, int len) {
22
24
  bs->len = len;
23
- bs->data = (uint64_t *) calloc((((bs->len-1) >> 6) + 1), sizeof(uint64_t)); // 2^6=64
25
+ bs->data = (uint64_t *) calloc(INTS(bs), sizeof(uint64_t));
24
26
  }
25
27
 
26
28
  void bitset_free(Bitset * bs) {
@@ -30,7 +32,7 @@ void bitset_free(Bitset * bs) {
30
32
  }
31
33
 
32
34
 
33
- Bitset * get_bitset(VALUE obj) {
35
+ static Bitset * get_bitset(VALUE obj) {
34
36
  Bitset * bs;
35
37
  Data_Get_Struct(obj, Bitset, bs);
36
38
  return bs;
@@ -53,44 +55,43 @@ static VALUE rb_bitset_size(VALUE self, VALUE len) {
53
55
  return INT2NUM(bs->len);
54
56
  }
55
57
 
56
- void raise_index_error() {
58
+ static void raise_index_error() {
57
59
  VALUE rb_eIndexError = rb_const_get(rb_cObject, rb_intern("IndexError"));
58
60
  rb_raise(rb_eIndexError, "Index out of bounds");
59
61
  }
60
62
 
61
- #define _bit_segment(bit) ((bit) >> 6UL)
62
- #define _bit_mask(bit) (((uint64_t) 1) << ((bit) & 0x3f))
63
+ #define _bit_no(bit) ((bit) & 0x3f)
64
+ #define _bit_segment(bit) ((bit) >> 6)
65
+ #define _bit_mask(bit) (((uint64_t) 1) << _bit_no(bit))
66
+ #define _seg_no_to_bit_no(seg_no) ((seg_no) << 6)
67
+ #define _get_bit(bs, idx) ((bs)->data[_bit_segment(idx)] & _bit_mask(idx))
68
+ #define _set_bit(bs, idx) ((bs)->data[_bit_segment(idx)] |= _bit_mask(idx))
69
+ #define _clear_bit(bs, idx) ((bs)->data[_bit_segment(idx)] &= ~_bit_mask(idx))
63
70
 
64
- void validate_index(Bitset * bs, int idx) {
71
+ static void validate_index(Bitset * bs, int idx) {
65
72
  if(idx < 0 || idx >= bs->len)
66
73
  raise_index_error();
67
74
  }
68
75
 
69
- uint64_t get_bit(Bitset * bs, int idx) {
70
- uint64_t segment = bs->data[_bit_segment(idx)];
71
- return segment & _bit_mask(idx);
72
- }
73
-
74
- void set_bit(Bitset * bs, int idx) {
75
- bs->data[_bit_segment(idx)] |= _bit_mask(idx);
76
- }
77
-
78
- void clear_bit(Bitset * bs, int idx) {
79
- bs->data[_bit_segment(idx)] &= ~_bit_mask(idx);
76
+ static void verify_equal_size(Bitset * bs1, Bitset * bs2) {
77
+ if (bs1->len != bs2->len) {
78
+ VALUE rb_eArgumentError = rb_const_get(rb_cObject, rb_intern("ArgumentError"));
79
+ rb_raise(rb_eArgumentError, "Operands size mismatch");
80
+ }
80
81
  }
81
82
 
82
83
  void assign_bit(Bitset * bs, int idx, VALUE value) {
83
84
  if(NIL_P(value) || value == Qfalse)
84
- clear_bit(bs, idx);
85
+ _clear_bit(bs, idx);
85
86
  else
86
- set_bit(bs, idx);
87
+ _set_bit(bs, idx);
87
88
  }
88
89
 
89
90
  static VALUE rb_bitset_aref(VALUE self, VALUE index) {
90
91
  Bitset * bs = get_bitset(self);
91
92
  int idx = NUM2INT(index);
92
93
  validate_index(bs, idx);
93
- return get_bit(bs, idx) > 0 ? Qtrue : Qfalse;
94
+ return _get_bit(bs, idx) > 0 ? Qtrue : Qfalse;
94
95
  }
95
96
 
96
97
  static VALUE rb_bitset_aset(VALUE self, VALUE index, VALUE value) {
@@ -108,7 +109,7 @@ static VALUE rb_bitset_set(int argc, VALUE * argv, VALUE self) {
108
109
  VALUE index = argv[i];
109
110
  int idx = NUM2INT(index);
110
111
  validate_index(bs, idx);
111
- set_bit(bs, idx);
112
+ _set_bit(bs, idx);
112
113
  }
113
114
  return Qtrue;
114
115
  }
@@ -120,7 +121,7 @@ static VALUE rb_bitset_clear(int argc, VALUE * argv, VALUE self) {
120
121
  VALUE index = argv[i];
121
122
  int idx = NUM2INT(index);
122
123
  validate_index(bs, idx);
123
- clear_bit(bs, idx);
124
+ _clear_bit(bs, idx);
124
125
  }
125
126
  return Qtrue;
126
127
  }
@@ -132,7 +133,7 @@ static VALUE rb_bitset_clear_p(int argc, VALUE * argv, VALUE self) {
132
133
  VALUE index = argv[i];
133
134
  int idx = NUM2INT(index);
134
135
  validate_index(bs, idx);
135
- if(get_bit(bs, idx) > 0)
136
+ if(_get_bit(bs, idx) > 0)
136
137
  return Qfalse;
137
138
  }
138
139
  return Qtrue;
@@ -145,7 +146,7 @@ static VALUE rb_bitset_set_p(int argc, VALUE * argv, VALUE self) {
145
146
  VALUE index = argv[i];
146
147
  int idx = NUM2INT(index);
147
148
  validate_index(bs, idx);
148
- if(get_bit(bs, idx) == 0)
149
+ if(_get_bit(bs, idx) == 0)
149
150
  return Qfalse;
150
151
  }
151
152
  return Qtrue;
@@ -154,13 +155,10 @@ static VALUE rb_bitset_set_p(int argc, VALUE * argv, VALUE self) {
154
155
  static VALUE rb_bitset_cardinality(VALUE self) {
155
156
  Bitset * bs = get_bitset(self);
156
157
  int i;
157
- int max = ((bs->len-1) >> 6) + 1;
158
+ int max = INTS(bs);
158
159
  int count = 0;
159
160
  for(i = 0; i < max; i++) {
160
- uint64_t segment = bs->data[i];
161
- if(i+1 == max)
162
- segment &= ((((uint64_t) 1) << (bs->len & 0x3F)) - 1);
163
- count += __builtin_popcountll(segment);
161
+ count += __builtin_popcountll(bs->data[i]);
164
162
  }
165
163
  return INT2NUM(count);
166
164
  }
@@ -168,11 +166,12 @@ static VALUE rb_bitset_cardinality(VALUE self) {
168
166
  static VALUE rb_bitset_intersect(VALUE self, VALUE other) {
169
167
  Bitset * bs = get_bitset(self);
170
168
  Bitset * other_bs = get_bitset(other);
169
+ verify_equal_size(bs, other_bs);
171
170
 
172
171
  Bitset * new_bs = bitset_new();
173
172
  bitset_setup(new_bs, bs->len);
174
173
 
175
- int max = ((bs->len-1) >> 6) + 1;
174
+ int max = INTS(bs);
176
175
  int i;
177
176
  for(i = 0; i < max; i++) {
178
177
  uint64_t segment = bs->data[i];
@@ -186,11 +185,12 @@ static VALUE rb_bitset_intersect(VALUE self, VALUE other) {
186
185
  static VALUE rb_bitset_union(VALUE self, VALUE other) {
187
186
  Bitset * bs = get_bitset(self);
188
187
  Bitset * other_bs = get_bitset(other);
188
+ verify_equal_size(bs, other_bs);
189
189
 
190
190
  Bitset * new_bs = bitset_new();
191
191
  bitset_setup(new_bs, bs->len);
192
192
 
193
- int max = ((bs->len-1) >> 6) + 1;
193
+ int max = INTS(bs);
194
194
  int i;
195
195
  for(i = 0; i < max; i++) {
196
196
  uint64_t segment = bs->data[i];
@@ -204,11 +204,12 @@ static VALUE rb_bitset_union(VALUE self, VALUE other) {
204
204
  static VALUE rb_bitset_difference(VALUE self, VALUE other) {
205
205
  Bitset * bs = get_bitset(self);
206
206
  Bitset * other_bs = get_bitset(other);
207
+ verify_equal_size(bs, other_bs);
207
208
 
208
209
  Bitset * new_bs = bitset_new();
209
210
  bitset_setup(new_bs, bs->len);
210
211
 
211
- int max = ((bs->len-1) >> 6) + 1;
212
+ int max = INTS(bs);
212
213
  int i;
213
214
  for(i = 0; i < max; i++) {
214
215
  uint64_t segment = bs->data[i];
@@ -222,11 +223,12 @@ static VALUE rb_bitset_difference(VALUE self, VALUE other) {
222
223
  static VALUE rb_bitset_xor(VALUE self, VALUE other) {
223
224
  Bitset * bs = get_bitset(self);
224
225
  Bitset * other_bs = get_bitset(other);
226
+ verify_equal_size(bs, other_bs);
225
227
 
226
228
  Bitset * new_bs = bitset_new();
227
229
  bitset_setup(new_bs, bs->len);
228
230
 
229
- int max = ((bs->len-1) >> 6) + 1;
231
+ int max = INTS(bs);
230
232
  int i;
231
233
  for(i = 0; i < max; i++) {
232
234
  uint64_t segment = bs->data[i];
@@ -243,12 +245,15 @@ static VALUE rb_bitset_not(VALUE self) {
243
245
  Bitset * new_bs = bitset_new();
244
246
  bitset_setup(new_bs, bs->len);
245
247
 
246
- int max = ((bs->len-1) >> 6) + 1;
248
+ int max = INTS(bs);
249
+
247
250
  int i;
248
251
  for(i = 0; i < max; i++) {
249
252
  uint64_t segment = bs->data[i];
250
253
  new_bs->data[i] = ~segment;
251
254
  }
255
+ if(_bit_no(bs->len) != 0)
256
+ new_bs->data[max-1] &= _bit_mask(bs->len) - 1;
252
257
 
253
258
  return Data_Wrap_Struct(cBitset, 0, bitset_free, new_bs);
254
259
  }
@@ -259,7 +264,7 @@ static VALUE rb_bitset_to_s(VALUE self) {
259
264
  int i;
260
265
  char * data = malloc(bs->len + 1);
261
266
  for(i = 0; i < bs->len; i++) {
262
- data[i] = get_bit(bs, i) ? '1' : '0';
267
+ data[i] = _get_bit(bs, i) ? '1' : '0';
263
268
  }
264
269
  data[bs->len] = 0;
265
270
 
@@ -276,7 +281,7 @@ static VALUE rb_bitset_from_s(VALUE self, VALUE s) {
276
281
  int i;
277
282
  for (i = 0; i < length; i++) {
278
283
  if (data[i] == '1') {
279
- set_bit(new_bs, i);
284
+ _set_bit(new_bs, i);
280
285
  }
281
286
  }
282
287
 
@@ -287,7 +292,7 @@ static VALUE rb_bitset_hamming(VALUE self, VALUE other) {
287
292
  Bitset * bs = get_bitset(self);
288
293
  Bitset * other_bs = get_bitset(other);
289
294
 
290
- int max = ((bs->len-1) >> 6) + 1;
295
+ int max = INTS(bs);
291
296
  int count = 0;
292
297
  int i;
293
298
  for(i = 0; i < max; i++) {
@@ -304,7 +309,7 @@ static VALUE rb_bitset_each(VALUE self) {
304
309
  int i;
305
310
 
306
311
  for(i = 0; i < bs->len; i++) {
307
- rb_yield(get_bit(bs, i) > 0 ? Qtrue : Qfalse);
312
+ rb_yield(_get_bit(bs, i) ? Qtrue : Qfalse);
308
313
  }
309
314
 
310
315
  return self;
@@ -335,11 +340,171 @@ static VALUE rb_bitset_marshall_load(VALUE self, VALUE hash) {
335
340
  return Qnil;
336
341
  }
337
342
 
343
+ static VALUE rb_bitset_dup(VALUE self) {
344
+ Bitset * bs = get_bitset(self);
345
+
346
+ Bitset * new_bs = bitset_new();
347
+ bitset_setup(new_bs, bs->len);
348
+
349
+ int max = INTS(bs);
350
+ memcpy(new_bs->data, bs->data, max * sizeof(bs->data[0]));
351
+ return Data_Wrap_Struct(cBitset, 0, bitset_free, new_bs);
352
+ }
353
+
354
+ /* Yield the bit numbers of each set bit in sequence to a block. If
355
+ there is no block, return an array of those numbers. */
356
+ static VALUE rb_bitset_each_set(VALUE self) {
357
+ Bitset * bs = get_bitset(self);
358
+ int seg_no;
359
+ int max = INTS(bs);
360
+ uint64_t* seg_ptr = bs->data;
361
+ int block_p = rb_block_given_p();
362
+ VALUE ary = Qnil;
363
+
364
+ if (!block_p) {
365
+ ary = rb_ary_new();
366
+ }
367
+
368
+ for (seg_no = 0; seg_no < max; ++seg_no, ++seg_ptr) {
369
+ uint64_t segment = *seg_ptr;
370
+ int bit_position = 0;
371
+ while (segment) {
372
+ VALUE v;
373
+
374
+ if (!(segment & 1)) {
375
+ int shift = __builtin_ctzll(segment);
376
+ bit_position += shift;
377
+ segment >>= shift;
378
+ }
379
+ v = INT2NUM(_seg_no_to_bit_no(seg_no) + bit_position);
380
+ if (block_p) {
381
+ rb_yield(v);
382
+ } else {
383
+ rb_ary_push(ary, v);
384
+ }
385
+ ++bit_position;
386
+ segment >>= 1;
387
+ }
388
+ }
389
+
390
+ return block_p ? self : ary;
391
+ }
392
+
393
+ static VALUE rb_bitset_empty_p(VALUE self) {
394
+ Bitset * bs = get_bitset(self);
395
+ int seg_no;
396
+ int max = INTS(bs);
397
+ uint64_t* seg_ptr = bs->data;
398
+
399
+ for (seg_no = 0; seg_no < max; ++seg_no, ++seg_ptr) {
400
+ if (*seg_ptr) {
401
+ return Qfalse;
402
+ }
403
+ }
404
+ return Qtrue;
405
+ }
406
+
407
+ static VALUE rb_bitset_select_bits(VALUE self, VALUE index_array) {
408
+ int i;
409
+ Bitset * bs = get_bitset(self);
410
+ struct RArray *arr = RARRAY(index_array);
411
+ int blen = bs->len;
412
+ int alen = RARRAY_LEN(index_array);
413
+ VALUE *ptr = RARRAY_PTR(index_array);
414
+ Bitset * new_bs = bitset_new();
415
+ bitset_setup(new_bs, alen);
416
+ for (i = 0; i < alen; ++i) {
417
+ int idx = NUM2INT(ptr[i]);
418
+ if (idx >= 0 && idx < blen && _get_bit(bs, idx)) {
419
+ _set_bit(new_bs, i);
420
+ }
421
+ }
422
+
423
+ return Data_Wrap_Struct(cBitset, 0, bitset_free, new_bs);
424
+ }
425
+
426
+ /** This could run a bit faster if you worked at it. */
427
+ static VALUE rb_bitset_reverse(VALUE self, VALUE index_array) {
428
+ int i;
429
+ Bitset * bs = get_bitset(self);
430
+ int len = bs->len;
431
+ Bitset * new_bs = bitset_new();
432
+ bitset_setup(new_bs, len);
433
+ for (i = 0; i < len; ++i) {
434
+ if (_get_bit(bs, i)) {
435
+ _set_bit(new_bs, len - i - 1);
436
+ }
437
+ }
438
+
439
+ return Data_Wrap_Struct(cBitset, 0, bitset_free, new_bs);
440
+ }
441
+
442
+ static VALUE rb_bitset_equal(VALUE self, VALUE other) {
443
+ int i;
444
+ Bitset * bs = get_bitset(self);
445
+ Bitset * other_bs = get_bitset(other);
446
+
447
+ if (bs->len != other_bs->len)
448
+ return Qfalse;
449
+ int max = INTS(bs);
450
+ for(i = 0; i < max; i++) {
451
+ if (bs->data[i] != other_bs->data[i]) {
452
+ return Qfalse;
453
+ }
454
+ }
455
+ return Qtrue;
456
+ }
457
+
458
+ typedef uint64_t (*bitwise_op)(uint64_t, uint64_t);
459
+ inline uint64_t and(uint64_t a, uint64_t b) { return a & b; }
460
+ inline uint64_t or(uint64_t a, uint64_t b) { return a | b; }
461
+ inline uint64_t xor(uint64_t a, uint64_t b) { return a ^ b; }
462
+ inline uint64_t difference(uint64_t a, uint64_t b) { return a & ~b; }
463
+
464
+ static VALUE mutable(VALUE self, VALUE other, bitwise_op operator) {
465
+ Bitset * bs = get_bitset(self);
466
+ Bitset * other_bs = get_bitset(other);
467
+ verify_equal_size(bs, other_bs);
468
+
469
+ int max = INTS(bs);
470
+ int i;
471
+ for(i = 0; i < max; i++) {
472
+ uint64_t segment = bs->data[i];
473
+ uint64_t other_segment = other_bs->data[i];
474
+ bs->data[i] = operator(segment, other_segment);
475
+ }
476
+
477
+ return self;
478
+ }
479
+
480
+ static VALUE rb_bitset_union_mutable(VALUE self, VALUE other) {
481
+ return mutable(self, other, &or);
482
+ }
483
+
484
+ static VALUE rb_bitset_intersect_mutable(VALUE self, VALUE other) {
485
+ return mutable(self, other, &and);
486
+ }
487
+
488
+ static VALUE rb_bitset_xor_mutable(VALUE self, VALUE other) {
489
+ return mutable(self, other, &xor);
490
+ }
491
+
492
+ static VALUE rb_bitset_difference_mutable(VALUE self, VALUE other) {
493
+ return mutable(self, other, &difference);
494
+ }
495
+
496
+ static VALUE rb_bitset_reset(VALUE self) {
497
+ Bitset * bs = get_bitset(self);
498
+ memset(bs->data, 0, (INTS(bs) * sizeof(uint64_t)) );
499
+ return self;
500
+ }
501
+
338
502
  void Init_bitset() {
339
503
  cBitset = rb_define_class("Bitset", rb_cObject);
340
504
  rb_include_module(cBitset, rb_mEnumerable);
341
505
  rb_define_alloc_func(cBitset, rb_bitset_alloc);
342
506
  rb_define_method(cBitset, "initialize", rb_bitset_initialize, 1);
507
+ rb_define_method(cBitset, "reset!", rb_bitset_reset, 0);
343
508
  rb_define_method(cBitset, "size", rb_bitset_size, 0);
344
509
  rb_define_method(cBitset, "[]", rb_bitset_aref, 1);
345
510
  rb_define_method(cBitset, "[]=", rb_bitset_aset, 2);
@@ -350,13 +515,22 @@ void Init_bitset() {
350
515
  rb_define_method(cBitset, "cardinality", rb_bitset_cardinality, 0);
351
516
  rb_define_method(cBitset, "intersect", rb_bitset_intersect, 1);
352
517
  rb_define_alias(cBitset, "&", "intersect");
518
+ rb_define_alias(cBitset, "and", "intersect");
519
+ rb_define_method(cBitset, "intersect!", rb_bitset_intersect_mutable, 1);
520
+ rb_define_alias(cBitset, "and!", "intersect!");
353
521
  rb_define_method(cBitset, "union", rb_bitset_union, 1);
354
522
  rb_define_alias(cBitset, "|", "union");
523
+ rb_define_alias(cBitset, "or", "union");
524
+ rb_define_method(cBitset, "union!", rb_bitset_union_mutable, 1);
525
+ rb_define_alias(cBitset, "or!", "union!");
355
526
  rb_define_method(cBitset, "difference", rb_bitset_difference, 1);
356
527
  rb_define_alias(cBitset, "-", "difference");
528
+ rb_define_method(cBitset, "difference!", rb_bitset_difference_mutable, 1);
357
529
  rb_define_method(cBitset, "xor", rb_bitset_xor, 1);
358
530
  rb_define_alias(cBitset, "^", "xor");
359
531
  rb_define_alias(cBitset, "symmetric_difference", "xor");
532
+ rb_define_method(cBitset, "xor!", rb_bitset_xor_mutable, 1);
533
+ rb_define_alias(cBitset, "symmetric_difference!", "xor!");
360
534
  rb_define_method(cBitset, "not", rb_bitset_not, 0);
361
535
  rb_define_alias(cBitset, "~", "not");
362
536
  rb_define_method(cBitset, "hamming", rb_bitset_hamming, 1);
@@ -365,4 +539,11 @@ void Init_bitset() {
365
539
  rb_define_singleton_method(cBitset, "from_s", rb_bitset_from_s, 1);
366
540
  rb_define_method(cBitset, "marshal_dump", rb_bitset_marshall_dump, 0);
367
541
  rb_define_method(cBitset, "marshal_load", rb_bitset_marshall_load, 1);
542
+ rb_define_method(cBitset, "dup", rb_bitset_dup, 0);
543
+ rb_define_alias(cBitset, "clone", "dup");
544
+ rb_define_method(cBitset, "each_set", rb_bitset_each_set, 0);
545
+ rb_define_method(cBitset, "empty?", rb_bitset_empty_p, 0);
546
+ rb_define_method(cBitset, "select_bits", rb_bitset_select_bits, 1);
547
+ rb_define_method(cBitset, "reverse", rb_bitset_reverse, 0);
548
+ rb_define_method(cBitset, "==", rb_bitset_equal, 1);
368
549
  }
@@ -0,0 +1,23 @@
1
+ class Bitset
2
+
3
+ # Return a string that represents this bitset packed into 8-bit
4
+ # characters. The first 3 bits represent the number of padding bits
5
+ # in the final byte of the string.
6
+
7
+ # You could make a good case that this is redundant with
8
+ # Marshal.dump and Marshal.load, but it does save a few bytes.
9
+ def pack
10
+ # Number of bits of zero padding in this representation.
11
+ padding_bits = (size+3) & 7
12
+ padding_bits = (padding_bits == 0) ? 0 : (8 - padding_bits)
13
+ [("%03b" % padding_bits) + self.to_s].pack("b*")
14
+ end
15
+
16
+ # Convert a string created using the pack method back into a bitset.
17
+ def self.unpack str
18
+ bits = str.unpack("b*")[0]
19
+ padding_bits = bits[0...3].to_i(2)
20
+ from_s(bits[3 .. -1 - padding_bits])
21
+ end
22
+
23
+ end
@@ -5,10 +5,14 @@ describe Bitset do
5
5
  Bitset.new(64)
6
6
  end
7
7
 
8
+ it 'raises ArgumentError wihen initialized with no argument' do
9
+ expect { Bitset.new }.to raise_error(ArgumentError)
10
+ end
11
+
8
12
  describe :size do
9
13
  it 'returns the correct size' do
10
- Bitset.new(64).size.should == 64
11
- Bitset.new(73).size.should == 73
14
+ expect(Bitset.new(64).size).to eq(64)
15
+ expect(Bitset.new(73).size).to eq(73)
12
16
  end
13
17
  end
14
18
 
@@ -16,17 +20,18 @@ describe Bitset do
16
20
  it 'returns True for set bits' do
17
21
  bs = Bitset.new(8)
18
22
  bs[0] = true
19
- bs[0].should == true
23
+ expect(bs[0]).to be true
20
24
  end
21
25
 
22
26
  it 'returns False for unset bits' do
23
27
  bs = Bitset.new(8)
24
- bs[0].should == false
28
+ expect(bs[0]).to be false
25
29
  end
26
30
 
27
31
  it 'raises an error when accessing out of bound indexes' do
28
32
  bs = Bitset.new(8)
29
33
  expect { bs[8] }.to raise_error(IndexError)
34
+ expect { bs[-1] }.to raise_error(IndexError)
30
35
  end
31
36
  end
32
37
 
@@ -35,23 +40,23 @@ describe Bitset do
35
40
  bs = Bitset.new(8)
36
41
 
37
42
  bs[0] = true
38
- bs[0].should == true
43
+ expect(bs[0]).to be true
39
44
 
40
45
  bs[1] = 123
41
- bs[1].should == true
46
+ expect(bs[1]).to be true
42
47
 
43
48
  bs[2] = "woo"
44
- bs[2].should == true
49
+ expect(bs[2]).to be true
45
50
  end
46
51
 
47
52
  it 'sets False for falsey values' do
48
53
  bs = Bitset.new(8)
49
54
 
50
55
  bs[0] = false
51
- bs[0].should == false
56
+ expect(bs[0]).to be false
52
57
 
53
58
  bs[1] = nil
54
- bs[1].should == false
59
+ expect(bs[1]).to be false
55
60
  end
56
61
 
57
62
  it 'raises an error when setting out of bound indexes' do
@@ -65,9 +70,10 @@ describe Bitset do
65
70
  bs = Bitset.new(8)
66
71
  bs.set 1,2,3
67
72
 
68
- bs[1].should == true
69
- bs[2].should == true
70
- bs[3].should == true
73
+ expect(bs[1]).to be true
74
+ expect(bs[0]).to be false
75
+ expect(bs[4]).to be false
76
+ expect(bs[3]).to be true
71
77
  end
72
78
  end
73
79
 
@@ -77,9 +83,9 @@ describe Bitset do
77
83
  bs.set 1,2,3
78
84
  bs.clear 1,3
79
85
 
80
- bs[1].should == false
81
- bs[2].should == true
82
- bs[3].should == false
86
+ expect(bs[1]).to be false
87
+ expect(bs[2]).to be true
88
+ expect(bs[3]).to be false
83
89
  end
84
90
  end
85
91
 
@@ -87,13 +93,13 @@ describe Bitset do
87
93
  it 'returns True if all bits indexed are set' do
88
94
  bs = Bitset.new(8)
89
95
  bs.set 1, 4, 5
90
- bs.set?(1,4,5).should == true
96
+ expect(bs.set?(1,4,5)).to be true
91
97
  end
92
98
 
93
99
  it 'returns False if not all bits indexed are set' do
94
100
  bs = Bitset.new(8)
95
101
  bs.set 1, 4
96
- bs.set?(1,4,5).should == false
102
+ expect(bs.set?(1,4,5)).to be false
97
103
  end
98
104
  end
99
105
 
@@ -101,44 +107,48 @@ describe Bitset do
101
107
  it 'returns True if all bits indexed are clear' do
102
108
  bs = Bitset.new(8)
103
109
  bs.set 1, 4, 5
104
- bs.clear?(0,2,3,6).should == true
110
+ expect(bs.clear?(0,2,3,6)).to be true
105
111
  end
106
112
 
107
113
  it 'returns works with the full range of 64 bit values' do
108
114
  bs = Bitset.new(68)
109
115
  bs.set 0, 2, 66
110
- bs.clear?(32, 33, 34).should == true
116
+ expect(bs.clear?(32, 33, 34)).to be true
111
117
  end
112
118
 
113
119
  it 'returns False if not all bits indexed are clear' do
114
120
  bs = Bitset.new(8)
115
121
  bs.set 1, 4
116
- bs.clear?(1,2,6).should == false
122
+ expect(bs.clear?(1,2,6)).to be false
117
123
  end
118
124
  end
119
125
 
120
126
  describe :cardinality do
121
127
  it 'returns the number of bits set' do
122
- bs = Bitset.new(8)
123
- bs.cardinality.should == 0
128
+ bs = Bitset.new(64)
129
+ expect(bs.cardinality).to eq(0)
124
130
 
125
131
  bs[0] = true
126
- bs.cardinality.should == 1
132
+ expect(bs.cardinality).to eq(1)
127
133
 
128
134
  bs[1] = true
129
- bs.cardinality.should == 2
135
+ expect(bs.cardinality).to eq(2)
130
136
 
131
137
  bs[2] = true
132
- bs.cardinality.should == 3
138
+ expect(bs.cardinality).to eq(3)
139
+
140
+ expect(bs.not.cardinality).to eq(bs.size - bs.cardinality)
133
141
  end
134
142
 
135
143
  it '... even for large numbers of bits' do
136
144
  bs = Bitset.new(10_000)
137
- bs.set(*(0...5000).to_a)
138
- bs.cardinality.should == 5000
145
+ size = 5000
146
+ bs.set(*(0...size).to_a)
147
+ expect(bs.cardinality).to eq(size)
139
148
 
140
149
  bs = Bitset.from_s "01001101000000000000000000000011000010100100000000000000010000101000000000000000100000000100000000000010100100010000000010000100000100000001001000110000000000100010000000010100000000000000110000000000000000000000000100000000100010010000000000000000000001000000000000000000000000000001000000000000000000000000000100000000010010000000000000000000100100000000000000001000000010000001000000000000001000001100010001000000000000001000001000001000000000000001100010000010010001000000010000100000000000110000"
141
- bs.cardinality.should == 63
150
+ expect(bs.cardinality).to eq(63)
151
+ expect(bs.not.cardinality).to eq(bs.size - bs.cardinality)
142
152
  end
143
153
  end
144
154
 
@@ -151,8 +161,8 @@ describe Bitset do
151
161
  bs2.set 1, 2, 4, 6
152
162
 
153
163
  bs3 = bs1 & bs2
154
- bs3.set?(1,4).should == true
155
- bs3.clear?(0,2,3,5,6,7).should == true
164
+ expect(bs3.set?(1,4)).to be true
165
+ expect(bs3.clear?(0,2,3,5,6,7)).to be true
156
166
  end
157
167
  end
158
168
 
@@ -165,8 +175,11 @@ describe Bitset do
165
175
  bs2.set 1, 2, 4, 6
166
176
 
167
177
  bs3 = bs1 | bs2
168
- bs3.set?(1,2,4,6,7).should == true
169
- bs3.clear?(0,3,5).should == true
178
+ expect(bs3.set?(1,2,4,6,7)).to be true
179
+ expect(bs3.clear?(0,3,5)).to be true
180
+ end
181
+ it 'throws if size mismatch' do
182
+ expect { Bitset.new(3) | Bitset.new(7) }.to raise_error(ArgumentError)
170
183
  end
171
184
  end
172
185
 
@@ -179,8 +192,11 @@ describe Bitset do
179
192
  bs2.set 1, 2, 4, 6
180
193
 
181
194
  bs3 = bs1 - bs2
182
- bs3.set?(7).should == true
183
- bs3.clear?(0,1,2,3,4,5,6).should == true
195
+ expect(bs3.set?(7)).to be true
196
+ expect(bs3.clear?(0,1,2,3,4,5,6)).to be true
197
+ end
198
+ it 'throws if size mismatch' do
199
+ expect { Bitset.new(3) - Bitset.new(7) }.to raise_error(ArgumentError)
184
200
  end
185
201
  end
186
202
 
@@ -193,19 +209,23 @@ describe Bitset do
193
209
  bs2.set 1, 2, 4, 6
194
210
 
195
211
  bs3 = bs1 ^ bs2
196
- bs3.set?(2,6,7).should == true
197
- bs3.clear?(0,1,3,4,5).should == true
212
+ expect(bs3.set?(2,6,7)).to be true
213
+ expect(bs3.clear?(0,1,3,4,5)).to be true
214
+ end
215
+
216
+ it 'throws if size mismatch' do
217
+ expect { Bitset.new(3) ^ Bitset.new(7) }.to raise_error(ArgumentError)
198
218
  end
199
219
  end
200
220
 
201
221
  describe :not do
202
- it "returns a new Bitset with is the not of one Bitset" do
222
+ it "returns a new Bitset which is the not of one Bitset" do
203
223
  bs1 = Bitset.new(8)
204
224
  bs1.set 1, 4, 7
205
225
 
206
226
  bs2 = bs1.not
207
- bs2.set?(0, 2, 3, 5, 6).should == true
208
- bs2.clear?(1, 4, 7).should == true
227
+ expect(bs2.set?(0, 2, 3, 5, 6)).to be true
228
+ expect(bs2.clear?(1, 4, 7)).to be true
209
229
  end
210
230
  end
211
231
 
@@ -217,7 +237,7 @@ describe Bitset do
217
237
  bs2 = Bitset.new(8)
218
238
  bs2.set 1, 2, 4, 6
219
239
 
220
- bs1.hamming(bs2).should == 3
240
+ expect(bs1.hamming(bs2)).to eq(3)
221
241
  end
222
242
  end
223
243
 
@@ -228,10 +248,50 @@ describe Bitset do
228
248
 
229
249
  i = 0
230
250
  bs.each do |bit|
231
- bit.should == bs[i]
251
+ expect(bit).to be bs[i]
232
252
  i += 1
233
253
  end
234
- i.should == 4
254
+ expect(i).to eq(4)
255
+ end
256
+ end
257
+
258
+ describe :each_set do
259
+ it 'iterates over each set bit in the Bitset' do
260
+ bs = Bitset.new(4)
261
+ sets = [0,3]
262
+ bs.set(*sets)
263
+ sets2 = []
264
+ bs.each_set { |bit| sets2 << bit }
265
+ expect(sets2).to eq(sets)
266
+ end
267
+
268
+ it 'without a block, it returns an array of set bits' do
269
+ bs = Bitset.new(4)
270
+ sets = [0,3]
271
+ bs.set(*sets)
272
+ expect(bs.each_set).to eq(sets)
273
+ end
274
+ end
275
+
276
+ describe :empty? do
277
+ it 'returns empty only if all zeroes' do
278
+ expect(Bitset.new(225).tap { |bs| bs[133] = true }.empty?).to be false
279
+ expect(Bitset.new(0).empty?).to be true
280
+ expect(Bitset.new(225).empty?).to be true
281
+ end
282
+ end
283
+
284
+ describe :dup do
285
+ it "returns a duplicate" do
286
+ bs = Bitset.from_s("11011")
287
+ expect(bs.dup.tap { |bs| bs.clear 1,3 }.to_s).to eq("10001")
288
+ expect(bs.to_s).to eq("11011")
289
+ end
290
+ end
291
+
292
+ describe :clone do
293
+ it "works" do
294
+ expect(Bitset.new(0).clone.to_s).to eq("")
235
295
  end
236
296
  end
237
297
 
@@ -239,18 +299,18 @@ describe Bitset do
239
299
  it 'correctly prints out a binary string' do
240
300
  bs = Bitset.new(4)
241
301
  bs.set 0, 2
242
- bs.to_s.should == "1010"
302
+ expect(bs.to_s).to eq("1010")
243
303
 
244
304
  bs = Bitset.new(68)
245
305
  bs.set 0, 2, 66
246
- bs.to_s.should == "101" + ("0" * 63) + "10"
306
+ expect(bs.to_s).to eq("101" + ("0" * 63) + "10")
247
307
  end
248
308
  end
249
309
 
250
310
  describe :from_s do
251
311
  it 'correctly creates a bitmap from a binary string' do
252
312
  bs = Bitset.from_s("10101")
253
- bs.set?(0, 2, 4).should == true
313
+ expect(bs.set?(0, 2, 4)).to be true
254
314
  end
255
315
  end
256
316
 
@@ -260,8 +320,65 @@ describe Bitset do
260
320
  bs.set 1, 65
261
321
 
262
322
  serialized = Marshal.load(Marshal.dump(bs))
263
- serialized.set?(1, 65).should == true
264
- serialized.cardinality.should == 2
323
+ expect(serialized.set?(1, 65)).to be true
324
+ expect(serialized.cardinality).to eq(2)
325
+ end
326
+ end
327
+
328
+ describe :union! do
329
+ it 'acts like |=' do
330
+ bs = Bitset.from_s "11011"
331
+ bs2 = Bitset.from_s "01111"
332
+ bs3 = bs.dup
333
+ bs.union!(bs2)
334
+ expect(bs).to eq(bs3 | bs2)
335
+ end
336
+
337
+ it 'throws if size mismatch' do
338
+ expect { Bitset.new(3).union!(Bitset.new(7)) }.to raise_error(ArgumentError)
339
+ end
340
+ end
341
+
342
+ describe :intersect! do
343
+ it 'acts like &=' do
344
+ bs = Bitset.from_s "11011"
345
+ bs2 = Bitset.from_s "01111"
346
+ bs3 = bs.dup
347
+ bs.intersect!(bs2)
348
+ expect(bs).to eq(bs3 & bs2)
349
+ end
350
+ end
351
+
352
+ describe :xor! do
353
+ it 'acts like ^=' do
354
+ bs = Bitset.from_s "11011"
355
+ bs2 = Bitset.from_s "01111"
356
+ bs3 = bs.dup
357
+ bs.xor!(bs2)
358
+ expect(bs).to eq(bs3 ^ bs2)
359
+ end
360
+
361
+ it 'throws if size mismatch' do
362
+ expect { Bitset.new(3).xor!(Bitset.new(7)) }.to raise_error(ArgumentError)
265
363
  end
266
364
  end
365
+
366
+ describe :difference! do
367
+ it 'acts like -=' do
368
+ bs = Bitset.from_s "11011"
369
+ bs2 = Bitset.from_s "01111"
370
+ bs3 = bs.dup
371
+ bs.difference!(bs2)
372
+ expect(bs).to eq(bs3 - bs2)
373
+ end
374
+ end
375
+
376
+ describe :reset! do
377
+ it 'causes empty? to become true' do
378
+ bs = Bitset.from_s "11011"
379
+ bs.reset!
380
+ expect(bs.empty?).to be true
381
+ end
382
+ end
383
+
267
384
  end
metadata CHANGED
@@ -1,72 +1,56 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: bitset
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 1
8
- - 0
9
- version: 0.1.0
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
10
5
  platform: ruby
11
- authors:
6
+ authors:
12
7
  - Tyler McMullen
13
8
  autorequire:
14
9
  bindir: bin
15
10
  cert_chain: []
16
-
17
- date: 2011-03-03 00:00:00 -08:00
18
- default_executable:
11
+ date: 2017-05-15 00:00:00.000000000 Z
19
12
  dependencies: []
20
-
21
- description: A fast C-based Bitset. It supports the standard set operations as well as operations you may expect on bit arrays. (popcount, for instance)
22
- email: tbmcmullen@gmail.com
13
+ description: A fast C-based Bitset. It supports the standard set operations as well
14
+ as operations you may expect on bit arrays. (popcount, for instance)
15
+ email: eric.boesch@nist.gov
23
16
  executables: []
24
-
25
- extensions:
17
+ extensions:
26
18
  - ext/bitset/extconf.rb
27
- extra_rdoc_files:
19
+ extra_rdoc_files:
28
20
  - LICENSE.txt
29
- - README.rdoc
30
- files:
21
+ - README.markdown
22
+ files:
31
23
  - LICENSE.txt
32
- - README.rdoc
24
+ - README.markdown
33
25
  - Rakefile
34
26
  - VERSION
35
27
  - bitset.gemspec
36
28
  - ext/bitset/bitset.c
37
29
  - ext/bitset/extconf.rb
30
+ - lib/bitset/bitset.rb
38
31
  - spec/bitset_spec.rb
39
- has_rdoc: true
40
- homepage: http://github.com/tyler/bitset
41
- licenses:
32
+ homepage: http://github.com/ericboesch/bitset
33
+ licenses:
42
34
  - MIT
35
+ metadata: {}
43
36
  post_install_message:
44
37
  rdoc_options: []
45
-
46
- require_paths:
38
+ require_paths:
47
39
  - lib
48
- required_ruby_version: !ruby/object:Gem::Requirement
49
- none: false
50
- requirements:
40
+ required_ruby_version: !ruby/object:Gem::Requirement
41
+ requirements:
51
42
  - - ">="
52
- - !ruby/object:Gem::Version
53
- segments:
54
- - 0
55
- version: "0"
56
- required_rubygems_version: !ruby/object:Gem::Requirement
57
- none: false
58
- requirements:
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ requirements:
59
47
  - - ">="
60
- - !ruby/object:Gem::Version
61
- segments:
62
- - 0
63
- version: "0"
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
64
50
  requirements: []
65
-
66
51
  rubyforge_project:
67
- rubygems_version: 1.3.7
52
+ rubygems_version: 2.6.12
68
53
  signing_key:
69
- specification_version: 3
54
+ specification_version: 4
70
55
  summary: Bitset implementation.
71
- test_files:
72
- - spec/bitset_spec.rb
56
+ test_files: []
@@ -1,3 +0,0 @@
1
- = Bitset
2
-
3
- A fast Bitset implementation for Ruby. Available as the 'bitset' gem.