14#include "debug_counter.h"
17#include "internal/array.h"
18#include "internal/compar.h"
19#include "internal/enum.h"
20#include "internal/gc.h"
21#include "internal/hash.h"
22#include "internal/numeric.h"
23#include "internal/object.h"
24#include "internal/proc.h"
25#include "internal/rational.h"
26#include "internal/vm.h"
37#include "ruby_assert.h"
68#define ARY_DEFAULT_SIZE 16
69#define ARY_MAX_SIZE (LONG_MAX / (int)sizeof(VALUE))
70#define SMALL_ARRAY_LEN 16
74should_be_T_ARRAY(
VALUE ary)
79#define ARY_HEAP_PTR(a) (assert(!ARY_EMBED_P(a)), RARRAY(a)->as.heap.ptr)
80#define ARY_HEAP_LEN(a) (assert(!ARY_EMBED_P(a)), RARRAY(a)->as.heap.len)
81#define ARY_HEAP_CAPA(a) (assert(!ARY_EMBED_P(a)), assert(!ARY_SHARED_ROOT_P(a)), \
82 RARRAY(a)->as.heap.aux.capa)
84#define ARY_EMBED_PTR(a) (assert(ARY_EMBED_P(a)), RARRAY(a)->as.ary)
85#define ARY_EMBED_LEN(a) \
86 (assert(ARY_EMBED_P(a)), \
87 (long)((RBASIC(a)->flags >> RARRAY_EMBED_LEN_SHIFT) & \
88 (RARRAY_EMBED_LEN_MASK >> RARRAY_EMBED_LEN_SHIFT)))
89#define ARY_HEAP_SIZE(a) (assert(!ARY_EMBED_P(a)), assert(ARY_OWNS_HEAP_P(a)), ARY_CAPA(a) * sizeof(VALUE))
91#define ARY_OWNS_HEAP_P(a) (assert(should_be_T_ARRAY((VALUE)(a))), \
92 !FL_TEST_RAW((a), RARRAY_SHARED_FLAG|RARRAY_EMBED_FLAG))
94#define FL_SET_EMBED(a) do { \
95 assert(!ARY_SHARED_P(a)); \
96 FL_SET((a), RARRAY_EMBED_FLAG); \
100#define FL_UNSET_EMBED(ary) FL_UNSET((ary), RARRAY_EMBED_FLAG|RARRAY_EMBED_LEN_MASK)
101#define FL_SET_SHARED(ary) do { \
102 assert(!ARY_EMBED_P(ary)); \
103 FL_SET((ary), RARRAY_SHARED_FLAG); \
105#define FL_UNSET_SHARED(ary) FL_UNSET((ary), RARRAY_SHARED_FLAG)
107#define ARY_SET_PTR(ary, p) do { \
108 assert(!ARY_EMBED_P(ary)); \
109 assert(!OBJ_FROZEN(ary)); \
110 RARRAY(ary)->as.heap.ptr = (p); \
112#define ARY_SET_EMBED_LEN(ary, n) do { \
114 assert(ARY_EMBED_P(ary)); \
115 RBASIC(ary)->flags &= ~RARRAY_EMBED_LEN_MASK; \
116 RBASIC(ary)->flags |= (tmp_n) << RARRAY_EMBED_LEN_SHIFT; \
118#define ARY_SET_HEAP_LEN(ary, n) do { \
119 assert(!ARY_EMBED_P(ary)); \
120 RARRAY(ary)->as.heap.len = (n); \
122#define ARY_SET_LEN(ary, n) do { \
123 if (ARY_EMBED_P(ary)) { \
124 ARY_SET_EMBED_LEN((ary), (n)); \
127 ARY_SET_HEAP_LEN((ary), (n)); \
129 assert(RARRAY_LEN(ary) == (n)); \
131#define ARY_INCREASE_PTR(ary, n) do { \
132 assert(!ARY_EMBED_P(ary)); \
133 assert(!OBJ_FROZEN(ary)); \
134 RARRAY(ary)->as.heap.ptr += (n); \
136#define ARY_INCREASE_LEN(ary, n) do { \
137 assert(!OBJ_FROZEN(ary)); \
138 if (ARY_EMBED_P(ary)) { \
139 ARY_SET_EMBED_LEN((ary), RARRAY_LEN(ary)+(n)); \
142 RARRAY(ary)->as.heap.len += (n); \
146#define ARY_CAPA(ary) (ARY_EMBED_P(ary) ? ary_embed_capa(ary) : \
147 ARY_SHARED_ROOT_P(ary) ? RARRAY_LEN(ary) : ARY_HEAP_CAPA(ary))
148#define ARY_SET_CAPA(ary, n) do { \
149 assert(!ARY_EMBED_P(ary)); \
150 assert(!ARY_SHARED_P(ary)); \
151 assert(!OBJ_FROZEN(ary)); \
152 RARRAY(ary)->as.heap.aux.capa = (n); \
155#define ARY_SHARED_ROOT_OCCUPIED(ary) (!OBJ_FROZEN(ary) && ARY_SHARED_ROOT_REFCNT(ary) == 1)
156#define ARY_SET_SHARED_ROOT_REFCNT(ary, value) do { \
157 assert(ARY_SHARED_ROOT_P(ary)); \
158 assert(!OBJ_FROZEN(ary)); \
159 assert((value) >= 0); \
160 RARRAY(ary)->as.heap.aux.capa = (value); \
162#define FL_SET_SHARED_ROOT(ary) do { \
163 assert(!OBJ_FROZEN(ary)); \
164 assert(!ARY_EMBED_P(ary)); \
165 FL_SET((ary), RARRAY_SHARED_ROOT_FLAG); \
171 assert(!ARY_SHARED_P(a));
179ary_embed_capa(
VALUE ary)
181 size_t size = rb_gc_obj_slot_size(ary) - offsetof(
struct RArray, as.
ary);
182 assert(size %
sizeof(
VALUE) == 0);
183 return size /
sizeof(
VALUE);
187ary_embed_size(
long capa)
193ary_embeddable_p(
long capa)
195 return rb_gc_size_allocatable_p(ary_embed_size(
capa));
199rb_ary_embeddable_p(
VALUE ary)
209 return !(ARY_SHARED_ROOT_P(ary) ||
OBJ_FROZEN(ary) || ARY_SHARED_P(ary));
213rb_ary_size_as_embedded(
VALUE ary)
217 if (ARY_EMBED_P(ary)) {
218 real_size = ary_embed_size(ARY_EMBED_LEN(ary));
220 else if (rb_ary_embeddable_p(ary)) {
221 real_size = ary_embed_size(ARY_HEAP_CAPA(ary));
224 real_size =
sizeof(
struct RArray);
231#define ary_verify(ary) ary_verify_(ary, __FILE__, __LINE__)
234ary_verify_(
VALUE ary,
const char *file,
int line)
238 if (ARY_SHARED_P(
ary)) {
240 const VALUE *ptr = ARY_HEAP_PTR(
ary);
243 assert(ARY_SHARED_ROOT_P(root) ||
OBJ_FROZEN(root));
244 assert(root_ptr <= ptr && ptr +
len <= root_ptr + root_len);
247 else if (ARY_EMBED_P(
ary)) {
248 assert(!ARY_SHARED_P(
ary));
256 for (i=0; i<
len; i++) {
271#define ary_verify(ary) ((void)0)
300ary_mem_clear(
VALUE ary,
long beg,
long size)
303 rb_mem_clear(ptr + beg, size);
308memfill(
register VALUE *mem,
register long size,
register VALUE val)
319 memfill(ptr + beg, size, val);
327 assert(!ARY_SHARED_P(buff_owner_ary));
329 if (argc > (
int)(128/
sizeof(
VALUE)) ) {
330 rb_gc_writebarrier_remember(buff_owner_ary);
338 for (i=0; i<argc; i++) {
348 ary_memcpy0(
ary, beg, argc, argv,
ary);
352ary_heap_alloc(
size_t capa)
360 ruby_sized_xfree((
void *)ptr, size);
366 ary_heap_free_ptr(
ary, ARY_HEAP_PTR(
ary), ARY_HEAP_SIZE(
ary));
370ary_heap_realloc(
VALUE ary,
size_t new_capa)
381 assert(rb_ary_embeddable_p(
ary));
382 if (!ARY_EMBED_P(
ary)) {
383 const VALUE *buf = ARY_HEAP_PTR(
ary);
384 long len = ARY_HEAP_LEN(
ary);
387 ARY_SET_EMBED_LEN(
ary,
len);
396ary_resize_capa(
VALUE ary,
long capacity)
400 assert(!ARY_SHARED_P(
ary));
402 if (capacity > ary_embed_capa(
ary)) {
403 size_t new_capa = capacity;
404 if (ARY_EMBED_P(
ary)) {
405 long len = ARY_EMBED_LEN(
ary);
406 VALUE *ptr = ary_heap_alloc(capacity);
410 ARY_SET_PTR(
ary, ptr);
411 ARY_SET_HEAP_LEN(
ary,
len);
414 new_capa = ary_heap_realloc(
ary, capacity);
416 ARY_SET_CAPA(
ary, new_capa);
419 if (!ARY_EMBED_P(
ary)) {
420 long len = ARY_HEAP_LEN(
ary);
421 long old_capa = ARY_HEAP_CAPA(
ary);
422 const VALUE *ptr = ARY_HEAP_PTR(
ary);
424 if (
len > capacity)
len = capacity;
426 ary_heap_free_ptr(
ary, ptr, old_capa);
439 long capacity = ARY_HEAP_LEN(
ary);
440 long old_capa = ARY_HEAP_CAPA(
ary);
441 assert(!ARY_SHARED_P(
ary));
442 assert(old_capa >= capacity);
443 if (old_capa > capacity) ary_heap_realloc(
ary, capacity);
451 long new_capa = ARY_CAPA(
ary) / 2;
453 if (new_capa < ARY_DEFAULT_SIZE) {
454 new_capa = ARY_DEFAULT_SIZE;
456 if (new_capa >= ARY_MAX_SIZE - min) {
457 new_capa = (ARY_MAX_SIZE - min) / 2;
460 ary_resize_capa(
ary, new_capa);
479 FL_UNSET_SHARED(
ary);
485 if (ARY_OWNS_HEAP_P(
ary)) {
488 else if (ARY_SHARED_P(
ary)) {
493 ARY_SET_EMBED_LEN(
ary, 0);
510 assert(!ARY_EMBED_P(
ary));
518 RB_DEBUG_COUNTER_INC(obj_ary_shared_create);
531 if (ARY_SHARED_P(
ary)) {
537 if (
len <= ary_embed_capa(
ary)) {
538 const VALUE *ptr = ARY_HEAP_PTR(
ary);
539 FL_UNSET_SHARED(
ary);
543 ARY_SET_EMBED_LEN(
ary,
len);
547 FL_UNSET_SHARED(
ary);
549 ARY_SET_CAPA(
ary, shared_len);
561 ARY_SET_PTR(
ary, ptr);
564 rb_gc_writebarrier_remember(
ary);
572 rb_ary_modify_check(
ary);
573 rb_ary_cancel_sharing(
ary);
577ary_ensure_room_for_push(
VALUE ary,
long add_len)
580 long new_len = old_len + add_len;
583 if (old_len > ARY_MAX_SIZE - add_len) {
586 if (ARY_SHARED_P(
ary)) {
587 if (new_len > ary_embed_capa(
ary)) {
591 rb_ary_modify_check(
ary);
602 ary_double_capa(
ary, new_len);
613 rb_ary_modify_check(
ary);
616 if (new_len >
capa) {
617 ary_double_capa(
ary, new_len);
641 return rb_obj_freeze(
ary);
654 if (!ARY_EMBED_P(ary1) && ARY_SHARED_P(ary1) &&
655 !ARY_EMBED_P(ary2) && ARY_SHARED_P(ary2) &&
656 ARY_SHARED_ROOT(ary1) == ARY_SHARED_ROOT(ary2) &&
657 ARY_HEAP_LEN(ary1) == ARY_HEAP_LEN(ary2)) {
666 size_t size = ary_embed_size(
capa);
667 assert(rb_gc_size_allocatable_p(size));
679ary_alloc_heap(
VALUE klass)
683 sizeof(
struct RArray), 0);
688empty_ary_alloc(
VALUE klass)
690 RUBY_DTRACE_CREATE_HOOK(ARRAY, 0);
691 return ary_alloc_embed(klass, 0);
700 rb_raise(rb_eArgError,
"negative array size (or size too big)");
702 if (
capa > ARY_MAX_SIZE) {
703 rb_raise(rb_eArgError,
"array size too big");
706 RUBY_DTRACE_CREATE_HOOK(ARRAY,
capa);
708 if (ary_embeddable_p(
capa)) {
709 ary = ary_alloc_embed(klass,
capa);
712 ary = ary_alloc_heap(klass);
714 assert(!ARY_EMBED_P(
ary));
716 ARY_SET_PTR(
ary, ary_heap_alloc(
capa));
717 ARY_SET_HEAP_LEN(
ary, 0);
732 return rb_ary_new_capa(0);
736(rb_ary_new_from_args)(
long n, ...)
745 for (i=0; i<n; i++) {
755rb_ary_tmp_new_from_values(
VALUE klass,
long n,
const VALUE *elts)
759 ary = ary_new(klass, n);
761 ary_memcpy(
ary, 0, n, elts);
769rb_ary_new_from_values(
long n,
const VALUE *elts)
771 return rb_ary_tmp_new_from_values(
rb_cArray, n, elts);
775ec_ary_alloc_embed(rb_execution_context_t *ec,
VALUE klass,
long capa)
777 size_t size = ary_embed_size(
capa);
778 assert(rb_gc_size_allocatable_p(size));
790ec_ary_alloc_heap(rb_execution_context_t *ec,
VALUE klass)
794 sizeof(
struct RArray), ec);
799ec_ary_new(rb_execution_context_t *ec,
VALUE klass,
long capa)
804 rb_raise(rb_eArgError,
"negative array size (or size too big)");
806 if (
capa > ARY_MAX_SIZE) {
807 rb_raise(rb_eArgError,
"array size too big");
810 RUBY_DTRACE_CREATE_HOOK(ARRAY,
capa);
812 if (ary_embeddable_p(
capa)) {
813 ary = ec_ary_alloc_embed(ec, klass,
capa);
816 ary = ec_ary_alloc_heap(ec, klass);
818 assert(!ARY_EMBED_P(
ary));
820 ARY_SET_PTR(
ary, ary_heap_alloc(
capa));
821 ARY_SET_HEAP_LEN(
ary, 0);
828rb_ec_ary_new_from_values(rb_execution_context_t *ec,
long n,
const VALUE *elts)
834 ary_memcpy(
ary, 0, n, elts);
849rb_ary_hidden_new_fill(
long capa)
860 if (ARY_OWNS_HEAP_P(
ary)) {
861 if (USE_DEBUG_COUNTER &&
862 !ARY_SHARED_ROOT_P(
ary) &&
864 RB_DEBUG_COUNTER_INC(obj_ary_extracapa);
867 RB_DEBUG_COUNTER_INC(obj_ary_ptr);
871 RB_DEBUG_COUNTER_INC(obj_ary_embed);
874 if (ARY_SHARED_P(
ary)) {
875 RB_DEBUG_COUNTER_INC(obj_ary_shared);
877 if (ARY_SHARED_ROOT_P(
ary) && ARY_SHARED_ROOT_OCCUPIED(
ary)) {
878 RB_DEBUG_COUNTER_INC(obj_ary_shared_root_occupied);
882RUBY_FUNC_EXPORTED
size_t
885 if (ARY_OWNS_HEAP_P(
ary)) {
886 return ARY_CAPA(
ary) *
sizeof(
VALUE);
898 if (ARY_SHARED_P(
ary)) {
899 return ARY_SHARED_ROOT(
ary);
901 else if (ARY_SHARED_ROOT_P(
ary)) {
905 if (!ARY_EMBED_P(
ary)) {
906 ary_shrink_capa(
ary);
916 VALUE shared = ary_alloc_heap(0);
917 FL_SET_SHARED_ROOT(shared);
919 if (ARY_EMBED_P(
ary)) {
921 ARY_SET_PTR(shared, ptr);
925 ARY_SET_HEAP_LEN(
ary,
len);
926 ARY_SET_PTR(
ary, ptr);
932 ARY_SET_LEN(shared,
capa);
934 rb_ary_set_shared(
ary, shared);
948 if (ary_embeddable_p(
len)) {
950 assert(ARY_EMBED_P(subst));
953 ARY_SET_EMBED_LEN(subst,
len);
957 return rb_ary_increment_share(ary_make_shared(
ary));
970 return rb_convert_type_with_id(
ary,
T_ARRAY,
"Array", idTo_ary);
972#define to_ary rb_to_array_type
977 return rb_check_convert_type_with_id(
ary,
T_ARRAY,
"Array", idTo_ary);
983 return rb_check_convert_type_with_id(
ary,
T_ARRAY,
"Array", idTo_a);
989 return rb_convert_type_with_id(
ary,
T_ARRAY,
"Array", idTo_a);
1009 return rb_check_array_type(
ary);
1014rb_ary_s_new(
int argc,
VALUE *argv,
VALUE klass)
1020 if (argc > 0 &&
FIXNUM_P(argv[0])) {
1022 if (size < 0) size = 0;
1025 ary = ary_new(klass, size);
1093 assert(ARY_EMBED_P(
ary));
1094 assert(ARY_EMBED_LEN(
ary) == 0);
1101 if (argc == 1 && !
FIXNUM_P(size)) {
1102 val = rb_check_array_type(size);
1104 rb_ary_replace(
ary, val);
1112 rb_raise(rb_eArgError,
"negative array size");
1114 if (
len > ARY_MAX_SIZE) {
1115 rb_raise(rb_eArgError,
"array size too big");
1119 ary_resize_capa(
ary,
len);
1124 rb_warn(
"block supersedes default value argument");
1126 for (i=0; i<
len; i++) {
1128 ARY_SET_LEN(
ary, i + 1);
1132 ary_memfill(
ary, 0,
len, val);
1147rb_ary_s_create(
int argc,
VALUE *argv,
VALUE klass)
1150 if (argc > 0 && argv) {
1151 ary_memcpy(
ary, 0, argc, argv);
1152 ARY_SET_LEN(
ary, argc);
1166 rb_raise(
rb_eIndexError,
"index %ld too small for array; minimum: %ld",
1170 else if (idx >= ARY_MAX_SIZE) {
1175 if (idx >= ARY_CAPA(
ary)) {
1176 ary_double_capa(
ary, idx);
1183 ARY_SET_LEN(
ary, idx + 1);
1185 ARY_SET(
ary, idx, val);
1191 assert(offset >= 0);
1195 VALUE result = ary_alloc_heap(klass);
1196 size_t embed_capa = ary_embed_capa(result);
1197 if ((
size_t)
len <= embed_capa) {
1198 FL_SET_EMBED(result);
1200 ARY_SET_EMBED_LEN(result,
len);
1203 VALUE shared = ary_make_shared(
ary);
1208 FL_UNSET_EMBED(result);
1212 rb_ary_set_shared(result, shared);
1214 ARY_INCREASE_PTR(result, offset);
1215 ARY_SET_LEN(result,
len);
1225ary_make_partial_step(
VALUE ary,
VALUE klass,
long offset,
long len,
long step)
1227 assert(offset >= 0);
1232 const long orig_len =
len;
1234 if (step > 0 && step >=
len) {
1235 VALUE result = ary_new(klass, 1);
1240 ARY_SET_EMBED_LEN(result, 1);
1243 else if (step < 0 && step < -
len) {
1247 long ustep = (step < 0) ? -step : step;
1248 len = roomof(
len, ustep);
1251 long j = offset + ((step > 0) ? 0 : (orig_len - 1));
1253 VALUE result = ary_new(klass,
len);
1254 if (ARY_EMBED_P(result)) {
1258 for (i = 0; i <
len; ++i) {
1262 ARY_SET_EMBED_LEN(result,
len);
1268 for (i = 0; i <
len; ++i) {
1273 ARY_SET_LEN(result,
len);
1285enum ary_take_pos_flags
1292ary_take_first_or_last_n(
VALUE ary,
long n,
enum ary_take_pos_flags last)
1301 rb_raise(rb_eArgError,
"negative array size");
1310ary_take_first_or_last(
int argc,
const VALUE *argv,
VALUE ary,
enum ary_take_pos_flags last)
1317 return ary_take_first_or_last_n(
ary,
NUM2LONG(argv[0]), last);
1341 VALUE target_ary = ary_ensure_room_for_push(
ary, 1);
1345 ARY_SET_LEN(
ary, idx + 1);
1354 VALUE target_ary = ary_ensure_room_for_push(
ary,
len);
1355 ary_memcpy0(
ary, oldlen,
len, argv, target_ary);
1356 ARY_SET_LEN(
ary, oldlen +
len);
1383 return rb_ary_cat(
ary, argv, argc);
1390 rb_ary_modify_check(
ary);
1392 if (n == 0)
return Qnil;
1393 if (ARY_OWNS_HEAP_P(
ary) &&
1394 n * 3 < ARY_CAPA(
ary) &&
1395 ARY_CAPA(
ary) > ARY_DEFAULT_SIZE)
1397 ary_resize_capa(
ary, n * 2);
1400 ARY_SET_LEN(
ary, n);
1442 return rb_ary_pop(
ary);
1445 rb_ary_modify_check(
ary);
1446 result = ary_take_first_or_last(argc, argv,
ary, ARY_TAKE_LAST);
1459 rb_ary_modify_check(
ary);
1465 rb_ary_behead(
ary, 1);
1510 return rb_ary_shift(
ary);
1513 rb_ary_modify_check(
ary);
1514 result = ary_take_first_or_last(argc, argv,
ary, ARY_TAKE_FIRST);
1516 rb_ary_behead(
ary,n);
1528 rb_ary_modify_check(
ary);
1530 if (!ARY_SHARED_P(
ary)) {
1535 ARY_INCREASE_LEN(
ary, -n);
1540 ary_mem_clear(
ary, 0, n);
1541 ary_make_shared(
ary);
1543 else if (ARY_SHARED_ROOT_OCCUPIED(ARY_SHARED_ROOT(
ary))) {
1544 ary_mem_clear(
ary, 0, n);
1547 ARY_INCREASE_PTR(
ary, n);
1548 ARY_INCREASE_LEN(
ary, -n);
1557 if (head - sharedp < argc) {
1558 long room =
capa -
len - argc;
1562 head = sharedp + argc + room;
1564 ARY_SET_PTR(
ary, head - argc);
1565 assert(ARY_SHARED_ROOT_OCCUPIED(ARY_SHARED_ROOT(
ary)));
1568 return ARY_SHARED_ROOT(
ary);
1572ary_modify_for_unshift(
VALUE ary,
int argc)
1575 long new_len =
len + argc;
1577 const VALUE *head, *sharedp;
1581 if (
capa - (
capa >> 6) <= new_len) {
1582 ary_double_capa(
ary, new_len);
1586 if (new_len > ARY_DEFAULT_SIZE * 4 && !ARY_EMBED_P(
ary)) {
1591 ary_make_shared(
ary);
1594 return make_room_for_unshift(
ary, head, (
void *)sharedp, argc,
capa,
len);
1608ary_ensure_room_for_unshift(
VALUE ary,
int argc)
1611 long new_len =
len + argc;
1613 if (
len > ARY_MAX_SIZE - argc) {
1616 else if (! ARY_SHARED_P(
ary)) {
1617 return ary_modify_for_unshift(
ary, argc);
1624 return ary_modify_for_unshift(
ary, argc);
1626 else if (new_len >
capa) {
1627 return ary_modify_for_unshift(
ary, argc);
1633 rb_ary_modify_check(
ary);
1634 return make_room_for_unshift(
ary, head, sharedp, argc,
capa,
len);
1658 rb_ary_modify_check(
ary);
1662 target_ary = ary_ensure_room_for_unshift(
ary, argc);
1663 ary_memcpy0(
ary, 0, argc, argv, target_ary);
1664 ARY_SET_LEN(
ary,
len + argc);
1671 return rb_ary_unshift_m(1, &item,
ary);
1680 if (offset < 0 ||
len <= offset) {
1689 return rb_ary_entry_internal(
ary, offset);
1693rb_ary_subseq_step(
VALUE ary,
long beg,
long len,
long step)
1698 if (beg > alen)
return Qnil;
1699 if (beg < 0 ||
len < 0)
return Qnil;
1701 if (alen <
len || alen < beg +
len) {
1705 if (
len == 0)
return ary_new(klass, 0);
1707 rb_raise(rb_eArgError,
"slice step cannot be zero");
1709 return ary_make_partial(
ary, klass, beg,
len);
1711 return ary_make_partial_step(
ary, klass, beg,
len, step);
1717 return rb_ary_subseq_step(
ary, beg,
len, 1);
1831 return rb_ary_aref2(
ary, argv[0], argv[1]);
1833 return rb_ary_aref1(
ary, argv[0]);
1844 return rb_ary_subseq(
ary, beg,
len);
1850 long beg,
len, step;
1857 switch (rb_arithmetic_sequence_beg_len_step(arg, &beg, &
len, &step,
RARRAY_LEN(
ary), 0)) {
1863 return rb_ary_subseq_step(
ary, beg,
len, step);
1895 return ary_take_first_or_last(argc, argv,
ary, ARY_TAKE_FIRST);
1901ary_first(
VALUE self)
1917 return ary_last(
ary);
1920 return ary_take_first_or_last(argc, argv,
ary, ARY_TAKE_LAST);
1970 if (block_given && argc == 2) {
1971 rb_warn(
"block supersedes default value argument");
1979 if (block_given)
return rb_yield(pos);
1981 rb_raise(
rb_eIndexError,
"index %ld outside of array bounds: %ld...%ld",
2043 rb_warn(
"given block not used");
2106 rb_warn(
"given block not used");
2122 VALUE tmp = rb_check_array_type(obj);
2124 if (!
NIL_P(tmp))
return tmp;
2139 rb_raise(
rb_eIndexError,
"index %ld too small for array; minimum: %ld",
2143 if (olen <
len || olen < beg +
len) {
2149 rofs = (rptr >= optr && rptr < optr + olen) ? rptr - optr : -1;
2154 if (beg > ARY_MAX_SIZE - rlen) {
2157 target_ary = ary_ensure_room_for_push(
ary, rlen-
len);
2159 ary_mem_clear(
ary, olen, beg - olen);
2162 ary_memcpy0(
ary, beg, rlen, rptr, target_ary);
2169 if (olen -
len > ARY_MAX_SIZE - rlen) {
2173 alen = olen + rlen -
len;
2174 if (alen >= ARY_CAPA(
ary)) {
2175 ary_double_capa(
ary, alen);
2182 ARY_SET_LEN(
ary, alen);
2186 rb_gc_writebarrier_remember(
ary);
2208 rb_ary_modify_check(
ary);
2209 if (ARY_SHARED_P(
ary)) {
2213 rb_bug(
"probable buffer overflow: %ld for %ld",
len,
capa);
2225 if (
len == olen)
return ary;
2226 if (
len > ARY_MAX_SIZE) {
2230 if (
len >= ARY_CAPA(
ary)) {
2231 ary_double_capa(
ary,
len);
2233 ary_mem_clear(
ary, olen,
len - olen);
2236 else if (ARY_EMBED_P(
ary)) {
2237 ARY_SET_EMBED_LEN(
ary,
len);
2239 else if (
len <= ary_embed_capa(
ary)) {
2240 const VALUE *ptr = ARY_HEAP_PTR(
ary);
2241 long ptr_capa = ARY_HEAP_SIZE(
ary);
2242 bool is_malloc_ptr = !ARY_SHARED_P(
ary);
2247 ARY_SET_EMBED_LEN(
ary,
len);
2249 if (is_malloc_ptr) ruby_sized_xfree((
void *)ptr, ptr_capa);
2252 if (olen >
len + ARY_DEFAULT_SIZE) {
2253 size_t new_capa = ary_heap_realloc(
ary,
len);
2254 ARY_SET_CAPA(
ary, new_capa);
2256 ARY_SET_HEAP_LEN(
ary,
len);
2265 rb_ary_store(
ary, key, val);
2272 VALUE rpl = rb_ary_to_ary(val);
2395 long offset, beg,
len;
2398 rb_ary_modify_check(
ary);
2402 return ary_aset_by_rb_ary_splice(
ary, beg,
len, argv[2]);
2406 return ary_aset_by_rb_ary_store(
ary, offset, argv[1]);
2410 return ary_aset_by_rb_ary_splice(
ary, beg,
len, argv[1]);
2414 return ary_aset_by_rb_ary_store(
ary, offset, argv[1]);
2459 rb_ary_modify_check(
ary);
2461 if (argc == 1)
return ary;
2468 rb_raise(
rb_eIndexError,
"index %ld too small for array; minimum: %ld",
2473 rb_ary_splice(
ary, pos, 0, argv + 1, argc - 1);
2483 return rb_ary_length(
ary);
2697 ARY_SET_LEN(dup,
len);
2710extern VALUE rb_output_fs;
2715recursive_join(
VALUE obj,
VALUE argp,
int recur)
2720 VALUE result = arg[2];
2721 int *first = (
int *)arg[3];
2724 rb_raise(rb_eArgError,
"recursive array join");
2727 ary_join_1(obj,
ary, sep, 0, result, first);
2739 for (i=0; i<max; i++) {
2741 if (!RB_TYPE_P(val,
T_STRING))
break;
2742 if (i > 0 && !
NIL_P(sep))
2743 rb_str_buf_append(result, sep);
2744 rb_str_buf_append(result, val);
2750ary_join_1_str(
VALUE dst,
VALUE src,
int *first)
2752 rb_str_buf_append(dst, src);
2754 rb_enc_copy(dst, src);
2763 rb_raise(rb_eArgError,
"recursive array join");
2772 args[3] = (
VALUE)first;
2783 if (i > 0 && !
NIL_P(sep))
2784 rb_str_buf_append(result, sep);
2788 ary_join_1_str(result, val, first);
2790 else if (RB_TYPE_P(val,
T_ARRAY)) {
2791 ary_join_1_ary(val,
ary, sep, result, val, first);
2794 ary_join_1_str(result, tmp, first);
2796 else if (!
NIL_P(tmp = rb_check_array_type(val))) {
2797 ary_join_1_ary(val,
ary, sep, result, tmp, first);
2800 ary_join_1_str(result, rb_obj_as_string(val), first);
2809 VALUE val, tmp, result;
2821 if (
NIL_P(tmp) || tmp != val) {
2825 result = rb_str_buf_new(
len + (n-i)*10);
2826 rb_enc_associate(result, rb_usascii_encoding());
2827 i = ary_join_0(
ary, sep, i, result);
2829 ary_join_1(
ary,
ary, sep, i, result, &first);
2833 len += RSTRING_LEN(tmp);
2837 rb_str_set_len(result, 0);
2884 return rb_ary_join(
ary, sep);
2898 else rb_enc_copy(str, s);
2899 rb_str_buf_append(str, s);
2927 return rb_ary_inspect(
ary);
2956 rb_ary_replace(dup,
ary);
2995 const VALUE e = rb_ary_elt(
ary, i);
2996 const VALUE elt = block_given ? rb_yield_force_blockarg(e) : e;
2997 const VALUE key_value_pair = rb_check_array_type(elt);
2998 if (
NIL_P(key_value_pair)) {
2999 rb_raise(
rb_eTypeError,
"wrong element type %"PRIsVALUE
" at %ld (expected array)",
3003 rb_raise(rb_eArgError,
"wrong array length at %ld (expected 2, was %ld)",
3044 ary_reverse(p1, p2);
3064 return rb_ary_reverse(
ary);
3088 do *p2-- = *p1++;
while (--
len > 0);
3095rotate_count(
long cnt,
long len)
3097 return (cnt < 0) ? (
len - (~cnt %
len) - 1) : (cnt %
len);
3101ary_rotate_ptr(
VALUE *ptr,
long len,
long cnt)
3105 memmove(ptr, ptr + 1,
sizeof(
VALUE)*(
len - 1));
3106 *(ptr +
len - 1) = tmp;
3108 else if (cnt ==
len - 1) {
3110 memmove(ptr + 1, ptr,
sizeof(
VALUE)*(
len - 1));
3115 if (cnt <
len) ary_reverse(ptr + cnt, ptr +
len);
3116 if (--cnt > 0) ary_reverse(ptr, ptr + cnt);
3117 if (
len > 0) ary_reverse(ptr, ptr +
len);
3128 if (
len > 1 && (cnt = rotate_count(cnt,
len)) > 0) {
3186 rb_ary_rotate(
ary, n);
3250 cnt = rotate_count(cnt,
len);
3253 ary_memcpy(rotated, 0,
len, ptr + cnt);
3254 ary_memcpy(rotated,
len, cnt, ptr);
3266sort_reentered(
VALUE ary)
3268 if (
RBASIC(ary)->klass) {
3280 sort_reentered(data->ary);
3284sort_1(
const void *ap,
const void *bp,
void *dummy)
3287 VALUE retval = sort_reentered(data->ary);
3295 n = rb_cmpint(retval, a, b);
3296 sort_returned(data);
3301sort_2(
const void *ap,
const void *bp,
void *dummy)
3304 VALUE retval = sort_reentered(data->ary);
3309 if ((
long)a > (
long)b)
return 1;
3310 if ((
long)a < (
long)b)
return -1;
3313 if (STRING_P(a) && STRING_P(b) && CMP_OPTIMIZABLE(STRING)) {
3317 return rb_float_cmp(a, b);
3320 retval = rb_funcallv(a, id_cmp, 1, &b);
3321 n = rb_cmpint(retval, a, b);
3322 sort_returned(data);
3372 assert(!ARY_SHARED_P(ary));
3374 VALUE tmp = ary_make_substitution(ary);
3377 RBASIC_CLEAR_CLASS(tmp);
3379 data.receiver = ary;
3385 if (ARY_EMBED_P(tmp)) {
3386 if (ARY_SHARED_P(ary)) {
3387 rb_ary_unshare(ary);
3390 if (ARY_EMBED_LEN(tmp) > ARY_CAPA(ary)) {
3391 ary_resize_capa(ary, ARY_EMBED_LEN(tmp));
3393 ary_memcpy(ary, 0, ARY_EMBED_LEN(tmp), ARY_EMBED_PTR(tmp));
3394 ARY_SET_LEN(ary, ARY_EMBED_LEN(tmp));
3397 if (!ARY_EMBED_P(ary) && ARY_HEAP_PTR(ary) == ARY_HEAP_PTR(tmp)) {
3398 FL_UNSET_SHARED(ary);
3402 assert(!ARY_SHARED_P(tmp));
3403 if (ARY_EMBED_P(ary)) {
3404 FL_UNSET_EMBED(ary);
3406 else if (ARY_SHARED_P(ary)) {
3408 rb_ary_unshare(ary);
3413 ARY_SET_PTR(ary, ARY_HEAP_PTR(tmp));
3414 ARY_SET_HEAP_LEN(ary,
len);
3415 ARY_SET_CAPA(ary, ARY_HEAP_LEN(tmp));
3420 ARY_SET_EMBED_LEN(tmp, 0);
3475 ary = rb_ary_dup(ary);
3476 rb_ary_sort_bang(ary);
3493rb_ary_bsearch(
VALUE ary)
3495 VALUE index_result = rb_ary_bsearch_index(ary);
3498 return rb_ary_entry(ary,
FIX2LONG(index_result));
3500 return index_result;
3513rb_ary_bsearch_index(
VALUE ary)
3516 int smaller = 0, satisfied = 0;
3520 while (low < high) {
3521 mid = low + ((high - low) / 2);
3522 val = rb_ary_entry(ary, mid);
3528 else if (v ==
Qtrue) {
3532 else if (!
RTEST(v)) {
3537 switch (rb_cmpint(rb_funcallv(v, id_cmp, 1, &zero), v, zero)) {
3539 case 1: smaller = 0;
break;
3540 case -1: smaller = 1;
3545 " (must be numeric, true, false or nil)",
3555 if (!satisfied)
return Qnil;
3593rb_ary_sort_by_bang(
VALUE ary)
3599 sorted =
rb_block_call(ary, rb_intern(
"sort_by"), 0, 0, sort_by_i, 0);
3600 rb_ary_replace(ary, sorted);
3625rb_ary_collect(
VALUE ary)
3659rb_ary_collect_bang(
VALUE ary)
3675 long beg,
len, i, j;
3677 for (i=0; i<argc; i++) {
3679 rb_ary_push(result, (*func)(obj,
FIX2LONG(argv[i])));
3684 long end = olen < beg+
len ? olen : beg+
len;
3685 for (j = beg; j < end; j++) {
3686 rb_ary_push(result, (*func)(obj, j));
3689 rb_ary_resize(result,
RARRAY_LEN(result) + (beg +
len) - j);
3692 rb_ary_push(result, (*func)(obj,
NUM2LONG(argv[i])));
3708 const long end = beg +
len;
3711 rb_ary_cat(result, src + beg, end > olen ? olen-beg :
len);
3714 rb_ary_store(result, prevlen +
len - 1,
Qnil);
3722 return rb_ary_push(result, rb_ary_entry(ary, beg));
3769rb_ary_values_at(
int argc,
VALUE *argv,
VALUE ary)
3772 VALUE result = rb_ary_new_capa(argc);
3773 for (i = 0; i < argc; ++i) {
3774 append_values_at_single(result, ary, olen, argv[i]);
3802rb_ary_select(
VALUE ary)
3811 rb_ary_push(result, rb_ary_elt(ary, i));
3823select_bang_i(
VALUE a)
3826 VALUE ary = arg->ary;
3829 for (i1 = i2 = 0; i1 <
RARRAY_LEN(ary); arg->len[0] = ++i1) {
3833 rb_ary_store(ary, i2, v);
3837 return (i1 == i2) ?
Qnil : ary;
3841select_bang_ensure(
VALUE a)
3844 VALUE ary = arg->ary;
3846 long i1 = arg->len[0], i2 = arg->len[1];
3848 if (i2 <
len && i2 < i1) {
3857 ARY_SET_LEN(ary, i2 + tail);
3885rb_ary_select_bang(
VALUE ary)
3893 args.len[0] = args.len[1] = 0;
3916rb_ary_keep_if(
VALUE ary)
3919 rb_ary_select_bang(ary);
3924ary_resize_smaller(
VALUE ary,
long len)
3928 ARY_SET_LEN(ary,
len);
3929 if (
len * 2 < ARY_CAPA(ary) &&
3930 ARY_CAPA(ary) > ARY_DEFAULT_SIZE) {
3931 ary_resize_capa(ary,
len * 2);
3978 for (i1 = i2 = 0; i1 <
RARRAY_LEN(ary); i1++) {
3986 rb_ary_store(ary, i2, e);
3997 ary_resize_smaller(ary, i2);
4008 for (i1 = i2 = 0; i1 <
RARRAY_LEN(ary); i1++) {
4015 rb_ary_store(ary, i2, e);
4023 ary_resize_smaller(ary, i2);
4035 if (pos < 0)
return Qnil;
4043 ARY_INCREASE_LEN(ary, -1);
4074 return rb_ary_delete_at(ary,
NUM2LONG(pos));
4078ary_slice_bang_by_rb_ary_splice(
VALUE ary,
long pos,
long len)
4085 else if (pos < -orig_len) {
4091 else if (orig_len < pos) {
4094 if (orig_len < pos +
len) {
4095 len = orig_len - pos;
4102 rb_ary_splice(ary, pos,
len, 0, 0);
4177rb_ary_slice_bang(
int argc,
VALUE *argv,
VALUE ary)
4182 rb_ary_modify_check(ary);
4189 return ary_slice_bang_by_rb_ary_splice(ary, pos,
len);
4196 return ary_slice_bang_by_rb_ary_splice(ary, pos,
len);
4206 return rb_ary_delete_at(ary,
NUM2LONG(arg1));
4218 rb_ary_push(result, v);
4225reject_bang_i(
VALUE a)
4228 VALUE ary = arg->ary;
4231 for (i1 = i2 = 0; i1 <
RARRAY_LEN(ary); arg->len[0] = ++i1) {
4235 rb_ary_store(ary, i2, v);
4239 return (i1 == i2) ?
Qnil : ary;
4243ary_reject_bang(
VALUE ary)
4246 rb_ary_modify_check(ary);
4248 args.len[0] = args.len[1] = 0;
4274rb_ary_reject_bang(
VALUE ary)
4278 return ary_reject_bang(ary);
4301rb_ary_reject(
VALUE ary)
4306 rejected_ary = rb_ary_new();
4307 ary_reject(ary, rejected_ary);
4308 return rejected_ary;
4330rb_ary_delete_if(
VALUE ary)
4334 ary_reject_bang(ary);
4343 rb_ary_push(args[0], val);
4349take_items(
VALUE obj,
long n)
4351 VALUE result = rb_check_array_type(obj);
4354 if (n == 0)
return result;
4355 if (!
NIL_P(result))
return rb_ary_subseq(result, 0, n);
4357 args[0] = result; args[1] = (
VALUE)n;
4358 if (UNDEF_P(rb_check_block_call(obj, idEach, 0, 0, take_i, (
VALUE)args)))
4359 rb_raise(
rb_eTypeError,
"wrong argument type %"PRIsVALUE
" (must respond to :each)",
4428 for (i=0; i<argc; i++) {
4429 argv[i] = take_items(argv[i],
len);
4433 int arity = rb_block_arity();
4442 for (j=0; j<argc; j++) {
4443 tmp[j+1] = rb_ary_elt(argv[j], i);
4455 for (j=0; j<argc; j++) {
4456 rb_ary_push(tmp, rb_ary_elt(argv[j], i));
4463 result = rb_ary_new_capa(
len);
4465 for (i=0; i<
len; i++) {
4466 VALUE tmp = rb_ary_new_capa(argc+1);
4469 for (j=0; j<argc; j++) {
4470 rb_ary_push(tmp, rb_ary_elt(argv[j], i));
4472 rb_ary_push(result, tmp);
4492rb_ary_transpose(
VALUE ary)
4494 long elen = -1, alen, i, j;
4495 VALUE tmp, result = 0;
4498 if (alen == 0)
return rb_ary_dup(ary);
4499 for (i=0; i<alen; i++) {
4500 tmp = to_ary(rb_ary_elt(ary, i));
4504 for (j=0; j<elen; j++) {
4509 rb_raise(
rb_eIndexError,
"element size differs (%ld should be %ld)",
4512 for (j=0; j<elen; j++) {
4513 rb_ary_store(rb_ary_elt(result, j), i, rb_ary_elt(tmp, j));
4533 rb_ary_modify_check(copy);
4534 orig = to_ary(orig);
4535 if (copy == orig)
return copy;
4540 if (
RARRAY_LEN(orig) <= ary_embed_capa(copy)) {
4541 assert(ARY_EMBED_P(copy));
4547 else if (ARY_EMBED_P(orig)) {
4548 long len = ARY_EMBED_LEN(orig);
4551 FL_UNSET_EMBED(copy);
4552 ARY_SET_PTR(copy, ptr);
4553 ARY_SET_LEN(copy,
len);
4554 ARY_SET_CAPA(copy,
len);
4563 VALUE shared_root = ary_make_shared(orig);
4564 FL_UNSET_EMBED(copy);
4565 ARY_SET_PTR(copy, ARY_HEAP_PTR(orig));
4566 ARY_SET_LEN(copy, ARY_HEAP_LEN(orig));
4567 rb_ary_set_shared(copy, shared_root);
4587 rb_ary_modify_check(ary);
4588 if (ARY_SHARED_P(ary)) {
4589 if (!ARY_EMBED_P(ary)) {
4590 rb_ary_unshare(ary);
4592 ARY_SET_EMBED_LEN(ary, 0);
4596 ARY_SET_LEN(ary, 0);
4597 if (ARY_DEFAULT_SIZE * 2 < ARY_CAPA(ary)) {
4598 ary_resize_capa(ary, ARY_DEFAULT_SIZE * 2);
4805 long beg = 0, end = 0,
len = 0;
4828 if (beg < 0) beg = 0;
4837 if (beg >= ARY_MAX_SIZE ||
len > ARY_MAX_SIZE - beg) {
4838 rb_raise(rb_eArgError,
"argument too big");
4842 if (end >= ARY_CAPA(ary)) {
4843 ary_resize_capa(ary, end);
4846 ARY_SET_LEN(ary, end);
4849 if (UNDEF_P(item)) {
4853 for (i=beg; i<end; i++) {
4860 ary_memfill(ary, beg,
len, item);
4882 long len, xlen, ylen;
4892 ARY_SET_LEN(z,
len);
4918rb_ary_concat_multi(
int argc,
VALUE *argv,
VALUE ary)
4920 rb_ary_modify_check(ary);
4923 rb_ary_concat(ary, argv[0]);
4925 else if (argc > 1) {
4927 VALUE args = rb_ary_hidden_new(argc);
4928 for (i = 0; i < argc; i++) {
4929 rb_ary_concat(args, argv[i]);
4931 ary_append(ary, args);
4941 return ary_append(x, to_ary(y));
4971 return rb_ary_join(ary, tmp);
4980 rb_raise(rb_eArgError,
"negative argument");
4983 rb_raise(rb_eArgError,
"argument too big");
4988 ARY_SET_LEN(ary2,
len);
4993 ary_memcpy(ary2, 0, t, ptr);
4994 while (t <=
len/2) {
5068recursive_equal(
VALUE ary1,
VALUE ary2,
int recur)
5071 const VALUE *p1, *p2;
5073 if (recur)
return Qtrue;
5080 for (i = 0; i < len1; i++) {
5122 if (ary1 == ary2)
return Qtrue;
5123 if (!RB_TYPE_P(ary2,
T_ARRAY)) {
5135recursive_eql(
VALUE ary1,
VALUE ary2,
int recur)
5139 if (recur)
return Qtrue;
5141 if (!
rb_eql(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
5167 if (ary1 == ary2)
return Qtrue;
5175rb_ary_hash_values(
long len,
const VALUE *elements)
5183 for (i=0; i<
len; i++) {
5184 n = rb_hash(elements[i]);
5205rb_ary_hash(
VALUE ary)
5252recursive_cmp(
VALUE ary1,
VALUE ary2,
int recur)
5256 if (recur)
return Qundef;
5261 for (i=0; i<
len; i++) {
5262 VALUE e1 = rb_ary_elt(ary1, i), e2 = rb_ary_elt(ary2, i);
5263 VALUE v = rb_funcallv(e1, id_cmp, 1, &e2);
5308 ary2 = rb_check_array_type(ary2);
5310 if (ary1 == ary2)
return INT2FIX(0);
5312 if (!UNDEF_P(v))
return v;
5326 rb_hash_add_new_element(hash, elt, elt);
5332ary_tmp_hash_new(
VALUE ary)
5335 VALUE hash = rb_hash_new_with_size(size);
5337 RBASIC_CLEAR_CLASS(hash);
5342ary_make_hash(
VALUE ary)
5344 VALUE hash = ary_tmp_hash_new(ary);
5345 return ary_add_hash(hash, ary);
5355 rb_hash_add_new_element(hash, k, v);
5361ary_make_hash_by(
VALUE ary)
5363 VALUE hash = ary_tmp_hash_new(ary);
5364 return ary_add_hash_by(hash, ary);
5390 ary2 = to_ary(ary2);
5391 if (
RARRAY_LEN(ary2) == 0) {
return ary_make_shared_copy(ary1); }
5392 ary3 = rb_ary_new();
5396 VALUE elt = rb_ary_elt(ary1, i);
5397 if (rb_ary_includes_by_eql(ary2, elt))
continue;
5398 rb_ary_push(ary3, elt);
5403 hash = ary_make_hash(ary2);
5405 if (rb_hash_stlike_lookup(hash,
RARRAY_AREF(ary1, i), NULL))
continue;
5406 rb_ary_push(ary3, rb_ary_elt(ary1, i));
5430rb_ary_difference_multi(
int argc,
VALUE *argv,
VALUE ary)
5435 bool *is_hash =
ALLOCV_N(
bool, t0, argc);
5436 ary_diff = rb_ary_new();
5439 for (i = 0; i < argc; i++) {
5440 argv[i] = to_ary(argv[i]);
5441 is_hash[i] = (length > SMALL_ARRAY_LEN &&
RARRAY_LEN(argv[i]) > SMALL_ARRAY_LEN);
5442 if (is_hash[i]) argv[i] = ary_make_hash(argv[i]);
5447 VALUE elt = rb_ary_elt(ary, i);
5448 for (j = 0; j < argc; j++) {
5450 if (rb_hash_stlike_lookup(argv[j],
RARRAY_AREF(ary, i), NULL))
5454 if (rb_ary_includes_by_eql(argv[j], elt))
break;
5457 if (j == argc) rb_ary_push(ary_diff, elt);
5488 VALUE hash, ary3, v;
5492 ary2 = to_ary(ary2);
5493 ary3 = rb_ary_new();
5499 if (!rb_ary_includes_by_eql(ary2, v))
continue;
5500 if (rb_ary_includes_by_eql(ary3, v))
continue;
5501 rb_ary_push(ary3, v);
5506 hash = ary_make_hash(ary2);
5511 if (rb_hash_stlike_delete(hash, &vv, 0)) {
5512 rb_ary_push(ary3, v);
5541rb_ary_intersection_multi(
int argc,
VALUE *argv,
VALUE ary)
5543 VALUE result = rb_ary_dup(ary);
5546 for (i = 0; i < argc; i++) {
5547 result = rb_ary_and(result, argv[i]);
5554ary_hash_orset(st_data_t *key, st_data_t *value, st_data_t arg,
int existing)
5556 if (existing)
return ST_STOP;
5557 *key = *value = (
VALUE)arg;
5566 VALUE elt = rb_ary_elt(ary, i);
5567 if (rb_ary_includes_by_eql(ary_union, elt))
continue;
5568 rb_ary_push(ary_union, elt);
5578 if (!rb_hash_stlike_update(hash, (st_data_t)elt, ary_hash_orset, (st_data_t)elt)) {
5604 ary2 = to_ary(ary2);
5606 VALUE ary3 = rb_ary_new();
5607 rb_ary_union(ary3, ary1);
5608 rb_ary_union(ary3, ary2);
5612 hash = ary_make_hash(ary1);
5613 rb_ary_union_hash(hash, ary2);
5615 return rb_hash_values(hash);
5635rb_ary_union_multi(
int argc,
VALUE *argv,
VALUE ary)
5642 for (i = 0; i < argc; i++) {
5643 argv[i] = to_ary(argv[i]);
5647 if (sum <= SMALL_ARRAY_LEN) {
5648 VALUE ary_union = rb_ary_new();
5650 rb_ary_union(ary_union, ary);
5651 for (i = 0; i < argc; i++) rb_ary_union(ary_union, argv[i]);
5656 hash = ary_make_hash(ary);
5657 for (i = 0; i < argc; i++) rb_ary_union_hash(hash, argv[i]);
5659 return rb_hash_values(hash);
5682 VALUE hash, v, result, shorter, longer;
5686 ary2 = to_ary(ary2);
5692 if (rb_ary_includes_by_eql(ary2, v))
return Qtrue;
5704 hash = ary_make_hash(shorter);
5710 if (rb_hash_stlike_lookup(hash, vv, 0)) {
5720ary_max_generic(
VALUE ary,
long i,
VALUE vmax)
5728 if (rb_cmpint(rb_funcallv(vmax, id_cmp, 1, &v), vmax, v) < 0) {
5737ary_max_opt_fixnum(
VALUE ary,
long i,
VALUE vmax)
5744 for (; i < n; ++i) {
5748 if ((
long)vmax < (
long)v) {
5753 return ary_max_generic(ary, i, vmax);
5761ary_max_opt_float(
VALUE ary,
long i,
VALUE vmax)
5768 for (; i < n; ++i) {
5772 if (rb_float_cmp(vmax, v) < 0) {
5777 return ary_max_generic(ary, i, vmax);
5785ary_max_opt_string(
VALUE ary,
long i,
VALUE vmax)
5792 for (; i < n; ++i) {
5801 return ary_max_generic(ary, i, vmax);
5855 return rb_nmin_run(ary, num, 0, 1, 1);
5861 if (UNDEF_P(result) || rb_cmpint(
rb_yield_values(2, v, result), v, result) > 0) {
5869 if (
FIXNUM_P(result) && CMP_OPTIMIZABLE(INTEGER)) {
5870 return ary_max_opt_fixnum(ary, 1, result);
5872 else if (STRING_P(result) && CMP_OPTIMIZABLE(STRING)) {
5873 return ary_max_opt_string(ary, 1, result);
5876 return ary_max_opt_float(ary, 1, result);
5879 return ary_max_generic(ary, 1, result);
5883 if (UNDEF_P(result))
return Qnil;
5888ary_min_generic(
VALUE ary,
long i,
VALUE vmin)
5896 if (rb_cmpint(rb_funcallv(vmin, id_cmp, 1, &v), vmin, v) > 0) {
5905ary_min_opt_fixnum(
VALUE ary,
long i,
VALUE vmin)
5912 for (; i < n; ++i) {
5916 if ((
long)vmin > (
long)a) {
5921 return ary_min_generic(ary, i, vmin);
5929ary_min_opt_float(
VALUE ary,
long i,
VALUE vmin)
5936 for (; i < n; ++i) {
5940 if (rb_float_cmp(vmin, a) > 0) {
5945 return ary_min_generic(ary, i, vmin);
5953ary_min_opt_string(
VALUE ary,
long i,
VALUE vmin)
5960 for (; i < n; ++i) {
5969 return ary_min_generic(ary, i, vmin);
6023 return rb_nmin_run(ary, num, 0, 0, 1);
6029 if (UNDEF_P(result) || rb_cmpint(
rb_yield_values(2, v, result), v, result) < 0) {
6037 if (
FIXNUM_P(result) && CMP_OPTIMIZABLE(INTEGER)) {
6038 return ary_min_opt_fixnum(ary, 1, result);
6040 else if (STRING_P(result) && CMP_OPTIMIZABLE(STRING)) {
6041 return ary_min_opt_string(ary, 1, result);
6044 return ary_min_opt_float(ary, 1, result);
6047 return ary_min_generic(ary, 1, result);
6051 if (UNDEF_P(result))
return Qnil;
6079rb_ary_minmax(
VALUE ary)
6084 return rb_assoc_new(rb_ary_min(0, 0, ary), rb_ary_max(0, 0, ary));
6088push_value(st_data_t key, st_data_t val, st_data_t ary)
6124rb_ary_uniq_bang(
VALUE ary)
6129 rb_ary_modify_check(ary);
6133 hash = ary_make_hash_by(ary);
6135 hash = ary_make_hash(ary);
6141 rb_ary_modify_check(ary);
6142 ARY_SET_LEN(ary, 0);
6143 if (ARY_SHARED_P(ary) && !ARY_EMBED_P(ary)) {
6144 rb_ary_unshare(ary);
6147 ary_resize_capa(ary, hash_size);
6177rb_ary_uniq(
VALUE ary)
6183 uniq = rb_ary_dup(ary);
6186 hash = ary_make_hash_by(ary);
6187 uniq = rb_hash_values(hash);
6190 hash = ary_make_hash(ary);
6191 uniq = rb_hash_values(hash);
6207rb_ary_compact_bang(
VALUE ary)
6224 ary_resize_smaller(ary, n);
6240rb_ary_compact(
VALUE ary)
6242 ary = rb_ary_dup(ary);
6243 rb_ary_compact_bang(ary);
6275rb_ary_count(
int argc,
VALUE *argv,
VALUE ary)
6291 VALUE obj = argv[0];
6294 rb_warn(
"given block not used");
6305flatten(
VALUE ary,
int level)
6308 VALUE stack, result, tmp = 0, elt;
6313 tmp = rb_check_array_type(elt);
6324 ARY_SET_LEN(result, i);
6326 stack = ary_new(0, ARY_DEFAULT_SIZE);
6327 rb_ary_push(stack, ary);
6328 rb_ary_push(stack,
LONG2NUM(i + 1));
6331 memo = rb_obj_hide(rb_ident_hash_new());
6332 rb_hash_aset(memo, ary,
Qtrue);
6333 rb_hash_aset(memo, tmp,
Qtrue);
6342 if (level >= 0 &&
RARRAY_LEN(stack) / 2 >= level) {
6343 rb_ary_push(result, elt);
6346 tmp = rb_check_array_type(elt);
6347 if (
RBASIC(result)->klass) {
6349 rb_hash_clear(memo);
6354 rb_ary_push(result, elt);
6358 if (rb_hash_aref(memo, tmp) ==
Qtrue) {
6359 rb_hash_clear(memo);
6360 rb_raise(rb_eArgError,
"tried to flatten recursive array");
6362 rb_hash_aset(memo, tmp,
Qtrue);
6364 rb_ary_push(stack, ary);
6374 rb_hash_delete(memo, ary);
6376 tmp = rb_ary_pop(stack);
6378 ary = rb_ary_pop(stack);
6382 rb_hash_clear(memo);
6421rb_ary_flatten_bang(
int argc,
VALUE *argv,
VALUE ary)
6423 int mod = 0, level = -1;
6427 rb_ary_modify_check(ary);
6429 if (level == 0)
return Qnil;
6431 result = flatten(ary, level);
6432 if (result == ary) {
6435 if (!(mod = ARY_EMBED_P(result))) rb_obj_freeze(result);
6436 rb_ary_replace(ary, result);
6437 if (mod) ARY_SET_EMBED_LEN(result, 0);
6476rb_ary_flatten(
int argc,
VALUE *argv,
VALUE ary)
6483 if (level == 0)
return ary_make_shared_copy(ary);
6486 result = flatten(ary, level);
6487 if (result == ary) {
6488 result = ary_make_shared_copy(ary);
6494#define RAND_UPTO(max) (long)rb_random_ulong_limited((randgen), (max)-1)
6497rb_ary_shuffle_bang(rb_execution_context_t *ec,
VALUE ary,
VALUE randgen)
6505 long j = RAND_UPTO(i);
6519rb_ary_shuffle(rb_execution_context_t *ec,
VALUE ary,
VALUE randgen)
6521 ary = rb_ary_dup(ary);
6522 rb_ary_shuffle_bang(ec, ary, randgen);
6530 long n,
len, i, j, k, idx[10];
6531 long rnds[numberof(idx)];
6532 long memo_threshold;
6541 return rb_ary_elt(ary, i);
6544 if (n < 0) rb_raise(rb_eArgError,
"negative sample number");
6546 if (n <= numberof(idx)) {
6547 for (i = 0; i < n; ++i) {
6548 rnds[i] = RAND_UPTO(
len - i);
6553 if (
len < k && n <= numberof(idx)) {
6554 for (i = 0; i < n; ++i) {
6555 if (rnds[i] >=
len)
return rb_ary_new_capa(0);
6561 return rb_ary_new_capa(0);
6564 return rb_ary_new_from_args(1,
RARRAY_AREF(ary, i));
6576 if (j >= i) l = i, g = ++j;
6577 if (k >= l && (++k >= g)) ++k;
6586 if (n <= numberof(idx)) {
6587 long sorted[numberof(idx)];
6588 sorted[0] = idx[0] = rnds[0];
6589 for (i=1; i<n; i++) {
6591 for (j = 0; j < i; ++j) {
6592 if (k < sorted[j])
break;
6595 memmove(&sorted[j+1], &sorted[j],
sizeof(sorted[0])*(i-j));
6596 sorted[j] = idx[i] = k;
6598 result = rb_ary_new_capa(n);
6600 for (i=0; i<n; i++) {
6605 else if (n <= memo_threshold / 2) {
6607#undef RUBY_UNTYPED_DATA_WARNING
6608#define RUBY_UNTYPED_DATA_WARNING 0
6610 st_table *memo = st_init_numtable_with_size(n);
6612 result = rb_ary_new_capa(n);
6614 for (i=0; i<n; i++) {
6615 long r = RAND_UPTO(
len-i) + i;
6617 if (r > max_idx) max_idx = r;
6620 if (
len <= max_idx) n = 0;
6621 else if (n >
len) n =
len;
6623 for (i=0; i<n; i++) {
6624 long j2 = j = ptr_result[i];
6627 if (st_lookup(memo, (st_data_t)i, &value)) i2 = (long)value;
6628 if (st_lookup(memo, (st_data_t)j, &value)) j2 = (long)value;
6629 st_insert(memo, (st_data_t)j, (st_data_t)i2);
6630 ptr_result[i] = ptr_ary[j2];
6635 st_free_table(memo);
6638 result = rb_ary_dup(ary);
6639 RBASIC_CLEAR_CLASS(result);
6642 for (i=0; i<n; i++) {
6643 j = RAND_UPTO(
len-i) + i;
6645 ptr_result[j] = ptr_result[i];
6649 RBASIC_SET_CLASS_RAW(result,
rb_cArray);
6651 ARY_SET_LEN(result, n);
6657ary_sample0(rb_execution_context_t *ec,
VALUE ary)
6673 if (mul <= 0)
return INT2FIX(0);
6675 return rb_fix_mul_fix(rb_ary_length(self), n);
6712rb_ary_cycle(
int argc,
VALUE *argv,
VALUE ary)
6719 if (argc == 0 ||
NIL_P(argv[0])) {
6724 if (n <= 0)
return Qnil;
6727 while (
RARRAY_LEN(ary) > 0 && (n < 0 || 0 < n--)) {
6741yield_indexed_values(
const VALUE values,
const long r,
const long *
const p)
6746 for (i = 0; i < r; i++) ARY_SET(result, i,
RARRAY_AREF(values, p[i]));
6747 ARY_SET_LEN(result, r);
6749 return !
RBASIC(values)->klass;
6765permute0(
const long n,
const long r,
long *
const p,
char *
const used,
const VALUE values)
6767 long i = 0, index = 0;
6770 const char *
const unused = memchr(&used[i], 0, n-i);
6785 for (i = 0; i < n; ++i) {
6786 if (used[i])
continue;
6788 if (!yield_indexed_values(values, r, p)) {
6804descending_factorial(
long from,
long how_many)
6809 while (--how_many > 0) {
6811 cnt = rb_int_mul(cnt,
LONG2FIX(v));
6821binomial_coefficient(
long comb,
long size)
6825 if (comb > size-comb) {
6831 else if (comb == 0) {
6835 for (i = 1; i < comb; ++i) {
6836 r = rb_int_mul(r,
LONG2FIX(size - i));
6837 r = rb_int_idiv(r,
LONG2FIX(i + 1));
6848 return descending_factorial(n, k);
6932rb_ary_permutation(
int argc,
VALUE *argv,
VALUE ary)
6942 if (r < 0 || n < r) {
6955 long *p =
ALLOCV_N(
long, t0, r+roomof(n,
sizeof(
long)));
6956 char *used = (
char*)(p + r);
6957 VALUE ary0 = ary_make_shared_copy(ary);
6958 RBASIC_CLEAR_CLASS(ary0);
6962 permute0(n, r, p, used, ary0);
6970combinate0(
const long len,
const long n,
long *
const stack,
const VALUE values)
6977 for (lev++; lev < n; lev++) {
6978 stack[lev+1] = stack[lev]+1;
6980 if (!yield_indexed_values(values, n, stack+1)) {
6984 if (lev == 0)
return;
6986 }
while (stack[lev+1]+n ==
len+lev+1);
6996 return binomial_coefficient(k, n);
7061 if (n < 0 ||
len < n) {
7073 VALUE ary0 = ary_make_shared_copy(ary);
7075 long *stack =
ALLOCV_N(
long, t0, n+1);
7077 RBASIC_CLEAR_CLASS(ary0);
7078 combinate0(
len, n, stack, ary0);
7098rpermute0(
const long n,
const long r,
long *
const p,
const VALUE values)
7100 long i = 0, index = 0;
7104 if (++index < r-1) {
7108 for (i = 0; i < n; ++i) {
7110 if (!yield_indexed_values(values, r, p)) {
7115 if (index <= 0)
return;
7116 }
while ((i = ++p[--index]) >= n);
7132 return rb_int_positive_pow(n, (
unsigned long)k);
7201rb_ary_repeated_permutation(
VALUE ary,
VALUE num)
7223 VALUE ary0 = ary_make_shared_copy(ary);
7224 RBASIC_CLEAR_CLASS(ary0);
7226 rpermute0(n, r, p, ary0);
7234rcombinate0(
const long n,
const long r,
long *
const p,
const long rest,
const VALUE values)
7236 long i = 0, index = 0;
7240 if (++index < r-1) {
7244 for (; i < n; ++i) {
7246 if (!yield_indexed_values(values, r, p)) {
7251 if (index <= 0)
return;
7252 }
while ((i = ++p[--index]) >= n);
7264 return binomial_coefficient(k, n + k - 1);
7331rb_ary_repeated_combination(
VALUE ary,
VALUE num)
7349 else if (
len == 0) {
7355 VALUE ary0 = ary_make_shared_copy(ary);
7356 RBASIC_CLEAR_CLASS(ary0);
7358 rcombinate0(
len, n, p, n, ary0);
7426rb_ary_product(
int argc,
VALUE *argv,
VALUE ary)
7429 volatile VALUE t0 = rb_ary_hidden_new(n);
7432 int *counters =
ALLOCV_N(
int, t1, n);
7437 RBASIC_CLEAR_CLASS(t0);
7442 for (i = 1; i < n; i++) arrays[i] =
Qnil;
7443 for (i = 1; i < n; i++) arrays[i] = to_ary(argv[i-1]);
7446 for (i = 0; i < n; i++) counters[i] = 0;
7451 for (i = 0; i < n; i++) {
7453 arrays[i] = ary_make_shared_copy(arrays[i]);
7458 for (i = 0; i < n; i++) {
7464 if (MUL_OVERFLOW_LONG_P(resultlen, k))
7474 for (j = 0; j < n; j++) {
7475 rb_ary_push(subarray, rb_ary_entry(arrays[j], counters[j]));
7479 if (
NIL_P(result)) {
7480 FL_SET(t0, RARRAY_SHARED_ROOT_FLAG);
7482 if (!
FL_TEST(t0, RARRAY_SHARED_ROOT_FLAG)) {
7486 FL_UNSET(t0, RARRAY_SHARED_ROOT_FLAG);
7490 rb_ary_push(result, subarray);
7499 while (counters[m] ==
RARRAY_LEN(arrays[m])) {
7502 if (--m < 0)
goto done;
7510 return NIL_P(result) ? ary : result;
7536 rb_raise(rb_eArgError,
"attempt to take negative size");
7538 return rb_ary_subseq(obj, 0,
len);
7565rb_ary_take_while(
VALUE ary)
7573 return rb_ary_take(ary,
LONG2FIX(i));
7599 rb_raise(rb_eArgError,
"attempt to drop negative size");
7602 result = rb_ary_subseq(ary, pos,
RARRAY_LEN(ary));
7603 if (
NIL_P(result)) result = rb_ary_new();
7629rb_ary_drop_while(
VALUE ary)
7637 return rb_ary_drop(ary,
LONG2FIX(i));
7677rb_ary_any_p(
int argc,
VALUE *argv,
VALUE ary)
7685 rb_warn(
"given block not used");
7692 for (i = 0; i <
len; ++i) {
7740rb_ary_all_p(
int argc,
VALUE *argv,
VALUE ary)
7748 rb_warn(
"given block not used");
7755 for (i = 0; i <
len; ++i) {
7800rb_ary_none_p(
int argc,
VALUE *argv,
VALUE ary)
7808 rb_warn(
"given block not used");
7815 for (i = 0; i <
len; ++i) {
7864rb_ary_one_p(
int argc,
VALUE *argv,
VALUE ary)
7873 rb_warn(
"given block not used");
7877 if (result)
return Qfalse;
7883 for (i = 0; i <
len; ++i) {
7885 if (result)
return Qfalse;
7893 if (result)
return Qfalse;
7924 self = rb_ary_at(self, *argv);
7925 if (!--argc)
return self;
7927 return rb_obj_dig(argc, argv, self,
Qnil);
7931finish_exact_sum(
long n,
VALUE r,
VALUE v,
int z)
7936 v = rb_rational_plus(r, v);
8003 goto init_is_a_value;
8017 else if (RB_BIGNUM_TYPE_P(e))
8018 v = rb_big_plus(e, v);
8023 r = rb_rational_plus(r, e);
8028 v = finish_exact_sum(n, r, v, argc!=0);
8032 v = finish_exact_sum(n, r, v, i!=0);
8044 goto has_float_value;
8054 else if (RB_BIGNUM_TYPE_P(e))
8061 if (isnan(f))
continue;
8067 if (isinf(f) && signbit(x) != signbit(f))
8073 if (isinf(f))
continue;
8076 if (fabs(f) >= fabs(x))
8089 goto has_some_value;
8103rb_ary_deconstruct(
VALUE ary)
8729#include "array.rbinc"
#define RUBY_ASSERT(expr)
Asserts that the given expression is truthy if and only if RUBY_DEBUG is truthy.
#define RUBY_ASSERT_ALWAYS(expr)
A variant of RUBY_ASSERT that does not interface with RUBY_DEBUG.
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
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_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Retrieves argument from argc and argv to given VALUE references according to the format string.
int rb_block_given_p(void)
Determines if the current method is given a block.
#define NEWOBJ_OF
Old name of RB_NEWOBJ_OF.
#define FL_UNSET_RAW
Old name of RB_FL_UNSET_RAW.
#define rb_str_buf_cat2
Old name of rb_usascii_str_new_cstr.
#define RFLOAT_VALUE
Old name of rb_float_value.
#define T_STRING
Old name of RUBY_T_STRING.
#define Qundef
Old name of RUBY_Qundef.
#define INT2FIX
Old name of RB_INT2FIX.
#define OBJ_FROZEN
Old name of RB_OBJ_FROZEN.
#define rb_str_buf_new2
Old name of rb_str_buf_new_cstr.
#define rb_ary_new4
Old name of rb_ary_new_from_values.
#define FIXABLE
Old name of RB_FIXABLE.
#define LONG2FIX
Old name of RB_INT2FIX.
#define T_RATIONAL
Old name of RUBY_T_RATIONAL.
#define ALLOC_N
Old name of RB_ALLOC_N.
#define NUM2DBL
Old name of rb_num2dbl.
#define FL_SET
Old name of RB_FL_SET.
#define rb_ary_new3
Old name of rb_ary_new_from_args.
#define LONG2NUM
Old name of RB_LONG2NUM.
#define rb_usascii_str_new2
Old name of rb_usascii_str_new_cstr.
#define Qtrue
Old name of RUBY_Qtrue.
#define ST2FIX
Old name of RB_ST2FIX.
#define NUM2INT
Old name of RB_NUM2INT.
#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 NIL_P
Old name of RB_NIL_P.
#define ALLOCV_N
Old name of RB_ALLOCV_N.
#define FL_WB_PROTECTED
Old name of RUBY_FL_WB_PROTECTED.
#define DBL2NUM
Old name of rb_float_new.
#define FL_TEST
Old name of RB_FL_TEST.
#define FL_FREEZE
Old name of RUBY_FL_FREEZE.
#define NUM2LONG
Old name of RB_NUM2LONG.
#define FL_UNSET
Old name of RB_FL_UNSET.
#define FIXNUM_P
Old name of RB_FIXNUM_P.
#define rb_ary_new2
Old name of rb_ary_new_capa.
#define FL_SET_RAW
Old name of RB_FL_SET_RAW.
#define ALLOCV_END
Old name of RB_ALLOCV_END.
void rb_category_warn(rb_warning_category_t category, const char *fmt,...)
Identical to rb_category_warning(), except it reports unless $VERBOSE is nil.
void rb_iter_break(void)
Breaks from a block.
VALUE rb_eFrozenError
FrozenError exception.
VALUE rb_eRangeError
RangeError exception.
VALUE rb_eTypeError
TypeError exception.
VALUE rb_eRuntimeError
RuntimeError exception.
void rb_warn(const char *fmt,...)
Identical to rb_warning(), except it reports unless $VERBOSE is nil.
VALUE rb_eIndexError
IndexError exception.
void rb_warning(const char *fmt,...)
Issues a warning.
@ RB_WARN_CATEGORY_DEPRECATED
Warning is for deprecated features.
VALUE rb_cArray
Array class.
VALUE rb_mEnumerable
Enumerable module.
VALUE rb_class_new_instance_pass_kw(int argc, const VALUE *argv, VALUE klass)
Identical to rb_class_new_instance(), except it passes the passed keywords if any to the #initialize ...
VALUE rb_obj_frozen_p(VALUE obj)
Just calls RB_OBJ_FROZEN() inside.
int rb_eql(VALUE lhs, VALUE rhs)
Checks for equality of the passed objects, in terms of Object#eql?.
VALUE rb_cNumeric
Numeric class.
VALUE rb_cRandom
Random class.
VALUE rb_obj_class(VALUE obj)
Queries the class of an object.
VALUE rb_inspect(VALUE obj)
Generates a human-readable textual representation of the given object.
double rb_num2dbl(VALUE num)
Converts an instance of rb_cNumeric into C's double.
VALUE rb_equal(VALUE lhs, VALUE rhs)
This function is an optimised version of calling #==.
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.
#define RB_OBJ_WRITTEN(old, oldv, young)
Identical to RB_OBJ_WRITE(), except it doesn't write any values, but only a WB declaration.
#define RB_OBJ_WRITE(old, slot, young)
Declaration of a "back" pointer.
VALUE rb_funcall(VALUE recv, ID mid, int n,...)
Calls a method.
VALUE rb_call_super(int argc, const VALUE *argv)
This resembles ruby's super.
#define RGENGC_WB_PROTECTED_ARRAY
This is a compile-time flag to enable/disable write barrier for struct RArray.
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn)
This roughly resembles return enum_for(__callee__) unless block_given?.
#define RETURN_ENUMERATOR(obj, argc, argv)
Identical to RETURN_SIZED_ENUMERATOR(), except its size is unknown.
#define UNLIMITED_ARGUMENTS
This macro is used in conjunction with rb_check_arity().
#define rb_check_frozen
Just another name of rb_check_frozen.
static int rb_check_arity(int argc, int min, int max)
Ensures that the passed integer is in the passed range.
VALUE rb_range_beg_len(VALUE range, long *begp, long *lenp, long len, int err)
Deconstructs a numerical range.
#define rb_hash_uint(h, i)
Just another name of st_hash_uint.
#define rb_hash_end(h)
Just another name of st_hash_end.
#define rb_str_new(str, len)
Allocates an instance of rb_cString.
#define rb_usascii_str_new(str, len)
Identical to rb_str_new, except it generates a string of "US ASCII" encoding.
#define rb_usascii_str_new_cstr(str)
Identical to rb_str_new_cstr, except it generates a string of "US ASCII" encoding.
st_index_t rb_hash_start(st_index_t i)
Starts a series of hashing.
int rb_str_cmp(VALUE lhs, VALUE rhs)
Compares two strings, as in strcmp(3).
VALUE rb_check_string_type(VALUE obj)
Try converting an object to its stringised representation using its to_str method,...
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,...
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.
int len
Length of the buffer.
void ruby_qsort(void *, const size_t, const size_t, int(*)(const void *, const void *, void *), void *)
Reentrant implementation of quick sort.
#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_values2(int n, const VALUE *argv)
Identical to rb_yield_values(), except it takes the parameters as a C array instead of variadic argum...
VALUE rb_yield(VALUE val)
Yields the block.
#define RBIMPL_ATTR_MAYBE_UNUSED()
Wraps (or simulates) [[maybe_unused]]
#define MEMCPY(p1, p2, type, n)
Handy macro to call memcpy.
#define MEMZERO(p, type, n)
Handy macro to erase a region of memory.
#define RB_GC_GUARD(v)
Prevents premature destruction of local objects.
#define MEMMOVE(p1, p2, type, n)
Handy macro to call memmove.
VALUE rb_block_call(VALUE q, ID w, int e, const VALUE *r, type *t, VALUE y)
Call a method with a block.
void rb_hash_foreach(VALUE q, int_type *w, VALUE e)
Iteration over the given hash.
VALUE rb_ensure(type *q, VALUE w, type *e, VALUE r)
An equivalent of ensure clause.
#define RARRAY_LEN
Just another name of rb_array_len.
#define RARRAY(obj)
Convenient casting macro.
static void RARRAY_ASET(VALUE ary, long i, VALUE v)
Assigns an object in an array.
#define RARRAY_PTR_USE(ary, ptr_name, expr)
Declares a section of code where raw pointers are used.
static VALUE * RARRAY_PTR(VALUE ary)
Wild use of a C pointer.
#define RARRAY_AREF(a, i)
#define RARRAY_CONST_PTR
Just another name of rb_array_const_ptr.
#define RBASIC(obj)
Convenient casting macro.
#define Data_Wrap_Struct(klass, mark, free, sval)
Converts sval, a pointer to your struct, into a Ruby object.
#define DATA_PTR(obj)
Convenient getter macro.
#define RHASH_SIZE(h)
Queries the size of the hash.
#define StringValue(v)
Ensures that the parameter object is a String.
#define RB_PASS_CALLED_KEYWORDS
Pass keywords if current method is called with keywords, useful for argument delegation.
#define RTEST
This is an old name of RB_TEST.
const VALUE shared_root
Parent of the array.
const VALUE ary[1]
Embedded elements.
union RArray::@045262372243116021320040343026053377105164277244 as
Array's specific fields.
intptr_t SIGNED_VALUE
A signed integer type that has the same width with VALUE.
uintptr_t VALUE
Type that represents a Ruby object.
static bool RB_FLOAT_TYPE_P(VALUE obj)
Queries if the object is an instance of rb_cFloat.