9#include "internal/bits.h"
10#include "internal/error.h"
11#include "internal/hash.h"
12#include "internal/proc.h"
13#include "internal/sanitizers.h"
14#include "internal/set_table.h"
15#include "internal/symbol.h"
16#include "internal/variable.h"
17#include "ruby_assert.h"
30#include "internal/gc.h"
36 union {
double d; st_index_t i;} u;
41static const uint64_t prime1 = ((uint64_t)0x2e0bb864 << 32) | 0xe9ea7df5;
42static const uint32_t prime2 = 0x830fcab9;
45mult_and_mix(uint64_t m1, uint64_t m2)
47#if defined HAVE_UINT128_T
48 uint128_t r = (uint128_t) m1 * (uint128_t) m2;
49 return (uint64_t) (r >> 64) ^ (uint64_t) r;
51 uint64_t hm1 = m1 >> 32, hm2 = m2 >> 32;
52 uint64_t lm1 = m1, lm2 = m2;
53 uint64_t v64_128 = hm1 * hm2;
54 uint64_t v32_96 = hm1 * lm2 + lm1 * hm2;
55 uint64_t v1_32 = lm1 * lm2;
57 return (v64_128 + (v32_96 >> 32)) ^ ((v32_96 << 32) + v1_32);
62key64_hash(uint64_t key, uint32_t seed)
64 return mult_and_mix(key + seed, prime1);
68#define set_index_hash(index) key64_hash(rb_hash_start(index), prime2)
71set_ident_hash(st_data_t n)
80 n ^= dbl_to_index(rb_float_value(n));
84 return (st_index_t)set_index_hash((st_index_t)n);
87static const struct st_hash_type identhash = {
92static const struct st_hash_type objhash = {
98static VALUE set_i_compare_by_identity(
VALUE set);
100#define id_each idEach
101static ID id_each_entry;
105static ID id_set_iter_lev;
106static ID id_subclass_compatible;
107static ID id_class_methods;
109#define RSET_INITIALIZED FL_USER1
110#define RSET_LEV_MASK (FL_USER13 | FL_USER14 | FL_USER15 | \
111 FL_USER16 | FL_USER17 | FL_USER18 | FL_USER19)
112#define RSET_LEV_SHIFT (FL_USHIFT + 13)
113#define RSET_LEV_MAX 127
115#define SET_ASSERT(expr) RUBY_ASSERT_MESG_WHEN(SET_DEBUG, expr, #expr)
117#define RSET_SIZE(set) set_table_size(RSET_TABLE(set))
118#define RSET_EMPTY(set) (RSET_SIZE(set) == 0)
119#define RSET_SIZE_NUM(set) SIZET2NUM(RSET_SIZE(set))
120#define RSET_IS_MEMBER(sobj, item) set_table_lookup(RSET_TABLE(set), (st_data_t)(item))
121#define RSET_COMPARE_BY_IDENTITY(set) (RSET_TABLE(set)->type == &identhash)
128mark_and_pin_key(st_data_t key, st_data_t data)
130 rb_gc_mark((
VALUE)key);
136mark_key(st_data_t key, st_data_t data)
138 rb_gc_mark_movable((
VALUE)key);
148 if (sobj->table.type == &identhash) {
149 set_table_foreach(&sobj->table, mark_and_pin_key, 0);
152 set_table_foreach(&sobj->table, mark_key, 0);
160 free((&sobj->table)->entries);
167 set_free_embedded(sobj);
168 memset(&sobj->table, 0,
sizeof(sobj->table));
172set_size(
const void *
ptr)
176 return (
unsigned long)set_memsize(&sobj->table) -
sizeof(sobj->table);
180set_foreach_replace(st_data_t key, st_data_t argp,
int error)
182 if (rb_gc_location((
VALUE)key) != (
VALUE)key) {
190set_replace_ref(st_data_t *key, st_data_t argp,
int existing)
192 rb_gc_mark_and_move((
VALUE *)key);
198set_update_references(
void *
ptr)
201 set_foreach_with_replace(&sobj->table, set_foreach_replace, set_replace_ref, 0);
205 .wrap_struct_name =
"set",
210 .dcompact = set_update_references,
212 .flags = RUBY_TYPED_EMBEDDABLE | RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE
224iter_lev_in_ivar(
VALUE set)
229 SET_ASSERT(lev >= 0);
230 return (
unsigned long)lev;
236iter_lev_in_ivar_set(
VALUE set,
unsigned long lev)
238 SET_ASSERT(lev >= RSET_LEV_MAX);
240 rb_ivar_set_internal(set, id_set_iter_lev,
LONG2FIX((
long)lev));
243static inline unsigned long
244iter_lev_in_flags(
VALUE set)
246 return (
unsigned long)((
RBASIC(set)->flags >> RSET_LEV_SHIFT) & RSET_LEV_MAX);
250iter_lev_in_flags_set(
VALUE set,
unsigned long lev)
252 SET_ASSERT(lev <= RSET_LEV_MAX);
253 RBASIC(set)->flags = ((
RBASIC(set)->flags & ~RSET_LEV_MASK) | ((
VALUE)lev << RSET_LEV_SHIFT));
257set_iterating_p(
VALUE set)
259 return iter_lev_in_flags(set) > 0;
263set_iter_lev_inc(
VALUE set)
265 unsigned long lev = iter_lev_in_flags(set);
266 if (lev == RSET_LEV_MAX) {
267 lev = iter_lev_in_ivar(set) + 1;
274 iter_lev_in_flags_set(set, lev);
275 if (lev < RSET_LEV_MAX)
return;
277 iter_lev_in_ivar_set(set, lev);
281set_iter_lev_dec(
VALUE set)
283 unsigned long lev = iter_lev_in_flags(set);
284 if (lev == RSET_LEV_MAX) {
285 lev = iter_lev_in_ivar(set);
286 if (lev > RSET_LEV_MAX) {
287 iter_lev_in_ivar_set(set, lev-1);
290 rb_attr_delete(set, id_set_iter_lev);
295 iter_lev_in_flags_set(set, lev - 1);
299set_foreach_ensure(
VALUE set)
301 set_iter_lev_dec(set);
309 set_foreach_func *func;
314set_iter_status_check(
int status)
316 if (status == ST_CONTINUE) {
324set_foreach_iter(st_data_t key, st_data_t argp,
int error)
328 if (error)
return ST_STOP;
331 int status = (*arg->func)((
VALUE)key, arg->arg);
333 if (RSET_TABLE(arg->set) != tbl) {
337 return set_iter_status_check(status);
341set_foreach_call(
VALUE arg)
345 ret = set_foreach_check(RSET_TABLE(set), set_foreach_iter,
346 (st_data_t)arg, (st_data_t)
Qundef);
354set_iter(
VALUE set, set_foreach_func *func,
VALUE farg)
363 if (RB_OBJ_FROZEN(set)) {
364 set_foreach_call((
VALUE)&arg);
367 set_iter_lev_inc(set);
368 rb_ensure(set_foreach_call, (
VALUE)&arg, set_foreach_ensure, set);
372NORETURN(
static void no_new_item(
void));
376 rb_raise(
rb_eRuntimeError,
"can't add a new item into set during iteration");
380set_compact_after_delete(
VALUE set)
382 if (!set_iterating_p(set)) {
383 set_compact_table(RSET_TABLE(set));
391 key = rb_hash_key_str(key);
392 if (key_addr) *key_addr = key;
394 int ret = set_insert(tab, (st_data_t)key);
402 return set_table_insert_wb(RSET_TABLE(set), set, key, key_addr);
406set_alloc_with_size(
VALUE klass, st_index_t size)
412 set_init_table_with_size(&sobj->table, &objhash, size);
419set_s_alloc(
VALUE klass)
421 return set_alloc_with_size(klass, 0);
432set_s_create(
int argc,
VALUE *argv,
VALUE klass)
434 VALUE set = set_alloc_with_size(klass, argc);
438 for (i=0; i < argc; i++) {
439 set_table_insert_wb(table, set, argv[i], NULL);
462 rb_raise(rb_eArgError,
"value must be a set");
467enum_method_id(
VALUE other)
470 return id_each_entry;
476 rb_raise(rb_eArgError,
"value must be enumerable");
483 return RSET_SIZE_NUM(set);
490 set_insert_wb(set, element, &element);
498 set_insert_wb(set, element, &element);
521set_i_initialize(
int argc,
VALUE *argv,
VALUE set)
523 if (
RBASIC(set)->flags & RSET_INITIALIZED) {
526 RBASIC(set)->flags |= RSET_INITIALIZED;
529 rb_check_arity(argc, 0, 1);
531 if (argc > 0 && (other = argv[0]) !=
Qnil) {
532 if (RB_TYPE_P(other,
T_ARRAY)) {
538 if (block_given) key =
rb_yield(key);
539 set_table_insert_wb(into, set, key, NULL);
544 rb_block_given_p() ? set_initialize_with_block : set_initialize_without_block,
556 if (set == other)
return set;
558 if (set_iterating_p(set)) {
565 set_free_embedded(sobj);
566 set_copy(&sobj->table, RSET_TABLE(other));
567 rb_gc_writebarrier_remember(set);
573set_inspect_i(st_data_t key, st_data_t arg)
577 if (args[1] ==
Qtrue) {
595 str = rb_sprintf(
"%"PRIsVALUE
"[...]", klass_name);
599 str = rb_sprintf(
"%"PRIsVALUE
"[", klass_name);
601 set_iter(set, set_inspect_i, (st_data_t)args);
623set_i_inspect(
VALUE set)
629set_to_a_i(st_data_t key, st_data_t arg)
647 st_index_t size = RSET_SIZE(set);
650 if (size == 0)
return ary;
652 if (ST_DATA_COMPATIBLE_P(
VALUE)) {
654 size = set_keys(RSET_TABLE(set),
ptr, size);
656 rb_gc_writebarrier_remember(ary);
657 rb_ary_set_len(ary, size);
660 set_iter(set, set_to_a_i, (st_data_t)ary);
686 rb_warn_deprecated(
"passing arguments to Set#to_set", NULL);
708 rb_check_arity(argc, 0, 1);
726 rb_check_frozen(set);
727 if (set_iterating_p(set)) {
728 if (!set_table_lookup(RSET_TABLE(set), (st_data_t)item)) {
733 set_insert_wb(set, item, NULL);
752 rb_check_frozen(set);
753 if (set_iterating_p(set)) {
754 if (!set_table_lookup(RSET_TABLE(set), (st_data_t)item)) {
760 return set_insert_wb(set, item, NULL) ?
Qnil : set;
774 rb_check_frozen(set);
775 if (set_table_delete(RSET_TABLE(set), (st_data_t *)&item)) {
776 set_compact_after_delete(set);
791 rb_check_frozen(set);
792 if (set_table_delete(RSET_TABLE(set), (st_data_t *)&item)) {
793 set_compact_after_delete(set);
800set_delete_if_i(st_data_t key, st_data_t dummy)
814set_i_delete_if(
VALUE set)
817 rb_check_frozen(set);
818 set_iter(set, set_delete_if_i, 0);
819 set_compact_after_delete(set);
832set_i_reject(
VALUE set)
835 rb_check_frozen(set);
838 size_t n = set_table_size(table);
839 set_iter(set, set_delete_if_i, 0);
841 if (n == set_table_size(table))
return Qnil;
843 set_compact_after_delete(set);
848set_classify_i(st_data_t key, st_data_t tmp)
851 VALUE hash = args[0];
853 VALUE set = rb_hash_lookup2(hash, hash_key,
Qundef);
855 set = set_s_alloc(args[1]);
856 if (
RTEST(args[2])) {
857 set_i_compare_by_identity(set);
859 rb_hash_aset(hash, hash_key, set);
885set_i_classify(
VALUE set)
889 args[0] = rb_hash_new();
891 args[2] = RBOOL(RSET_COMPARE_BY_IDENTITY(set));
892 set_iter(set, set_classify_i, (st_data_t)args);
898set_divide_union_find_root(
long *uf_parents,
long index,
long *tmp_array)
900 long root = uf_parents[index];
901 long update_size = 0;
902 while (root != index) {
903 tmp_array[update_size++] = index;
905 root = uf_parents[index];
907 for (
long j = 0; j < update_size; j++) {
908 long idx = tmp_array[j];
909 uf_parents[idx] = root;
915set_divide_union_find_merge(
long *uf_parents,
long i,
long j,
long *tmp_array)
917 long root_i = set_divide_union_find_root(uf_parents, i, tmp_array);
918 long root_j = set_divide_union_find_root(uf_parents, j, tmp_array);
919 if (root_i != root_j) uf_parents[root_j] = root_i;
923set_divide_arity2(
VALUE set)
926 long size, *uf_parents, *tmp_array;
928 VALUE items = set_i_to_a(set);
931 tmp_array =
ALLOCV_N(
long, tmp, size);
932 uf_parents =
ALLOCV_N(
long, uf, size);
933 for (
long i = 0; i < size; i++) {
936 for (
long i = 0; i < size - 1; i++) {
938 for (
long j = i + 1; j < size; j++) {
942 set_divide_union_find_merge(uf_parents, i, j, tmp_array);
947 VALUE hash = rb_hash_new();
948 for (
long i = 0; i < size; i++) {
950 long root = set_divide_union_find_root(uf_parents, i, tmp_array);
952 if (subset ==
Qnil) {
953 subset = set_s_alloc(set_class);
954 if (RSET_COMPARE_BY_IDENTITY(set)) {
955 set_i_compare_by_identity(subset);
957 rb_hash_aset(hash,
LONG2FIX(root), subset);
958 set_i_add(final_set, subset);
960 set_i_add(subset, v);
967static void set_merge_enum_into(
VALUE set,
VALUE arg);
993set_i_divide(
VALUE set)
997 if (rb_block_arity() == 2) {
998 return set_divide_arity2(set);
1001 VALUE values = rb_hash_values(set_i_classify(set));
1003 set_merge_enum_into(set, values);
1008set_clear_i(st_data_t key, st_data_t dummy)
1024set_i_clear(
VALUE set)
1026 rb_check_frozen(set);
1027 if (RSET_SIZE(set) == 0)
return set;
1028 if (set_iterating_p(set)) {
1029 set_iter(set, set_clear_i, 0);
1032 set_table_clear(RSET_TABLE(set));
1033 set_compact_after_delete(set);
1047set_intersection_i(st_data_t key, st_data_t tmp)
1050 if (set_table_lookup(data->other, key)) {
1051 set_table_insert_wb(data->into, data->set, key, NULL);
1060 set_intersection_i((st_data_t)i, (st_data_t)data);
1078 if (RSET_COMPARE_BY_IDENTITY(set)) {
1079 set_i_compare_by_identity(new_set);
1082 set_table *ntable = RSET_TABLE(new_set);
1087 if (set_table_size(stable) >= set_table_size(otable)) {
1100 set_iter(set, set_intersection_i, (st_data_t)data);
1110 rb_block_call(other, enum_method_id(other), 0, 0, set_intersection_block, data);
1144 return RBOOL(RSET_IS_MEMBER(set, item));
1153set_merge_i(st_data_t key, st_data_t data)
1156 set_table_insert_wb(args->into, args->set, key, NULL);
1163 VALUE element = key;
1164 set_insert_wb(set, element, &element);
1174 .into = RSET_TABLE(set)
1176 set_iter(arg, set_merge_i, (st_data_t)&args);
1178 else if (RB_TYPE_P(arg,
T_ARRAY)) {
1182 set_table_insert_wb(into, set,
RARRAY_AREF(arg, i), NULL);
1201 rb_raise(rb_eArgError,
"no keywords accepted");
1204 if (set_iterating_p(set)) {
1208 rb_check_frozen(set);
1212 for (i=0; i < argc; i++) {
1213 set_merge_enum_into(set, argv[i]);
1220set_reset_table_with_type(
VALUE set,
const struct st_hash_type *
type)
1222 rb_check_frozen(set);
1228 size_t size = set_table_size(old);
1230 set_table *
new = set_init_table_with_size(NULL,
type, size);
1235 set_iter(set, set_merge_i, (st_data_t)&args);
1236 set_free_embedded(sobj);
1237 memcpy(&sobj->table,
new,
sizeof(*
new));
1241 sobj->table.type =
type;
1254set_i_compare_by_identity(
VALUE set)
1256 if (RSET_COMPARE_BY_IDENTITY(set))
return set;
1258 if (set_iterating_p(set)) {
1262 return set_reset_table_with_type(set, &identhash);
1273set_i_compare_by_identity_p(
VALUE set)
1275 return RBOOL(RSET_COMPARE_BY_IDENTITY(set));
1285set_i_size(
VALUE set)
1287 return RSET_SIZE_NUM(set);
1297set_i_empty(
VALUE set)
1299 return RBOOL(RSET_EMPTY(set));
1303set_xor_i(st_data_t key, st_data_t data)
1308 if (set_table_insert_wb(table, set, element, &element)) {
1309 set_table_delete(table, &element);
1331 set_iter(other, set_xor_i, (st_data_t)new_set);
1335 if (RSET_COMPARE_BY_IDENTITY(new_set)) {
1336 set_i_compare_by_identity(tmp);
1338 set_merge_enum_into(tmp, other);
1339 set_iter(tmp, set_xor_i, (st_data_t)new_set);
1341 set_compact_after_delete(set);
1360 set_merge_enum_into(set, other);
1365set_remove_i(st_data_t key, st_data_t from)
1367 set_table_delete((
struct set_table *)from, (st_data_t *)&key);
1374 rb_check_frozen(set);
1375 set_table_delete(RSET_TABLE(set), (st_data_t *)&key);
1383 set_iter(arg, set_remove_i, (st_data_t)RSET_TABLE(set));
1388 set_compact_after_delete(set);
1401 rb_check_frozen(set);
1402 set_remove_enum_from(set, other);
1419 return set_i_subtract(
rb_obj_dup(set), other);
1423set_each_i(st_data_t key, st_data_t dummy)
1439set_i_each(
VALUE set)
1442 set_iter(set, set_each_i, 0);
1447set_collect_i(st_data_t key, st_data_t data)
1462set_i_collect(
VALUE set)
1465 rb_check_frozen(set);
1468 if (RSET_COMPARE_BY_IDENTITY(set)) {
1469 set_i_compare_by_identity(new_set);
1471 set_iter(set, set_collect_i, (st_data_t)new_set);
1472 set_i_initialize_copy(set, new_set);
1478set_keep_if_i(st_data_t key, st_data_t into)
1481 set_table_delete((
set_table *)into, &key);
1495set_i_keep_if(
VALUE set)
1498 rb_check_frozen(set);
1500 set_iter(set, set_keep_if_i, (st_data_t)RSET_TABLE(set));
1501 set_compact_after_delete(set);
1515set_i_select(
VALUE set)
1518 rb_check_frozen(set);
1521 size_t n = set_table_size(table);
1522 set_iter(set, set_keep_if_i, (st_data_t)table);
1523 set_compact_after_delete(set);
1525 return (n == set_table_size(table)) ?
Qnil : set;
1542 rb_check_frozen(set);
1545 set_i_initialize_copy(set, other);
1548 if (set_iterating_p(set)) {
1553 enum_method_id(other);
1555 set_table_clear(RSET_TABLE(set));
1556 set_merge_enum_into(set, other);
1558 set_compact_after_delete(set);
1571set_i_reset(
VALUE set)
1573 if (set_iterating_p(set)) {
1577 return set_reset_table_with_type(set, RSET_TABLE(set)->
type);
1583set_flatten_merge_i(st_data_t item, st_data_t arg)
1586 VALUE set = args[0];
1588 VALUE e_id = rb_obj_id(item);
1589 VALUE hash = args[2];
1590 switch(rb_hash_aref(hash, e_id)) {
1594 rb_raise(rb_eArgError,
"tried to flatten recursive Set");
1599 rb_hash_aset(hash, e_id,
Qtrue);
1600 set_flatten_merge(set, item, hash);
1601 rb_hash_aset(hash, e_id,
Qfalse);
1604 set_i_add(set, item);
1612 VALUE args[3] = {set, from, hash};
1613 set_iter(from, set_flatten_merge_i, (st_data_t)args);
1624set_i_flatten(
VALUE set)
1627 if (RSET_COMPARE_BY_IDENTITY(set)) {
1628 set_i_compare_by_identity(new_set);
1630 set_flatten_merge(new_set, set, rb_hash_new());
1635set_contains_set_i(st_data_t item, st_data_t arg)
1638 *(
bool *)arg =
true;
1652set_i_flatten_bang(
VALUE set)
1654 bool contains_set =
false;
1655 set_iter(set, set_contains_set_i, (st_data_t)&contains_set);
1656 if (!contains_set)
return Qnil;
1657 rb_check_frozen(set);
1658 return set_i_replace(set, set_i_flatten(set));
1667set_le_i(st_data_t key, st_data_t arg)
1670 if (set_table_lookup(data->table, key))
return ST_CONTINUE;
1679 .table = RSET_TABLE(other),
1682 set_iter(set, set_le_i, (st_data_t)&data);
1696 if (RSET_SIZE(set) >= RSET_SIZE(other))
return Qfalse;
1697 return set_le(set, other);
1710 if (RSET_SIZE(set) > RSET_SIZE(other))
return Qfalse;
1711 return set_le(set, other);
1724 if (RSET_SIZE(set) <= RSET_SIZE(other))
return Qfalse;
1725 return set_le(other, set);
1738 if (RSET_SIZE(set) < RSET_SIZE(other))
return Qfalse;
1739 return set_le(other, set);
1743set_intersect_i(st_data_t key, st_data_t arg)
1746 if (set_table_lookup((
set_table *)args[0], key)) {
1769 size_t set_size = RSET_SIZE(set);
1770 size_t other_size = RSET_SIZE(other);
1775 if (set_size < other_size) {
1777 args[0] = (
VALUE)RSET_TABLE(other);
1781 args[0] = (
VALUE)RSET_TABLE(set);
1783 set_iter(iter_arg, set_intersect_i, (st_data_t)args);
1790 rb_raise(rb_eArgError,
"value must be enumerable");
1809 return RBOOL(!
RTEST(set_i_intersect(set, other)));
1824 size_t set_size = RSET_SIZE(set);
1825 size_t other_size = RSET_SIZE(other);
1827 if (set_size < other_size) {
1828 if (set_le(set, other) ==
Qtrue) {
1832 else if (set_size > other_size) {
1833 if (set_le(other, set) ==
Qtrue) {
1837 else if (set_le(set, other) ==
Qtrue) {
1851set_eql_i(st_data_t item, st_data_t arg)
1855 if (!set_table_lookup(RSET_TABLE(data->set), item)) {
1863set_recursive_eql(
VALUE set,
VALUE dt,
int recur)
1865 if (recur)
return Qtrue;
1867 data->result =
Qtrue;
1868 set_iter(set, set_eql_i, dt);
1869 return data->result;
1882 if (set == other)
return Qtrue;
1886 size_t ssize = set_table_size(stable);
1887 size_t osize = set_table_size(otable);
1889 if (ssize != osize)
return Qfalse;
1890 if (ssize == 0 && osize == 0)
return Qtrue;
1891 if (stable->type != otable->type)
return Qfalse;
1899set_hash_i(st_data_t item, st_data_t(arg))
1901 st_index_t *hval = (st_index_t *)arg;
1902 st_index_t ival = rb_hash(item);
1903 *hval ^= rb_st_hash(&ival,
sizeof(st_index_t), 0);
1914set_i_hash(
VALUE set)
1916 st_index_t size = RSET_SIZE(set);
1917 st_index_t hval = rb_st_hash_start(size);
1920 set_iter(set, set_hash_i, (
VALUE)&hval);
1922 hval = rb_st_hash_end(hval);
1928set_to_hash_i(st_data_t key, st_data_t arg)
1935set_i_to_h(
VALUE set)
1937 st_index_t size = RSET_SIZE(set);
1939 if (RSET_COMPARE_BY_IDENTITY(set)) {
1940 hash = rb_ident_hash_new_with_size(size);
1943 hash = rb_hash_new_with_size(size);
1945 rb_hash_set_default(hash,
Qfalse);
1947 if (size == 0)
return hash;
1949 set_iter(set, set_to_hash_i, (st_data_t)hash);
1954compat_dumper(
VALUE set)
1962set_i_from_hash_i(st_data_t key, st_data_t val, st_data_t set)
1974 Check_Type(hash,
T_HASH);
1975 if (rb_hash_compare_by_id_p(hash)) set_i_compare_by_identity(set);
1976 rb_hash_stlike_foreach(hash, set_i_from_hash_i, (st_data_t)set);
1983 return set_i_from_hash(self,
rb_ivar_get(a, id_i_hash));
1991 set_iter(set, func, arg);
1997 return set_alloc_with_size(
rb_cSet, 0);
2003 return set_alloc_with_size(
rb_cSet, (st_index_t)
capa);
2009 return RSET_IS_MEMBER(set, element);
2015 return set_i_add_p(set, element) !=
Qnil;
2021 return set_i_clear(set);
2027 return set_i_delete_p(set, element) !=
Qnil;
2033 return RSET_SIZE(set);
2273 id_each_entry = rb_intern_const(
"each_entry");
2274 id_any_p = rb_intern_const(
"any?");
2275 id_new = rb_intern_const(
"new");
2276 id_i_hash = rb_intern_const(
"@hash");
2277 id_subclass_compatible = rb_intern_const(
"SubclassCompatible");
2278 id_class_methods = rb_intern_const(
"ClassMethods");
2279 id_set_iter_lev = rb_make_internal_id();
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
#define rb_define_private_method(klass, mid, func, arity)
Defines klass#mid and makes it private.
void rb_include_module(VALUE klass, VALUE module)
Includes a module to a class.
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
void rb_extend_object(VALUE obj, VALUE module)
Extend the object with the module.
VALUE rb_singleton_class(VALUE obj)
Finds or creates the singleton class of the passed object.
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
int rb_keyword_given_p(void)
Determines if the current method is given a keyword argument.
int rb_block_given_p(void)
Determines if the current method is given a block.
#define rb_str_buf_cat2
Old name of rb_usascii_str_new_cstr.
#define Qundef
Old name of RUBY_Qundef.
#define CLASS_OF
Old name of rb_class_of.
#define LONG2FIX
Old name of RB_INT2FIX.
#define T_HASH
Old name of RUBY_T_HASH.
#define FLONUM_P
Old name of RB_FLONUM_P.
#define Qtrue
Old name of RUBY_Qtrue.
#define ST2FIX
Old name of RB_ST2FIX.
#define INT2NUM
Old name of RB_INT2NUM.
#define Qnil
Old name of RUBY_Qnil.
#define Qfalse
Old name of RUBY_Qfalse.
#define FIX2LONG
Old name of RB_FIX2LONG.
#define T_ARRAY
Old name of RUBY_T_ARRAY.
#define ALLOCV_N
Old name of RB_ALLOCV_N.
#define POSFIXABLE
Old name of RB_POSFIXABLE.
#define FIXNUM_P
Old name of RB_FIXNUM_P.
#define ALLOCV_END
Old name of RB_ALLOCV_END.
VALUE rb_eRuntimeError
RuntimeError exception.
VALUE rb_ensure(VALUE(*b_proc)(VALUE), VALUE data1, VALUE(*e_proc)(VALUE), VALUE data2)
An equivalent to ensure clause.
VALUE rb_class_new_instance(int argc, const VALUE *argv, VALUE klass)
Allocates, then initialises an instance of the given class.
VALUE rb_mEnumerable
Enumerable module.
VALUE rb_obj_class(VALUE obj)
Queries the class of an object.
VALUE rb_obj_dup(VALUE obj)
Duplicates the given object.
VALUE rb_inspect(VALUE obj)
Generates a human-readable textual representation of the given object.
VALUE rb_obj_is_instance_of(VALUE obj, VALUE klass)
Queries if the given object is a direct instance of the given class.
VALUE rb_obj_is_kind_of(VALUE obj, VALUE klass)
Queries if the given object is an instance (of possibly descendants) of the given class.
VALUE rb_cString
String class.
#define RB_OBJ_WRITTEN(old, oldv, young)
Identical to RB_OBJ_WRITE(), except it doesn't write any values, but only a WB declaration.
VALUE rb_str_export_to_enc(VALUE obj, rb_encoding *enc)
Identical to rb_str_export(), except it additionally takes an encoding.
VALUE rb_funcall_passing_block(VALUE recv, ID mid, int argc, const VALUE *argv)
Identical to rb_funcallv_public(), except you can pass the passed block.
VALUE rb_funcall(VALUE recv, ID mid, int n,...)
Calls a method.
VALUE rb_ary_new_capa(long capa)
Identical to rb_ary_new(), except it additionally specifies how many rooms of objects it should alloc...
VALUE rb_ary_push(VALUE ary, VALUE elem)
Special case of rb_ary_cat() that it adds only one element.
VALUE rb_ary_freeze(VALUE obj)
Freeze an array, preventing further modifications.
VALUE rb_ary_join(VALUE ary, VALUE sep)
Recursively stringises the elements of the passed array, flattens that result, then joins the sequenc...
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn)
This roughly resembles return enum_for(__callee__) unless block_given?.
void rb_provide(const char *feature)
Declares that the given feature is already provided by someone else.
#define rb_hash_uint(h, i)
Just another name of st_hash_uint.
VALUE rb_str_buf_append(VALUE dst, VALUE src)
Identical to rb_str_cat_cstr(), except it takes Ruby's string instead of C's.
VALUE rb_str_buf_cat_ascii(VALUE dst, const char *src)
Identical to rb_str_cat_cstr(), except it additionally assumes the source string be a NUL terminated ...
VALUE rb_exec_recursive(VALUE(*f)(VALUE g, VALUE h, int r), VALUE g, VALUE h)
"Recursion" API entry point.
VALUE rb_exec_recursive_paired(VALUE(*f)(VALUE g, VALUE h, int r), VALUE g, VALUE p, VALUE h)
Identical to rb_exec_recursive(), except it checks for the recursion on the ordered pair of { g,...
VALUE rb_const_get(VALUE space, ID name)
Identical to rb_const_defined(), except it returns the actual defined value.
VALUE rb_ivar_set(VALUE obj, ID name, VALUE val)
Identical to rb_iv_set(), except it accepts the name as an ID instead of a C string.
VALUE rb_ivar_get(VALUE obj, ID name)
Identical to rb_iv_get(), except it accepts the name as an ID instead of a C string.
VALUE rb_class_path(VALUE mod)
Identical to rb_mod_name(), except it returns #<Class: ...> style inspection for anonymous modules.
int rb_respond_to(VALUE obj, ID mid)
Queries if the object responds to the method.
void rb_define_alloc_func(VALUE klass, rb_alloc_func_t func)
Sets the allocator function of a class.
int capa
Designed capacity of the buffer.
char * ptr
Pointer to the underlying memory region, of at least capa bytes.
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)
Shim for block function parameters.
VALUE rb_yield_values(int n,...)
Identical to rb_yield(), except it takes variadic number of parameters and pass them to the block.
VALUE rb_yield(VALUE val)
Yields the block.
void rb_marshal_define_compat(VALUE newclass, VALUE oldclass, VALUE(*dumper)(VALUE), VALUE(*loader)(VALUE, VALUE))
Marshal format compatibility layer.
#define RB_GC_GUARD(v)
Prevents premature destruction of local objects.
VALUE rb_block_call(VALUE q, ID w, int e, const VALUE *r, type *t, VALUE y)
Call a method with a block.
VALUE type(ANYARGS)
ANYARGS-ed function type.
#define RARRAY_LEN
Just another name of rb_array_len.
#define RARRAY_PTR_USE(ary, ptr_name, expr)
Declares a section of code where raw pointers are used.
#define RARRAY_AREF(a, i)
#define RBASIC(obj)
Convenient casting macro.
#define TypedData_Get_Struct(obj, type, data_type, sval)
Obtains a C struct from inside of a wrapper Ruby object.
struct rb_data_type_struct rb_data_type_t
This is the struct that holds necessary info for a struct.
#define TypedData_Make_Struct(klass, type, data_type, sval)
Identical to TypedData_Wrap_Struct, except it allocates a new data region internally instead of takin...
VALUE rb_require(const char *feature)
Identical to rb_require_string(), except it takes C's string instead of Ruby's.
size_t rb_set_size(VALUE set)
Returns the number of elements in the set.
VALUE rb_set_clear(VALUE set)
Removes all entries from set.
bool rb_set_delete(VALUE set, VALUE element)
Removes the element from from set.
bool rb_set_add(VALUE set, VALUE element)
Adds element to set.
void rb_set_foreach(VALUE set, int(*func)(VALUE element, VALUE arg), VALUE arg)
Iterates over a set.
bool rb_set_lookup(VALUE set, VALUE element)
Whether the set contains the given element.
VALUE rb_set_new(void)
Creates a new, empty set object.
VALUE rb_set_new_capa(size_t capa)
Identical to rb_set_new(), except it additionally specifies how many elements it is expected to conta...
#define RTEST
This is an old name of RB_TEST.
set_table_entry * entries
Array of size 2^entry_power.
uintptr_t ID
Type that represents a Ruby identifier such as a variable name.
uintptr_t VALUE
Type that represents a Ruby object.