victory 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+ }