victory 0.2.0 → 0.3.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,652 @@
1
+ #include "ruby.h"
2
+ #include "builtin.h"
3
+
4
+ #include <stdint.h>
5
+ #include <stdbool.h>
6
+ #include <string.h>
7
+ #include <stdio.h>
8
+ #include <limits.h>
9
+
10
+ static VALUE mContainers;
11
+ static VALUE cBitset;
12
+
13
+ typedef struct {
14
+ int len;
15
+ uint64_t * data;
16
+ } Bitset;
17
+
18
+ // Avoid using (len-1), just in case len == 0.
19
+ #define BYTES(_bs) (((_bs)->len+7) >> 3)
20
+ #define INTS(_bs) (((_bs)->len+63) >> 6)
21
+ // 2^6=64
22
+
23
+ #define _bit_no(bit) ((bit) & 0x3f)
24
+ #define _bit_segment(bit) ((bit) >> 6)
25
+ #define _bit_mask(bit) (((uint64_t) 1) << _bit_no(bit))
26
+ #define _seg_no_to_bit_no(seg_no) ((seg_no) << 6)
27
+ #define _get_bit(bs, idx) ((bs)->data[_bit_segment(idx)] & _bit_mask(idx))
28
+ #define _set_bit(bs, idx) ((bs)->data[_bit_segment(idx)] |= _bit_mask(idx))
29
+ #define _clear_bit(bs, idx) ((bs)->data[_bit_segment(idx)] &= ~_bit_mask(idx))
30
+
31
+ Bitset * bitset_new() {
32
+ return (Bitset *) calloc(1, sizeof(Bitset));
33
+ }
34
+
35
+ void bitset_setup(Bitset * bs, int len) {
36
+ bs->len = len;
37
+ bs->data = (uint64_t *) calloc(INTS(bs), sizeof(uint64_t));
38
+ }
39
+
40
+ void bitset_free(Bitset * bs) {
41
+ if(bs->data)
42
+ free(bs->data);
43
+ free(bs);
44
+ }
45
+
46
+
47
+ static Bitset * get_bitset(VALUE obj) {
48
+ Bitset * bs;
49
+ Data_Get_Struct(obj, Bitset, bs);
50
+ return bs;
51
+ }
52
+
53
+ static VALUE rb_bitset_alloc(VALUE klass) {
54
+ VALUE obj;
55
+ obj = Data_Wrap_Struct(klass, 0, bitset_free, bitset_new());
56
+ return obj;
57
+ }
58
+
59
+ static VALUE rb_bitset_initialize(VALUE self, VALUE ary) {
60
+ Bitset * bs = get_bitset(self);
61
+ if (RB_TYPE_P(ary, T_ARRAY)) {
62
+ int i;
63
+ int len = (int) RARRAY_LEN(ary);
64
+ bitset_setup(bs, len);
65
+ for (i = 0; i < len; ++i) {
66
+ // This could be more efficient, but if you're converting
67
+ // from a Ruby array of bits, you're not looking
68
+ // at blazing speed anyhow.
69
+ if (RTEST(rb_ary_entry(ary, i))) {
70
+ _set_bit(bs, i);
71
+ }
72
+ }
73
+ } else {
74
+ bitset_setup(bs, NUM2INT(ary));
75
+ }
76
+ return self;
77
+ }
78
+
79
+ static VALUE rb_bitset_size(VALUE self, VALUE len) {
80
+ Bitset * bs = get_bitset(self);
81
+ return INT2NUM(bs->len);
82
+ }
83
+
84
+ static void raise_index_error() {
85
+ rb_raise(rb_const_get(rb_cObject, rb_intern("IndexError")), "Index out of bounds");
86
+ }
87
+
88
+ static void validate_index(Bitset * bs, int idx) {
89
+ if(idx < 0 || idx >= bs->len)
90
+ raise_index_error();
91
+ }
92
+
93
+ static void verify_equal_size(Bitset * bs1, Bitset * bs2) {
94
+ if (bs1->len != bs2->len) {
95
+ VALUE rb_eArgumentError = rb_const_get(rb_cObject, rb_intern("ArgumentError"));
96
+ rb_raise(rb_eArgumentError, "Operands size mismatch");
97
+ }
98
+ }
99
+
100
+ void assign_bit(Bitset * bs, int idx, VALUE value) {
101
+ if(NIL_P(value) || value == Qfalse)
102
+ _clear_bit(bs, idx);
103
+ else
104
+ _set_bit(bs, idx);
105
+ }
106
+
107
+ static VALUE rb_bitset_aref(VALUE self, VALUE index) {
108
+ Bitset * bs = get_bitset(self);
109
+ int idx = NUM2INT(index);
110
+ validate_index(bs, idx);
111
+ return _get_bit(bs, idx) > 0 ? Qtrue : Qfalse;
112
+ }
113
+
114
+ static VALUE rb_bitset_aset(VALUE self, VALUE index, VALUE value) {
115
+ Bitset * bs = get_bitset(self);
116
+ int idx = NUM2INT(index);
117
+ validate_index(bs, idx);
118
+ assign_bit(bs, idx, value);
119
+ return Qtrue;
120
+ }
121
+
122
+ static VALUE rb_bitset_set(int argc, VALUE * argv, VALUE self) {
123
+ int i;
124
+ Bitset * bs = get_bitset(self);
125
+
126
+ if (argc == 1 && rb_obj_is_kind_of(argv[0], rb_const_get(rb_cObject, rb_intern("Array")))) {
127
+ for(i = 0; i < RARRAY_LEN(argv[0]); i++) {
128
+ VALUE index = RARRAY_PTR(argv[0])[i];
129
+ int idx = NUM2INT(index);
130
+ validate_index(bs, idx);
131
+ _set_bit(bs, idx);
132
+ }
133
+ } else {
134
+ for(i = 0; i < argc; i++) {
135
+ VALUE index = argv[i];
136
+ int idx = NUM2INT(index);
137
+ validate_index(bs, idx);
138
+ _set_bit(bs, idx);
139
+ }
140
+ }
141
+ return Qtrue;
142
+ }
143
+
144
+ static VALUE rb_bitset_clear(int argc, VALUE * argv, VALUE self) {
145
+ int i;
146
+ Bitset * bs = get_bitset(self);
147
+
148
+ if (argc == 1 && rb_obj_is_kind_of(argv[0], rb_const_get(rb_cObject, rb_intern("Array")))) {
149
+ for(i = 0; i < RARRAY_LEN(argv[0]); i++) {
150
+ VALUE index = RARRAY_PTR(argv[0])[i];
151
+ int idx = NUM2INT(index);
152
+ validate_index(bs, idx);
153
+ _clear_bit(bs, idx);
154
+ }
155
+ } else {
156
+ for(i = 0; i < argc; i++) {
157
+ VALUE index = argv[i];
158
+ int idx = NUM2INT(index);
159
+ validate_index(bs, idx);
160
+ _clear_bit(bs, idx);
161
+ }
162
+ }
163
+ return Qtrue;
164
+ }
165
+
166
+ static VALUE rb_bitset_clear_p(int argc, VALUE * argv, VALUE self) {
167
+ int i;
168
+ Bitset * bs = get_bitset(self);
169
+ for(i = 0; i < argc; i++) {
170
+ VALUE index = argv[i];
171
+ int idx = NUM2INT(index);
172
+ validate_index(bs, idx);
173
+ if(_get_bit(bs, idx) > 0)
174
+ return Qfalse;
175
+ }
176
+ return Qtrue;
177
+ }
178
+
179
+ static VALUE rb_bitset_set_p(int argc, VALUE * argv, VALUE self) {
180
+ int i;
181
+ Bitset * bs = get_bitset(self);
182
+ for(i = 0; i < argc; i++) {
183
+ VALUE index = argv[i];
184
+ int idx = NUM2INT(index);
185
+ validate_index(bs, idx);
186
+ if(_get_bit(bs, idx) == 0)
187
+ return Qfalse;
188
+ }
189
+ return Qtrue;
190
+ }
191
+
192
+ static int cardinality(Bitset * bs) {
193
+ int i;
194
+ int max = INTS(bs);
195
+ int count = 0;
196
+ for(i = 0; i < max; i++) {
197
+ count += psnip_builtin_popcount64(bs->data[i]);
198
+ }
199
+ return count;
200
+ }
201
+
202
+ static VALUE rb_bitset_cardinality(VALUE self) {
203
+ Bitset * bs = get_bitset(self);
204
+ return INT2NUM(cardinality(bs));
205
+ }
206
+
207
+ static VALUE rb_bitset_intersect(VALUE self, VALUE other) {
208
+ Bitset * bs = get_bitset(self);
209
+ Bitset * other_bs = get_bitset(other);
210
+ Bitset * new_bs;
211
+ int max = INTS(bs);
212
+ int i;
213
+
214
+ verify_equal_size(bs, other_bs);
215
+ new_bs = bitset_new();
216
+ bitset_setup(new_bs, bs->len);
217
+
218
+ for(i = 0; i < max; i++) {
219
+ uint64_t segment = bs->data[i];
220
+ uint64_t other_segment = other_bs->data[i];
221
+ new_bs->data[i] = segment & other_segment;
222
+ }
223
+
224
+ return Data_Wrap_Struct(cBitset, 0, bitset_free, new_bs);
225
+ }
226
+
227
+ static VALUE rb_bitset_union(VALUE self, VALUE other) {
228
+ Bitset * bs = get_bitset(self);
229
+ Bitset * other_bs = get_bitset(other);
230
+ Bitset * new_bs;
231
+ int max = INTS(bs);
232
+ int i;
233
+
234
+ verify_equal_size(bs, other_bs);
235
+ new_bs = bitset_new();
236
+ bitset_setup(new_bs, bs->len);
237
+
238
+ for(i = 0; i < max; i++) {
239
+ uint64_t segment = bs->data[i];
240
+ uint64_t other_segment = other_bs->data[i];
241
+ new_bs->data[i] = segment | other_segment;
242
+ }
243
+
244
+ return Data_Wrap_Struct(cBitset, 0, bitset_free, new_bs);
245
+ }
246
+
247
+ static VALUE rb_bitset_difference(VALUE self, VALUE other) {
248
+ Bitset * bs = get_bitset(self);
249
+ Bitset * other_bs = get_bitset(other);
250
+ Bitset * new_bs;
251
+ int max = INTS(bs);
252
+ int i;
253
+
254
+ verify_equal_size(bs, other_bs);
255
+ new_bs = bitset_new();
256
+ bitset_setup(new_bs, bs->len);
257
+
258
+ for(i = 0; i < max; i++) {
259
+ uint64_t segment = bs->data[i];
260
+ uint64_t other_segment = other_bs->data[i];
261
+ new_bs->data[i] = segment & ~other_segment;
262
+ }
263
+
264
+ return Data_Wrap_Struct(cBitset, 0, bitset_free, new_bs);
265
+ }
266
+
267
+ static VALUE rb_bitset_xor(VALUE self, VALUE other) {
268
+ Bitset * bs = get_bitset(self);
269
+ Bitset * other_bs = get_bitset(other);
270
+ Bitset * new_bs;
271
+ int max = INTS(bs);
272
+ int i;
273
+
274
+ verify_equal_size(bs, other_bs);
275
+ new_bs = bitset_new();
276
+ bitset_setup(new_bs, bs->len);
277
+
278
+ for(i = 0; i < max; i++) {
279
+ uint64_t segment = bs->data[i];
280
+ uint64_t other_segment = other_bs->data[i];
281
+ new_bs->data[i] = segment ^ other_segment;
282
+ }
283
+
284
+ return Data_Wrap_Struct(cBitset, 0, bitset_free, new_bs);
285
+ }
286
+
287
+ static VALUE rb_bitset_not(VALUE self) {
288
+ Bitset * bs = get_bitset(self);
289
+ Bitset * new_bs = bitset_new();
290
+ int max = INTS(bs);
291
+ int i;
292
+
293
+ bitset_setup(new_bs, bs->len);
294
+ for(i = 0; i < max; i++) {
295
+ uint64_t segment = bs->data[i];
296
+ new_bs->data[i] = ~segment;
297
+ }
298
+ if(_bit_no(bs->len) != 0)
299
+ new_bs->data[max-1] &= _bit_mask(bs->len) - 1;
300
+
301
+ return Data_Wrap_Struct(cBitset, 0, bitset_free, new_bs);
302
+ }
303
+
304
+ static VALUE rb_bitset_to_s(VALUE self) {
305
+ Bitset * bs = get_bitset(self);
306
+
307
+ int i;
308
+ char * data = malloc(bs->len + 1);
309
+ for(i = 0; i < bs->len; i++) {
310
+ data[i] = _get_bit(bs, i) ? '1' : '0';
311
+ }
312
+ data[bs->len] = 0;
313
+
314
+ return rb_str_new2(data);
315
+ }
316
+
317
+ static VALUE rb_bitset_from_s(VALUE self, VALUE s) {
318
+ int length = RSTRING_LEN(s);
319
+ char* data = StringValuePtr(s);
320
+ Bitset * new_bs = bitset_new();
321
+ int i;
322
+
323
+ bitset_setup(new_bs, length);
324
+
325
+ for (i = 0; i < length; i++) {
326
+ if (data[i] == '1') {
327
+ _set_bit(new_bs, i);
328
+ }
329
+ }
330
+
331
+ return Data_Wrap_Struct(cBitset, 0, bitset_free, new_bs);
332
+ }
333
+
334
+ static VALUE rb_bitset_hamming(VALUE self, VALUE other) {
335
+ Bitset * bs = get_bitset(self);
336
+ Bitset * other_bs = get_bitset(other);
337
+
338
+ int max = INTS(bs);
339
+ int count = 0;
340
+ int i;
341
+ for(i = 0; i < max; i++) {
342
+ uint64_t segment = bs->data[i];
343
+ uint64_t other_segment = other_bs->data[i];
344
+ count += psnip_builtin_popcount64(segment ^ other_segment);
345
+ }
346
+
347
+ return INT2NUM(count);
348
+ }
349
+
350
+ static VALUE rb_bitset_each(VALUE self) {
351
+ Bitset * bs = get_bitset(self);
352
+ int i;
353
+
354
+ for(i = 0; i < bs->len; i++) {
355
+ rb_yield(_get_bit(bs, i) ? Qtrue : Qfalse);
356
+ }
357
+
358
+ return self;
359
+ }
360
+
361
+ static VALUE rb_bitset_marshall_dump(VALUE self) {
362
+ Bitset * bs = get_bitset(self);
363
+ VALUE hash = rb_hash_new();
364
+ VALUE data = rb_str_new((const char *) bs->data, BYTES(bs));
365
+
366
+ rb_hash_aset(hash, ID2SYM(rb_intern("len")), UINT2NUM(bs->len));
367
+ rb_hash_aset(hash, ID2SYM(rb_intern("data")), data);
368
+
369
+ return hash;
370
+ }
371
+
372
+ static VALUE rb_bitset_marshall_load(VALUE self, VALUE hash) {
373
+ Bitset * bs = get_bitset(self);
374
+ int len = NUM2INT(rb_hash_aref(hash, ID2SYM(rb_intern("len"))));
375
+
376
+ VALUE data = rb_hash_aref(hash, ID2SYM(rb_intern("data")));
377
+
378
+ bitset_setup(bs, len);
379
+
380
+ bs->data = (uint64_t *) calloc(INTS(bs), sizeof(uint64_t));
381
+ memcpy(bs->data, RSTRING_PTR(data), BYTES(bs));
382
+
383
+ return Qnil;
384
+ }
385
+
386
+ static VALUE rb_bitset_to_binary_array(VALUE self) {
387
+ Bitset * bs = get_bitset(self);
388
+ int i;
389
+
390
+ VALUE array = rb_ary_new2(bs->len / 2);
391
+ for(i = 0; i < bs->len; i++) {
392
+ rb_ary_push(array, INT2NUM(_get_bit(bs, i) > 0 ? 1 : 0));
393
+ }
394
+
395
+ return array;
396
+ }
397
+
398
+ static VALUE rb_bitset_dup(VALUE self) {
399
+ Bitset * bs = get_bitset(self);
400
+ int max = INTS(bs);
401
+
402
+ Bitset * new_bs = bitset_new();
403
+ bitset_setup(new_bs, bs->len);
404
+
405
+ memcpy(new_bs->data, bs->data, max * sizeof(bs->data[0]));
406
+ return Data_Wrap_Struct(cBitset, 0, bitset_free, new_bs);
407
+ }
408
+
409
+ /* Yield the bit numbers of each set bit in sequence to a block. If
410
+ there is no block, return an array of those numbers. */
411
+ static VALUE rb_bitset_each_set(int argc, VALUE * argv, VALUE self) {
412
+ Bitset * bs = get_bitset(self);
413
+ int seg_no;
414
+ int max = INTS(bs);
415
+ uint64_t* seg_ptr = bs->data;
416
+ int block_p = rb_block_given_p();
417
+ VALUE ary = Qnil;
418
+ int set_bit_no = -1;
419
+
420
+ /* If there is one argument, it is an index into the notional
421
+ output array, and return an int. If there are two arguments,
422
+ return up to <n> arguments where is the second argument. */
423
+ int min_set_bit_no = (argc > 0) ? NUM2INT(argv[0]) : 0;
424
+ int max_set_bit_no;
425
+
426
+ if (argc > 2) {
427
+ VALUE error = rb_const_get(rb_cObject, rb_intern("ArgumentError"));
428
+ rb_raise(error, "wrong number of arguments (given %d, expected 0..2)",
429
+ argc);
430
+ }
431
+
432
+ if (min_set_bit_no < 0) {
433
+ /* Convert negative numbers into offsets from the end of the array. */
434
+ min_set_bit_no = cardinality(bs) + min_set_bit_no;
435
+ }
436
+
437
+ max_set_bit_no = (argc == 0)
438
+ ? INT_MAX
439
+ : (argc == 1)
440
+ ? (min_set_bit_no + 1)
441
+ : (min_set_bit_no + NUM2INT(argv[1]));
442
+
443
+ if (min_set_bit_no < 0 || max_set_bit_no < min_set_bit_no)
444
+ return Qnil;
445
+
446
+ if (argc != 1 && !block_p) {
447
+ ary = rb_ary_new();
448
+ }
449
+ if (min_set_bit_no < 0 || max_set_bit_no < min_set_bit_no)
450
+ return Qnil;
451
+
452
+ for (seg_no = 0; seg_no < max; ++seg_no, ++seg_ptr) {
453
+ uint64_t segment = *seg_ptr;
454
+ int bit_position = 0;
455
+ bool finished = false;
456
+ while (segment) {
457
+ VALUE v;
458
+
459
+ if (!(segment & 1)) {
460
+ int shift = psnip_builtin_ctz64(segment);
461
+ bit_position += shift;
462
+ segment >>= shift;
463
+ }
464
+ v = INT2NUM(_seg_no_to_bit_no(seg_no) + bit_position);
465
+ ++bit_position;
466
+ segment >>= 1;
467
+ ++set_bit_no;
468
+ if (set_bit_no < min_set_bit_no) {
469
+ continue;
470
+ }
471
+ if (set_bit_no >= max_set_bit_no) {
472
+ finished = true;
473
+ break;
474
+ }
475
+ if (block_p) {
476
+ rb_yield(v);
477
+ } else if (argc == 1) {
478
+ return v;
479
+ } else {
480
+ rb_ary_push(ary, v);
481
+ }
482
+ }
483
+ if (finished) {
484
+ break;
485
+ }
486
+ }
487
+
488
+ return block_p ? self : ary;
489
+ }
490
+
491
+ static VALUE rb_bitset_empty_p(VALUE self) {
492
+ Bitset * bs = get_bitset(self);
493
+ int seg_no;
494
+ int max = INTS(bs);
495
+ uint64_t* seg_ptr = bs->data;
496
+
497
+ for (seg_no = 0; seg_no < max; ++seg_no, ++seg_ptr) {
498
+ if (*seg_ptr) {
499
+ return Qfalse;
500
+ }
501
+ }
502
+ return Qtrue;
503
+ }
504
+
505
+ static VALUE rb_bitset_values_at(VALUE self, VALUE index_array) {
506
+ int i;
507
+ Bitset * bs = get_bitset(self);
508
+ int blen = bs->len;
509
+ int alen = RARRAY_LEN(index_array);
510
+ VALUE *ptr = RARRAY_PTR(index_array);
511
+ Bitset * new_bs = bitset_new();
512
+ bitset_setup(new_bs, alen);
513
+ for (i = 0; i < alen; ++i) {
514
+ int idx = NUM2INT(ptr[i]);
515
+ if (idx >= 0 && idx < blen && _get_bit(bs, idx)) {
516
+ _set_bit(new_bs, i);
517
+ }
518
+ }
519
+
520
+ return Data_Wrap_Struct(cBitset, 0, bitset_free, new_bs);
521
+ }
522
+
523
+ /** This could run a bit faster if you worked at it. */
524
+ static VALUE rb_bitset_reverse(VALUE self, VALUE index_array) {
525
+ int i;
526
+ Bitset * bs = get_bitset(self);
527
+ int len = bs->len;
528
+ Bitset * new_bs = bitset_new();
529
+ bitset_setup(new_bs, len);
530
+ for (i = 0; i < len; ++i) {
531
+ if (_get_bit(bs, i)) {
532
+ _set_bit(new_bs, len - i - 1);
533
+ }
534
+ }
535
+
536
+ return Data_Wrap_Struct(cBitset, 0, bitset_free, new_bs);
537
+ }
538
+
539
+ static VALUE rb_bitset_equal(VALUE self, VALUE other) {
540
+ int i;
541
+ Bitset * bs = get_bitset(self);
542
+ Bitset * other_bs = get_bitset(other);
543
+ int max = INTS(bs);
544
+
545
+ if (bs->len != other_bs->len)
546
+ return Qfalse;
547
+ for(i = 0; i < max; i++) {
548
+ if (bs->data[i] != other_bs->data[i]) {
549
+ return Qfalse;
550
+ }
551
+ }
552
+ return Qtrue;
553
+ }
554
+
555
+ typedef uint64_t (*bitwise_op)(uint64_t, uint64_t);
556
+ inline uint64_t and(uint64_t a, uint64_t b) { return a & b; }
557
+ inline uint64_t or(uint64_t a, uint64_t b) { return a | b; }
558
+ inline uint64_t xor(uint64_t a, uint64_t b) { return a ^ b; }
559
+ inline uint64_t difference(uint64_t a, uint64_t b) { return a & ~b; }
560
+
561
+ static VALUE mutable(VALUE self, VALUE other, bitwise_op operator) {
562
+ Bitset * bs = get_bitset(self);
563
+ Bitset * other_bs = get_bitset(other);
564
+ int max = INTS(bs);
565
+ int i;
566
+ verify_equal_size(bs, other_bs);
567
+
568
+ for(i = 0; i < max; i++) {
569
+ uint64_t segment = bs->data[i];
570
+ uint64_t other_segment = other_bs->data[i];
571
+ bs->data[i] = operator(segment, other_segment);
572
+ }
573
+
574
+ return self;
575
+ }
576
+
577
+ static VALUE rb_bitset_union_mutable(VALUE self, VALUE other) {
578
+ return mutable(self, other, &or);
579
+ }
580
+
581
+ static VALUE rb_bitset_intersect_mutable(VALUE self, VALUE other) {
582
+ return mutable(self, other, &and);
583
+ }
584
+
585
+ static VALUE rb_bitset_xor_mutable(VALUE self, VALUE other) {
586
+ return mutable(self, other, &xor);
587
+ }
588
+
589
+ static VALUE rb_bitset_difference_mutable(VALUE self, VALUE other) {
590
+ return mutable(self, other, &difference);
591
+ }
592
+
593
+ static VALUE rb_bitset_reset(VALUE self) {
594
+ Bitset * bs = get_bitset(self);
595
+ memset(bs->data, 0, (INTS(bs) * sizeof(uint64_t)) );
596
+ return self;
597
+ }
598
+
599
+ void Init_CBitset() {
600
+ mContainers = rb_define_module("Containers");
601
+ cBitset = rb_define_class_under(mContainers, "Bitset", rb_cObject);
602
+ rb_include_module(cBitset, rb_mEnumerable);
603
+ rb_define_alloc_func(cBitset, rb_bitset_alloc);
604
+ rb_define_method(cBitset, "initialize", rb_bitset_initialize, 1);
605
+ rb_define_method(cBitset, "reset!", rb_bitset_reset, 0);
606
+ rb_define_method(cBitset, "size", rb_bitset_size, 0);
607
+ rb_define_method(cBitset, "[]", rb_bitset_aref, 1);
608
+ rb_define_method(cBitset, "[]=", rb_bitset_aset, 2);
609
+ rb_define_method(cBitset, "set", rb_bitset_set, -1);
610
+ rb_define_method(cBitset, "clear", rb_bitset_clear, -1);
611
+ rb_define_method(cBitset, "set?", rb_bitset_set_p, -1);
612
+ rb_define_method(cBitset, "clear?", rb_bitset_clear_p, -1);
613
+ rb_define_method(cBitset, "cardinality", rb_bitset_cardinality, 0);
614
+ rb_define_method(cBitset, "intersect", rb_bitset_intersect, 1);
615
+ rb_define_alias(cBitset, "&", "intersect");
616
+ rb_define_alias(cBitset, "and", "intersect");
617
+ rb_define_method(cBitset, "intersect!", rb_bitset_intersect_mutable, 1);
618
+ rb_define_alias(cBitset, "and!", "intersect!");
619
+ rb_define_method(cBitset, "union", rb_bitset_union, 1);
620
+ rb_define_alias(cBitset, "|", "union");
621
+ rb_define_alias(cBitset, "or", "union");
622
+ rb_define_method(cBitset, "union!", rb_bitset_union_mutable, 1);
623
+ rb_define_alias(cBitset, "or!", "union!");
624
+ rb_define_method(cBitset, "difference", rb_bitset_difference, 1);
625
+ rb_define_alias(cBitset, "-", "difference");
626
+ rb_define_method(cBitset, "difference!", rb_bitset_difference_mutable, 1);
627
+ rb_define_method(cBitset, "xor", rb_bitset_xor, 1);
628
+ rb_define_alias(cBitset, "^", "xor");
629
+ rb_define_alias(cBitset, "symmetric_difference", "xor");
630
+ rb_define_method(cBitset, "xor!", rb_bitset_xor_mutable, 1);
631
+ rb_define_alias(cBitset, "symmetric_difference!", "xor!");
632
+ rb_define_method(cBitset, "not", rb_bitset_not, 0);
633
+ rb_define_alias(cBitset, "~", "not");
634
+ rb_define_method(cBitset, "hamming", rb_bitset_hamming, 1);
635
+ rb_define_method(cBitset, "each", rb_bitset_each, 0);
636
+ rb_define_method(cBitset, "to_s", rb_bitset_to_s, 0);
637
+ rb_define_singleton_method(cBitset, "from_s", rb_bitset_from_s, 1);
638
+ rb_define_method(cBitset, "marshal_dump", rb_bitset_marshall_dump, 0);
639
+ rb_define_method(cBitset, "marshal_load", rb_bitset_marshall_load, 1);
640
+ rb_define_method(cBitset, "to_binary_array", rb_bitset_to_binary_array, 0);
641
+ rb_define_method(cBitset, "dup", rb_bitset_dup, 0);
642
+ rb_define_alias(cBitset, "clone", "dup");
643
+ rb_define_method(cBitset, "each_set", rb_bitset_each_set, -1);
644
+ rb_define_alias(cBitset, "to_a", "each_set");
645
+ /* #each_set allows an optional block, and #to_a normally doesn't.
646
+ But an alias is simpler than having two different functions. */
647
+ rb_define_method(cBitset, "empty?", rb_bitset_empty_p, 0);
648
+ rb_define_method(cBitset, "values_at", rb_bitset_values_at, 1);
649
+ rb_define_alias(cBitset, "select_bits", "values_at");
650
+ rb_define_method(cBitset, "reverse", rb_bitset_reverse, 0);
651
+ rb_define_method(cBitset, "==", rb_bitset_equal, 1);
652
+ }