summaryrefslogtreecommitdiff
path: root/spec/ruby/optional/capi/ext/hash_spec.c
blob: 69ef02d5da6e24b4f1cac47a9c07e871dc0ac861 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#include "ruby.h"
#include "rubyspec.h"

#ifdef __cplusplus
extern "C" {
#endif

VALUE hash_spec_rb_hash(VALUE self, VALUE hash) {
  return rb_hash(hash);
}

VALUE hash_spec_rb_Hash(VALUE self, VALUE val) {
  return rb_Hash(val);
}

VALUE hash_spec_rb_hash_dup(VALUE self, VALUE hash) {
  return rb_hash_dup(hash);
}

VALUE hash_spec_rb_hash_fetch(VALUE self, VALUE hash, VALUE key) {
  return rb_hash_fetch(hash, key);
}

VALUE hash_spec_rb_hash_freeze(VALUE self, VALUE hash) {
  return rb_hash_freeze(hash);
}

VALUE hash_spec_rb_hash_aref(VALUE self, VALUE hash, VALUE key) {
  return rb_hash_aref(hash, key);
}

VALUE hash_spec_rb_hash_aref_nil(VALUE self, VALUE hash, VALUE key) {
  VALUE ret = rb_hash_aref(hash, key);
  return NIL_P(ret) ? Qtrue : Qfalse;
}

VALUE hash_spec_rb_hash_aset(VALUE self, VALUE hash, VALUE key, VALUE val) {
  return rb_hash_aset(hash, key, val);
}

VALUE hash_spec_rb_hash_clear(VALUE self, VALUE hash) {
  return rb_hash_clear(hash);
}

VALUE hash_spec_rb_hash_delete(VALUE self, VALUE hash, VALUE key) {
  return rb_hash_delete(hash, key);
}

VALUE hash_spec_rb_hash_delete_if(VALUE self, VALUE hash) {
  return rb_hash_delete_if(hash);
}

static int foreach_i(VALUE key, VALUE val, VALUE other) {
  rb_hash_aset(other, key, val);
  return 0; /* ST_CONTINUE; */
}

static int foreach_stop_i(VALUE key, VALUE val, VALUE other) {
  rb_hash_aset(other, key, val);
  return 1; /* ST_STOP; */
}

static int foreach_delete_i(VALUE key, VALUE val, VALUE other) {
  rb_hash_aset(other, key, val);
  return 2; /* ST_DELETE; */
}

VALUE hash_spec_rb_hash_foreach(VALUE self, VALUE hsh) {
  VALUE other = rb_hash_new();
  rb_hash_foreach(hsh, foreach_i, other);
  return other;
}

VALUE hash_spec_rb_hash_foreach_stop(VALUE self, VALUE hsh) {
  VALUE other = rb_hash_new();
  rb_hash_foreach(hsh, foreach_stop_i, other);
  return other;
}

VALUE hash_spec_rb_hash_foreach_delete(VALUE self, VALUE hsh) {
  VALUE other = rb_hash_new();
  rb_hash_foreach(hsh, foreach_delete_i, other);
  return other;
}

VALUE hash_spec_rb_hash_lookup(VALUE self, VALUE hash, VALUE key) {
  return rb_hash_lookup(hash, key);
}

VALUE hash_spec_rb_hash_lookup_nil(VALUE self, VALUE hash, VALUE key) {
  VALUE ret = rb_hash_lookup(hash, key);
  return ret == Qnil ? Qtrue : Qfalse;
}

VALUE hash_spec_rb_hash_lookup2(VALUE self, VALUE hash, VALUE key, VALUE def) {
  return rb_hash_lookup2(hash, key, def);
}

VALUE hash_spec_rb_hash_lookup2_default_undef(VALUE self, VALUE hash, VALUE key) {
  VALUE ret = rb_hash_lookup2(hash, key, Qundef);
  return ret == Qundef ? Qtrue : Qfalse;
}

VALUE hash_spec_rb_hash_new(VALUE self) {
  return rb_hash_new();
}

#ifdef RUBY_VERSION_IS_3_2
VALUE hash_spec_rb_hash_new_capa(VALUE self, VALUE capacity) {
  return rb_hash_new_capa(NUM2LONG(capacity));
}
#endif

VALUE rb_ident_hash_new(void); /* internal.h, used in ripper */

VALUE hash_spec_rb_ident_hash_new(VALUE self) {
  return rb_ident_hash_new();
}

VALUE hash_spec_rb_hash_size(VALUE self, VALUE hash) {
  return rb_hash_size(hash);
}

VALUE hash_spec_rb_hash_set_ifnone(VALUE self, VALUE hash, VALUE def) {
  return rb_hash_set_ifnone(hash, def);
}

VALUE hash_spec_compute_a_hash_code(VALUE self, VALUE seed) {
  int int_seed = FIX2INT(seed);
  st_index_t h = rb_hash_start(int_seed);
  h = rb_hash_uint32(h, 540u);
  h = rb_hash_uint32(h, 340u);
  h = rb_hash_end(h);
  return ULONG2NUM(h);
}

void Init_hash_spec(void) {
  VALUE cls = rb_define_class("CApiHashSpecs", rb_cObject);
  rb_define_method(cls, "rb_hash", hash_spec_rb_hash, 1);
  rb_define_method(cls, "rb_Hash", hash_spec_rb_Hash, 1);
  rb_define_method(cls, "rb_hash_dup", hash_spec_rb_hash_dup, 1);
  rb_define_method(cls, "rb_hash_freeze", hash_spec_rb_hash_freeze, 1);
  rb_define_method(cls, "rb_hash_aref", hash_spec_rb_hash_aref, 2);
  rb_define_method(cls, "rb_hash_aref_nil", hash_spec_rb_hash_aref_nil, 2);
  rb_define_method(cls, "rb_hash_aset", hash_spec_rb_hash_aset, 3);
  rb_define_method(cls, "rb_hash_clear", hash_spec_rb_hash_clear, 1);
  rb_define_method(cls, "rb_hash_delete", hash_spec_rb_hash_delete, 2);
  rb_define_method(cls, "rb_hash_delete_if", hash_spec_rb_hash_delete_if, 1);
  rb_define_method(cls, "rb_hash_fetch", hash_spec_rb_hash_fetch, 2);
  rb_define_method(cls, "rb_hash_foreach", hash_spec_rb_hash_foreach, 1);
  rb_define_method(cls, "rb_hash_foreach_stop", hash_spec_rb_hash_foreach_stop, 1);
  rb_define_method(cls, "rb_hash_foreach_delete", hash_spec_rb_hash_foreach_delete, 1);
  rb_define_method(cls, "rb_hash_lookup_nil", hash_spec_rb_hash_lookup_nil, 2);
  rb_define_method(cls, "rb_hash_lookup", hash_spec_rb_hash_lookup, 2);
  rb_define_method(cls, "rb_hash_lookup2", hash_spec_rb_hash_lookup2, 3);
  rb_define_method(cls, "rb_hash_lookup2_default_undef", hash_spec_rb_hash_lookup2_default_undef, 2);
  rb_define_method(cls, "rb_hash_new", hash_spec_rb_hash_new, 0);
#ifdef RUBY_VERSION_IS_3_2
  rb_define_method(cls, "rb_hash_new_capa", hash_spec_rb_hash_new_capa, 1);
#endif
  rb_define_method(cls, "rb_ident_hash_new", hash_spec_rb_ident_hash_new, 0);
  rb_define_method(cls, "rb_hash_size", hash_spec_rb_hash_size, 1);
  rb_define_method(cls, "rb_hash_set_ifnone", hash_spec_rb_hash_set_ifnone, 2);
  rb_define_method(cls, "compute_a_hash_code", hash_spec_compute_a_hash_code, 1);
}

#ifdef __cplusplus
}
#endif