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"
40#include "ruby_assert.h"
43VALUE rb_cArray_empty_frozen;
72#define ARY_DEFAULT_SIZE 16
73#define ARY_MAX_SIZE (LONG_MAX / (int)sizeof(VALUE))
74#define SMALL_ARRAY_LEN 16
78should_be_T_ARRAY(
VALUE ary)
83#define ARY_HEAP_PTR(a) (RUBY_ASSERT(!ARY_EMBED_P(a)), RARRAY(a)->as.heap.ptr)
84#define ARY_HEAP_LEN(a) (RUBY_ASSERT(!ARY_EMBED_P(a)), RARRAY(a)->as.heap.len)
85#define ARY_HEAP_CAPA(a) (RUBY_ASSERT(!ARY_EMBED_P(a)), RUBY_ASSERT(!ARY_SHARED_ROOT_P(a)), \
86 RARRAY(a)->as.heap.aux.capa)
88#define ARY_EMBED_PTR(a) (RUBY_ASSERT(ARY_EMBED_P(a)), RARRAY(a)->as.ary)
89#define ARY_EMBED_LEN(a) \
90 (RUBY_ASSERT(ARY_EMBED_P(a)), \
91 (long)((RBASIC(a)->flags >> RARRAY_EMBED_LEN_SHIFT) & \
92 (RARRAY_EMBED_LEN_MASK >> RARRAY_EMBED_LEN_SHIFT)))
93#define ARY_HEAP_SIZE(a) (RUBY_ASSERT(!ARY_EMBED_P(a)), RUBY_ASSERT(ARY_OWNS_HEAP_P(a)), ARY_CAPA(a) * sizeof(VALUE))
95#define ARY_OWNS_HEAP_P(a) (RUBY_ASSERT(should_be_T_ARRAY((VALUE)(a))), \
96 !FL_TEST_RAW((a), RARRAY_SHARED_FLAG|RARRAY_EMBED_FLAG))
98#define FL_SET_EMBED(a) do { \
99 RUBY_ASSERT(!ARY_SHARED_P(a)); \
100 FL_SET((a), RARRAY_EMBED_FLAG); \
104#define FL_UNSET_EMBED(ary) FL_UNSET((ary), RARRAY_EMBED_FLAG|RARRAY_EMBED_LEN_MASK)
105#define FL_SET_SHARED(ary) do { \
106 RUBY_ASSERT(!ARY_EMBED_P(ary)); \
107 FL_SET((ary), RARRAY_SHARED_FLAG); \
109#define FL_UNSET_SHARED(ary) FL_UNSET((ary), RARRAY_SHARED_FLAG)
111#define ARY_SET_PTR_FORCE(ary, p) \
112 (RARRAY(ary)->as.heap.ptr = (p))
113#define ARY_SET_PTR(ary, p) do { \
114 RUBY_ASSERT(!ARY_EMBED_P(ary)); \
115 RUBY_ASSERT(!OBJ_FROZEN(ary)); \
116 ARY_SET_PTR_FORCE(ary, p); \
118#define ARY_SET_EMBED_LEN(ary, n) do { \
120 RUBY_ASSERT(ARY_EMBED_P(ary)); \
121 RBASIC(ary)->flags &= ~RARRAY_EMBED_LEN_MASK; \
122 RBASIC(ary)->flags |= (tmp_n) << RARRAY_EMBED_LEN_SHIFT; \
124#define ARY_SET_HEAP_LEN(ary, n) do { \
125 RUBY_ASSERT(!ARY_EMBED_P(ary)); \
126 RARRAY(ary)->as.heap.len = (n); \
128#define ARY_SET_LEN(ary, n) do { \
129 if (ARY_EMBED_P(ary)) { \
130 ARY_SET_EMBED_LEN((ary), (n)); \
133 ARY_SET_HEAP_LEN((ary), (n)); \
135 RUBY_ASSERT(RARRAY_LEN(ary) == (n)); \
137#define ARY_INCREASE_PTR(ary, n) do { \
138 RUBY_ASSERT(!ARY_EMBED_P(ary)); \
139 RUBY_ASSERT(!OBJ_FROZEN(ary)); \
140 RARRAY(ary)->as.heap.ptr += (n); \
142#define ARY_INCREASE_LEN(ary, n) do { \
143 RUBY_ASSERT(!OBJ_FROZEN(ary)); \
144 if (ARY_EMBED_P(ary)) { \
145 ARY_SET_EMBED_LEN((ary), RARRAY_LEN(ary)+(n)); \
148 RARRAY(ary)->as.heap.len += (n); \
152#define ARY_CAPA(ary) (ARY_EMBED_P(ary) ? ary_embed_capa(ary) : \
153 ARY_SHARED_ROOT_P(ary) ? RARRAY_LEN(ary) : ARY_HEAP_CAPA(ary))
154#define ARY_SET_CAPA_FORCE(ary, n) \
155 RARRAY(ary)->as.heap.aux.capa = (n);
156#define ARY_SET_CAPA(ary, n) do { \
157 RUBY_ASSERT(!ARY_EMBED_P(ary)); \
158 RUBY_ASSERT(!ARY_SHARED_P(ary)); \
159 RUBY_ASSERT(!OBJ_FROZEN(ary)); \
160 ARY_SET_CAPA_FORCE(ary, n); \
163#define ARY_SHARED_ROOT_OCCUPIED(ary) (!OBJ_FROZEN(ary) && ARY_SHARED_ROOT_REFCNT(ary) == 1)
164#define ARY_SET_SHARED_ROOT_REFCNT(ary, value) do { \
165 RUBY_ASSERT(ARY_SHARED_ROOT_P(ary)); \
166 RUBY_ASSERT(!OBJ_FROZEN(ary)); \
167 RUBY_ASSERT((value) >= 0); \
168 RARRAY(ary)->as.heap.aux.capa = (value); \
170#define FL_SET_SHARED_ROOT(ary) do { \
171 RUBY_ASSERT(!OBJ_FROZEN(ary)); \
172 RUBY_ASSERT(!ARY_EMBED_P(ary)); \
173 FL_SET((ary), RARRAY_SHARED_ROOT_FLAG); \
182 RARRAY_ASET(a, i, v);
187ary_embed_capa(
VALUE ary)
189 size_t size = rb_gc_obj_slot_size(ary) - offsetof(
struct RArray, as.ary);
191 return size /
sizeof(
VALUE);
195ary_embed_size(
long capa)
197 size_t size = offsetof(
struct RArray, as.ary) + (
sizeof(
VALUE) *
capa);
198 if (size <
sizeof(
struct RArray)) size =
sizeof(
struct RArray);
203ary_embeddable_p(
long capa)
205 return rb_gc_size_allocatable_p(ary_embed_size(
capa));
209rb_ary_embeddable_p(
VALUE ary)
219 return !(ARY_SHARED_ROOT_P(ary) ||
OBJ_FROZEN(ary) || ARY_SHARED_P(ary));
223rb_ary_size_as_embedded(
VALUE ary)
227 if (ARY_EMBED_P(ary)) {
228 real_size = ary_embed_size(ARY_EMBED_LEN(ary));
230 else if (rb_ary_embeddable_p(ary)) {
231 real_size = ary_embed_size(ARY_HEAP_CAPA(ary));
234 real_size =
sizeof(
struct RArray);
241#define ary_verify(ary) ary_verify_(ary, __FILE__, __LINE__)
244ary_verify_(
VALUE ary,
const char *file,
int line)
248 if (ARY_SHARED_P(ary)) {
249 VALUE root = ARY_SHARED_ROOT(ary);
250 const VALUE *
ptr = ARY_HEAP_PTR(ary);
257 else if (ARY_EMBED_P(ary)) {
266 for (i=0; i<
len; i++) {
275#define ary_verify(ary) ((void)0)
279rb_ary_ptr_use_start(
VALUE ary)
288rb_ary_ptr_use_end(
VALUE ary)
304ary_mem_clear(
VALUE ary,
long beg,
long size)
312memfill(
register VALUE *mem,
register long size,
register VALUE val)
320ary_memfill(
VALUE ary,
long beg,
long size,
VALUE val)
323 memfill(
ptr + beg, size, val);
329ary_memcpy0(
VALUE ary,
long beg,
long argc,
const VALUE *argv,
VALUE buff_owner_ary)
333 if (argc > (
int)(128/
sizeof(
VALUE)) ) {
334 rb_gc_writebarrier_remember(buff_owner_ary);
342 for (i=0; i<argc; i++) {
350ary_memcpy(
VALUE ary,
long beg,
long argc,
const VALUE *argv)
352 ary_memcpy0(ary, beg, argc, argv, ary);
356ary_heap_alloc_buffer(
size_t capa)
364 ruby_sized_xfree((
void *)
ptr, size);
368ary_heap_free(
VALUE ary)
370 ary_heap_free_ptr(ary, ARY_HEAP_PTR(ary), ARY_HEAP_SIZE(ary));
374ary_heap_realloc(
VALUE ary,
size_t new_capa)
377 SIZED_REALLOC_N(
RARRAY(ary)->as.heap.ptr,
VALUE, new_capa, ARY_HEAP_CAPA(ary));
384rb_ary_make_embedded(
VALUE ary)
387 if (!ARY_EMBED_P(ary)) {
388 const VALUE *buf = ARY_HEAP_PTR(ary);
389 long len = ARY_HEAP_LEN(ary);
392 ARY_SET_EMBED_LEN(ary,
len);
396 ary_heap_free_ptr(ary, buf,
len *
sizeof(
VALUE));
401ary_resize_capa(
VALUE ary,
long capacity)
407 if (capacity > ary_embed_capa(ary)) {
408 size_t new_capa = capacity;
409 if (ARY_EMBED_P(ary)) {
410 long len = ARY_EMBED_LEN(ary);
411 VALUE *
ptr = ary_heap_alloc_buffer(capacity);
415 ARY_SET_PTR(ary,
ptr);
416 ARY_SET_HEAP_LEN(ary,
len);
419 new_capa = ary_heap_realloc(ary, capacity);
421 ARY_SET_CAPA(ary, new_capa);
424 if (!ARY_EMBED_P(ary)) {
425 long len = ARY_HEAP_LEN(ary);
426 long old_capa = ARY_HEAP_CAPA(ary);
427 const VALUE *
ptr = ARY_HEAP_PTR(ary);
429 if (
len > capacity)
len = capacity;
431 ary_heap_free_ptr(ary,
ptr, old_capa);
434 ARY_SET_LEN(ary,
len);
442ary_shrink_capa(
VALUE ary)
444 long capacity = ARY_HEAP_LEN(ary);
445 long old_capa = ARY_HEAP_CAPA(ary);
448 if (old_capa > capacity) {
449 size_t new_capa = ary_heap_realloc(ary, capacity);
450 ARY_SET_CAPA(ary, new_capa);
457ary_double_capa(
VALUE ary,
long min)
459 long new_capa = ARY_CAPA(ary) / 2;
461 if (new_capa < ARY_DEFAULT_SIZE) {
462 new_capa = ARY_DEFAULT_SIZE;
464 if (new_capa >= ARY_MAX_SIZE - min) {
465 new_capa = (ARY_MAX_SIZE - min) / 2;
468 ary_resize_capa(ary, new_capa);
474rb_ary_decrement_share(
VALUE shared_root)
477 long num = ARY_SHARED_ROOT_REFCNT(shared_root);
478 ARY_SET_SHARED_ROOT_REFCNT(shared_root, num - 1);
483rb_ary_unshare(
VALUE ary)
485 VALUE shared_root = ARY_SHARED_ROOT(ary);
486 rb_ary_decrement_share(shared_root);
487 FL_UNSET_SHARED(ary);
491rb_ary_reset(
VALUE ary)
493 if (ARY_OWNS_HEAP_P(ary)) {
496 else if (ARY_SHARED_P(ary)) {
501 ARY_SET_EMBED_LEN(ary, 0);
505rb_ary_increment_share(
VALUE shared_root)
508 long num = ARY_SHARED_ROOT_REFCNT(shared_root);
510 ARY_SET_SHARED_ROOT_REFCNT(shared_root, num + 1);
516rb_ary_set_shared(
VALUE ary,
VALUE shared_root)
522 rb_ary_increment_share(shared_root);
526 RB_DEBUG_COUNTER_INC(obj_ary_shared_create);
530rb_ary_modify_check(
VALUE ary)
534 rb_check_frozen(ary);
539rb_ary_cancel_sharing(
VALUE ary)
541 if (ARY_SHARED_P(ary)) {
543 VALUE shared_root = ARY_SHARED_ROOT(ary);
545 ary_verify(shared_root);
547 if (
len <= ary_embed_capa(ary)) {
548 const VALUE *
ptr = ARY_HEAP_PTR(ary);
549 FL_UNSET_SHARED(ary);
552 rb_ary_decrement_share(shared_root);
553 ARY_SET_EMBED_LEN(ary,
len);
555 else if (ARY_SHARED_ROOT_OCCUPIED(shared_root) &&
len > ((shared_len =
RARRAY_LEN(shared_root))>>1)) {
557 FL_UNSET_SHARED(ary);
559 ARY_SET_CAPA(ary, shared_len);
563 FL_SET_EMBED(shared_root);
564 rb_ary_decrement_share(shared_root);
570 ARY_SET_CAPA_FORCE(ary,
len);
571 ARY_SET_PTR_FORCE(ary,
ptr);
574 rb_gc_writebarrier_remember(ary);
582 rb_ary_modify_check(ary);
583 rb_ary_cancel_sharing(ary);
587ary_ensure_room_for_push(
VALUE ary,
long add_len)
590 long new_len = old_len + add_len;
593 if (old_len > ARY_MAX_SIZE - add_len) {
596 if (ARY_SHARED_P(ary)) {
597 if (new_len > ary_embed_capa(ary)) {
598 VALUE shared_root = ARY_SHARED_ROOT(ary);
599 if (ARY_SHARED_ROOT_OCCUPIED(shared_root)) {
601 rb_ary_modify_check(ary);
604 ary_verify(shared_root);
610 capa = ARY_CAPA(ary);
612 ary_double_capa(ary, new_len);
623 rb_ary_modify_check(ary);
625 capa = ARY_CAPA(ary);
626 if (new_len >
capa) {
627 ary_double_capa(ary, new_len);
658 if (!ARY_EMBED_P(ary) && !ARY_SHARED_P(ary) && !ARY_SHARED_ROOT_P(ary)) {
659 ary_shrink_capa(ary);
675 if (!ARY_EMBED_P(ary1) && ARY_SHARED_P(ary1) &&
676 !ARY_EMBED_P(ary2) && ARY_SHARED_P(ary2) &&
677 ARY_SHARED_ROOT(ary1) == ARY_SHARED_ROOT(ary2) &&
678 ARY_HEAP_LEN(ary1) == ARY_HEAP_LEN(ary2)) {
687 size_t size = ary_embed_size(
capa);
689 NEWOBJ_OF(ary,
struct RArray, klass,
700ary_alloc_heap(
VALUE klass)
702 NEWOBJ_OF(ary,
struct RArray, klass,
704 sizeof(
struct RArray), 0);
706 ary->as.heap.len = 0;
707 ary->as.heap.aux.capa = 0;
708 ary->as.heap.ptr = NULL;
714empty_ary_alloc(
VALUE klass)
716 RUBY_DTRACE_CREATE_HOOK(ARRAY, 0);
717 return ary_alloc_embed(klass, 0);
728 rb_raise(rb_eArgError,
"negative array size (or size too big)");
730 if (
capa > ARY_MAX_SIZE) {
731 rb_raise(rb_eArgError,
"array size too big");
734 RUBY_DTRACE_CREATE_HOOK(ARRAY,
capa);
736 if (ary_embeddable_p(
capa)) {
737 ary = ary_alloc_embed(klass,
capa);
740 ary = ary_alloc_heap(klass);
741 ARY_SET_CAPA(ary,
capa);
744 ARY_SET_PTR(ary, ary_heap_alloc_buffer(
capa));
745 ARY_SET_HEAP_LEN(ary, 0);
764(rb_ary_new_from_args)(
long n, ...)
773 for (i=0; i<n; i++) {
774 ARY_SET(ary, i, va_arg(ar,
VALUE));
783rb_ary_tmp_new_from_values(
VALUE klass,
long n,
const VALUE *elts)
787 ary = ary_new(klass, n);
789 ary_memcpy(ary, 0, n, elts);
799 return rb_ary_tmp_new_from_values(
rb_cArray, n, elts);
803ec_ary_alloc_embed(rb_execution_context_t *ec,
VALUE klass,
long capa)
805 size_t size = ary_embed_size(
capa);
807 NEWOBJ_OF(ary,
struct RArray, klass,
818ec_ary_alloc_heap(rb_execution_context_t *ec,
VALUE klass)
820 NEWOBJ_OF(ary,
struct RArray, klass,
822 sizeof(
struct RArray), ec);
824 ary->as.heap.len = 0;
825 ary->as.heap.aux.capa = 0;
826 ary->as.heap.ptr = NULL;
832ec_ary_new(rb_execution_context_t *ec,
VALUE klass,
long capa)
837 rb_raise(rb_eArgError,
"negative array size (or size too big)");
839 if (
capa > ARY_MAX_SIZE) {
840 rb_raise(rb_eArgError,
"array size too big");
843 RUBY_DTRACE_CREATE_HOOK(ARRAY,
capa);
845 if (ary_embeddable_p(
capa)) {
846 ary = ec_ary_alloc_embed(ec, klass,
capa);
849 ary = ec_ary_alloc_heap(ec, klass);
850 ARY_SET_CAPA(ary,
capa);
853 ARY_SET_PTR(ary, ary_heap_alloc_buffer(
capa));
854 ARY_SET_HEAP_LEN(ary, 0);
861rb_ec_ary_new_from_values(rb_execution_context_t *ec,
long n,
const VALUE *elts)
867 ary_memcpy(ary, 0, n, elts);
882rb_ary_hidden_new_fill(
long capa)
886 ARY_SET_LEN(ary,
capa);
893 if (ARY_OWNS_HEAP_P(ary)) {
894 if (USE_DEBUG_COUNTER &&
895 !ARY_SHARED_ROOT_P(ary) &&
897 RB_DEBUG_COUNTER_INC(obj_ary_extracapa);
900 RB_DEBUG_COUNTER_INC(obj_ary_ptr);
904 RB_DEBUG_COUNTER_INC(obj_ary_embed);
907 if (ARY_SHARED_P(ary)) {
908 RB_DEBUG_COUNTER_INC(obj_ary_shared);
910 if (ARY_SHARED_ROOT_P(ary) && ARY_SHARED_ROOT_OCCUPIED(ary)) {
911 RB_DEBUG_COUNTER_INC(obj_ary_shared_root_occupied);
915static VALUE fake_ary_flags;
918init_fake_ary_flags(
void)
920 struct RArray fake_ary = {0};
928rb_setup_fake_ary(
struct RArray *fake_ary,
const VALUE *list,
long len)
931 RBASIC_CLEAR_CLASS((
VALUE)fake_ary);
934 fake_ary->as.heap.ptr = list;
935 fake_ary->as.heap.len =
len;
936 fake_ary->as.heap.aux.capa =
len;
937 return (
VALUE)fake_ary;
941rb_ary_memsize(
VALUE ary)
943 if (ARY_OWNS_HEAP_P(ary)) {
944 return ARY_CAPA(ary) *
sizeof(
VALUE);
952ary_make_shared(
VALUE ary)
956 if (ARY_SHARED_P(ary)) {
957 return ARY_SHARED_ROOT(ary);
959 else if (ARY_SHARED_ROOT_P(ary)) {
966 long capa = ARY_CAPA(ary);
971 VALUE shared = ary_alloc_heap(0);
972 FL_SET_SHARED_ROOT(shared);
974 if (ARY_EMBED_P(ary)) {
976 ARY_SET_PTR(shared,
ptr);
980 ARY_SET_HEAP_LEN(ary,
len);
981 ARY_SET_PTR(ary,
ptr);
987 ARY_SET_LEN(shared,
capa);
989 rb_ary_set_shared(ary, shared);
999ary_make_substitution(
VALUE ary)
1003 if (ary_embeddable_p(
len)) {
1008 ARY_SET_EMBED_LEN(subst,
len);
1012 return rb_ary_increment_share(ary_make_shared(ary));
1023rb_to_array_type(
VALUE ary)
1025 return rb_convert_type_with_id(ary,
T_ARRAY,
"Array", idTo_ary);
1027#define to_ary rb_to_array_type
1032 return rb_check_convert_type_with_id(ary,
T_ARRAY,
"Array", idTo_ary);
1036rb_check_to_array(
VALUE ary)
1038 return rb_check_convert_type_with_id(ary,
T_ARRAY,
"Array", idTo_a);
1042rb_to_array(
VALUE ary)
1044 return rb_convert_type_with_id(ary,
T_ARRAY,
"Array", idTo_a);
1073rb_ary_s_new(
int argc,
VALUE *argv,
VALUE klass)
1079 if (argc > 0 &&
FIXNUM_P(argv[0])) {
1081 if (size < 0) size = 0;
1084 ary = ary_new(klass, size);
1147rb_ary_initialize(
int argc,
VALUE *argv,
VALUE ary)
1163 if (argc == 1 && !
FIXNUM_P(size)) {
1174 rb_raise(rb_eArgError,
"negative array size");
1176 if (
len > ARY_MAX_SIZE) {
1177 rb_raise(rb_eArgError,
"array size too big");
1181 ary_resize_capa(ary,
len);
1186 rb_warn(
"block supersedes default value argument");
1188 for (i=0; i<
len; i++) {
1190 ARY_SET_LEN(ary, i + 1);
1194 ary_memfill(ary, 0,
len, val);
1195 ARY_SET_LEN(ary,
len);
1211rb_ary_s_create(
int argc,
VALUE *argv,
VALUE klass)
1213 VALUE ary = ary_new(klass, argc);
1214 if (argc > 0 && argv) {
1215 ary_memcpy(ary, 0, argc, argv);
1216 ARY_SET_LEN(ary, argc);
1230 rb_raise(
rb_eIndexError,
"index %ld too small for array; minimum: %ld",
1234 else if (idx >= ARY_MAX_SIZE) {
1239 if (idx >= ARY_CAPA(ary)) {
1240 ary_double_capa(ary, idx);
1243 ary_mem_clear(ary,
len, idx -
len + 1);
1247 ARY_SET_LEN(ary, idx + 1);
1249 ARY_SET(ary, idx, val);
1253ary_make_partial(
VALUE ary,
VALUE klass,
long offset,
long len)
1259 VALUE result = ary_alloc_heap(klass);
1260 size_t embed_capa = ary_embed_capa(result);
1261 if ((
size_t)
len <= embed_capa) {
1262 FL_SET_EMBED(result);
1264 ARY_SET_EMBED_LEN(result,
len);
1267 VALUE shared = ary_make_shared(ary);
1272 FL_UNSET_EMBED(result);
1276 rb_ary_set_shared(result, shared);
1278 ARY_INCREASE_PTR(result, offset);
1279 ARY_SET_LEN(result,
len);
1289ary_make_partial_step(
VALUE ary,
VALUE klass,
long offset,
long len,
long step)
1296 const long orig_len =
len;
1298 if (step > 0 && step >=
len) {
1299 VALUE result = ary_new(klass, 1);
1304 ARY_SET_EMBED_LEN(result, 1);
1307 else if (step < 0 && step < -
len) {
1311 long ustep = (step < 0) ? -step : step;
1312 len = roomof(
len, ustep);
1315 long j = offset + ((step > 0) ? 0 : (orig_len - 1));
1317 VALUE result = ary_new(klass,
len);
1318 if (ARY_EMBED_P(result)) {
1322 for (i = 0; i <
len; ++i) {
1326 ARY_SET_EMBED_LEN(result,
len);
1332 for (i = 0; i <
len; ++i) {
1337 ARY_SET_LEN(result,
len);
1344ary_make_shared_copy(
VALUE ary)
1349enum ary_take_pos_flags
1356ary_take_first_or_last_n(
VALUE ary,
long n,
enum ary_take_pos_flags last)
1365 rb_raise(rb_eArgError,
"negative array size");
1370 return ary_make_partial(ary,
rb_cArray, offset, n);
1374ary_take_first_or_last(
int argc,
const VALUE *argv,
VALUE ary,
enum ary_take_pos_flags last)
1376 argc = rb_check_arity(argc, 0, 1);
1381 return ary_take_first_or_last_n(ary,
NUM2LONG(argv[0]), last);
1402 long idx =
RARRAY_LEN((ary_verify(ary), ary));
1403 VALUE target_ary = ary_ensure_room_for_push(ary, 1);
1407 ARY_SET_LEN(ary, idx + 1);
1416 VALUE target_ary = ary_ensure_room_for_push(ary,
len);
1417 ary_memcpy0(ary, oldlen,
len, argv, target_ary);
1418 ARY_SET_LEN(ary, oldlen +
len);
1441rb_ary_push_m(
int argc,
VALUE *argv,
VALUE ary)
1450 rb_ary_modify_check(ary);
1452 if (n == 0)
return Qnil;
1453 if (ARY_OWNS_HEAP_P(ary) &&
1454 n * 3 < ARY_CAPA(ary) &&
1455 ARY_CAPA(ary) > ARY_DEFAULT_SIZE)
1457 ary_resize_capa(ary, n * 2);
1462 ARY_SET_LEN(ary, n - 1);
1498rb_ary_pop_m(
int argc,
VALUE *argv,
VALUE ary)
1506 rb_ary_modify_check(ary);
1507 result = ary_take_first_or_last(argc, argv, ary, ARY_TAKE_LAST);
1520 rb_ary_modify_check(ary);
1526 rb_ary_behead(ary, 1);
1570rb_ary_shift_m(
int argc,
VALUE *argv,
VALUE ary)
1579 rb_ary_modify_check(ary);
1580 result = ary_take_first_or_last(argc, argv, ary, ARY_TAKE_FIRST);
1582 rb_ary_behead(ary,n);
1588rb_ary_behead(
VALUE ary,
long n)
1594 rb_ary_modify_check(ary);
1596 if (!ARY_SHARED_P(ary)) {
1597 if (ARY_EMBED_P(ary) ||
RARRAY_LEN(ary) < ARY_DEFAULT_SIZE) {
1601 ARY_INCREASE_LEN(ary, -n);
1606 ary_mem_clear(ary, 0, n);
1607 ary_make_shared(ary);
1609 else if (ARY_SHARED_ROOT_OCCUPIED(ARY_SHARED_ROOT(ary))) {
1610 ary_mem_clear(ary, 0, n);
1613 ARY_INCREASE_PTR(ary, n);
1614 ARY_INCREASE_LEN(ary, -n);
1623 if (head - sharedp < argc) {
1624 long room =
capa -
len - argc;
1628 head = sharedp + argc + room;
1630 ARY_SET_PTR(ary, head - argc);
1631 RUBY_ASSERT(ARY_SHARED_ROOT_OCCUPIED(ARY_SHARED_ROOT(ary)));
1634 return ARY_SHARED_ROOT(ary);
1638ary_modify_for_unshift(
VALUE ary,
int argc)
1641 long new_len =
len + argc;
1643 const VALUE *head, *sharedp;
1646 capa = ARY_CAPA(ary);
1647 if (
capa - (
capa >> 6) <= new_len) {
1648 ary_double_capa(ary, new_len);
1652 if (new_len > ARY_DEFAULT_SIZE * 4 && !ARY_EMBED_P(ary)) {
1656 capa = ARY_CAPA(ary);
1657 ary_make_shared(ary);
1660 return make_room_for_unshift(ary, head, (
void *)sharedp, argc,
capa,
len);
1674ary_ensure_room_for_unshift(
VALUE ary,
int argc)
1677 long new_len =
len + argc;
1679 if (
len > ARY_MAX_SIZE - argc) {
1682 else if (! ARY_SHARED_P(ary)) {
1683 return ary_modify_for_unshift(ary, argc);
1686 VALUE shared_root = ARY_SHARED_ROOT(ary);
1689 if (! ARY_SHARED_ROOT_OCCUPIED(shared_root)) {
1690 return ary_modify_for_unshift(ary, argc);
1692 else if (new_len >
capa) {
1693 return ary_modify_for_unshift(ary, argc);
1699 rb_ary_modify_check(ary);
1700 return make_room_for_unshift(ary, head, sharedp, argc,
capa,
len);
1720rb_ary_unshift_m(
int argc,
VALUE *argv,
VALUE ary)
1726 rb_ary_modify_check(ary);
1730 target_ary = ary_ensure_room_for_unshift(ary, argc);
1731 ary_memcpy0(ary, 0, argc, argv, target_ary);
1732 ARY_SET_LEN(ary,
len + argc);
1739 return rb_ary_unshift_m(1, &item, ary);
1744rb_ary_elt(
VALUE ary,
long offset)
1748 if (offset < 0 ||
len <= offset) {
1757 return rb_ary_entry_internal(ary, offset);
1761rb_ary_subseq_step(
VALUE ary,
long beg,
long len,
long step)
1766 if (beg > alen)
return Qnil;
1767 if (beg < 0 ||
len < 0)
return Qnil;
1769 if (alen <
len || alen < beg +
len) {
1773 if (
len == 0)
return ary_new(klass, 0);
1775 rb_raise(rb_eArgError,
"slice step cannot be zero");
1777 return ary_make_partial(ary, klass, beg,
len);
1779 return ary_make_partial_step(ary, klass, beg,
len, step);
1785 return rb_ary_subseq_step(ary, beg,
len, 1);
1915 rb_check_arity(argc, 1, 2);
1917 return rb_ary_aref2(ary, argv[0], argv[1]);
1919 return rb_ary_aref1(ary, argv[0]);
1936 long beg,
len, step;
1943 switch (rb_arithmetic_sequence_beg_len_step(arg, &beg, &
len, &step,
RARRAY_LEN(ary), 0)) {
1949 return rb_ary_subseq_step(ary, beg,
len, step);
1987rb_ary_first(
int argc,
VALUE *argv,
VALUE ary)
1994 return ary_take_first_or_last(argc, argv, ary, ARY_TAKE_FIRST);
2000ary_first(
VALUE self)
2013rb_ary_last(
int argc,
const VALUE *argv,
VALUE ary)
2016 return ary_last(ary);
2019 return ary_take_first_or_last(argc, argv, ary, ARY_TAKE_LAST);
2064rb_ary_fetch(
int argc,
VALUE *argv,
VALUE ary)
2072 if (block_given && argc == 2) {
2073 rb_warn(
"block supersedes default value argument");
2081 if (block_given)
return rb_yield(pos);
2083 rb_raise(
rb_eIndexError,
"index %ld outside of array bounds: %ld...%ld",
2118 if_none = rb_check_arity(argc, 0, 1) ? argv[0] :
Qnil;
2120 for (idx = 0; idx <
RARRAY_LEN(ary); idx++) {
2127 if (!
NIL_P(if_none)) {
2128 return rb_funcallv(if_none, idCall, 0, 0);
2155rb_ary_rfind(
int argc,
VALUE *argv,
VALUE ary)
2161 if_none = rb_check_arity(argc, 0, 1) ? argv[0] :
Qnil;
2171 idx = (idx >=
len) ?
len : idx;
2174 if (!
NIL_P(if_none)) {
2175 return rb_funcallv(if_none, idCall, 0, 0);
2215rb_ary_index(
int argc,
VALUE *argv,
VALUE ary)
2229 rb_check_arity(argc, 0, 1);
2232 rb_warn(
"given block not used");
2271rb_ary_rindex(
int argc,
VALUE *argv,
VALUE ary)
2287 rb_check_arity(argc, 0, 1);
2290 rb_warn(
"given block not used");
2308 if (!
NIL_P(tmp))
return tmp;
2313rb_ary_splice(
VALUE ary,
long beg,
long len,
const VALUE *rptr,
long rlen,
int self_insert)
2322 rb_raise(
rb_eIndexError,
"index %ld too small for array; minimum: %ld",
2326 if (olen <
len || olen < beg +
len) {
2332 if (beg > ARY_MAX_SIZE - rlen) {
2335 target_ary = ary_ensure_room_for_push(ary, rlen-
len);
2337 ary_mem_clear(ary, olen, beg - olen);
2341 ary_memcpy0(ary, beg, rlen, rptr, target_ary);
2343 ARY_SET_LEN(ary,
len);
2348 if (olen -
len > ARY_MAX_SIZE - rlen) {
2352 alen = olen + rlen -
len;
2353 if (alen >= ARY_CAPA(ary)) {
2354 ary_double_capa(ary, alen);
2361 ARY_SET_LEN(ary, alen);
2365 rb_gc_writebarrier_remember(ary);
2387 rb_ary_modify_check(ary);
2388 if (ARY_SHARED_P(ary)) {
2391 if (
len > (
capa = (
long)ARY_CAPA(ary))) {
2392 rb_bug(
"probable buffer overflow: %ld for %ld",
len,
capa);
2394 ARY_SET_LEN(ary,
len);
2404 if (
len == olen)
return ary;
2405 if (
len > ARY_MAX_SIZE) {
2409 if (
len > ARY_CAPA(ary)) {
2410 ary_double_capa(ary,
len);
2412 ary_mem_clear(ary, olen,
len - olen);
2413 ARY_SET_LEN(ary,
len);
2415 else if (ARY_EMBED_P(ary)) {
2416 ARY_SET_EMBED_LEN(ary,
len);
2418 else if (
len <= ary_embed_capa(ary)) {
2419 const VALUE *
ptr = ARY_HEAP_PTR(ary);
2420 long ptr_capa = ARY_HEAP_SIZE(ary);
2421 bool is_malloc_ptr = !ARY_SHARED_P(ary);
2426 ARY_SET_EMBED_LEN(ary,
len);
2428 if (is_malloc_ptr) ruby_sized_xfree((
void *)
ptr, ptr_capa);
2431 if (olen >
len + ARY_DEFAULT_SIZE) {
2432 size_t new_capa = ary_heap_realloc(ary,
len);
2433 ARY_SET_CAPA(ary, new_capa);
2435 ARY_SET_HEAP_LEN(ary,
len);
2442ary_aset_by_rb_ary_store(
VALUE ary,
long key,
VALUE val)
2449ary_aset_by_rb_ary_splice(
VALUE ary,
long beg,
long len,
VALUE val)
2604 long offset, beg,
len;
2606 rb_check_arity(argc, 2, 3);
2607 rb_ary_modify_check(ary);
2611 return ary_aset_by_rb_ary_splice(ary, beg,
len, argv[2]);
2615 return ary_aset_by_rb_ary_store(ary, offset, argv[1]);
2619 return ary_aset_by_rb_ary_splice(ary, beg,
len, argv[1]);
2623 return ary_aset_by_rb_ary_store(ary, offset, argv[1]);
2663rb_ary_insert(
int argc,
VALUE *argv,
VALUE ary)
2668 rb_ary_modify_check(ary);
2670 if (argc == 1)
return ary;
2677 rb_raise(
rb_eIndexError,
"index %ld too small for array; minimum: %ld",
2682 rb_ary_splice(ary, pos, 0, argv + 1, argc - 1, FALSE);
2687rb_ary_length(
VALUE ary);
2692 return rb_ary_length(ary);
2789rb_ary_each_index(
VALUE ary)
2825rb_ary_reverse_each(
VALUE ary)
2856rb_ary_length(
VALUE ary)
2873rb_ary_empty_p(
VALUE ary)
2884 ARY_SET_LEN(dup,
len);
2902recursive_join(
VALUE obj,
VALUE argp,
int recur)
2907 VALUE result = arg[2];
2908 int *first = (
int *)arg[3];
2911 rb_raise(rb_eArgError,
"recursive array join");
2914 ary_join_1(obj, ary, sep, 0, result, first);
2925 if (max > 0) rb_enc_copy(result,
RARRAY_AREF(ary, 0));
2926 for (i=0; i<max; i++) {
2928 if (!RB_TYPE_P(val,
T_STRING))
break;
2929 if (i > 0 && !
NIL_P(sep))
2937ary_join_1_str(
VALUE dst,
VALUE src,
int *first)
2941 rb_enc_copy(dst, src);
2950 rb_raise(rb_eArgError,
"recursive array join");
2959 args[3] = (
VALUE)first;
2970 if (i > 0 && !
NIL_P(sep))
2975 ary_join_1_str(result, val, first);
2977 else if (RB_TYPE_P(val,
T_ARRAY)) {
2978 ary_join_1_ary(val, ary, sep, result, val, first);
2981 ary_join_1_str(result, tmp, first);
2984 ary_join_1_ary(val, ary, sep, result, tmp, first);
2996 VALUE val, tmp, result;
3005 for (i=0; i < len_memo; i++) {
3007 if (RB_UNLIKELY(!RB_TYPE_P(val,
T_STRING))) {
3009 if (
NIL_P(tmp) || tmp != val) {
3014 rb_enc_associate(result, rb_usascii_encoding());
3015 i = ary_join_0(ary, sep, i, result);
3017 ary_join_1(ary, ary, sep, i, result, &first);
3020 len += RSTRING_LEN(tmp);
3024 len += RSTRING_LEN(val);
3031 ary_join_0(ary, sep,
RARRAY_LEN(ary), result);
3066rb_ary_join_m(
int argc,
VALUE *argv,
VALUE ary)
3070 if (rb_check_arity(argc, 0, 1) == 0 ||
NIL_P(sep = argv[0])) {
3081inspect_ary(
VALUE ary,
VALUE dummy,
int recur)
3091 else rb_enc_copy(str, s);
3113rb_ary_inspect(
VALUE ary)
3122 return rb_ary_inspect(ary);
3143rb_ary_to_a(
VALUE ary)
3179rb_ary_to_h(
VALUE ary)
3186 const VALUE e = rb_ary_elt(ary, i);
3187 const VALUE elt = block_given ? rb_yield_force_blockarg(e) : e;
3189 if (
NIL_P(key_value_pair)) {
3190 rb_raise(
rb_eTypeError,
"wrong element type %"PRIsVALUE
" at %ld (expected array)",
3194 rb_raise(rb_eArgError,
"wrong array length at %ld (expected 2, was %ld)",
3210rb_ary_to_ary_m(
VALUE ary)
3235 ary_reverse(p1, p2);
3256rb_ary_reverse_bang(
VALUE ary)
3273rb_ary_reverse_m(
VALUE ary)
3281 do *p2-- = *p1++;
while (--
len > 0);
3288rotate_count(
long cnt,
long len)
3290 return (cnt < 0) ? (
len - (~cnt %
len) - 1) : (cnt %
len);
3301 else if (cnt ==
len - 1) {
3309 if (--cnt > 0) ary_reverse(
ptr,
ptr + cnt);
3321 if (
len > 1 && (cnt = rotate_count(cnt,
len)) > 0) {
3362rb_ary_rotate_bang(
int argc,
VALUE *argv,
VALUE ary)
3364 long n = (rb_check_arity(argc, 0, 1) ?
NUM2LONG(argv[0]) : 1);
3403rb_ary_rotate_m(
int argc,
VALUE *argv,
VALUE ary)
3408 long cnt = (rb_check_arity(argc, 0, 1) ?
NUM2LONG(argv[0]) : 1);
3413 cnt = rotate_count(cnt,
len);
3416 ary_memcpy(rotated, 0,
len,
ptr + cnt);
3417 ary_memcpy(rotated,
len, cnt,
ptr);
3423struct ary_sort_data {
3429sort_reentered(
VALUE ary)
3431 if (
RBASIC(ary)->klass) {
3438sort_returned(
struct ary_sort_data *data)
3443 sort_reentered(data->ary);
3447sort_1(
const void *ap,
const void *bp,
void *dummy)
3449 struct ary_sort_data *data = dummy;
3450 VALUE retval = sort_reentered(data->ary);
3458 n = rb_cmpint(retval, a, b);
3459 sort_returned(data);
3464sort_2(
const void *ap,
const void *bp,
void *dummy)
3466 struct ary_sort_data *data = dummy;
3467 VALUE retval = sort_reentered(data->ary);
3472 if ((
long)a > (
long)b)
return 1;
3473 if ((
long)a < (
long)b)
return -1;
3476 if (STRING_P(a) && STRING_P(b) && CMP_OPTIMIZABLE(STRING)) {
3479 if (RB_FLOAT_TYPE_P(a) && CMP_OPTIMIZABLE(FLOAT)) {
3480 return rb_float_cmp(a, b);
3483 retval = rb_funcallv(a, id_cmp, 1, &b);
3484 n = rb_cmpint(retval, a, b);
3485 sort_returned(data);
3506 VALUE tmp = ary_make_substitution(ary);
3507 struct ary_sort_data data;
3509 RBASIC_CLEAR_CLASS(tmp);
3511 data.receiver = ary;
3517 if (ARY_EMBED_P(tmp)) {
3518 if (ARY_SHARED_P(ary)) {
3519 rb_ary_unshare(ary);
3522 if (ARY_EMBED_LEN(tmp) > ARY_CAPA(ary)) {
3523 ary_resize_capa(ary, ARY_EMBED_LEN(tmp));
3525 ary_memcpy(ary, 0, ARY_EMBED_LEN(tmp), ARY_EMBED_PTR(tmp));
3526 ARY_SET_LEN(ary, ARY_EMBED_LEN(tmp));
3529 if (!ARY_EMBED_P(ary) && ARY_HEAP_PTR(ary) == ARY_HEAP_PTR(tmp)) {
3530 FL_UNSET_SHARED(ary);
3535 if (ARY_EMBED_P(ary)) {
3536 FL_UNSET_EMBED(ary);
3538 else if (ARY_SHARED_P(ary)) {
3540 rb_ary_unshare(ary);
3545 ARY_SET_PTR(ary, ARY_HEAP_PTR(tmp));
3546 ARY_SET_HEAP_LEN(ary,
len);
3547 ARY_SET_CAPA(ary, ARY_HEAP_LEN(tmp));
3551 ARY_SET_EMBED_LEN(tmp, 0);
3619rb_ary_bsearch(
VALUE ary)
3621 VALUE index_result = rb_ary_bsearch_index(ary);
3626 return index_result;
3643rb_ary_bsearch_index(
VALUE ary)
3646 int smaller = 0, satisfied = 0;
3650 while (low < high) {
3651 mid = low + ((high - low) / 2);
3658 else if (v ==
Qtrue) {
3662 else if (!
RTEST(v)) {
3667 switch (rb_cmpint(rb_funcallv(v, id_cmp, 1, &zero), v, zero)) {
3669 case 1: smaller = 0;
break;
3670 case -1: smaller = 1;
3675 " (must be numeric, true, false or nil)",
3685 if (!satisfied)
return Qnil;
3719rb_ary_sort_by_bang(
VALUE ary)
3726 sorted =
rb_block_call(ary, rb_intern(
"sort_by"), 0, 0, sort_by_i, 0);
3754rb_ary_collect(
VALUE ary)
3789rb_ary_collect_bang(
VALUE ary)
3805 long beg,
len, i, j;
3807 for (i=0; i<argc; i++) {
3814 long end = olen < beg+
len ? olen : beg+
len;
3815 for (j = beg; j < end; j++) {
3838 const long end = beg +
len;
3962rb_ary_values_at(
int argc,
VALUE *argv,
VALUE ary)
3966 for (i = 0; i < argc; ++i) {
3967 append_values_at_single(result, ary, olen, argv[i]);
3995rb_ary_select(
VALUE ary)
4010struct select_bang_arg {
4016select_bang_i(
VALUE a)
4018 volatile struct select_bang_arg *arg = (
void *)a;
4019 VALUE ary = arg->ary;
4022 for (i1 = i2 = 0; i1 <
RARRAY_LEN(ary); arg->len[0] = ++i1) {
4030 return (i1 == i2) ?
Qnil : ary;
4034select_bang_ensure(
VALUE a)
4036 volatile struct select_bang_arg *arg = (
void *)a;
4037 VALUE ary = arg->ary;
4039 long i1 = arg->len[0], i2 = arg->len[1];
4041 if (i2 <
len && i2 < i1) {
4050 ARY_SET_LEN(ary, i2 + tail);
4078rb_ary_select_bang(
VALUE ary)
4080 struct select_bang_arg args;
4086 args.len[0] = args.len[1] = 0;
4107rb_ary_keep_if(
VALUE ary)
4110 rb_ary_select_bang(ary);
4115ary_resize_smaller(
VALUE ary,
long len)
4119 ARY_SET_LEN(ary,
len);
4120 if (
len * 2 < ARY_CAPA(ary) &&
4121 ARY_CAPA(ary) > ARY_DEFAULT_SIZE) {
4122 ary_resize_capa(ary,
len * 2);
4170 for (i1 = i2 = 0; i1 <
RARRAY_LEN(ary); i1++) {
4189 ary_resize_smaller(ary, i2);
4200 for (i1 = i2 = 0; i1 <
RARRAY_LEN(ary); i1++) {
4215 ary_resize_smaller(ary, i2);
4227 if (pos < 0)
return Qnil;
4235 ARY_INCREASE_LEN(ary, -1);
4275ary_slice_bang_by_rb_ary_splice(
VALUE ary,
long pos,
long len)
4282 else if (pos < -orig_len) {
4288 else if (orig_len < pos) {
4291 if (orig_len < pos +
len) {
4292 len = orig_len - pos;
4299 rb_ary_splice(ary, pos,
len, 0, 0, FALSE);
4397rb_ary_slice_bang(
int argc,
VALUE *argv,
VALUE ary)
4402 rb_ary_modify_check(ary);
4403 rb_check_arity(argc, 1, 2);
4409 return ary_slice_bang_by_rb_ary_splice(ary, pos,
len);
4416 return ary_slice_bang_by_rb_ary_splice(ary, pos,
len);
4445reject_bang_i(
VALUE a)
4447 volatile struct select_bang_arg *arg = (
void *)a;
4448 VALUE ary = arg->ary;
4451 for (i1 = i2 = 0; i1 <
RARRAY_LEN(ary); arg->len[0] = ++i1) {
4459 return (i1 == i2) ?
Qnil : ary;
4463ary_reject_bang(
VALUE ary)
4465 struct select_bang_arg args;
4466 rb_ary_modify_check(ary);
4468 args.len[0] = args.len[1] = 0;
4493rb_ary_reject_bang(
VALUE ary)
4497 return ary_reject_bang(ary);
4518rb_ary_reject(
VALUE ary)
4524 ary_reject(ary, rejected_ary);
4525 return rejected_ary;
4546rb_ary_delete_if(
VALUE ary)
4550 ary_reject_bang(ary);
4565take_items(
VALUE obj,
long n)
4570 if (n == 0)
return result;
4573 args[0] = result; args[1] = (
VALUE)n;
4574 if (UNDEF_P(rb_check_block_call(obj, idEach, 0, 0, take_i, (
VALUE)args)))
4575 rb_raise(
rb_eTypeError,
"wrong argument type %"PRIsVALUE
" (must respond to :each)",
4681 for (i=0; i<argc; i++) {
4682 argv[i] = take_items(argv[i],
len);
4686 int arity = rb_block_arity();
4695 for (j=0; j<argc; j++) {
4696 tmp[j+1] = rb_ary_elt(argv[j], i);
4708 for (j=0; j<argc; j++) {
4718 for (i=0; i<
len; i++) {
4722 for (j=0; j<argc; j++) {
4748rb_ary_transpose(
VALUE ary)
4750 long elen = -1, alen, i, j;
4751 VALUE tmp, result = 0;
4755 for (i=0; i<alen; i++) {
4756 tmp = to_ary(rb_ary_elt(ary, i));
4760 for (j=0; j<elen; j++) {
4765 rb_raise(
rb_eIndexError,
"element size differs (%ld should be %ld)",
4768 for (j=0; j<elen; j++) {
4769 rb_ary_store(rb_ary_elt(result, j), i, rb_ary_elt(tmp, j));
4793 rb_ary_modify_check(copy);
4794 orig = to_ary(orig);
4795 if (copy == orig)
return copy;
4800 if (
RARRAY_LEN(orig) <= ary_embed_capa(copy)) {
4807 else if (ARY_EMBED_P(orig)) {
4808 long len = ARY_EMBED_LEN(orig);
4811 FL_UNSET_EMBED(copy);
4812 ARY_SET_PTR(copy,
ptr);
4813 ARY_SET_LEN(copy,
len);
4814 ARY_SET_CAPA(copy,
len);
4823 VALUE shared_root = ary_make_shared(orig);
4824 FL_UNSET_EMBED(copy);
4825 ARY_SET_PTR(copy, ARY_HEAP_PTR(orig));
4826 ARY_SET_LEN(copy, ARY_HEAP_LEN(orig));
4827 rb_ary_set_shared(copy, shared_root);
4850 rb_ary_modify_check(ary);
4851 if (ARY_SHARED_P(ary)) {
4852 rb_ary_unshare(ary);
4854 ARY_SET_EMBED_LEN(ary, 0);
4857 ARY_SET_LEN(ary, 0);
4858 if (ARY_DEFAULT_SIZE * 2 < ARY_CAPA(ary)) {
4859 ary_resize_capa(ary, ARY_DEFAULT_SIZE * 2);
5050 long beg = 0, end = 0,
len = 0;
5073 if (beg < 0) beg = 0;
5082 if (beg >= ARY_MAX_SIZE ||
len > ARY_MAX_SIZE - beg) {
5083 rb_raise(rb_eArgError,
"argument too big");
5087 if (end >= ARY_CAPA(ary)) {
5088 ary_resize_capa(ary, end);
5091 ARY_SET_LEN(ary, end);
5094 if (UNDEF_P(item)) {
5098 for (i=beg; i<end; i++) {
5105 ary_memfill(ary, beg,
len, item);
5127 long len, xlen, ylen;
5137 ARY_SET_LEN(z,
len);
5166rb_ary_concat_multi(
int argc,
VALUE *argv,
VALUE ary)
5168 rb_ary_modify_check(ary);
5173 else if (argc > 1) {
5176 for (i = 0; i < argc; i++) {
5179 ary_append(ary, args);
5189 return ary_append(x, to_ary(y));
5228 rb_raise(rb_eArgError,
"negative argument");
5231 rb_raise(rb_eArgError,
"argument too big");
5236 ARY_SET_LEN(ary2,
len);
5241 ary_memcpy(ary2, 0, t,
ptr);
5242 while (t <=
len/2) {
5319recursive_equal(
VALUE ary1,
VALUE ary2,
int recur)
5322 const VALUE *p1, *p2;
5324 if (recur)
return Qtrue;
5331 for (i = 0; i < len1; i++) {
5379 if (ary1 == ary2)
return Qtrue;
5380 if (!RB_TYPE_P(ary2,
T_ARRAY)) {
5392recursive_eql(
VALUE ary1,
VALUE ary2,
int recur)
5396 if (recur)
return Qtrue;
5398 if (!
rb_eql(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
5426 if (ary1 == ary2)
return Qtrue;
5434ary_hash_values(
long len,
const VALUE *elements,
const VALUE ary)
5442 for (i=0; i<
len; i++) {
5443 n = rb_hash(elements[i]);
5455rb_ary_hash_values(
long len,
const VALUE *elements)
5457 return ary_hash_values(
len, elements, 0);
5476rb_ary_hash(
VALUE ary)
5527recursive_cmp(
VALUE ary1,
VALUE ary2,
int recur)
5531 if (recur)
return Qundef;
5536 for (i=0; i<
len; i++) {
5537 VALUE e1 = rb_ary_elt(ary1, i), e2 = rb_ary_elt(ary2, i);
5538 VALUE v = rb_funcallv(e1, id_cmp, 1, &e2);
5592 if (ary1 == ary2)
return INT2FIX(0);
5594 if (!UNDEF_P(v))
return v;
5608 rb_hash_add_new_element(hash, elt, elt);
5614ary_tmp_hash_new(
VALUE ary)
5617 VALUE hash = rb_hash_new_with_size(size);
5619 RBASIC_CLEAR_CLASS(hash);
5624ary_make_hash(
VALUE ary)
5626 VALUE hash = ary_tmp_hash_new(ary);
5627 return ary_add_hash(hash, ary);
5637 rb_hash_add_new_element(hash, k, v);
5643ary_make_hash_by(
VALUE ary)
5645 VALUE hash = ary_tmp_hash_new(ary);
5646 return ary_add_hash_by(hash, ary);
5674 ary2 = to_ary(ary2);
5675 if (
RARRAY_LEN(ary2) == 0) {
return ary_make_shared_copy(ary1); }
5680 VALUE elt = rb_ary_elt(ary1, i);
5681 if (rb_ary_includes_by_eql(ary2, elt))
continue;
5687 hash = ary_make_hash(ary2);
5689 if (rb_hash_stlike_lookup(hash,
RARRAY_AREF(ary1, i), NULL))
continue;
5716rb_ary_difference_multi(
int argc,
VALUE *argv,
VALUE ary)
5721 bool *is_hash =
ALLOCV_N(
bool, t0, argc);
5725 for (i = 0; i < argc; i++) {
5726 argv[i] = to_ary(argv[i]);
5727 is_hash[i] = (length > SMALL_ARRAY_LEN &&
RARRAY_LEN(argv[i]) > SMALL_ARRAY_LEN);
5728 if (is_hash[i]) argv[i] = ary_make_hash(argv[i]);
5733 VALUE elt = rb_ary_elt(ary, i);
5734 for (j = 0; j < argc; j++) {
5736 if (rb_hash_stlike_lookup(argv[j], elt, NULL))
5740 if (rb_ary_includes_by_eql(argv[j], elt))
break;
5779 VALUE hash, ary3, v;
5783 ary2 = to_ary(ary2);
5790 if (!rb_ary_includes_by_eql(ary2, v))
continue;
5791 if (rb_ary_includes_by_eql(ary3, v))
continue;
5797 hash = ary_make_hash(ary2);
5802 if (rb_hash_stlike_delete(hash, &vv, 0)) {
5832rb_ary_intersection_multi(
int argc,
VALUE *argv,
VALUE ary)
5837 for (i = 0; i < argc; i++) {
5838 result = rb_ary_and(result, argv[i]);
5845ary_hash_orset(st_data_t *key, st_data_t *value, st_data_t arg,
int existing)
5847 if (existing)
return ST_STOP;
5848 *key = *value = (
VALUE)arg;
5857 VALUE elt = rb_ary_elt(ary, i);
5858 if (rb_ary_includes_by_eql(ary_union, elt))
continue;
5869 if (!rb_hash_stlike_update(hash, (st_data_t)elt, ary_hash_orset, (st_data_t)elt)) {
5895 ary2 = to_ary(ary2);
5898 rb_ary_union(ary3, ary1);
5899 rb_ary_union(ary3, ary2);
5903 hash = ary_make_hash(ary1);
5904 rb_ary_union_hash(hash, ary2);
5906 return rb_hash_values(hash);
5933rb_ary_union_multi(
int argc,
VALUE *argv,
VALUE ary)
5940 for (i = 0; i < argc; i++) {
5941 argv[i] = to_ary(argv[i]);
5945 if (sum <= SMALL_ARRAY_LEN) {
5948 rb_ary_union(ary_union, ary);
5949 for (i = 0; i < argc; i++) rb_ary_union(ary_union, argv[i]);
5954 hash = ary_make_hash(ary);
5955 for (i = 0; i < argc; i++) rb_ary_union_hash(hash, argv[i]);
5957 return rb_hash_values(hash);
5977 VALUE hash, v, result, shorter, longer;
5981 ary2 = to_ary(ary2);
5987 if (rb_ary_includes_by_eql(ary2, v))
return Qtrue;
5999 hash = ary_make_hash(shorter);
6005 if (rb_hash_stlike_lookup(hash, vv, 0)) {
6015ary_max_generic(
VALUE ary,
long i,
VALUE vmax)
6023 if (rb_cmpint(rb_funcallv(vmax, id_cmp, 1, &v), vmax, v) < 0) {
6032ary_max_opt_fixnum(
VALUE ary,
long i,
VALUE vmax)
6039 for (; i < n; ++i) {
6043 if ((
long)vmax < (
long)v) {
6048 return ary_max_generic(ary, i, vmax);
6056ary_max_opt_float(
VALUE ary,
long i,
VALUE vmax)
6063 for (; i < n; ++i) {
6066 if (RB_FLOAT_TYPE_P(v)) {
6067 if (rb_float_cmp(vmax, v) < 0) {
6072 return ary_max_generic(ary, i, vmax);
6080ary_max_opt_string(
VALUE ary,
long i,
VALUE vmax)
6087 for (; i < n; ++i) {
6096 return ary_max_generic(ary, i, vmax);
6158 if (rb_check_arity(argc, 0, 1) && !
NIL_P(num = argv[0]))
6159 return rb_nmin_run(ary, num, 0, 1, 1);
6165 if (UNDEF_P(result) || rb_cmpint(
rb_yield_values(2, v, result), v, result) > 0) {
6173 if (
FIXNUM_P(result) && CMP_OPTIMIZABLE(INTEGER)) {
6174 return ary_max_opt_fixnum(ary, 1, result);
6176 else if (STRING_P(result) && CMP_OPTIMIZABLE(STRING)) {
6177 return ary_max_opt_string(ary, 1, result);
6179 else if (RB_FLOAT_TYPE_P(result) && CMP_OPTIMIZABLE(FLOAT)) {
6180 return ary_max_opt_float(ary, 1, result);
6183 return ary_max_generic(ary, 1, result);
6187 if (UNDEF_P(result))
return Qnil;
6192ary_min_generic(
VALUE ary,
long i,
VALUE vmin)
6200 if (rb_cmpint(rb_funcallv(vmin, id_cmp, 1, &v), vmin, v) > 0) {
6209ary_min_opt_fixnum(
VALUE ary,
long i,
VALUE vmin)
6216 for (; i < n; ++i) {
6220 if ((
long)vmin > (
long)a) {
6225 return ary_min_generic(ary, i, vmin);
6233ary_min_opt_float(
VALUE ary,
long i,
VALUE vmin)
6240 for (; i < n; ++i) {
6243 if (RB_FLOAT_TYPE_P(a)) {
6244 if (rb_float_cmp(vmin, a) > 0) {
6249 return ary_min_generic(ary, i, vmin);
6257ary_min_opt_string(
VALUE ary,
long i,
VALUE vmin)
6264 for (; i < n; ++i) {
6273 return ary_min_generic(ary, i, vmin);
6335 if (rb_check_arity(argc, 0, 1) && !
NIL_P(num = argv[0]))
6336 return rb_nmin_run(ary, num, 0, 0, 1);
6342 if (UNDEF_P(result) || rb_cmpint(
rb_yield_values(2, v, result), v, result) < 0) {
6350 if (
FIXNUM_P(result) && CMP_OPTIMIZABLE(INTEGER)) {
6351 return ary_min_opt_fixnum(ary, 1, result);
6353 else if (STRING_P(result) && CMP_OPTIMIZABLE(STRING)) {
6354 return ary_min_opt_string(ary, 1, result);
6356 else if (RB_FLOAT_TYPE_P(result) && CMP_OPTIMIZABLE(FLOAT)) {
6357 return ary_min_opt_float(ary, 1, result);
6360 return ary_min_generic(ary, 1, result);
6364 if (UNDEF_P(result))
return Qnil;
6391rb_ary_minmax(
VALUE ary)
6396 return rb_assoc_new(rb_ary_min(0, 0, ary), rb_ary_max(0, 0, ary));
6400push_value(st_data_t key, st_data_t val, st_data_t ary)
6434rb_ary_uniq_bang(
VALUE ary)
6439 rb_ary_modify_check(ary);
6443 hash = ary_make_hash_by(ary);
6445 hash = ary_make_hash(ary);
6451 rb_ary_modify_check(ary);
6452 ARY_SET_LEN(ary, 0);
6453 if (ARY_SHARED_P(ary)) {
6454 rb_ary_unshare(ary);
6457 ary_resize_capa(ary, hash_size);
6458 rb_hash_foreach(hash, push_value, ary);
6490rb_ary_uniq(
VALUE ary)
6499 hash = ary_make_hash_by(ary);
6500 uniq = rb_hash_values(hash);
6503 hash = ary_make_hash(ary);
6504 uniq = rb_hash_values(hash);
6527rb_ary_compact_bang(
VALUE ary)
6544 ary_resize_smaller(ary, n);
6564rb_ary_compact(
VALUE ary)
6567 rb_ary_compact_bang(ary);
6599rb_ary_count(
int argc,
VALUE *argv,
VALUE ary)
6603 if (rb_check_arity(argc, 0, 1) == 0) {
6615 VALUE obj = argv[0];
6618 rb_warn(
"given block not used");
6629flatten(
VALUE ary,
int level)
6632 VALUE stack, result, tmp = 0, elt;
6648 ARY_SET_LEN(result, i);
6650 stack = ary_new(0, ARY_DEFAULT_SIZE);
6656 rb_hash_aset(memo, ary,
Qtrue);
6657 rb_hash_aset(memo, tmp,
Qtrue);
6666 if (level >= 0 &&
RARRAY_LEN(stack) / 2 >= level) {
6671 if (
RBASIC(result)->klass) {
6673 rb_hash_clear(memo);
6682 if (rb_hash_aref(memo, tmp) ==
Qtrue) {
6683 rb_hash_clear(memo);
6684 rb_raise(rb_eArgError,
"tried to flatten recursive array");
6686 rb_hash_aset(memo, tmp,
Qtrue);
6698 rb_hash_delete(memo, ary);
6706 rb_hash_clear(memo);
6749rb_ary_flatten_bang(
int argc,
VALUE *argv,
VALUE ary)
6751 int mod = 0, level = -1;
6754 lv = (rb_check_arity(argc, 0, 1) ? argv[0] :
Qnil);
6755 rb_ary_modify_check(ary);
6757 if (level == 0)
return Qnil;
6759 result = flatten(ary, level);
6760 if (result == ary) {
6765 if (mod) ARY_SET_EMBED_LEN(result, 0);
6806rb_ary_flatten(
int argc,
VALUE *argv,
VALUE ary)
6811 if (rb_check_arity(argc, 0, 1) && !
NIL_P(argv[0])) {
6813 if (level == 0)
return ary_make_shared_copy(ary);
6816 result = flatten(ary, level);
6817 if (result == ary) {
6818 result = ary_make_shared_copy(ary);
6824#define RAND_UPTO(max) (long)rb_random_ulong_limited((randgen), (max)-1)
6827rb_ary_shuffle_bang(rb_execution_context_t *ec,
VALUE ary,
VALUE randgen)
6835 long j = RAND_UPTO(i);
6849rb_ary_shuffle(rb_execution_context_t *ec,
VALUE ary,
VALUE randgen)
6852 rb_ary_shuffle_bang(ec, ary, randgen);
6857 .wrap_struct_name =
"ary_sample_memo",
6861 .flags = RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY
6868 long n,
len, i, j, k, idx[10];
6869 long rnds[numberof(idx)];
6870 long memo_threshold;
6879 return rb_ary_elt(ary, i);
6882 if (n < 0) rb_raise(rb_eArgError,
"negative sample number");
6884 if (n <= numberof(idx)) {
6885 for (i = 0; i < n; ++i) {
6886 rnds[i] = RAND_UPTO(
len - i);
6891 if (
len < k && n <= numberof(idx)) {
6892 for (i = 0; i < n; ++i) {
6902 return rb_ary_new_from_args(1,
RARRAY_AREF(ary, i));
6914 if (j >= i) l = i, g = ++j;
6915 if (k >= l && (++k >= g)) ++k;
6924 if (n <= numberof(idx)) {
6925 long sorted[numberof(idx)];
6926 sorted[0] = idx[0] = rnds[0];
6927 for (i=1; i<n; i++) {
6929 for (j = 0; j < i; ++j) {
6930 if (k < sorted[j])
break;
6933 memmove(&sorted[j+1], &sorted[j],
sizeof(sorted[0])*(i-j));
6934 sorted[j] = idx[i] = k;
6938 for (i=0; i<n; i++) {
6943 else if (n <= memo_threshold / 2) {
6946 st_table *memo = st_init_numtable_with_size(n);
6950 for (i=0; i<n; i++) {
6951 long r = RAND_UPTO(
len-i) + i;
6953 if (r > max_idx) max_idx = r;
6956 if (
len <= max_idx) n = 0;
6957 else if (n >
len) n =
len;
6959 for (i=0; i<n; i++) {
6960 long j2 = j = ptr_result[i];
6963 if (st_lookup(memo, (st_data_t)i, &value)) i2 = (long)value;
6964 if (st_lookup(memo, (st_data_t)j, &value)) j2 = (long)value;
6965 st_insert(memo, (st_data_t)j, (st_data_t)i2);
6966 ptr_result[i] = ptr_ary[j2];
6971 st_free_table(memo);
6976 RBASIC_CLEAR_CLASS(result);
6979 for (i=0; i<n; i++) {
6980 j = RAND_UPTO(
len-i) + i;
6982 ptr_result[j] = ptr_result[i];
6986 RBASIC_SET_CLASS_RAW(result,
rb_cArray);
6988 ARY_SET_LEN(result, n);
6994ary_sized_alloc(rb_execution_context_t *ec,
VALUE self)
7000ary_sample0(rb_execution_context_t *ec,
VALUE ary)
7016 if (mul <= 0)
return INT2FIX(0);
7018 return rb_fix_mul_fix(rb_ary_length(self), n);
7055rb_ary_cycle(
int argc,
VALUE *argv,
VALUE ary)
7059 rb_check_arity(argc, 0, 1);
7062 if (argc == 0 ||
NIL_P(argv[0])) {
7067 if (n <= 0)
return Qnil;
7070 while (
RARRAY_LEN(ary) > 0 && (n < 0 || 0 < n--)) {
7084yield_indexed_values(
const VALUE values,
const long r,
const long *
const p)
7089 for (i = 0; i < r; i++) ARY_SET(result, i,
RARRAY_AREF(values, p[i]));
7090 ARY_SET_LEN(result, r);
7092 return !
RBASIC(values)->klass;
7108permute0(
const long n,
const long r,
long *
const p,
char *
const used,
const VALUE values)
7110 long i = 0, index = 0;
7113 const char *
const unused = memchr(&used[i], 0, n-i);
7128 for (i = 0; i < n; ++i) {
7129 if (used[i])
continue;
7131 if (!yield_indexed_values(values, r, p)) {
7147descending_factorial(
long from,
long how_many)
7152 while (--how_many > 0) {
7154 cnt = rb_int_mul(cnt,
LONG2FIX(v));
7164binomial_coefficient(
long comb,
long size)
7168 if (comb > size-comb) {
7174 else if (comb == 0) {
7178 for (i = 1; i < comb; ++i) {
7179 r = rb_int_mul(r,
LONG2FIX(size - i));
7180 r = rb_int_idiv(r,
LONG2FIX(i + 1));
7191 return descending_factorial(n, k);
7237rb_ary_permutation(
int argc,
VALUE *argv,
VALUE ary)
7244 if (rb_check_arity(argc, 0, 1) && !
NIL_P(argv[0]))
7247 if (r < 0 || n < r) {
7260 long *p =
ALLOCV_N(
long, t0, r+roomof(n,
sizeof(
long)));
7261 char *used = (
char*)(p + r);
7262 VALUE ary0 = ary_make_shared_copy(ary);
7263 RBASIC_CLEAR_CLASS(ary0);
7267 permute0(n, r, p, used, ary0);
7275combinate0(
const long len,
const long n,
long *
const stack,
const VALUE values)
7282 for (lev++; lev < n; lev++) {
7283 stack[lev+1] = stack[lev]+1;
7285 if (!yield_indexed_values(values, n, stack+1)) {
7289 if (lev == 0)
return;
7291 }
while (stack[lev+1]+n ==
len+lev+1);
7301 return binomial_coefficient(k, n);
7356 if (n < 0 ||
len < n) {
7368 VALUE ary0 = ary_make_shared_copy(ary);
7370 long *stack =
ALLOCV_N(
long, t0, n+1);
7372 RBASIC_CLEAR_CLASS(ary0);
7373 combinate0(
len, n, stack, ary0);
7393rpermute0(
const long n,
const long r,
long *
const p,
const VALUE values)
7395 long i = 0, index = 0;
7399 if (++index < r-1) {
7403 for (i = 0; i < n; ++i) {
7405 if (!yield_indexed_values(values, r, p)) {
7410 if (index <= 0)
return;
7411 }
while ((i = ++p[--index]) >= n);
7469rb_ary_repeated_permutation(
VALUE ary,
VALUE num)
7491 VALUE ary0 = ary_make_shared_copy(ary);
7492 RBASIC_CLEAR_CLASS(ary0);
7494 rpermute0(n, r, p, ary0);
7502rcombinate0(
const long n,
const long r,
long *
const p,
const long rest,
const VALUE values)
7504 long i = 0, index = 0;
7508 if (++index < r-1) {
7512 for (; i < n; ++i) {
7514 if (!yield_indexed_values(values, r, p)) {
7519 if (index <= 0)
return;
7520 }
while ((i = ++p[--index]) >= n);
7532 return binomial_coefficient(k, n + k - 1);
7575rb_ary_repeated_combination(
VALUE ary,
VALUE num)
7593 else if (
len == 0) {
7599 VALUE ary0 = ary_make_shared_copy(ary);
7600 RBASIC_CLEAR_CLASS(ary0);
7602 rcombinate0(
len, n, p, n, ary0);
7663rb_ary_product(
int argc,
VALUE *argv,
VALUE ary)
7668 VALUE *arrays = RARRAY_PTR(t0);
7669 int *counters =
ALLOCV_N(
int, t1, n);
7674 RBASIC_CLEAR_CLASS(t0);
7679 for (i = 1; i < n; i++) arrays[i] =
Qnil;
7680 for (i = 1; i < n; i++) arrays[i] = to_ary(argv[i-1]);
7683 for (i = 0; i < n; i++) counters[i] = 0;
7688 for (i = 0; i < n; i++) {
7690 arrays[i] = ary_make_shared_copy(arrays[i]);
7695 for (i = 0; i < n; i++) {
7701 if (MUL_OVERFLOW_LONG_P(resultlen, k))
7711 for (j = 0; j < n; j++) {
7716 if (
NIL_P(result)) {
7717 FL_SET(t0, RARRAY_SHARED_ROOT_FLAG);
7719 if (!
FL_TEST(t0, RARRAY_SHARED_ROOT_FLAG)) {
7723 FL_UNSET(t0, RARRAY_SHARED_ROOT_FLAG);
7736 while (counters[m] ==
RARRAY_LEN(arrays[m])) {
7739 if (--m < 0)
goto done;
7747 return NIL_P(result) ? ary : result;
7773 rb_raise(rb_eArgError,
"attempt to take negative size");
7800rb_ary_take_while(
VALUE ary)
7808 return rb_ary_take(ary,
LONG2FIX(i));
7836 rb_raise(rb_eArgError,
"attempt to drop negative size");
7863rb_ary_drop_while(
VALUE ary)
7871 return rb_ary_drop(ary,
LONG2FIX(i));
7914rb_ary_any_p(
int argc,
VALUE *argv,
VALUE ary)
7918 rb_check_arity(argc, 0, 1);
7922 rb_warn(
"given block not used");
7929 for (i = 0; i <
len; ++i) {
7981rb_ary_all_p(
int argc,
VALUE *argv,
VALUE ary)
7985 rb_check_arity(argc, 0, 1);
7989 rb_warn(
"given block not used");
7996 for (i = 0; i <
len; ++i) {
8042rb_ary_none_p(
int argc,
VALUE *argv,
VALUE ary)
8046 rb_check_arity(argc, 0, 1);
8050 rb_warn(
"given block not used");
8057 for (i = 0; i <
len; ++i) {
8106rb_ary_one_p(
int argc,
VALUE *argv,
VALUE ary)
8111 rb_check_arity(argc, 0, 1);
8115 rb_warn(
"given block not used");
8119 if (result)
return Qfalse;
8125 for (i = 0; i <
len; ++i) {
8127 if (result)
return Qfalse;
8135 if (result)
return Qfalse;
8167 self = rb_ary_at(self, *argv);
8168 if (!--argc)
return self;
8170 return rb_obj_dig(argc, argv, self,
Qnil);
8174finish_exact_sum(
long n,
VALUE r,
VALUE v,
int z)
8179 v = rb_rational_plus(r, v);
8235 v = (rb_check_arity(argc, 0, 1) ? argv[0] :
LONG2FIX(0));
8245 bool init_is_float = RB_FLOAT_TYPE_P(v);
8246 if (init_is_float) {
8251 goto init_is_a_value;
8265 else if (RB_BIGNUM_TYPE_P(e))
8266 v = rb_big_plus(e, v);
8271 r = rb_rational_plus(r, e);
8276 v = finish_exact_sum(n, r, v, argc!=0);
8277 if (init_is_float) v = rb_float_plus(argv[0], v);
8281 v = finish_exact_sum(n, r, v, i!=0);
8283 if (init_is_float ? (--i, e = argv[0],
true) : RB_FLOAT_TYPE_P(e)) {
8293 goto has_float_value;
8298 if (RB_FLOAT_TYPE_P(e))
8303 else if (RB_BIGNUM_TYPE_P(e))
8310 if (isnan(f))
continue;
8316 if (isinf(f) && signbit(x) != signbit(f))
8322 if (isinf(f))
continue;
8325 if (fabs(f) >= fabs(x))
8338 goto has_some_value;
8352rb_ary_deconstruct(
VALUE ary)
8863 fake_ary_flags = init_fake_ary_flags();
8993 rb_vm_register_global_object(rb_cArray_empty_frozen);
8996#include "array.rbinc"
#define RUBY_ASSERT_ALWAYS(expr,...)
A variant of RUBY_ASSERT that does not interface with RUBY_DEBUG.
#define RBIMPL_ASSERT_OR_ASSUME(...)
This is either RUBY_ASSERT or RBIMPL_ASSUME, depending on RUBY_DEBUG.
#define RUBY_ASSERT(...)
Asserts that the given expression is truthy if and only if RUBY_DEBUG is truthy.
#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 RB_INTEGER_TYPE_P
Old name of rb_integer_type_p.
#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 OBJ_FREEZE
Old name of RB_OBJ_FREEZE.
#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 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.
VALUE rb_ensure(VALUE(*b_proc)(VALUE), VALUE data1, VALUE(*e_proc)(VALUE), VALUE data2)
An equivalent to ensure clause.
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_obj_hide(VALUE obj)
Make the object invisible from Ruby code.
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.
VALUE rb_obj_freeze(VALUE obj)
Just calls rb_obj_freeze_inline() inside.
#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.
VALUE rb_ary_rotate(VALUE ary, long rot)
Destructively rotates the passed array in-place to towards its end.
VALUE rb_ary_new_from_values(long n, const VALUE *elts)
Identical to rb_ary_new_from_args(), except how objects are passed.
VALUE rb_ary_cmp(VALUE lhs, VALUE rhs)
Recursively compares each elements of the two arrays one-by-one using <=>.
VALUE rb_ary_rassoc(VALUE alist, VALUE key)
Identical to rb_ary_assoc(), except it scans the passed array from the opposite direction.
VALUE rb_ary_concat(VALUE lhs, VALUE rhs)
Destructively appends the contents of latter into the end of former.
VALUE rb_ary_assoc(VALUE alist, VALUE key)
Looks up the passed key, assuming the passed array is an alist.
VALUE rb_ary_reverse(VALUE ary)
Destructively reverses the passed array in-place.
VALUE rb_ary_shared_with_p(VALUE lhs, VALUE rhs)
Queries if the passed two arrays share the same backend storage.
VALUE rb_ary_shift(VALUE ary)
Destructively deletes an element from the beginning of the passed array and returns what was deleted.
VALUE rb_ary_sort(VALUE ary)
Creates a copy of the passed array, whose elements are sorted according to their <=> result.
VALUE rb_ary_resurrect(VALUE ary)
I guess there is no use case of this function in extension libraries, but this is a routine identical...
VALUE rb_ary_dup(VALUE ary)
Duplicates an array.
VALUE rb_ary_includes(VALUE ary, VALUE elem)
Queries if the passed array has the passed entry.
VALUE rb_ary_aref(int argc, const VALUE *argv, VALUE ary)
Queries element(s) of an array.
VALUE rb_get_values_at(VALUE obj, long olen, int argc, const VALUE *argv, VALUE(*func)(VALUE obj, long oidx))
This was a generalisation of Array#values_at, Struct#values_at, and MatchData#values_at.
void rb_ary_free(VALUE ary)
Destroys the given array for no reason.
VALUE rb_ary_each(VALUE ary)
Iteratively yields each element of the passed array to the implicitly passed block if any.
VALUE rb_ary_delete_at(VALUE ary, long pos)
Destructively removes an element which resides at the specific index of the passed array.
VALUE rb_ary_plus(VALUE lhs, VALUE rhs)
Creates a new array, concatenating the former to the latter.
VALUE rb_ary_cat(VALUE ary, const VALUE *train, long len)
Destructively appends multiple elements at the end of the array.
void rb_ary_modify(VALUE ary)
Declares that the array is about to be modified.
VALUE rb_ary_replace(VALUE copy, VALUE orig)
Replaces the contents of the former object with the contents of the latter.
VALUE rb_check_array_type(VALUE obj)
Try converting an object to its array representation using its to_ary method, if any.
VALUE rb_ary_to_ary(VALUE obj)
Force converts an object to an array.
VALUE rb_ary_new(void)
Allocates a new, empty array.
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_resize(VALUE ary, long len)
Expands or shrinks the passed array to the passed length.
VALUE rb_ary_pop(VALUE ary)
Destructively deletes an element from the end of the passed array and returns what was deleted.
VALUE rb_ary_hidden_new(long capa)
Allocates a hidden (no class) empty array.
VALUE rb_ary_clear(VALUE ary)
Destructively removes everything form an array.
VALUE rb_ary_subseq(VALUE ary, long beg, long len)
Obtains a part of the passed array.
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_to_s(VALUE ary)
Converts an array into a human-readable string.
VALUE rb_ary_entry(VALUE ary, long off)
Queries an element of an array.
VALUE rb_ary_sort_bang(VALUE ary)
Destructively sorts the passed array in-place, according to each elements' <=> result.
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Identical to rb_ary_new_from_values(), except it expects exactly two parameters.
void rb_mem_clear(VALUE *buf, long len)
Fills the memory region with a series of RUBY_Qnil.
VALUE rb_ary_delete(VALUE ary, VALUE elem)
Destructively removes elements from the passed array, so that there would be no elements inside that ...
VALUE rb_ary_join(VALUE ary, VALUE sep)
Recursively stringises the elements of the passed array, flattens that result, then joins the sequenc...
void rb_ary_store(VALUE ary, long key, VALUE val)
Destructively stores the passed value to the passed array's passed index.
#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().
VALUE rb_output_fs
The field separator character for outputs, or the $,.
VALUE rb_int_positive_pow(long x, unsigned long y)
Raises the passed x to the power of y.
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.
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.
void rb_str_set_len(VALUE str, long len)
Overwrites the length of the string.
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_str_buf_new(long capa)
Allocates a "string buffer".
VALUE rb_obj_as_string(VALUE obj)
Try converting an object to its stringised representation using its to_s method, if any.
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.
char * ptr
Pointer to the underlying memory region, of at least capa bytes.
int len
Length of the buffer.
#define RB_OBJ_SHAREABLE_P(obj)
Queries if the passed object has previously classified as shareable or not.
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.
#define RARRAY_LEN
Just another name of rb_array_len.
#define RARRAY(obj)
Convenient casting macro.
#define RARRAY_PTR_USE(ary, ptr_name, expr)
Declares a section of code where raw pointers are used.
#define RARRAY_AREF(a, i)
#define RARRAY_CONST_PTR
Just another name of rb_array_const_ptr.
#define RBASIC(obj)
Convenient casting macro.
void(*) RUBY_DATA_FUNC(void *)
This is the type of callbacks registered to RData.
#define RHASH_SIZE(h)
Queries the size of the hash.
#define StringValue(v)
Ensures that the parameter object is a String.
#define RTYPEDDATA_DATA(v)
Convenient getter macro.
#define TypedData_Wrap_Struct(klass, data_type, sval)
Converts sval, a pointer to your struct, into a Ruby object.
struct rb_data_type_struct rb_data_type_t
This is the struct that holds necessary info for a struct.
#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.
struct RBasic basic
Basic part, including flags and class.
VALUE flags
Per-object flags.
intptr_t SIGNED_VALUE
A signed integer type that has the same width with VALUE.
uintptr_t VALUE
Type that represents a Ruby object.