Ruby  3.4.0dev (2024-11-22 revision 801e66352e698eb533c535f600d958bc1e07e75e)
array.c (801e66352e698eb533c535f600d958bc1e07e75e)
1 /**********************************************************************
2 
3  array.c -
4 
5  $Author$
6  created at: Fri Aug 6 09:46:12 JST 1993
7 
8  Copyright (C) 1993-2007 Yukihiro Matsumoto
9  Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
10  Copyright (C) 2000 Information-technology Promotion Agency, Japan
11 
12 **********************************************************************/
13 
14 #include "debug_counter.h"
15 #include "id.h"
16 #include "internal.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"
27 #include "probes.h"
28 #include "ruby/encoding.h"
29 #include "ruby/st.h"
30 #include "ruby/util.h"
31 #include "vm_core.h"
32 #include "builtin.h"
33 
34 #if !ARRAY_DEBUG
35 # undef NDEBUG
36 # define NDEBUG
37 #endif
38 #include "ruby_assert.h"
39 
41 VALUE rb_cArray_empty_frozen;
42 
43 /* Flags of RArray
44  *
45  * 0: RARRAY_SHARED_FLAG (equal to ELTS_SHARED)
46  * The array is shared. The buffer this array points to is owned by
47  * another array (the shared root).
48  * 1: RARRAY_EMBED_FLAG
49  * The array is embedded (its contents follow the header, rather than
50  * being on a separately allocated buffer).
51  * 3-9: RARRAY_EMBED_LEN
52  * The length of the array when RARRAY_EMBED_FLAG is set.
53  * 12: RARRAY_SHARED_ROOT_FLAG
54  * The array is a shared root that does reference counting. The buffer
55  * this array points to is owned by this array but may be pointed to
56  * by other arrays.
57  * Note: Frozen arrays may be a shared root without this flag being
58  * set. Frozen arrays do not have reference counting because
59  * they cannot be modified. Not updating the reference count
60  * improves copy-on-write performance. Their reference count is
61  * assumed to be infinity.
62  * 14: RARRAY_PTR_IN_USE_FLAG
63  * The buffer of the array is in use. This is only used during
64  * debugging.
65  */
66 
67 /* for OPTIMIZED_CMP: */
68 #define id_cmp idCmp
69 
70 #define ARY_DEFAULT_SIZE 16
71 #define ARY_MAX_SIZE (LONG_MAX / (int)sizeof(VALUE))
72 #define SMALL_ARRAY_LEN 16
73 
75 static int
76 should_be_T_ARRAY(VALUE ary)
77 {
78  return RB_TYPE_P(ary, T_ARRAY);
79 }
80 
81 #define ARY_HEAP_PTR(a) (RUBY_ASSERT(!ARY_EMBED_P(a)), RARRAY(a)->as.heap.ptr)
82 #define ARY_HEAP_LEN(a) (RUBY_ASSERT(!ARY_EMBED_P(a)), RARRAY(a)->as.heap.len)
83 #define ARY_HEAP_CAPA(a) (RUBY_ASSERT(!ARY_EMBED_P(a)), RUBY_ASSERT(!ARY_SHARED_ROOT_P(a)), \
84  RARRAY(a)->as.heap.aux.capa)
85 
86 #define ARY_EMBED_PTR(a) (RUBY_ASSERT(ARY_EMBED_P(a)), RARRAY(a)->as.ary)
87 #define ARY_EMBED_LEN(a) \
88  (RUBY_ASSERT(ARY_EMBED_P(a)), \
89  (long)((RBASIC(a)->flags >> RARRAY_EMBED_LEN_SHIFT) & \
90  (RARRAY_EMBED_LEN_MASK >> RARRAY_EMBED_LEN_SHIFT)))
91 #define ARY_HEAP_SIZE(a) (RUBY_ASSERT(!ARY_EMBED_P(a)), RUBY_ASSERT(ARY_OWNS_HEAP_P(a)), ARY_CAPA(a) * sizeof(VALUE))
92 
93 #define ARY_OWNS_HEAP_P(a) (RUBY_ASSERT(should_be_T_ARRAY((VALUE)(a))), \
94  !FL_TEST_RAW((a), RARRAY_SHARED_FLAG|RARRAY_EMBED_FLAG))
95 
96 #define FL_SET_EMBED(a) do { \
97  RUBY_ASSERT(!ARY_SHARED_P(a)); \
98  FL_SET((a), RARRAY_EMBED_FLAG); \
99  ary_verify(a); \
100 } while (0)
101 
102 #define FL_UNSET_EMBED(ary) FL_UNSET((ary), RARRAY_EMBED_FLAG|RARRAY_EMBED_LEN_MASK)
103 #define FL_SET_SHARED(ary) do { \
104  RUBY_ASSERT(!ARY_EMBED_P(ary)); \
105  FL_SET((ary), RARRAY_SHARED_FLAG); \
106 } while (0)
107 #define FL_UNSET_SHARED(ary) FL_UNSET((ary), RARRAY_SHARED_FLAG)
108 
109 #define ARY_SET_PTR(ary, p) do { \
110  RUBY_ASSERT(!ARY_EMBED_P(ary)); \
111  RUBY_ASSERT(!OBJ_FROZEN(ary)); \
112  RARRAY(ary)->as.heap.ptr = (p); \
113 } while (0)
114 #define ARY_SET_EMBED_LEN(ary, n) do { \
115  long tmp_n = (n); \
116  RUBY_ASSERT(ARY_EMBED_P(ary)); \
117  RBASIC(ary)->flags &= ~RARRAY_EMBED_LEN_MASK; \
118  RBASIC(ary)->flags |= (tmp_n) << RARRAY_EMBED_LEN_SHIFT; \
119 } while (0)
120 #define ARY_SET_HEAP_LEN(ary, n) do { \
121  RUBY_ASSERT(!ARY_EMBED_P(ary)); \
122  RARRAY(ary)->as.heap.len = (n); \
123 } while (0)
124 #define ARY_SET_LEN(ary, n) do { \
125  if (ARY_EMBED_P(ary)) { \
126  ARY_SET_EMBED_LEN((ary), (n)); \
127  } \
128  else { \
129  ARY_SET_HEAP_LEN((ary), (n)); \
130  } \
131  RUBY_ASSERT(RARRAY_LEN(ary) == (n)); \
132 } while (0)
133 #define ARY_INCREASE_PTR(ary, n) do { \
134  RUBY_ASSERT(!ARY_EMBED_P(ary)); \
135  RUBY_ASSERT(!OBJ_FROZEN(ary)); \
136  RARRAY(ary)->as.heap.ptr += (n); \
137 } while (0)
138 #define ARY_INCREASE_LEN(ary, n) do { \
139  RUBY_ASSERT(!OBJ_FROZEN(ary)); \
140  if (ARY_EMBED_P(ary)) { \
141  ARY_SET_EMBED_LEN((ary), RARRAY_LEN(ary)+(n)); \
142  } \
143  else { \
144  RARRAY(ary)->as.heap.len += (n); \
145  } \
146 } while (0)
147 
148 #define ARY_CAPA(ary) (ARY_EMBED_P(ary) ? ary_embed_capa(ary) : \
149  ARY_SHARED_ROOT_P(ary) ? RARRAY_LEN(ary) : ARY_HEAP_CAPA(ary))
150 #define ARY_SET_CAPA(ary, n) do { \
151  RUBY_ASSERT(!ARY_EMBED_P(ary)); \
152  RUBY_ASSERT(!ARY_SHARED_P(ary)); \
153  RUBY_ASSERT(!OBJ_FROZEN(ary)); \
154  RARRAY(ary)->as.heap.aux.capa = (n); \
155 } while (0)
156 
157 #define ARY_SHARED_ROOT_OCCUPIED(ary) (!OBJ_FROZEN(ary) && ARY_SHARED_ROOT_REFCNT(ary) == 1)
158 #define ARY_SET_SHARED_ROOT_REFCNT(ary, value) do { \
159  RUBY_ASSERT(ARY_SHARED_ROOT_P(ary)); \
160  RUBY_ASSERT(!OBJ_FROZEN(ary)); \
161  RUBY_ASSERT((value) >= 0); \
162  RARRAY(ary)->as.heap.aux.capa = (value); \
163 } while (0)
164 #define FL_SET_SHARED_ROOT(ary) do { \
165  RUBY_ASSERT(!OBJ_FROZEN(ary)); \
166  RUBY_ASSERT(!ARY_EMBED_P(ary)); \
167  FL_SET((ary), RARRAY_SHARED_ROOT_FLAG); \
168 } while (0)
169 
170 static inline void
171 ARY_SET(VALUE a, long i, VALUE v)
172 {
173  RUBY_ASSERT(!ARY_SHARED_P(a));
174  RUBY_ASSERT(!OBJ_FROZEN(a));
175 
176  RARRAY_ASET(a, i, v);
177 }
178 #undef RARRAY_ASET
179 
180 static long
181 ary_embed_capa(VALUE ary)
182 {
183  size_t size = rb_gc_obj_slot_size(ary) - offsetof(struct RArray, as.ary);
184  RUBY_ASSERT(size % sizeof(VALUE) == 0);
185  return size / sizeof(VALUE);
186 }
187 
188 static size_t
189 ary_embed_size(long capa)
190 {
191  return offsetof(struct RArray, as.ary) + (sizeof(VALUE) * capa);
192 }
193 
194 static bool
195 ary_embeddable_p(long capa)
196 {
197  return rb_gc_size_allocatable_p(ary_embed_size(capa));
198 }
199 
200 bool
201 rb_ary_embeddable_p(VALUE ary)
202 {
203  /* An array cannot be turned embeddable when the array is:
204  * - Shared root: other objects may point to the buffer of this array
205  * so we cannot make it embedded.
206  * - Frozen: this array may also be a shared root without the shared root
207  * flag.
208  * - Shared: we don't want to re-embed an array that points to a shared
209  * root (to save memory).
210  */
211  return !(ARY_SHARED_ROOT_P(ary) || OBJ_FROZEN(ary) || ARY_SHARED_P(ary));
212 }
213 
214 size_t
215 rb_ary_size_as_embedded(VALUE ary)
216 {
217  size_t real_size;
218 
219  if (ARY_EMBED_P(ary)) {
220  real_size = ary_embed_size(ARY_EMBED_LEN(ary));
221  }
222  else if (rb_ary_embeddable_p(ary)) {
223  real_size = ary_embed_size(ARY_HEAP_CAPA(ary));
224  }
225  else {
226  real_size = sizeof(struct RArray);
227  }
228  return real_size;
229 }
230 
231 
232 #if ARRAY_DEBUG
233 #define ary_verify(ary) ary_verify_(ary, __FILE__, __LINE__)
234 
235 static VALUE
236 ary_verify_(VALUE ary, const char *file, int line)
237 {
239 
240  if (ARY_SHARED_P(ary)) {
241  VALUE root = ARY_SHARED_ROOT(ary);
242  const VALUE *ptr = ARY_HEAP_PTR(ary);
243  const VALUE *root_ptr = RARRAY_CONST_PTR(root);
244  long len = ARY_HEAP_LEN(ary), root_len = RARRAY_LEN(root);
245  RUBY_ASSERT(ARY_SHARED_ROOT_P(root) || OBJ_FROZEN(root));
246  RUBY_ASSERT(root_ptr <= ptr && ptr + len <= root_ptr + root_len);
247  ary_verify(root);
248  }
249  else if (ARY_EMBED_P(ary)) {
250  RUBY_ASSERT(!ARY_SHARED_P(ary));
251  RUBY_ASSERT(RARRAY_LEN(ary) <= ary_embed_capa(ary));
252  }
253  else {
254  const VALUE *ptr = RARRAY_CONST_PTR(ary);
255  long i, len = RARRAY_LEN(ary);
256  volatile VALUE v;
257  if (len > 1) len = 1; /* check only HEAD */
258  for (i=0; i<len; i++) {
259  v = ptr[i]; /* access check */
260  }
261  v = v;
262  }
263 
264  return ary;
265 }
266 
267 void
268 rb_ary_verify(VALUE ary)
269 {
270  ary_verify(ary);
271 }
272 #else
273 #define ary_verify(ary) ((void)0)
274 #endif
275 
276 VALUE *
277 rb_ary_ptr_use_start(VALUE ary)
278 {
279 #if ARRAY_DEBUG
280  FL_SET_RAW(ary, RARRAY_PTR_IN_USE_FLAG);
281 #endif
282  return (VALUE *)RARRAY_CONST_PTR(ary);
283 }
284 
285 void
286 rb_ary_ptr_use_end(VALUE ary)
287 {
288 #if ARRAY_DEBUG
289  FL_UNSET_RAW(ary, RARRAY_PTR_IN_USE_FLAG);
290 #endif
291 }
292 
293 void
294 rb_mem_clear(VALUE *mem, long size)
295 {
296  while (size--) {
297  *mem++ = Qnil;
298  }
299 }
300 
301 static void
302 ary_mem_clear(VALUE ary, long beg, long size)
303 {
305  rb_mem_clear(ptr + beg, size);
306  });
307 }
308 
309 static inline void
310 memfill(register VALUE *mem, register long size, register VALUE val)
311 {
312  while (size--) {
313  *mem++ = val;
314  }
315 }
316 
317 static void
318 ary_memfill(VALUE ary, long beg, long size, VALUE val)
319 {
321  memfill(ptr + beg, size, val);
322  RB_OBJ_WRITTEN(ary, Qundef, val);
323  });
324 }
325 
326 static void
327 ary_memcpy0(VALUE ary, long beg, long argc, const VALUE *argv, VALUE buff_owner_ary)
328 {
329  RUBY_ASSERT(!ARY_SHARED_P(buff_owner_ary));
330 
331  if (argc > (int)(128/sizeof(VALUE)) /* is magic number (cache line size) */) {
332  rb_gc_writebarrier_remember(buff_owner_ary);
334  MEMCPY(ptr+beg, argv, VALUE, argc);
335  });
336  }
337  else {
338  int i;
340  for (i=0; i<argc; i++) {
341  RB_OBJ_WRITE(buff_owner_ary, &ptr[i+beg], argv[i]);
342  }
343  });
344  }
345 }
346 
347 static void
348 ary_memcpy(VALUE ary, long beg, long argc, const VALUE *argv)
349 {
350  ary_memcpy0(ary, beg, argc, argv, ary);
351 }
352 
353 static VALUE *
354 ary_heap_alloc_buffer(size_t capa)
355 {
356  return ALLOC_N(VALUE, capa);
357 }
358 
359 static void
360 ary_heap_free_ptr(VALUE ary, const VALUE *ptr, long size)
361 {
362  ruby_sized_xfree((void *)ptr, size);
363 }
364 
365 static void
366 ary_heap_free(VALUE ary)
367 {
368  ary_heap_free_ptr(ary, ARY_HEAP_PTR(ary), ARY_HEAP_SIZE(ary));
369 }
370 
371 static size_t
372 ary_heap_realloc(VALUE ary, size_t new_capa)
373 {
375  SIZED_REALLOC_N(RARRAY(ary)->as.heap.ptr, VALUE, new_capa, ARY_HEAP_CAPA(ary));
376  ary_verify(ary);
377 
378  return new_capa;
379 }
380 
381 void
382 rb_ary_make_embedded(VALUE ary)
383 {
384  RUBY_ASSERT(rb_ary_embeddable_p(ary));
385  if (!ARY_EMBED_P(ary)) {
386  const VALUE *buf = ARY_HEAP_PTR(ary);
387  long len = ARY_HEAP_LEN(ary);
388 
389  FL_SET_EMBED(ary);
390  ARY_SET_EMBED_LEN(ary, len);
391 
392  MEMCPY((void *)ARY_EMBED_PTR(ary), (void *)buf, VALUE, len);
393 
394  ary_heap_free_ptr(ary, buf, len * sizeof(VALUE));
395  }
396 }
397 
398 static void
399 ary_resize_capa(VALUE ary, long capacity)
400 {
401  RUBY_ASSERT(RARRAY_LEN(ary) <= capacity);
403  RUBY_ASSERT(!ARY_SHARED_P(ary));
404 
405  if (capacity > ary_embed_capa(ary)) {
406  size_t new_capa = capacity;
407  if (ARY_EMBED_P(ary)) {
408  long len = ARY_EMBED_LEN(ary);
409  VALUE *ptr = ary_heap_alloc_buffer(capacity);
410 
411  MEMCPY(ptr, ARY_EMBED_PTR(ary), VALUE, len);
412  FL_UNSET_EMBED(ary);
413  ARY_SET_PTR(ary, ptr);
414  ARY_SET_HEAP_LEN(ary, len);
415  }
416  else {
417  new_capa = ary_heap_realloc(ary, capacity);
418  }
419  ARY_SET_CAPA(ary, new_capa);
420  }
421  else {
422  if (!ARY_EMBED_P(ary)) {
423  long len = ARY_HEAP_LEN(ary);
424  long old_capa = ARY_HEAP_CAPA(ary);
425  const VALUE *ptr = ARY_HEAP_PTR(ary);
426 
427  if (len > capacity) len = capacity;
428  MEMCPY((VALUE *)RARRAY(ary)->as.ary, ptr, VALUE, len);
429  ary_heap_free_ptr(ary, ptr, old_capa);
430 
431  FL_SET_EMBED(ary);
432  ARY_SET_LEN(ary, len);
433  }
434  }
435 
436  ary_verify(ary);
437 }
438 
439 static inline void
440 ary_shrink_capa(VALUE ary)
441 {
442  long capacity = ARY_HEAP_LEN(ary);
443  long old_capa = ARY_HEAP_CAPA(ary);
444  RUBY_ASSERT(!ARY_SHARED_P(ary));
445  RUBY_ASSERT(old_capa >= capacity);
446  if (old_capa > capacity) {
447  size_t new_capa = ary_heap_realloc(ary, capacity);
448  ARY_SET_CAPA(ary, new_capa);
449  }
450 
451  ary_verify(ary);
452 }
453 
454 static void
455 ary_double_capa(VALUE ary, long min)
456 {
457  long new_capa = ARY_CAPA(ary) / 2;
458 
459  if (new_capa < ARY_DEFAULT_SIZE) {
460  new_capa = ARY_DEFAULT_SIZE;
461  }
462  if (new_capa >= ARY_MAX_SIZE - min) {
463  new_capa = (ARY_MAX_SIZE - min) / 2;
464  }
465  new_capa += min;
466  ary_resize_capa(ary, new_capa);
467 
468  ary_verify(ary);
469 }
470 
471 static void
472 rb_ary_decrement_share(VALUE shared_root)
473 {
474  if (!OBJ_FROZEN(shared_root)) {
475  long num = ARY_SHARED_ROOT_REFCNT(shared_root);
476  ARY_SET_SHARED_ROOT_REFCNT(shared_root, num - 1);
477  }
478 }
479 
480 static void
481 rb_ary_unshare(VALUE ary)
482 {
483  VALUE shared_root = ARY_SHARED_ROOT(ary);
484  rb_ary_decrement_share(shared_root);
485  FL_UNSET_SHARED(ary);
486 }
487 
488 static void
489 rb_ary_reset(VALUE ary)
490 {
491  if (ARY_OWNS_HEAP_P(ary)) {
492  ary_heap_free(ary);
493  }
494  else if (ARY_SHARED_P(ary)) {
495  rb_ary_unshare(ary);
496  }
497 
498  FL_SET_EMBED(ary);
499  ARY_SET_EMBED_LEN(ary, 0);
500 }
501 
502 static VALUE
503 rb_ary_increment_share(VALUE shared_root)
504 {
505  if (!OBJ_FROZEN(shared_root)) {
506  long num = ARY_SHARED_ROOT_REFCNT(shared_root);
507  RUBY_ASSERT(num >= 0);
508  ARY_SET_SHARED_ROOT_REFCNT(shared_root, num + 1);
509  }
510  return shared_root;
511 }
512 
513 static void
514 rb_ary_set_shared(VALUE ary, VALUE shared_root)
515 {
516  RUBY_ASSERT(!ARY_EMBED_P(ary));
518  RUBY_ASSERT(ARY_SHARED_ROOT_P(shared_root) || OBJ_FROZEN(shared_root));
519 
520  rb_ary_increment_share(shared_root);
521  FL_SET_SHARED(ary);
522  RB_OBJ_WRITE(ary, &RARRAY(ary)->as.heap.aux.shared_root, shared_root);
523 
524  RB_DEBUG_COUNTER_INC(obj_ary_shared_create);
525 }
526 
527 static inline void
528 rb_ary_modify_check(VALUE ary)
529 {
530  rb_check_frozen(ary);
531  ary_verify(ary);
532 }
533 
534 void
535 rb_ary_cancel_sharing(VALUE ary)
536 {
537  if (ARY_SHARED_P(ary)) {
538  long shared_len, len = RARRAY_LEN(ary);
539  VALUE shared_root = ARY_SHARED_ROOT(ary);
540 
541  ary_verify(shared_root);
542 
543  if (len <= ary_embed_capa(ary)) {
544  const VALUE *ptr = ARY_HEAP_PTR(ary);
545  FL_UNSET_SHARED(ary);
546  FL_SET_EMBED(ary);
547  MEMCPY((VALUE *)ARY_EMBED_PTR(ary), ptr, VALUE, len);
548  rb_ary_decrement_share(shared_root);
549  ARY_SET_EMBED_LEN(ary, len);
550  }
551  else if (ARY_SHARED_ROOT_OCCUPIED(shared_root) && len > ((shared_len = RARRAY_LEN(shared_root))>>1)) {
553  FL_UNSET_SHARED(ary);
554  ARY_SET_PTR(ary, RARRAY_CONST_PTR(shared_root));
555  ARY_SET_CAPA(ary, shared_len);
557  MEMMOVE(ptr, ptr+shift, VALUE, len);
558  });
559  FL_SET_EMBED(shared_root);
560  rb_ary_decrement_share(shared_root);
561  }
562  else {
563  VALUE *ptr = ary_heap_alloc_buffer(len);
564  MEMCPY(ptr, ARY_HEAP_PTR(ary), VALUE, len);
565  rb_ary_unshare(ary);
566  ARY_SET_CAPA(ary, len);
567  ARY_SET_PTR(ary, ptr);
568  }
569 
570  rb_gc_writebarrier_remember(ary);
571  }
572  ary_verify(ary);
573 }
574 
575 void
577 {
578  rb_ary_modify_check(ary);
579  rb_ary_cancel_sharing(ary);
580 }
581 
582 static VALUE
583 ary_ensure_room_for_push(VALUE ary, long add_len)
584 {
585  long old_len = RARRAY_LEN(ary);
586  long new_len = old_len + add_len;
587  long capa;
588 
589  if (old_len > ARY_MAX_SIZE - add_len) {
590  rb_raise(rb_eIndexError, "index %ld too big", new_len);
591  }
592  if (ARY_SHARED_P(ary)) {
593  if (new_len > ary_embed_capa(ary)) {
594  VALUE shared_root = ARY_SHARED_ROOT(ary);
595  if (ARY_SHARED_ROOT_OCCUPIED(shared_root)) {
596  if (ARY_HEAP_PTR(ary) - RARRAY_CONST_PTR(shared_root) + new_len <= RARRAY_LEN(shared_root)) {
597  rb_ary_modify_check(ary);
598 
599  ary_verify(ary);
600  ary_verify(shared_root);
601  return shared_root;
602  }
603  else {
604  /* if array is shared, then it is likely it participate in push/shift pattern */
606  capa = ARY_CAPA(ary);
607  if (new_len > capa - (capa >> 6)) {
608  ary_double_capa(ary, new_len);
609  }
610  ary_verify(ary);
611  return ary;
612  }
613  }
614  }
615  ary_verify(ary);
617  }
618  else {
619  rb_ary_modify_check(ary);
620  }
621  capa = ARY_CAPA(ary);
622  if (new_len > capa) {
623  ary_double_capa(ary, new_len);
624  }
625 
626  ary_verify(ary);
627  return ary;
628 }
629 
630 /*
631  * call-seq:
632  * freeze -> self
633  *
634  * Freezes +self+ (if not already frozen); returns +self+:
635  *
636  * a = []
637  * a.frozen? # => false
638  * a.freeze
639  * a.frozen? # => true
640  *
641  * No further changes may be made to +self+;
642  * raises FrozenError if a change is attempted.
643  *
644  * Related: Kernel#frozen?.
645  */
646 
647 VALUE
649 {
651 
652  if (OBJ_FROZEN(ary)) return ary;
653 
654  if (!ARY_EMBED_P(ary) && !ARY_SHARED_P(ary) && !ARY_SHARED_ROOT_P(ary)) {
655  ary_shrink_capa(ary);
656  }
657 
658  return rb_obj_freeze(ary);
659 }
660 
661 /* This can be used to take a snapshot of an array (with
662  e.g. rb_ary_replace) and check later whether the array has been
663  modified from the snapshot. The snapshot is cheap, though if
664  something does modify the array it will pay the cost of copying
665  it. If Array#pop or Array#shift has been called, the array will
666  be still shared with the snapshot, but the array length will
667  differ. */
668 VALUE
670 {
671  if (!ARY_EMBED_P(ary1) && ARY_SHARED_P(ary1) &&
672  !ARY_EMBED_P(ary2) && ARY_SHARED_P(ary2) &&
673  ARY_SHARED_ROOT(ary1) == ARY_SHARED_ROOT(ary2) &&
674  ARY_HEAP_LEN(ary1) == ARY_HEAP_LEN(ary2)) {
675  return Qtrue;
676  }
677  return Qfalse;
678 }
679 
680 static VALUE
681 ary_alloc_embed(VALUE klass, long capa)
682 {
683  size_t size = ary_embed_size(capa);
684  RUBY_ASSERT(rb_gc_size_allocatable_p(size));
685  NEWOBJ_OF(ary, struct RArray, klass,
686  T_ARRAY | RARRAY_EMBED_FLAG | (RGENGC_WB_PROTECTED_ARRAY ? FL_WB_PROTECTED : 0),
687  size, 0);
688  /* Created array is:
689  * FL_SET_EMBED((VALUE)ary);
690  * ARY_SET_EMBED_LEN((VALUE)ary, 0);
691  */
692  return (VALUE)ary;
693 }
694 
695 static VALUE
696 ary_alloc_heap(VALUE klass)
697 {
698  NEWOBJ_OF(ary, struct RArray, klass,
700  sizeof(struct RArray), 0);
701  return (VALUE)ary;
702 }
703 
704 static VALUE
705 empty_ary_alloc(VALUE klass)
706 {
707  RUBY_DTRACE_CREATE_HOOK(ARRAY, 0);
708  return ary_alloc_embed(klass, 0);
709 }
710 
711 static VALUE
712 ary_new(VALUE klass, long capa)
713 {
714  VALUE ary;
715 
716  if (capa < 0) {
717  rb_raise(rb_eArgError, "negative array size (or size too big)");
718  }
719  if (capa > ARY_MAX_SIZE) {
720  rb_raise(rb_eArgError, "array size too big");
721  }
722 
723  RUBY_DTRACE_CREATE_HOOK(ARRAY, capa);
724 
725  if (ary_embeddable_p(capa)) {
726  ary = ary_alloc_embed(klass, capa);
727  }
728  else {
729  ary = ary_alloc_heap(klass);
730  ARY_SET_CAPA(ary, capa);
731  RUBY_ASSERT(!ARY_EMBED_P(ary));
732 
733  ARY_SET_PTR(ary, ary_heap_alloc_buffer(capa));
734  ARY_SET_HEAP_LEN(ary, 0);
735  }
736 
737  return ary;
738 }
739 
740 VALUE
742 {
743  return ary_new(rb_cArray, capa);
744 }
745 
746 VALUE
748 {
749  return rb_ary_new_capa(0);
750 }
751 
753 (rb_ary_new_from_args)(long n, ...)
754 {
755  va_list ar;
756  VALUE ary;
757  long i;
758 
759  ary = rb_ary_new2(n);
760 
761  va_start(ar, n);
762  for (i=0; i<n; i++) {
763  ARY_SET(ary, i, va_arg(ar, VALUE));
764  }
765  va_end(ar);
766 
767  ARY_SET_LEN(ary, n);
768  return ary;
769 }
770 
771 VALUE
772 rb_ary_tmp_new_from_values(VALUE klass, long n, const VALUE *elts)
773 {
774  VALUE ary;
775 
776  ary = ary_new(klass, n);
777  if (n > 0 && elts) {
778  ary_memcpy(ary, 0, n, elts);
779  ARY_SET_LEN(ary, n);
780  }
781 
782  return ary;
783 }
784 
785 VALUE
786 rb_ary_new_from_values(long n, const VALUE *elts)
787 {
788  return rb_ary_tmp_new_from_values(rb_cArray, n, elts);
789 }
790 
791 static VALUE
792 ec_ary_alloc_embed(rb_execution_context_t *ec, VALUE klass, long capa)
793 {
794  size_t size = ary_embed_size(capa);
795  RUBY_ASSERT(rb_gc_size_allocatable_p(size));
796  NEWOBJ_OF(ary, struct RArray, klass,
797  T_ARRAY | RARRAY_EMBED_FLAG | (RGENGC_WB_PROTECTED_ARRAY ? FL_WB_PROTECTED : 0),
798  size, ec);
799  /* Created array is:
800  * FL_SET_EMBED((VALUE)ary);
801  * ARY_SET_EMBED_LEN((VALUE)ary, 0);
802  */
803  return (VALUE)ary;
804 }
805 
806 static VALUE
807 ec_ary_alloc_heap(rb_execution_context_t *ec, VALUE klass)
808 {
809  NEWOBJ_OF(ary, struct RArray, klass,
811  sizeof(struct RArray), ec);
812  return (VALUE)ary;
813 }
814 
815 static VALUE
816 ec_ary_new(rb_execution_context_t *ec, VALUE klass, long capa)
817 {
818  VALUE ary;
819 
820  if (capa < 0) {
821  rb_raise(rb_eArgError, "negative array size (or size too big)");
822  }
823  if (capa > ARY_MAX_SIZE) {
824  rb_raise(rb_eArgError, "array size too big");
825  }
826 
827  RUBY_DTRACE_CREATE_HOOK(ARRAY, capa);
828 
829  if (ary_embeddable_p(capa)) {
830  ary = ec_ary_alloc_embed(ec, klass, capa);
831  }
832  else {
833  ary = ec_ary_alloc_heap(ec, klass);
834  ARY_SET_CAPA(ary, capa);
835  RUBY_ASSERT(!ARY_EMBED_P(ary));
836 
837  ARY_SET_PTR(ary, ary_heap_alloc_buffer(capa));
838  ARY_SET_HEAP_LEN(ary, 0);
839  }
840 
841  return ary;
842 }
843 
844 VALUE
845 rb_ec_ary_new_from_values(rb_execution_context_t *ec, long n, const VALUE *elts)
846 {
847  VALUE ary;
848 
849  ary = ec_ary_new(ec, rb_cArray, n);
850  if (n > 0 && elts) {
851  ary_memcpy(ary, 0, n, elts);
852  ARY_SET_LEN(ary, n);
853  }
854 
855  return ary;
856 }
857 
858 VALUE
860 {
861  VALUE ary = ary_new(0, capa);
862  return ary;
863 }
864 
865 VALUE
866 rb_ary_hidden_new_fill(long capa)
867 {
869  ary_memfill(ary, 0, capa, Qnil);
870  ARY_SET_LEN(ary, capa);
871  return ary;
872 }
873 
874 void
876 {
877  if (ARY_OWNS_HEAP_P(ary)) {
878  if (USE_DEBUG_COUNTER &&
879  !ARY_SHARED_ROOT_P(ary) &&
880  ARY_HEAP_CAPA(ary) > RARRAY_LEN(ary)) {
881  RB_DEBUG_COUNTER_INC(obj_ary_extracapa);
882  }
883 
884  RB_DEBUG_COUNTER_INC(obj_ary_ptr);
885  ary_heap_free(ary);
886  }
887  else {
888  RB_DEBUG_COUNTER_INC(obj_ary_embed);
889  }
890 
891  if (ARY_SHARED_P(ary)) {
892  RB_DEBUG_COUNTER_INC(obj_ary_shared);
893  }
894  if (ARY_SHARED_ROOT_P(ary) && ARY_SHARED_ROOT_OCCUPIED(ary)) {
895  RB_DEBUG_COUNTER_INC(obj_ary_shared_root_occupied);
896  }
897 }
898 
899 static VALUE fake_ary_flags;
900 
901 static VALUE
902 init_fake_ary_flags(void)
903 {
904  struct RArray fake_ary = {0};
905  fake_ary.basic.flags = T_ARRAY;
906  VALUE ary = (VALUE)&fake_ary;
908  return fake_ary.basic.flags;
909 }
910 
911 VALUE
912 rb_setup_fake_ary(struct RArray *fake_ary, const VALUE *list, long len)
913 {
914  fake_ary->basic.flags = fake_ary_flags;
915  RBASIC_CLEAR_CLASS((VALUE)fake_ary);
916 
917  // bypass frozen checks
918  fake_ary->as.heap.ptr = list;
919  fake_ary->as.heap.len = len;
920  fake_ary->as.heap.aux.capa = len;
921  return (VALUE)fake_ary;
922 }
923 
924 size_t
925 rb_ary_memsize(VALUE ary)
926 {
927  if (ARY_OWNS_HEAP_P(ary)) {
928  return ARY_CAPA(ary) * sizeof(VALUE);
929  }
930  else {
931  return 0;
932  }
933 }
934 
935 static VALUE
936 ary_make_shared(VALUE ary)
937 {
938  ary_verify(ary);
939 
940  if (ARY_SHARED_P(ary)) {
941  return ARY_SHARED_ROOT(ary);
942  }
943  else if (ARY_SHARED_ROOT_P(ary)) {
944  return ary;
945  }
946  else if (OBJ_FROZEN(ary)) {
947  return ary;
948  }
949  else {
950  long capa = ARY_CAPA(ary);
951  long len = RARRAY_LEN(ary);
952 
953  /* Shared roots cannot be embedded because the reference count
954  * (refcnt) is stored in as.heap.aux.capa. */
955  VALUE shared = ary_alloc_heap(0);
956  FL_SET_SHARED_ROOT(shared);
957 
958  if (ARY_EMBED_P(ary)) {
959  VALUE *ptr = ary_heap_alloc_buffer(capa);
960  ARY_SET_PTR(shared, ptr);
961  ary_memcpy(shared, 0, len, RARRAY_CONST_PTR(ary));
962 
963  FL_UNSET_EMBED(ary);
964  ARY_SET_HEAP_LEN(ary, len);
965  ARY_SET_PTR(ary, ptr);
966  }
967  else {
968  ARY_SET_PTR(shared, RARRAY_CONST_PTR(ary));
969  }
970 
971  ARY_SET_LEN(shared, capa);
972  ary_mem_clear(shared, len, capa - len);
973  rb_ary_set_shared(ary, shared);
974 
975  ary_verify(shared);
976  ary_verify(ary);
977 
978  return shared;
979  }
980 }
981 
982 static VALUE
983 ary_make_substitution(VALUE ary)
984 {
985  long len = RARRAY_LEN(ary);
986 
987  if (ary_embeddable_p(len)) {
988  VALUE subst = rb_ary_new_capa(len);
989  RUBY_ASSERT(ARY_EMBED_P(subst));
990 
991  ary_memcpy(subst, 0, len, RARRAY_CONST_PTR(ary));
992  ARY_SET_EMBED_LEN(subst, len);
993  return subst;
994  }
995  else {
996  return rb_ary_increment_share(ary_make_shared(ary));
997  }
998 }
999 
1000 VALUE
1002 {
1003  return rb_ary_new3(2, car, cdr);
1004 }
1005 
1006 VALUE
1007 rb_to_array_type(VALUE ary)
1008 {
1009  return rb_convert_type_with_id(ary, T_ARRAY, "Array", idTo_ary);
1010 }
1011 #define to_ary rb_to_array_type
1012 
1013 VALUE
1015 {
1016  return rb_check_convert_type_with_id(ary, T_ARRAY, "Array", idTo_ary);
1017 }
1018 
1019 VALUE
1020 rb_check_to_array(VALUE ary)
1021 {
1022  return rb_check_convert_type_with_id(ary, T_ARRAY, "Array", idTo_a);
1023 }
1024 
1025 VALUE
1026 rb_to_array(VALUE ary)
1027 {
1028  return rb_convert_type_with_id(ary, T_ARRAY, "Array", idTo_a);
1029 }
1030 
1031 /*
1032  * call-seq:
1033  * Array.try_convert(object) -> object, new_array, or nil
1034  *
1035  * Attempts to return an array, based on the given +object+.
1036  *
1037  * If +object+ is an array, returns +object+.
1038  *
1039  * Otherwise if +object+ responds to <tt>:to_ary</tt>.
1040  * calls <tt>object.to_ary</tt>:
1041  * if the return value is an array or +nil+, returns that value;
1042  * if not, raises TypeError.
1043  *
1044  * Otherwise returns +nil+.
1045  *
1046  * Related: see {Methods for Creating an Array}[rdoc-ref:Array@Methods+for+Creating+an+Array].
1047  */
1048 
1049 static VALUE
1050 rb_ary_s_try_convert(VALUE dummy, VALUE ary)
1051 {
1052  return rb_check_array_type(ary);
1053 }
1054 
1055 /* :nodoc: */
1056 static VALUE
1057 rb_ary_s_new(int argc, VALUE *argv, VALUE klass)
1058 {
1059  VALUE ary;
1060 
1061  if (klass == rb_cArray) {
1062  long size = 0;
1063  if (argc > 0 && FIXNUM_P(argv[0])) {
1064  size = FIX2LONG(argv[0]);
1065  if (size < 0) size = 0;
1066  }
1067 
1068  ary = ary_new(klass, size);
1069 
1071  }
1072  else {
1073  ary = rb_class_new_instance_pass_kw(argc, argv, klass);
1074  }
1075 
1076  return ary;
1077 }
1078 
1079 /*
1080  * call-seq:
1081  * Array.new -> new_empty_array
1082  * Array.new(array) -> new_array
1083  * Array.new(size, default_value = nil) -> new_array
1084  * Array.new(size = 0) {|index| ... } -> new_array
1085  *
1086  * Returns a new array.
1087  *
1088  * With no block and no argument given, returns a new empty array:
1089  *
1090  * Array.new # => []
1091  *
1092  * With no block and array argument given, returns a new array with the same elements:
1093  *
1094  * Array.new([:foo, 'bar', 2]) # => [:foo, "bar", 2]
1095  *
1096  * With no block and integer argument given, returns a new array containing
1097  * that many instances of the given +default_value+:
1098  *
1099  * Array.new(0) # => []
1100  * Array.new(3) # => [nil, nil, nil]
1101  * Array.new(2, 3) # => [3, 3]
1102  *
1103  * With a block given, returns an array of the given +size+;
1104  * calls the block with each +index+ in the range <tt>(0...size)</tt>;
1105  * the element at that +index+ in the returned array is the blocks return value:
1106  *
1107  * Array.new(3) {|index| "Element #{index}" } # => ["Element 0", "Element 1", "Element 2"]
1108  *
1109  * A common pitfall for new Rubyists is providing an expression as +default_value+:
1110  *
1111  * array = Array.new(2, {})
1112  * array # => [{}, {}]
1113  * array[0][:a] = 1
1114  * array # => [{a: 1}, {a: 1}], as array[0] and array[1] are same object
1115  *
1116  * If you want the elements of the array to be distinct, you should pass a block:
1117  *
1118  * array = Array.new(2) { {} }
1119  * array # => [{}, {}]
1120  * array[0][:a] = 1
1121  * array # => [{a: 1}, {}], as array[0] and array[1] are different objects
1122  *
1123  * Raises TypeError if the first argument is not either an array
1124  * or an {integer-convertible object}[rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects]).
1125  * Raises ArgumentError if the first argument is a negative integer.
1126  *
1127  * Related: see {Methods for Creating an Array}[rdoc-ref:Array@Methods+for+Creating+an+Array].
1128  */
1129 
1130 static VALUE
1131 rb_ary_initialize(int argc, VALUE *argv, VALUE ary)
1132 {
1133  long len;
1134  VALUE size, val;
1135 
1136  rb_ary_modify(ary);
1137  if (argc == 0) {
1138  rb_ary_reset(ary);
1139  RUBY_ASSERT(ARY_EMBED_P(ary));
1140  RUBY_ASSERT(ARY_EMBED_LEN(ary) == 0);
1141  if (rb_block_given_p()) {
1142  rb_warning("given block not used");
1143  }
1144  return ary;
1145  }
1146  rb_scan_args(argc, argv, "02", &size, &val);
1147  if (argc == 1 && !FIXNUM_P(size)) {
1148  val = rb_check_array_type(size);
1149  if (!NIL_P(val)) {
1150  rb_ary_replace(ary, val);
1151  return ary;
1152  }
1153  }
1154 
1155  len = NUM2LONG(size);
1156  /* NUM2LONG() may call size.to_int, ary can be frozen, modified, etc */
1157  if (len < 0) {
1158  rb_raise(rb_eArgError, "negative array size");
1159  }
1160  if (len > ARY_MAX_SIZE) {
1161  rb_raise(rb_eArgError, "array size too big");
1162  }
1163  /* recheck after argument conversion */
1164  rb_ary_modify(ary);
1165  ary_resize_capa(ary, len);
1166  if (rb_block_given_p()) {
1167  long i;
1168 
1169  if (argc == 2) {
1170  rb_warn("block supersedes default value argument");
1171  }
1172  for (i=0; i<len; i++) {
1173  rb_ary_store(ary, i, rb_yield(LONG2NUM(i)));
1174  ARY_SET_LEN(ary, i + 1);
1175  }
1176  }
1177  else {
1178  ary_memfill(ary, 0, len, val);
1179  ARY_SET_LEN(ary, len);
1180  }
1181  return ary;
1182 }
1183 
1184 /*
1185  * Returns a new array, populated with the given objects:
1186  *
1187  * Array[1, 'a', /^A/] # => [1, "a", /^A/]
1188  * Array[] # => []
1189  * Array.[](1, 'a', /^A/) # => [1, "a", /^A/]
1190  *
1191  * Related: see {Methods for Creating an Array}[rdoc-ref:Array@Methods+for+Creating+an+Array].
1192  */
1193 
1194 static VALUE
1195 rb_ary_s_create(int argc, VALUE *argv, VALUE klass)
1196 {
1197  VALUE ary = ary_new(klass, argc);
1198  if (argc > 0 && argv) {
1199  ary_memcpy(ary, 0, argc, argv);
1200  ARY_SET_LEN(ary, argc);
1201  }
1202 
1203  return ary;
1204 }
1205 
1206 void
1207 rb_ary_store(VALUE ary, long idx, VALUE val)
1208 {
1209  long len = RARRAY_LEN(ary);
1210 
1211  if (idx < 0) {
1212  idx += len;
1213  if (idx < 0) {
1214  rb_raise(rb_eIndexError, "index %ld too small for array; minimum: %ld",
1215  idx - len, -len);
1216  }
1217  }
1218  else if (idx >= ARY_MAX_SIZE) {
1219  rb_raise(rb_eIndexError, "index %ld too big", idx);
1220  }
1221 
1222  rb_ary_modify(ary);
1223  if (idx >= ARY_CAPA(ary)) {
1224  ary_double_capa(ary, idx);
1225  }
1226  if (idx > len) {
1227  ary_mem_clear(ary, len, idx - len + 1);
1228  }
1229 
1230  if (idx >= len) {
1231  ARY_SET_LEN(ary, idx + 1);
1232  }
1233  ARY_SET(ary, idx, val);
1234 }
1235 
1236 static VALUE
1237 ary_make_partial(VALUE ary, VALUE klass, long offset, long len)
1238 {
1239  RUBY_ASSERT(offset >= 0);
1240  RUBY_ASSERT(len >= 0);
1241  RUBY_ASSERT(offset+len <= RARRAY_LEN(ary));
1242 
1243  VALUE result = ary_alloc_heap(klass);
1244  size_t embed_capa = ary_embed_capa(result);
1245  if ((size_t)len <= embed_capa) {
1246  FL_SET_EMBED(result);
1247  ary_memcpy(result, 0, len, RARRAY_CONST_PTR(ary) + offset);
1248  ARY_SET_EMBED_LEN(result, len);
1249  }
1250  else {
1251  VALUE shared = ary_make_shared(ary);
1252 
1253  /* The ary_make_shared call may allocate, which can trigger a GC
1254  * compaction. This can cause the array to be embedded because it has
1255  * a length of 0. */
1256  FL_UNSET_EMBED(result);
1257 
1258  ARY_SET_PTR(result, RARRAY_CONST_PTR(ary));
1259  ARY_SET_LEN(result, RARRAY_LEN(ary));
1260  rb_ary_set_shared(result, shared);
1261 
1262  ARY_INCREASE_PTR(result, offset);
1263  ARY_SET_LEN(result, len);
1264 
1265  ary_verify(shared);
1266  }
1267 
1268  ary_verify(result);
1269  return result;
1270 }
1271 
1272 static VALUE
1273 ary_make_partial_step(VALUE ary, VALUE klass, long offset, long len, long step)
1274 {
1275  RUBY_ASSERT(offset >= 0);
1276  RUBY_ASSERT(len >= 0);
1277  RUBY_ASSERT(offset+len <= RARRAY_LEN(ary));
1278  RUBY_ASSERT(step != 0);
1279 
1280  const long orig_len = len;
1281 
1282  if (step > 0 && step >= len) {
1283  VALUE result = ary_new(klass, 1);
1284  VALUE *ptr = (VALUE *)ARY_EMBED_PTR(result);
1285  const VALUE *values = RARRAY_CONST_PTR(ary);
1286 
1287  RB_OBJ_WRITE(result, ptr, values[offset]);
1288  ARY_SET_EMBED_LEN(result, 1);
1289  return result;
1290  }
1291  else if (step < 0 && step < -len) {
1292  step = -len;
1293  }
1294 
1295  long ustep = (step < 0) ? -step : step;
1296  len = roomof(len, ustep);
1297 
1298  long i;
1299  long j = offset + ((step > 0) ? 0 : (orig_len - 1));
1300 
1301  VALUE result = ary_new(klass, len);
1302  if (ARY_EMBED_P(result)) {
1303  VALUE *ptr = (VALUE *)ARY_EMBED_PTR(result);
1304  const VALUE *values = RARRAY_CONST_PTR(ary);
1305 
1306  for (i = 0; i < len; ++i) {
1307  RB_OBJ_WRITE(result, ptr+i, values[j]);
1308  j += step;
1309  }
1310  ARY_SET_EMBED_LEN(result, len);
1311  }
1312  else {
1313  const VALUE *values = RARRAY_CONST_PTR(ary);
1314 
1315  RARRAY_PTR_USE(result, ptr, {
1316  for (i = 0; i < len; ++i) {
1317  RB_OBJ_WRITE(result, ptr+i, values[j]);
1318  j += step;
1319  }
1320  });
1321  ARY_SET_LEN(result, len);
1322  }
1323 
1324  return result;
1325 }
1326 
1327 static VALUE
1328 ary_make_shared_copy(VALUE ary)
1329 {
1330  return ary_make_partial(ary, rb_cArray, 0, RARRAY_LEN(ary));
1331 }
1332 
1333 enum ary_take_pos_flags
1334 {
1335  ARY_TAKE_FIRST = 0,
1336  ARY_TAKE_LAST = 1
1337 };
1338 
1339 static VALUE
1340 ary_take_first_or_last_n(VALUE ary, long n, enum ary_take_pos_flags last)
1341 {
1342  long len = RARRAY_LEN(ary);
1343  long offset = 0;
1344 
1345  if (n > len) {
1346  n = len;
1347  }
1348  else if (n < 0) {
1349  rb_raise(rb_eArgError, "negative array size");
1350  }
1351  if (last) {
1352  offset = len - n;
1353  }
1354  return ary_make_partial(ary, rb_cArray, offset, n);
1355 }
1356 
1357 static VALUE
1358 ary_take_first_or_last(int argc, const VALUE *argv, VALUE ary, enum ary_take_pos_flags last)
1359 {
1360  argc = rb_check_arity(argc, 0, 1);
1361  /* the case optional argument is omitted should be handled in
1362  * callers of this function. if another arity case is added,
1363  * this arity check needs to rewrite. */
1364  RUBY_ASSERT_ALWAYS(argc == 1);
1365  return ary_take_first_or_last_n(ary, NUM2LONG(argv[0]), last);
1366 }
1367 
1368 /*
1369  * call-seq:
1370  * self << object -> self
1371  *
1372  * Appends +object+ as the last element in +self+; returns +self+:
1373  *
1374  * [:foo, 'bar', 2] << :baz # => [:foo, "bar", 2, :baz]
1375  *
1376  * Appends +object+ as a single element, even if it is another array:
1377  *
1378  * [:foo, 'bar', 2] << [3, 4] # => [:foo, "bar", 2, [3, 4]]
1379  *
1380  * Related: see {Methods for Assigning}[rdoc-ref:Array@Methods+for+Assigning].
1381  */
1382 
1383 VALUE
1385 {
1386  long idx = RARRAY_LEN((ary_verify(ary), ary));
1387  VALUE target_ary = ary_ensure_room_for_push(ary, 1);
1388  RARRAY_PTR_USE(ary, ptr, {
1389  RB_OBJ_WRITE(target_ary, &ptr[idx], item);
1390  });
1391  ARY_SET_LEN(ary, idx + 1);
1392  ary_verify(ary);
1393  return ary;
1394 }
1395 
1396 VALUE
1397 rb_ary_cat(VALUE ary, const VALUE *argv, long len)
1398 {
1399  long oldlen = RARRAY_LEN(ary);
1400  VALUE target_ary = ary_ensure_room_for_push(ary, len);
1401  ary_memcpy0(ary, oldlen, len, argv, target_ary);
1402  ARY_SET_LEN(ary, oldlen + len);
1403  return ary;
1404 }
1405 
1406 /*
1407  * call-seq:
1408  * push(*objects) -> self
1409  * append(*objects) -> self
1410  *
1411  * Appends each argument in +objects+ to +self+; returns +self+:
1412  *
1413  * a = [:foo, 'bar', 2] # => [:foo, "bar", 2]
1414  * a.push(:baz, :bat) # => [:foo, "bar", 2, :baz, :bat]
1415  *
1416  * Appends each argument as a single element, even if it is another array:
1417  *
1418  * a = [:foo, 'bar', 2] # => [:foo, "bar", 2]
1419  a.push([:baz, :bat], [:bam, :bad]) # => [:foo, "bar", 2, [:baz, :bat], [:bam, :bad]]
1420  *
1421  * Related: see {Methods for Assigning}[rdoc-ref:Array@Methods+for+Assigning].
1422  */
1423 
1424 static VALUE
1425 rb_ary_push_m(int argc, VALUE *argv, VALUE ary)
1426 {
1427  return rb_ary_cat(ary, argv, argc);
1428 }
1429 
1430 VALUE
1432 {
1433  long n;
1434  rb_ary_modify_check(ary);
1435  n = RARRAY_LEN(ary);
1436  if (n == 0) return Qnil;
1437  if (ARY_OWNS_HEAP_P(ary) &&
1438  n * 3 < ARY_CAPA(ary) &&
1439  ARY_CAPA(ary) > ARY_DEFAULT_SIZE)
1440  {
1441  ary_resize_capa(ary, n * 2);
1442  }
1443  --n;
1444  ARY_SET_LEN(ary, n);
1445  ary_verify(ary);
1446  return RARRAY_AREF(ary, n);
1447 }
1448 
1449 /*
1450  * call-seq:
1451  * pop -> object or nil
1452  * pop(count) -> new_array
1453  *
1454  * Removes and returns trailing elements of +self+.
1455  *
1456  * With no argument given, removes and returns the last element, if available;
1457  * otherwise returns +nil+:
1458  *
1459  * a = [:foo, 'bar', 2]
1460  * a.pop # => 2
1461  * a # => [:foo, "bar"]
1462  * [].pop # => nil
1463  *
1464  * With non-negative integer argument +count+ given,
1465  * returns a new array containing the trailing +count+ elements of +self+, as available:
1466  *
1467  * a = [:foo, 'bar', 2]
1468  * a.pop(2) # => ["bar", 2]
1469  * a # => [:foo]
1470  *
1471  * a = [:foo, 'bar', 2]
1472  * a.pop(50) # => [:foo, "bar", 2]
1473  * a # => []
1474  *
1475  * Related: Array#push;
1476  * see also {Methods for Deleting}[rdoc-ref:Array@Methods+for+Deleting].
1477  */
1478 
1479 static VALUE
1480 rb_ary_pop_m(int argc, VALUE *argv, VALUE ary)
1481 {
1482  VALUE result;
1483 
1484  if (argc == 0) {
1485  return rb_ary_pop(ary);
1486  }
1487 
1488  rb_ary_modify_check(ary);
1489  result = ary_take_first_or_last(argc, argv, ary, ARY_TAKE_LAST);
1490  ARY_INCREASE_LEN(ary, -RARRAY_LEN(result));
1491  ary_verify(ary);
1492  return result;
1493 }
1494 
1495 VALUE
1497 {
1498  VALUE top;
1499  long len = RARRAY_LEN(ary);
1500 
1501  if (len == 0) {
1502  rb_ary_modify_check(ary);
1503  return Qnil;
1504  }
1505 
1506  top = RARRAY_AREF(ary, 0);
1507 
1508  rb_ary_behead(ary, 1);
1509 
1510  return top;
1511 }
1512 
1513 /*
1514  * call-seq:
1515  * shift -> object or nil
1516  * shift(count) -> new_array or nil
1517  *
1518  * Removes and returns leading elements from +self+.
1519  *
1520  * With no argument, removes and returns one element, if available,
1521  * or +nil+ otherwise:
1522  *
1523  * a = [0, 1, 2, 3]
1524  * a.shift # => 0
1525  * a # => [1, 2, 3]
1526  * [].shift # => nil
1527  *
1528  * With non-negative numeric argument +count+ given,
1529  * removes and returns the first +count+ elements:
1530  *
1531  * a = [0, 1, 2, 3]
1532  * a.shift(2) # => [0, 1]
1533  * a # => [2, 3]
1534  * a.shift(1.1) # => [2]
1535  * a # => [3]
1536  * a.shift(0) # => []
1537  * a # => [3]
1538  *
1539  * If +count+ is large,
1540  * removes and returns all elements:
1541  *
1542  * a = [0, 1, 2, 3]
1543  * a.shift(50) # => [0, 1, 2, 3]
1544  * a # => []
1545  *
1546  * If +self+ is empty, returns a new empty array.
1547  *
1548  * Related: see {Methods for Deleting}[rdoc-ref:Array@Methods+for+Deleting].
1549  */
1550 
1551 static VALUE
1552 rb_ary_shift_m(int argc, VALUE *argv, VALUE ary)
1553 {
1554  VALUE result;
1555  long n;
1556 
1557  if (argc == 0) {
1558  return rb_ary_shift(ary);
1559  }
1560 
1561  rb_ary_modify_check(ary);
1562  result = ary_take_first_or_last(argc, argv, ary, ARY_TAKE_FIRST);
1563  n = RARRAY_LEN(result);
1564  rb_ary_behead(ary,n);
1565 
1566  return result;
1567 }
1568 
1569 VALUE
1570 rb_ary_behead(VALUE ary, long n)
1571 {
1572  if (n <= 0) {
1573  return ary;
1574  }
1575 
1576  rb_ary_modify_check(ary);
1577 
1578  if (!ARY_SHARED_P(ary)) {
1579  if (ARY_EMBED_P(ary) || RARRAY_LEN(ary) < ARY_DEFAULT_SIZE) {
1580  RARRAY_PTR_USE(ary, ptr, {
1581  MEMMOVE(ptr, ptr + n, VALUE, RARRAY_LEN(ary) - n);
1582  }); /* WB: no new reference */
1583  ARY_INCREASE_LEN(ary, -n);
1584  ary_verify(ary);
1585  return ary;
1586  }
1587 
1588  ary_mem_clear(ary, 0, n);
1589  ary_make_shared(ary);
1590  }
1591  else if (ARY_SHARED_ROOT_OCCUPIED(ARY_SHARED_ROOT(ary))) {
1592  ary_mem_clear(ary, 0, n);
1593  }
1594 
1595  ARY_INCREASE_PTR(ary, n);
1596  ARY_INCREASE_LEN(ary, -n);
1597  ary_verify(ary);
1598 
1599  return ary;
1600 }
1601 
1602 static VALUE
1603 make_room_for_unshift(VALUE ary, const VALUE *head, VALUE *sharedp, int argc, long capa, long len)
1604 {
1605  if (head - sharedp < argc) {
1606  long room = capa - len - argc;
1607 
1608  room -= room >> 4;
1609  MEMMOVE((VALUE *)sharedp + argc + room, head, VALUE, len);
1610  head = sharedp + argc + room;
1611  }
1612  ARY_SET_PTR(ary, head - argc);
1613  RUBY_ASSERT(ARY_SHARED_ROOT_OCCUPIED(ARY_SHARED_ROOT(ary)));
1614 
1615  ary_verify(ary);
1616  return ARY_SHARED_ROOT(ary);
1617 }
1618 
1619 static VALUE
1620 ary_modify_for_unshift(VALUE ary, int argc)
1621 {
1622  long len = RARRAY_LEN(ary);
1623  long new_len = len + argc;
1624  long capa;
1625  const VALUE *head, *sharedp;
1626 
1627  rb_ary_modify(ary);
1628  capa = ARY_CAPA(ary);
1629  if (capa - (capa >> 6) <= new_len) {
1630  ary_double_capa(ary, new_len);
1631  }
1632 
1633  /* use shared array for big "queues" */
1634  if (new_len > ARY_DEFAULT_SIZE * 4 && !ARY_EMBED_P(ary)) {
1635  ary_verify(ary);
1636 
1637  /* make a room for unshifted items */
1638  capa = ARY_CAPA(ary);
1639  ary_make_shared(ary);
1640 
1641  head = sharedp = RARRAY_CONST_PTR(ary);
1642  return make_room_for_unshift(ary, head, (void *)sharedp, argc, capa, len);
1643  }
1644  else {
1645  /* sliding items */
1646  RARRAY_PTR_USE(ary, ptr, {
1647  MEMMOVE(ptr + argc, ptr, VALUE, len);
1648  });
1649 
1650  ary_verify(ary);
1651  return ary;
1652  }
1653 }
1654 
1655 static VALUE
1656 ary_ensure_room_for_unshift(VALUE ary, int argc)
1657 {
1658  long len = RARRAY_LEN(ary);
1659  long new_len = len + argc;
1660 
1661  if (len > ARY_MAX_SIZE - argc) {
1662  rb_raise(rb_eIndexError, "index %ld too big", new_len);
1663  }
1664  else if (! ARY_SHARED_P(ary)) {
1665  return ary_modify_for_unshift(ary, argc);
1666  }
1667  else {
1668  VALUE shared_root = ARY_SHARED_ROOT(ary);
1669  long capa = RARRAY_LEN(shared_root);
1670 
1671  if (! ARY_SHARED_ROOT_OCCUPIED(shared_root)) {
1672  return ary_modify_for_unshift(ary, argc);
1673  }
1674  else if (new_len > capa) {
1675  return ary_modify_for_unshift(ary, argc);
1676  }
1677  else {
1678  const VALUE * head = RARRAY_CONST_PTR(ary);
1679  void *sharedp = (void *)RARRAY_CONST_PTR(shared_root);
1680 
1681  rb_ary_modify_check(ary);
1682  return make_room_for_unshift(ary, head, sharedp, argc, capa, len);
1683  }
1684  }
1685 }
1686 
1687 /*
1688  * call-seq:
1689  * unshift(*objects) -> self
1690  * prepend(*objects) -> self
1691  *
1692  * Prepends the given +objects+ to +self+:
1693  *
1694  * a = [:foo, 'bar', 2]
1695  * a.unshift(:bam, :bat) # => [:bam, :bat, :foo, "bar", 2]
1696  *
1697  * Related: Array#shift;
1698  * see also {Methods for Assigning}[rdoc-ref:Array@Methods+for+Assigning].
1699  */
1700 
1701 VALUE
1702 rb_ary_unshift_m(int argc, VALUE *argv, VALUE ary)
1703 {
1704  long len = RARRAY_LEN(ary);
1705  VALUE target_ary;
1706 
1707  if (argc == 0) {
1708  rb_ary_modify_check(ary);
1709  return ary;
1710  }
1711 
1712  target_ary = ary_ensure_room_for_unshift(ary, argc);
1713  ary_memcpy0(ary, 0, argc, argv, target_ary);
1714  ARY_SET_LEN(ary, len + argc);
1715  return ary;
1716 }
1717 
1718 VALUE
1720 {
1721  return rb_ary_unshift_m(1, &item, ary);
1722 }
1723 
1724 /* faster version - use this if you don't need to treat negative offset */
1725 static inline VALUE
1726 rb_ary_elt(VALUE ary, long offset)
1727 {
1728  long len = RARRAY_LEN(ary);
1729  if (len == 0) return Qnil;
1730  if (offset < 0 || len <= offset) {
1731  return Qnil;
1732  }
1733  return RARRAY_AREF(ary, offset);
1734 }
1735 
1736 VALUE
1737 rb_ary_entry(VALUE ary, long offset)
1738 {
1739  return rb_ary_entry_internal(ary, offset);
1740 }
1741 
1742 VALUE
1743 rb_ary_subseq_step(VALUE ary, long beg, long len, long step)
1744 {
1745  VALUE klass;
1746  long alen = RARRAY_LEN(ary);
1747 
1748  if (beg > alen) return Qnil;
1749  if (beg < 0 || len < 0) return Qnil;
1750 
1751  if (alen < len || alen < beg + len) {
1752  len = alen - beg;
1753  }
1754  klass = rb_cArray;
1755  if (len == 0) return ary_new(klass, 0);
1756  if (step == 0)
1757  rb_raise(rb_eArgError, "slice step cannot be zero");
1758  if (step == 1)
1759  return ary_make_partial(ary, klass, beg, len);
1760  else
1761  return ary_make_partial_step(ary, klass, beg, len, step);
1762 }
1763 
1764 VALUE
1765 rb_ary_subseq(VALUE ary, long beg, long len)
1766 {
1767  return rb_ary_subseq_step(ary, beg, len, 1);
1768 }
1769 
1770 static VALUE rb_ary_aref2(VALUE ary, VALUE b, VALUE e);
1771 
1772 /*
1773  * call-seq:
1774  * self[index] -> object or nil
1775  * self[start, length] -> object or nil
1776  * self[range] -> object or nil
1777  * self[aseq] -> object or nil
1778  * slice(index) -> object or nil
1779  * slice(start, length) -> object or nil
1780  * slice(range) -> object or nil
1781  * slice(aseq) -> object or nil
1782  *
1783  * Returns elements from +self+; does not modify +self+.
1784  *
1785  * In brief:
1786  *
1787  * a = [:foo, 'bar', 2]
1788  *
1789  * # Single argument index: returns one element.
1790  * a[0] # => :foo # Zero-based index.
1791  * a[-1] # => 2 # Negative index counts backwards from end.
1792  *
1793  * # Arguments start and length: returns an array.
1794  * a[1, 2] # => ["bar", 2]
1795  * a[-2, 2] # => ["bar", 2] # Negative start counts backwards from end.
1796  *
1797  * # Single argument range: returns an array.
1798  * a[0..1] # => [:foo, "bar"]
1799  * a[0..-2] # => [:foo, "bar"] # Negative range-begin counts backwards from end.
1800  * a[-2..2] # => ["bar", 2] # Negative range-end counts backwards from end.
1801  *
1802  * When a single integer argument +index+ is given, returns the element at offset +index+:
1803  *
1804  * a = [:foo, 'bar', 2]
1805  * a[0] # => :foo
1806  * a[2] # => 2
1807  * a # => [:foo, "bar", 2]
1808  *
1809  * If +index+ is negative, counts backwards from the end of +self+:
1810  *
1811  * a = [:foo, 'bar', 2]
1812  * a[-1] # => 2
1813  * a[-2] # => "bar"
1814  *
1815  * If +index+ is out of range, returns +nil+.
1816  *
1817  * When two Integer arguments +start+ and +length+ are given,
1818  * returns a new +Array+ of size +length+ containing successive elements beginning at offset +start+:
1819  *
1820  * a = [:foo, 'bar', 2]
1821  * a[0, 2] # => [:foo, "bar"]
1822  * a[1, 2] # => ["bar", 2]
1823  *
1824  * If <tt>start + length</tt> is greater than <tt>self.length</tt>,
1825  * returns all elements from offset +start+ to the end:
1826  *
1827  * a = [:foo, 'bar', 2]
1828  * a[0, 4] # => [:foo, "bar", 2]
1829  * a[1, 3] # => ["bar", 2]
1830  * a[2, 2] # => [2]
1831  *
1832  * If <tt>start == self.size</tt> and <tt>length >= 0</tt>,
1833  * returns a new empty +Array+.
1834  *
1835  * If +length+ is negative, returns +nil+.
1836  *
1837  * When a single Range argument +range+ is given,
1838  * treats <tt>range.min</tt> as +start+ above
1839  * and <tt>range.size</tt> as +length+ above:
1840  *
1841  * a = [:foo, 'bar', 2]
1842  * a[0..1] # => [:foo, "bar"]
1843  * a[1..2] # => ["bar", 2]
1844  *
1845  * Special case: If <tt>range.start == a.size</tt>, returns a new empty +Array+.
1846  *
1847  * If <tt>range.end</tt> is negative, calculates the end index from the end:
1848  *
1849  * a = [:foo, 'bar', 2]
1850  * a[0..-1] # => [:foo, "bar", 2]
1851  * a[0..-2] # => [:foo, "bar"]
1852  * a[0..-3] # => [:foo]
1853  *
1854  * If <tt>range.start</tt> is negative, calculates the start index from the end:
1855  *
1856  * a = [:foo, 'bar', 2]
1857  * a[-1..2] # => [2]
1858  * a[-2..2] # => ["bar", 2]
1859  * a[-3..2] # => [:foo, "bar", 2]
1860  *
1861  * If <tt>range.start</tt> is larger than the array size, returns +nil+.
1862  *
1863  * a = [:foo, 'bar', 2]
1864  * a[4..1] # => nil
1865  * a[4..0] # => nil
1866  * a[4..-1] # => nil
1867  *
1868  * When a single Enumerator::ArithmeticSequence argument +aseq+ is given,
1869  * returns an +Array+ of elements corresponding to the indexes produced by
1870  * the sequence.
1871  *
1872  * a = ['--', 'data1', '--', 'data2', '--', 'data3']
1873  * a[(1..).step(2)] # => ["data1", "data2", "data3"]
1874  *
1875  * Unlike slicing with range, if the start or the end of the arithmetic sequence
1876  * is larger than array size, throws RangeError.
1877  *
1878  * a = ['--', 'data1', '--', 'data2', '--', 'data3']
1879  * a[(1..11).step(2)]
1880  * # RangeError (((1..11).step(2)) out of range)
1881  * a[(7..).step(2)]
1882  * # RangeError (((7..).step(2)) out of range)
1883  *
1884  * If given a single argument, and its type is not one of the listed, tries to
1885  * convert it to Integer, and raises if it is impossible:
1886  *
1887  * a = [:foo, 'bar', 2]
1888  * # Raises TypeError (no implicit conversion of Symbol into Integer):
1889  * a[:foo]
1890  *
1891  * Related: see {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching].
1892  */
1893 
1894 VALUE
1895 rb_ary_aref(int argc, const VALUE *argv, VALUE ary)
1896 {
1897  rb_check_arity(argc, 1, 2);
1898  if (argc == 2) {
1899  return rb_ary_aref2(ary, argv[0], argv[1]);
1900  }
1901  return rb_ary_aref1(ary, argv[0]);
1902 }
1903 
1904 static VALUE
1905 rb_ary_aref2(VALUE ary, VALUE b, VALUE e)
1906 {
1907  long beg = NUM2LONG(b);
1908  long len = NUM2LONG(e);
1909  if (beg < 0) {
1910  beg += RARRAY_LEN(ary);
1911  }
1912  return rb_ary_subseq(ary, beg, len);
1913 }
1914 
1915 VALUE
1916 rb_ary_aref1(VALUE ary, VALUE arg)
1917 {
1918  long beg, len, step;
1919 
1920  /* special case - speeding up */
1921  if (FIXNUM_P(arg)) {
1922  return rb_ary_entry(ary, FIX2LONG(arg));
1923  }
1924  /* check if idx is Range or ArithmeticSequence */
1925  switch (rb_arithmetic_sequence_beg_len_step(arg, &beg, &len, &step, RARRAY_LEN(ary), 0)) {
1926  case Qfalse:
1927  break;
1928  case Qnil:
1929  return Qnil;
1930  default:
1931  return rb_ary_subseq_step(ary, beg, len, step);
1932  }
1933 
1934  return rb_ary_entry(ary, NUM2LONG(arg));
1935 }
1936 
1937 /*
1938  * call-seq:
1939  * at(index) -> object or nil
1940  *
1941  * Returns the element of +self+ specified by the given +index+
1942  * or +nil+ if there is no such element;
1943  * +index+ must be an
1944  * {integer-convertible object}[rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects].
1945  *
1946  * For non-negative +index+, returns the element of +self+ at offset +index+:
1947  *
1948  * a = [:foo, 'bar', 2]
1949  * a.at(0) # => :foo
1950  * a.at(2) # => 2
1951  * a.at(2.0) # => 2
1952  *
1953  * For negative +index+, counts backwards from the end of +self+:
1954  *
1955  * a.at(-2) # => "bar"
1956  *
1957  * Related: Array#[];
1958  * see also {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching].
1959  */
1960 
1961 VALUE
1962 rb_ary_at(VALUE ary, VALUE pos)
1963 {
1964  return rb_ary_entry(ary, NUM2LONG(pos));
1965 }
1966 
1967 #if 0
1968 static VALUE
1969 rb_ary_first(int argc, VALUE *argv, VALUE ary)
1970 {
1971  if (argc == 0) {
1972  if (RARRAY_LEN(ary) == 0) return Qnil;
1973  return RARRAY_AREF(ary, 0);
1974  }
1975  else {
1976  return ary_take_first_or_last(argc, argv, ary, ARY_TAKE_FIRST);
1977  }
1978 }
1979 #endif
1980 
1981 static VALUE
1982 ary_first(VALUE self)
1983 {
1984  return (RARRAY_LEN(self) == 0) ? Qnil : RARRAY_AREF(self, 0);
1985 }
1986 
1987 static VALUE
1988 ary_last(VALUE self)
1989 {
1990  long len = RARRAY_LEN(self);
1991  return (len == 0) ? Qnil : RARRAY_AREF(self, len-1);
1992 }
1993 
1994 VALUE
1995 rb_ary_last(int argc, const VALUE *argv, VALUE ary) // used by parse.y
1996 {
1997  if (argc == 0) {
1998  return ary_last(ary);
1999  }
2000  else {
2001  return ary_take_first_or_last(argc, argv, ary, ARY_TAKE_LAST);
2002  }
2003 }
2004 
2005 /*
2006  * call-seq:
2007  * fetch(index) -> element
2008  * fetch(index, default_value) -> element or default_value
2009  * fetch(index) {|index| ... } -> element or block_return_value
2010  *
2011  * Returns the element of +self+ at offset +index+ if +index+ is in range; +index+ must be an
2012  * {integer-convertible object}[rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects].
2013  *
2014  * With the single argument +index+ and no block,
2015  * returns the element at offset +index+:
2016  *
2017  * a = [:foo, 'bar', 2]
2018  * a.fetch(1) # => "bar"
2019  * a.fetch(1.1) # => "bar"
2020  *
2021  * If +index+ is negative, counts from the end of the array:
2022  *
2023  * a = [:foo, 'bar', 2]
2024  * a.fetch(-1) # => 2
2025  * a.fetch(-2) # => "bar"
2026  *
2027  * With arguments +index+ and +default_value+ (which may be any object) and no block,
2028  * returns +default_value+ if +index+ is out-of-range:
2029  *
2030  * a = [:foo, 'bar', 2]
2031  * a.fetch(1, nil) # => "bar"
2032  * a.fetch(3, :foo) # => :foo
2033  *
2034  * With argument +index+ and a block,
2035  * returns the element at offset +index+ if index is in range
2036  * (and the block is not called); otherwise calls the block with index and returns its return value:
2037  *
2038  * a = [:foo, 'bar', 2]
2039  * a.fetch(1) {|index| raise 'Cannot happen' } # => "bar"
2040  * a.fetch(50) {|index| "Value for #{index}" } # => "Value for 50"
2041  *
2042  * Related: see {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching].
2043  */
2044 
2045 static VALUE
2046 rb_ary_fetch(int argc, VALUE *argv, VALUE ary)
2047 {
2048  VALUE pos, ifnone;
2049  long block_given;
2050  long idx;
2051 
2052  rb_scan_args(argc, argv, "11", &pos, &ifnone);
2053  block_given = rb_block_given_p();
2054  if (block_given && argc == 2) {
2055  rb_warn("block supersedes default value argument");
2056  }
2057  idx = NUM2LONG(pos);
2058 
2059  if (idx < 0) {
2060  idx += RARRAY_LEN(ary);
2061  }
2062  if (idx < 0 || RARRAY_LEN(ary) <= idx) {
2063  if (block_given) return rb_yield(pos);
2064  if (argc == 1) {
2065  rb_raise(rb_eIndexError, "index %ld outside of array bounds: %ld...%ld",
2066  idx - (idx < 0 ? RARRAY_LEN(ary) : 0), -RARRAY_LEN(ary), RARRAY_LEN(ary));
2067  }
2068  return ifnone;
2069  }
2070  return RARRAY_AREF(ary, idx);
2071 }
2072 
2073 /*
2074  * call-seq:
2075  * find_index(object) -> integer or nil
2076  * find_index {|element| ... } -> integer or nil
2077  * find_index -> new_enumerator
2078  * index(object) -> integer or nil
2079  * index {|element| ... } -> integer or nil
2080  * index -> new_enumerator
2081  *
2082  * Returns the zero-based integer index of a specified element, or +nil+.
2083  *
2084  * With only argument +object+ given,
2085  * returns the index of the first element +element+
2086  * for which <tt>object == element</tt>:
2087  *
2088  * a = [:foo, 'bar', 2, 'bar']
2089  * a.index('bar') # => 1
2090  *
2091  * Returns +nil+ if no such element found.
2092  *
2093  * With only a block given,
2094  * calls the block with each successive element;
2095  * returns the index of the first element for which the block returns a truthy value:
2096  *
2097  * a = [:foo, 'bar', 2, 'bar']
2098  * a.index {|element| element == 'bar' } # => 1
2099  *
2100  * Returns +nil+ if the block never returns a truthy value.
2101  *
2102  * With neither an argument nor a block given, returns a new Enumerator.
2103  *
2104  * Related: see {Methods for Querying}[rdoc-ref:Array@Methods+for+Querying].
2105  */
2106 
2107 static VALUE
2108 rb_ary_index(int argc, VALUE *argv, VALUE ary)
2109 {
2110  VALUE val;
2111  long i;
2112 
2113  if (argc == 0) {
2114  RETURN_ENUMERATOR(ary, 0, 0);
2115  for (i=0; i<RARRAY_LEN(ary); i++) {
2116  if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) {
2117  return LONG2NUM(i);
2118  }
2119  }
2120  return Qnil;
2121  }
2122  rb_check_arity(argc, 0, 1);
2123  val = argv[0];
2124  if (rb_block_given_p())
2125  rb_warn("given block not used");
2126  for (i=0; i<RARRAY_LEN(ary); i++) {
2127  VALUE e = RARRAY_AREF(ary, i);
2128  if (rb_equal(e, val)) {
2129  return LONG2NUM(i);
2130  }
2131  }
2132  return Qnil;
2133 }
2134 
2135 /*
2136  * call-seq:
2137  * rindex(object) -> integer or nil
2138  * rindex {|element| ... } -> integer or nil
2139  * rindex -> new_enumerator
2140  *
2141  * Returns the index of the last element for which <tt>object == element</tt>.
2142  *
2143  * With argument +object+ given, returns the index of the last such element found:
2144  *
2145  * a = [:foo, 'bar', 2, 'bar']
2146  * a.rindex('bar') # => 3
2147  *
2148  * Returns +nil+ if no such object found.
2149  *
2150  * With a block given, calls the block with each successive element;
2151  * returns the index of the last element for which the block returns a truthy value:
2152  *
2153  * a = [:foo, 'bar', 2, 'bar']
2154  * a.rindex {|element| element == 'bar' } # => 3
2155  *
2156  * Returns +nil+ if the block never returns a truthy value.
2157  *
2158  * When neither an argument nor a block is given, returns a new Enumerator.
2159  *
2160  * Related: see {Methods for Querying}[rdoc-ref:Array@Methods+for+Querying].
2161  */
2162 
2163 static VALUE
2164 rb_ary_rindex(int argc, VALUE *argv, VALUE ary)
2165 {
2166  VALUE val;
2167  long i = RARRAY_LEN(ary), len;
2168 
2169  if (argc == 0) {
2170  RETURN_ENUMERATOR(ary, 0, 0);
2171  while (i--) {
2172  if (RTEST(rb_yield(RARRAY_AREF(ary, i))))
2173  return LONG2NUM(i);
2174  if (i > (len = RARRAY_LEN(ary))) {
2175  i = len;
2176  }
2177  }
2178  return Qnil;
2179  }
2180  rb_check_arity(argc, 0, 1);
2181  val = argv[0];
2182  if (rb_block_given_p())
2183  rb_warn("given block not used");
2184  while (i--) {
2185  VALUE e = RARRAY_AREF(ary, i);
2186  if (rb_equal(e, val)) {
2187  return LONG2NUM(i);
2188  }
2189  if (i > RARRAY_LEN(ary)) {
2190  break;
2191  }
2192  }
2193  return Qnil;
2194 }
2195 
2196 VALUE
2198 {
2199  VALUE tmp = rb_check_array_type(obj);
2200 
2201  if (!NIL_P(tmp)) return tmp;
2202  return rb_ary_new3(1, obj);
2203 }
2204 
2205 static void
2206 rb_ary_splice(VALUE ary, long beg, long len, const VALUE *rptr, long rlen)
2207 {
2208  long olen;
2209  long rofs;
2210 
2211  if (len < 0) rb_raise(rb_eIndexError, "negative length (%ld)", len);
2212  olen = RARRAY_LEN(ary);
2213  if (beg < 0) {
2214  beg += olen;
2215  if (beg < 0) {
2216  rb_raise(rb_eIndexError, "index %ld too small for array; minimum: %ld",
2217  beg - olen, -olen);
2218  }
2219  }
2220  if (olen < len || olen < beg + len) {
2221  len = olen - beg;
2222  }
2223 
2224  {
2225  const VALUE *optr = RARRAY_CONST_PTR(ary);
2226  rofs = (rptr >= optr && rptr < optr + olen) ? rptr - optr : -1;
2227  }
2228 
2229  if (beg >= olen) {
2230  VALUE target_ary;
2231  if (beg > ARY_MAX_SIZE - rlen) {
2232  rb_raise(rb_eIndexError, "index %ld too big", beg);
2233  }
2234  target_ary = ary_ensure_room_for_push(ary, rlen-len); /* len is 0 or negative */
2235  len = beg + rlen;
2236  ary_mem_clear(ary, olen, beg - olen);
2237  if (rlen > 0) {
2238  if (rofs != -1) rptr = RARRAY_CONST_PTR(ary) + rofs;
2239  ary_memcpy0(ary, beg, rlen, rptr, target_ary);
2240  }
2241  ARY_SET_LEN(ary, len);
2242  }
2243  else {
2244  long alen;
2245 
2246  if (olen - len > ARY_MAX_SIZE - rlen) {
2247  rb_raise(rb_eIndexError, "index %ld too big", olen + rlen - len);
2248  }
2249  rb_ary_modify(ary);
2250  alen = olen + rlen - len;
2251  if (alen >= ARY_CAPA(ary)) {
2252  ary_double_capa(ary, alen);
2253  }
2254 
2255  if (len != rlen) {
2257  MEMMOVE(ptr + beg + rlen, ptr + beg + len,
2258  VALUE, olen - (beg + len)));
2259  ARY_SET_LEN(ary, alen);
2260  }
2261  if (rlen > 0) {
2262  if (rofs == -1) {
2263  rb_gc_writebarrier_remember(ary);
2264  }
2265  else {
2266  /* In this case, we're copying from a region in this array, so
2267  * we don't need to fire the write barrier. */
2268  rptr = RARRAY_CONST_PTR(ary) + rofs;
2269  }
2270 
2271  /* do not use RARRAY_PTR() because it can causes GC.
2272  * ary can contain T_NONE object because it is not cleared.
2273  */
2275  MEMMOVE(ptr + beg, rptr, VALUE, rlen));
2276  }
2277  }
2278 }
2279 
2280 void
2281 rb_ary_set_len(VALUE ary, long len)
2282 {
2283  long capa;
2284 
2285  rb_ary_modify_check(ary);
2286  if (ARY_SHARED_P(ary)) {
2287  rb_raise(rb_eRuntimeError, "can't set length of shared ");
2288  }
2289  if (len > (capa = (long)ARY_CAPA(ary))) {
2290  rb_bug("probable buffer overflow: %ld for %ld", len, capa);
2291  }
2292  ARY_SET_LEN(ary, len);
2293 }
2294 
2295 VALUE
2297 {
2298  long olen;
2299 
2300  rb_ary_modify(ary);
2301  olen = RARRAY_LEN(ary);
2302  if (len == olen) return ary;
2303  if (len > ARY_MAX_SIZE) {
2304  rb_raise(rb_eIndexError, "index %ld too big", len);
2305  }
2306  if (len > olen) {
2307  if (len >= ARY_CAPA(ary)) {
2308  ary_double_capa(ary, len);
2309  }
2310  ary_mem_clear(ary, olen, len - olen);
2311  ARY_SET_LEN(ary, len);
2312  }
2313  else if (ARY_EMBED_P(ary)) {
2314  ARY_SET_EMBED_LEN(ary, len);
2315  }
2316  else if (len <= ary_embed_capa(ary)) {
2317  const VALUE *ptr = ARY_HEAP_PTR(ary);
2318  long ptr_capa = ARY_HEAP_SIZE(ary);
2319  bool is_malloc_ptr = !ARY_SHARED_P(ary);
2320 
2321  FL_SET_EMBED(ary);
2322 
2323  MEMCPY((VALUE *)ARY_EMBED_PTR(ary), ptr, VALUE, len); /* WB: no new reference */
2324  ARY_SET_EMBED_LEN(ary, len);
2325 
2326  if (is_malloc_ptr) ruby_sized_xfree((void *)ptr, ptr_capa);
2327  }
2328  else {
2329  if (olen > len + ARY_DEFAULT_SIZE) {
2330  size_t new_capa = ary_heap_realloc(ary, len);
2331  ARY_SET_CAPA(ary, new_capa);
2332  }
2333  ARY_SET_HEAP_LEN(ary, len);
2334  }
2335  ary_verify(ary);
2336  return ary;
2337 }
2338 
2339 static VALUE
2340 ary_aset_by_rb_ary_store(VALUE ary, long key, VALUE val)
2341 {
2342  rb_ary_store(ary, key, val);
2343  return val;
2344 }
2345 
2346 static VALUE
2347 ary_aset_by_rb_ary_splice(VALUE ary, long beg, long len, VALUE val)
2348 {
2349  VALUE rpl = rb_ary_to_ary(val);
2350  rb_ary_splice(ary, beg, len, RARRAY_CONST_PTR(rpl), RARRAY_LEN(rpl));
2351  RB_GC_GUARD(rpl);
2352  return val;
2353 }
2354 
2355 /*
2356  * call-seq:
2357  * self[index] = object -> object
2358  * self[start, length] = object -> object
2359  * self[range] = object -> object
2360  *
2361  * Assigns elements in +self+, based on the given +object+; returns +object+.
2362  *
2363  * In brief:
2364  *
2365  * a_orig = [:foo, 'bar', 2]
2366  *
2367  * # With argument index.
2368  * a = a_orig.dup
2369  * a[0] = 'foo' # => "foo"
2370  * a # => ["foo", "bar", 2]
2371  * a = a_orig.dup
2372  * a[7] = 'foo' # => "foo"
2373  * a # => [:foo, "bar", 2, nil, nil, nil, nil, "foo"]
2374  *
2375  * # With arguments start and length.
2376  * a = a_orig.dup
2377  * a[0, 2] = 'foo' # => "foo"
2378  * a # => ["foo", 2]
2379  * a = a_orig.dup
2380  * a[6, 50] = 'foo' # => "foo"
2381  * a # => [:foo, "bar", 2, nil, nil, nil, "foo"]
2382  *
2383  * # With argument range.
2384  * a = a_orig.dup
2385  * a[0..1] = 'foo' # => "foo"
2386  * a # => ["foo", 2]
2387  * a = a_orig.dup
2388  * a[6..50] = 'foo' # => "foo"
2389  * a # => [:foo, "bar", 2, nil, nil, nil, "foo"]
2390  *
2391  * When Integer argument +index+ is given, assigns +object+ to an element in +self+.
2392  *
2393  * If +index+ is non-negative, assigns +object+ the element at offset +index+:
2394  *
2395  * a = [:foo, 'bar', 2]
2396  * a[0] = 'foo' # => "foo"
2397  * a # => ["foo", "bar", 2]
2398  *
2399  * If +index+ is greater than <tt>self.length</tt>, extends the array:
2400  *
2401  * a = [:foo, 'bar', 2]
2402  * a[7] = 'foo' # => "foo"
2403  * a # => [:foo, "bar", 2, nil, nil, nil, nil, "foo"]
2404  *
2405  * If +index+ is negative, counts backwards from the end of the array:
2406  *
2407  * a = [:foo, 'bar', 2]
2408  * a[-1] = 'two' # => "two"
2409  * a # => [:foo, "bar", "two"]
2410  *
2411  * When Integer arguments +start+ and +length+ are given and +object+ is not an +Array+,
2412  * removes <tt>length - 1</tt> elements beginning at offset +start+,
2413  * and assigns +object+ at offset +start+:
2414  *
2415  * a = [:foo, 'bar', 2]
2416  * a[0, 2] = 'foo' # => "foo"
2417  * a # => ["foo", 2]
2418  *
2419  * If +start+ is negative, counts backwards from the end of the array:
2420  *
2421  * a = [:foo, 'bar', 2]
2422  * a[-2, 2] = 'foo' # => "foo"
2423  * a # => [:foo, "foo"]
2424  *
2425  * If +start+ is non-negative and outside the array (<tt> >= self.size</tt>),
2426  * extends the array with +nil+, assigns +object+ at offset +start+,
2427  * and ignores +length+:
2428  *
2429  * a = [:foo, 'bar', 2]
2430  * a[6, 50] = 'foo' # => "foo"
2431  * a # => [:foo, "bar", 2, nil, nil, nil, "foo"]
2432  *
2433  * If +length+ is zero, shifts elements at and following offset +start+
2434  * and assigns +object+ at offset +start+:
2435  *
2436  * a = [:foo, 'bar', 2]
2437  * a[1, 0] = 'foo' # => "foo"
2438  * a # => [:foo, "foo", "bar", 2]
2439  *
2440  * If +length+ is too large for the existing array, does not extend the array:
2441  *
2442  * a = [:foo, 'bar', 2]
2443  * a[1, 5] = 'foo' # => "foo"
2444  * a # => [:foo, "foo"]
2445  *
2446  * When Range argument +range+ is given and +object+ is not an +Array+,
2447  * removes <tt>length - 1</tt> elements beginning at offset +start+,
2448  * and assigns +object+ at offset +start+:
2449  *
2450  * a = [:foo, 'bar', 2]
2451  * a[0..1] = 'foo' # => "foo"
2452  * a # => ["foo", 2]
2453  *
2454  * if <tt>range.begin</tt> is negative, counts backwards from the end of the array:
2455  *
2456  * a = [:foo, 'bar', 2]
2457  * a[-2..2] = 'foo' # => "foo"
2458  * a # => [:foo, "foo"]
2459  *
2460  * If the array length is less than <tt>range.begin</tt>,
2461  * extends the array with +nil+, assigns +object+ at offset <tt>range.begin</tt>,
2462  * and ignores +length+:
2463  *
2464  * a = [:foo, 'bar', 2]
2465  * a[6..50] = 'foo' # => "foo"
2466  * a # => [:foo, "bar", 2, nil, nil, nil, "foo"]
2467  *
2468  * If <tt>range.end</tt> is zero, shifts elements at and following offset +start+
2469  * and assigns +object+ at offset +start+:
2470  *
2471  * a = [:foo, 'bar', 2]
2472  * a[1..0] = 'foo' # => "foo"
2473  * a # => [:foo, "foo", "bar", 2]
2474  *
2475  * If <tt>range.end</tt> is negative, assigns +object+ at offset +start+,
2476  * retains <tt>range.end.abs -1</tt> elements past that, and removes those beyond:
2477  *
2478  * a = [:foo, 'bar', 2]
2479  * a[1..-1] = 'foo' # => "foo"
2480  * a # => [:foo, "foo"]
2481  * a = [:foo, 'bar', 2]
2482  * a[1..-2] = 'foo' # => "foo"
2483  * a # => [:foo, "foo", 2]
2484  * a = [:foo, 'bar', 2]
2485  * a[1..-3] = 'foo' # => "foo"
2486  * a # => [:foo, "foo", "bar", 2]
2487  * a = [:foo, 'bar', 2]
2488  *
2489  * If <tt>range.end</tt> is too large for the existing array,
2490  * replaces array elements, but does not extend the array with +nil+ values:
2491  *
2492  * a = [:foo, 'bar', 2]
2493  * a[1..5] = 'foo' # => "foo"
2494  * a # => [:foo, "foo"]
2495  *
2496  * Related: see {Methods for Assigning}[rdoc-ref:Array@Methods+for+Assigning].
2497  */
2498 
2499 static VALUE
2500 rb_ary_aset(int argc, VALUE *argv, VALUE ary)
2501 {
2502  long offset, beg, len;
2503 
2504  rb_check_arity(argc, 2, 3);
2505  rb_ary_modify_check(ary);
2506  if (argc == 3) {
2507  beg = NUM2LONG(argv[0]);
2508  len = NUM2LONG(argv[1]);
2509  return ary_aset_by_rb_ary_splice(ary, beg, len, argv[2]);
2510  }
2511  if (FIXNUM_P(argv[0])) {
2512  offset = FIX2LONG(argv[0]);
2513  return ary_aset_by_rb_ary_store(ary, offset, argv[1]);
2514  }
2515  if (rb_range_beg_len(argv[0], &beg, &len, RARRAY_LEN(ary), 1)) {
2516  /* check if idx is Range */
2517  return ary_aset_by_rb_ary_splice(ary, beg, len, argv[1]);
2518  }
2519 
2520  offset = NUM2LONG(argv[0]);
2521  return ary_aset_by_rb_ary_store(ary, offset, argv[1]);
2522 }
2523 
2524 /*
2525  * call-seq:
2526  * insert(index, *objects) -> self
2527  *
2528  * Inserts the given +objects+ as elements of +self+;
2529  * returns +self+.
2530  *
2531  * When +index+ is non-negative, inserts +objects+
2532  * _before_ the element at offset +index+:
2533  *
2534  * a = ['a', 'b', 'c'] # => ["a", "b", "c"]
2535  * a.insert(1, :x, :y, :z) # => ["a", :x, :y, :z, "b", "c"]
2536  *
2537  * Extends the array if +index+ is beyond the array (<tt>index >= self.size</tt>):
2538  *
2539  * a = ['a', 'b', 'c'] # => ["a", "b", "c"]
2540  * a.insert(5, :x, :y, :z) # => ["a", "b", "c", nil, nil, :x, :y, :z]
2541  *
2542  * When +index+ is negative, inserts +objects+
2543  * _after_ the element at offset <tt>index + self.size</tt>:
2544  *
2545  * a = ['a', 'b', 'c'] # => ["a", "b", "c"]
2546  * a.insert(-2, :x, :y, :z) # => ["a", "b", :x, :y, :z, "c"]
2547  *
2548  * With no +objects+ given, does nothing:
2549  *
2550  * a = ['a', 'b', 'c'] # => ["a", "b", "c"]
2551  * a.insert(1) # => ["a", "b", "c"]
2552  * a.insert(50) # => ["a", "b", "c"]
2553  * a.insert(-50) # => ["a", "b", "c"]
2554  *
2555  * Raises IndexError if +objects+ are given and +index+ is negative and out of range.
2556  *
2557  * Related: see {Methods for Assigning}[rdoc-ref:Array@Methods+for+Assigning].
2558  */
2559 
2560 static VALUE
2561 rb_ary_insert(int argc, VALUE *argv, VALUE ary)
2562 {
2563  long pos;
2564 
2566  rb_ary_modify_check(ary);
2567  pos = NUM2LONG(argv[0]);
2568  if (argc == 1) return ary;
2569  if (pos == -1) {
2570  pos = RARRAY_LEN(ary);
2571  }
2572  else if (pos < 0) {
2573  long minpos = -RARRAY_LEN(ary) - 1;
2574  if (pos < minpos) {
2575  rb_raise(rb_eIndexError, "index %ld too small for array; minimum: %ld",
2576  pos, minpos);
2577  }
2578  pos++;
2579  }
2580  rb_ary_splice(ary, pos, 0, argv + 1, argc - 1);
2581  return ary;
2582 }
2583 
2584 static VALUE
2585 rb_ary_length(VALUE ary);
2586 
2587 static VALUE
2588 ary_enum_length(VALUE ary, VALUE args, VALUE eobj)
2589 {
2590  return rb_ary_length(ary);
2591 }
2592 
2593 // Primitive to avoid a race condition in Array#each.
2594 // Return `true` and write `value` and `index` if the element exists.
2595 static VALUE
2596 ary_fetch_next(VALUE self, VALUE *index, VALUE *value)
2597 {
2598  long i = NUM2LONG(*index);
2599  if (i >= RARRAY_LEN(self)) {
2600  return Qfalse;
2601  }
2602  *value = RARRAY_AREF(self, i);
2603  *index = LONG2NUM(i + 1);
2604  return Qtrue;
2605 }
2606 
2607 /*
2608  * call-seq:
2609  * each {|element| ... } -> self
2610  * each -> new_enumerator
2611  *
2612  * With a block given, iterates over the elements of +self+,
2613  * passing each element to the block;
2614  * returns +self+:
2615  *
2616  * a = [:foo, 'bar', 2]
2617  * a.each {|element| puts "#{element.class} #{element}" }
2618  *
2619  * Output:
2620  *
2621  * Symbol foo
2622  * String bar
2623  * Integer 2
2624  *
2625  * Allows the array to be modified during iteration:
2626  *
2627  * a = [:foo, 'bar', 2]
2628  * a.each {|element| puts element; a.clear if element.to_s.start_with?('b') }
2629  *
2630  * Output:
2631  *
2632  * foo
2633  * bar
2634  *
2635  * With no block given, returns a new Enumerator.
2636  *
2637  * Related: see {Methods for Iterating}[rdoc-ref:Array@Methods+for+Iterating].
2638  */
2639 
2640 VALUE
2642 {
2643  long i;
2644  ary_verify(ary);
2645  RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
2646  for (i=0; i<RARRAY_LEN(ary); i++) {
2647  rb_yield(RARRAY_AREF(ary, i));
2648  }
2649  return ary;
2650 }
2651 
2652 /*
2653  * call-seq:
2654  * each_index {|index| ... } -> self
2655  * each_index -> new_enumerator
2656  *
2657  * With a block given, iterates over the elements of +self+,
2658  * passing each <i>array index</i> to the block;
2659  * returns +self+:
2660  *
2661  * a = [:foo, 'bar', 2]
2662  * a.each_index {|index| puts "#{index} #{a[index]}" }
2663  *
2664  * Output:
2665  *
2666  * 0 foo
2667  * 1 bar
2668  * 2 2
2669  *
2670  * Allows the array to be modified during iteration:
2671  *
2672  * a = [:foo, 'bar', 2]
2673  * a.each_index {|index| puts index; a.clear if index > 0 }
2674  * a # => []
2675  *
2676  * Output:
2677  *
2678  * 0
2679  * 1
2680  *
2681  * With no block given, returns a new Enumerator.
2682  *
2683  * Related: see {Methods for Iterating}[rdoc-ref:Array@Methods+for+Iterating].
2684  */
2685 
2686 static VALUE
2687 rb_ary_each_index(VALUE ary)
2688 {
2689  long i;
2690  RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
2691 
2692  for (i=0; i<RARRAY_LEN(ary); i++) {
2693  rb_yield(LONG2NUM(i));
2694  }
2695  return ary;
2696 }
2697 
2698 /*
2699  * call-seq:
2700  * reverse_each {|element| ... } -> self
2701  * reverse_each -> Enumerator
2702  *
2703  * When a block given, iterates backwards over the elements of +self+,
2704  * passing, in reverse order, each element to the block;
2705  * returns +self+:
2706  *
2707  * a = []
2708  * [0, 1, 2].reverse_each {|element| a.push(element) }
2709  * a # => [2, 1, 0]
2710  *
2711  * Allows the array to be modified during iteration:
2712  *
2713  * a = ['a', 'b', 'c']
2714  * a.reverse_each {|element| a.clear if element.start_with?('b') }
2715  * a # => []
2716  *
2717  * When no block given, returns a new Enumerator.
2718  *
2719  * Related: see {Methods for Iterating}[rdoc-ref:Array@Methods+for+Iterating].
2720  */
2721 
2722 static VALUE
2723 rb_ary_reverse_each(VALUE ary)
2724 {
2725  long len;
2726 
2727  RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
2728  len = RARRAY_LEN(ary);
2729  while (len--) {
2730  long nlen;
2732  nlen = RARRAY_LEN(ary);
2733  if (nlen < len) {
2734  len = nlen;
2735  }
2736  }
2737  return ary;
2738 }
2739 
2740 /*
2741  * call-seq:
2742  * length -> integer
2743  * size -> integer
2744  *
2745  * Returns the count of elements in +self+:
2746  *
2747  * [0, 1, 2].length # => 3
2748  * [].length # => 0
2749  *
2750  * Related: see {Methods for Querying}[rdoc-ref:Array@Methods+for+Querying].
2751  */
2752 
2753 static VALUE
2754 rb_ary_length(VALUE ary)
2755 {
2756  long len = RARRAY_LEN(ary);
2757  return LONG2NUM(len);
2758 }
2759 
2760 /*
2761  * call-seq:
2762  * array.empty? -> true or false
2763  *
2764  * Returns +true+ if the count of elements in +self+ is zero,
2765  * +false+ otherwise.
2766  *
2767  * Related: see {Methods for Querying}[rdoc-ref:Array@Methods+for+Querying].
2768  */
2769 
2770 static VALUE
2771 rb_ary_empty_p(VALUE ary)
2772 {
2773  return RBOOL(RARRAY_LEN(ary) == 0);
2774 }
2775 
2776 VALUE
2778 {
2779  long len = RARRAY_LEN(ary);
2780  VALUE dup = rb_ary_new2(len);
2781  ary_memcpy(dup, 0, len, RARRAY_CONST_PTR(ary));
2782  ARY_SET_LEN(dup, len);
2783 
2784  ary_verify(ary);
2785  ary_verify(dup);
2786  return dup;
2787 }
2788 
2789 VALUE
2791 {
2792  return ary_make_partial(ary, rb_cArray, 0, RARRAY_LEN(ary));
2793 }
2794 
2795 extern VALUE rb_output_fs;
2796 
2797 static void ary_join_1(VALUE obj, VALUE ary, VALUE sep, long i, VALUE result, int *first);
2798 
2799 static VALUE
2800 recursive_join(VALUE obj, VALUE argp, int recur)
2801 {
2802  VALUE *arg = (VALUE *)argp;
2803  VALUE ary = arg[0];
2804  VALUE sep = arg[1];
2805  VALUE result = arg[2];
2806  int *first = (int *)arg[3];
2807 
2808  if (recur) {
2809  rb_raise(rb_eArgError, "recursive array join");
2810  }
2811  else {
2812  ary_join_1(obj, ary, sep, 0, result, first);
2813  }
2814  return Qnil;
2815 }
2816 
2817 static long
2818 ary_join_0(VALUE ary, VALUE sep, long max, VALUE result)
2819 {
2820  long i;
2821  VALUE val;
2822 
2823  if (max > 0) rb_enc_copy(result, RARRAY_AREF(ary, 0));
2824  for (i=0; i<max; i++) {
2825  val = RARRAY_AREF(ary, i);
2826  if (!RB_TYPE_P(val, T_STRING)) break;
2827  if (i > 0 && !NIL_P(sep))
2828  rb_str_buf_append(result, sep);
2829  rb_str_buf_append(result, val);
2830  }
2831  return i;
2832 }
2833 
2834 static void
2835 ary_join_1_str(VALUE dst, VALUE src, int *first)
2836 {
2837  rb_str_buf_append(dst, src);
2838  if (*first) {
2839  rb_enc_copy(dst, src);
2840  *first = FALSE;
2841  }
2842 }
2843 
2844 static void
2845 ary_join_1_ary(VALUE obj, VALUE ary, VALUE sep, VALUE result, VALUE val, int *first)
2846 {
2847  if (val == ary) {
2848  rb_raise(rb_eArgError, "recursive array join");
2849  }
2850  else {
2851  VALUE args[4];
2852 
2853  *first = FALSE;
2854  args[0] = val;
2855  args[1] = sep;
2856  args[2] = result;
2857  args[3] = (VALUE)first;
2858  rb_exec_recursive(recursive_join, obj, (VALUE)args);
2859  }
2860 }
2861 
2862 static void
2863 ary_join_1(VALUE obj, VALUE ary, VALUE sep, long i, VALUE result, int *first)
2864 {
2865  VALUE val, tmp;
2866 
2867  for (; i<RARRAY_LEN(ary); i++) {
2868  if (i > 0 && !NIL_P(sep))
2869  rb_str_buf_append(result, sep);
2870 
2871  val = RARRAY_AREF(ary, i);
2872  if (RB_TYPE_P(val, T_STRING)) {
2873  ary_join_1_str(result, val, first);
2874  }
2875  else if (RB_TYPE_P(val, T_ARRAY)) {
2876  ary_join_1_ary(val, ary, sep, result, val, first);
2877  }
2878  else if (!NIL_P(tmp = rb_check_string_type(val))) {
2879  ary_join_1_str(result, tmp, first);
2880  }
2881  else if (!NIL_P(tmp = rb_check_array_type(val))) {
2882  ary_join_1_ary(val, ary, sep, result, tmp, first);
2883  }
2884  else {
2885  ary_join_1_str(result, rb_obj_as_string(val), first);
2886  }
2887  }
2888 }
2889 
2890 VALUE
2892 {
2893  long len = 1, i;
2894  VALUE val, tmp, result;
2895 
2896  if (RARRAY_LEN(ary) == 0) return rb_usascii_str_new(0, 0);
2897 
2898  if (!NIL_P(sep)) {
2899  StringValue(sep);
2900  len += RSTRING_LEN(sep) * (RARRAY_LEN(ary) - 1);
2901  }
2902  for (i=0; i<RARRAY_LEN(ary); i++) {
2903  val = RARRAY_AREF(ary, i);
2904  tmp = rb_check_string_type(val);
2905 
2906  if (NIL_P(tmp) || tmp != val) {
2907  int first;
2908  long n = RARRAY_LEN(ary);
2909  if (i > n) i = n;
2910  result = rb_str_buf_new(len + (n-i)*10);
2912  i = ary_join_0(ary, sep, i, result);
2913  first = i == 0;
2914  ary_join_1(ary, ary, sep, i, result, &first);
2915  return result;
2916  }
2917 
2918  len += RSTRING_LEN(tmp);
2919  }
2920 
2921  result = rb_str_new(0, len);
2922  rb_str_set_len(result, 0);
2923 
2924  ary_join_0(ary, sep, RARRAY_LEN(ary), result);
2925 
2926  return result;
2927 }
2928 
2929 /*
2930  * call-seq:
2931  * array.join(separator = $,) -> new_string
2932  *
2933  * Returns the new string formed by joining the converted elements of +self+;
2934  * for each element +element+:
2935  *
2936  * - Converts recursively using <tt>element.join(separator)</tt>
2937  * if +element+ is a <tt>kind_of?(Array)</tt>.
2938  * - Otherwise, converts using <tt>element.to_s</tt>.
2939  *
2940  * With no argument given, joins using the output field separator, <tt>$,</tt>:
2941  *
2942  * a = [:foo, 'bar', 2]
2943  * $, # => nil
2944  * a.join # => "foobar2"
2945  *
2946  * With string argument +separator+ given, joins using that separator:
2947  *
2948  * a = [:foo, 'bar', 2]
2949  * a.join("\n") # => "foo\nbar\n2"
2950  *
2951  * Joins recursively for nested arrays:
2952  *
2953  * a = [:foo, [:bar, [:baz, :bat]]]
2954  * a.join # => "foobarbazbat"
2955  *
2956  * Related: see {Methods for Converting}[rdoc-ref:Array@Methods+for+Converting].
2957  */
2958 static VALUE
2959 rb_ary_join_m(int argc, VALUE *argv, VALUE ary)
2960 {
2961  VALUE sep;
2962 
2963  if (rb_check_arity(argc, 0, 1) == 0 || NIL_P(sep = argv[0])) {
2964  sep = rb_output_fs;
2965  if (!NIL_P(sep)) {
2966  rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, "$, is set to non-nil value");
2967  }
2968  }
2969 
2970  return rb_ary_join(ary, sep);
2971 }
2972 
2973 static VALUE
2974 inspect_ary(VALUE ary, VALUE dummy, int recur)
2975 {
2976  long i;
2977  VALUE s, str;
2978 
2979  if (recur) return rb_usascii_str_new_cstr("[...]");
2980  str = rb_str_buf_new2("[");
2981  for (i=0; i<RARRAY_LEN(ary); i++) {
2982  s = rb_inspect(RARRAY_AREF(ary, i));
2983  if (i > 0) rb_str_buf_cat2(str, ", ");
2984  else rb_enc_copy(str, s);
2985  rb_str_buf_append(str, s);
2986  }
2987  rb_str_buf_cat2(str, "]");
2988  return str;
2989 }
2990 
2991 /*
2992  * call-seq:
2993  * inspect -> new_string
2994  * to_s -> new_string
2995  *
2996  * Returns the new string formed by calling method <tt>#inspect</tt>
2997  * on each array element:
2998  *
2999  * a = [:foo, 'bar', 2]
3000  * a.inspect # => "[:foo, \"bar\", 2]"
3001  *
3002  * Related: see {Methods for Converting}[rdoc-ref:Array@Methods+for+Converting].
3003  */
3004 
3005 static VALUE
3006 rb_ary_inspect(VALUE ary)
3007 {
3008  if (RARRAY_LEN(ary) == 0) return rb_usascii_str_new2("[]");
3009  return rb_exec_recursive(inspect_ary, ary, 0);
3010 }
3011 
3012 VALUE
3014 {
3015  return rb_ary_inspect(ary);
3016 }
3017 
3018 /*
3019  * call-seq:
3020  * to_a -> self or new_array
3021  *
3022  * When +self+ is an instance of +Array+, returns +self+.
3023  *
3024  * Otherwise, returns a new array containing the elements of +self+:
3025  *
3026  * class MyArray < Array; end
3027  * my_a = MyArray.new(['foo', 'bar', 'two'])
3028  * a = my_a.to_a
3029  * a # => ["foo", "bar", "two"]
3030  * a.class # => Array # Not MyArray.
3031  *
3032  * Related: see {Methods for Converting}[rdoc-ref:Array@Methods+for+Converting].
3033  */
3034 
3035 static VALUE
3036 rb_ary_to_a(VALUE ary)
3037 {
3038  if (rb_obj_class(ary) != rb_cArray) {
3039  VALUE dup = rb_ary_new2(RARRAY_LEN(ary));
3040  rb_ary_replace(dup, ary);
3041  return dup;
3042  }
3043  return ary;
3044 }
3045 
3046 /*
3047  * call-seq:
3048  * to_h -> new_hash
3049  * to_h {|element| ... } -> new_hash
3050  *
3051  * Returns a new hash formed from +self+.
3052  *
3053  * With no block given, each element of +self+ must be a 2-element sub-array;
3054  * forms each sub-array into a key-value pair in the new hash:
3055  *
3056  * a = [['foo', 'zero'], ['bar', 'one'], ['baz', 'two']]
3057  * a.to_h # => {"foo"=>"zero", "bar"=>"one", "baz"=>"two"}
3058  * [].to_h # => {}
3059  *
3060  * With a block given, the block must return a 2-element array;
3061  * calls the block with each element of +self+;
3062  * forms each returned array into a key-value pair in the returned hash:
3063  *
3064  * a = ['foo', :bar, 1, [2, 3], {baz: 4}]
3065  * a.to_h {|element| [element, element.class] }
3066  * # => {"foo"=>String, :bar=>Symbol, 1=>Integer, [2, 3]=>Array, {:baz=>4}=>Hash}
3067  *
3068  * Related: see {Methods for Converting}[rdoc-ref:Array@Methods+for+Converting].
3069  */
3070 
3071 static VALUE
3072 rb_ary_to_h(VALUE ary)
3073 {
3074  long i;
3075  VALUE hash = rb_hash_new_with_size(RARRAY_LEN(ary));
3076  int block_given = rb_block_given_p();
3077 
3078  for (i=0; i<RARRAY_LEN(ary); i++) {
3079  const VALUE e = rb_ary_elt(ary, i);
3080  const VALUE elt = block_given ? rb_yield_force_blockarg(e) : e;
3081  const VALUE key_value_pair = rb_check_array_type(elt);
3082  if (NIL_P(key_value_pair)) {
3083  rb_raise(rb_eTypeError, "wrong element type %"PRIsVALUE" at %ld (expected array)",
3084  rb_obj_class(elt), i);
3085  }
3086  if (RARRAY_LEN(key_value_pair) != 2) {
3087  rb_raise(rb_eArgError, "wrong array length at %ld (expected 2, was %ld)",
3088  i, RARRAY_LEN(key_value_pair));
3089  }
3090  rb_hash_aset(hash, RARRAY_AREF(key_value_pair, 0), RARRAY_AREF(key_value_pair, 1));
3091  }
3092  return hash;
3093 }
3094 
3095 /*
3096  * call-seq:
3097  * array.to_ary -> self
3098  *
3099  * Returns +self+.
3100  */
3101 
3102 static VALUE
3103 rb_ary_to_ary_m(VALUE ary)
3104 {
3105  return ary;
3106 }
3107 
3108 static void
3109 ary_reverse(VALUE *p1, VALUE *p2)
3110 {
3111  while (p1 < p2) {
3112  VALUE tmp = *p1;
3113  *p1++ = *p2;
3114  *p2-- = tmp;
3115  }
3116 }
3117 
3118 VALUE
3120 {
3121  VALUE *p2;
3122  long len = RARRAY_LEN(ary);
3123 
3124  rb_ary_modify(ary);
3125  if (len > 1) {
3126  RARRAY_PTR_USE(ary, p1, {
3127  p2 = p1 + len - 1; /* points last item */
3128  ary_reverse(p1, p2);
3129  }); /* WB: no new reference */
3130  }
3131  return ary;
3132 }
3133 
3134 /*
3135  * call-seq:
3136  * reverse! -> self
3137  *
3138  * Reverses the order of the elements of +self+;
3139  * returns +self+:
3140  *
3141  * a = [0, 1, 2]
3142  * a.reverse! # => [2, 1, 0]
3143  * a # => [2, 1, 0]
3144  *
3145  * Related: see {Methods for Assigning}[rdoc-ref:Array@Methods+for+Assigning].
3146  */
3147 
3148 static VALUE
3149 rb_ary_reverse_bang(VALUE ary)
3150 {
3151  return rb_ary_reverse(ary);
3152 }
3153 
3154 /*
3155  * call-seq:
3156  * reverse -> new_array
3157  *
3158  * Returns a new array containing the elements of +self+ in reverse order:
3159  *
3160  * [0, 1, 2].reverse # => [2, 1, 0]
3161  *
3162  * Related: see {Methods for Combining}[rdoc-ref:Array@Methods+for+Combining].
3163  */
3164 
3165 static VALUE
3166 rb_ary_reverse_m(VALUE ary)
3167 {
3168  long len = RARRAY_LEN(ary);
3169  VALUE dup = rb_ary_new2(len);
3170 
3171  if (len > 0) {
3172  const VALUE *p1 = RARRAY_CONST_PTR(ary);
3173  VALUE *p2 = (VALUE *)RARRAY_CONST_PTR(dup) + len - 1;
3174  do *p2-- = *p1++; while (--len > 0);
3175  }
3176  ARY_SET_LEN(dup, RARRAY_LEN(ary));
3177  return dup;
3178 }
3179 
3180 static inline long
3181 rotate_count(long cnt, long len)
3182 {
3183  return (cnt < 0) ? (len - (~cnt % len) - 1) : (cnt % len);
3184 }
3185 
3186 static void
3187 ary_rotate_ptr(VALUE *ptr, long len, long cnt)
3188 {
3189  if (cnt == 1) {
3190  VALUE tmp = *ptr;
3191  memmove(ptr, ptr + 1, sizeof(VALUE)*(len - 1));
3192  *(ptr + len - 1) = tmp;
3193  }
3194  else if (cnt == len - 1) {
3195  VALUE tmp = *(ptr + len - 1);
3196  memmove(ptr + 1, ptr, sizeof(VALUE)*(len - 1));
3197  *ptr = tmp;
3198  }
3199  else {
3200  --len;
3201  if (cnt < len) ary_reverse(ptr + cnt, ptr + len);
3202  if (--cnt > 0) ary_reverse(ptr, ptr + cnt);
3203  if (len > 0) ary_reverse(ptr, ptr + len);
3204  }
3205 }
3206 
3207 VALUE
3209 {
3210  rb_ary_modify(ary);
3211 
3212  if (cnt != 0) {
3213  long len = RARRAY_LEN(ary);
3214  if (len > 1 && (cnt = rotate_count(cnt, len)) > 0) {
3215  RARRAY_PTR_USE(ary, ptr, ary_rotate_ptr(ptr, len, cnt));
3216  return ary;
3217  }
3218  }
3219  return Qnil;
3220 }
3221 
3222 /*
3223  * call-seq:
3224  * rotate!(count = 1) -> self
3225  *
3226  * Rotates +self+ in place by moving elements from one end to the other; returns +self+.
3227  *
3228  * With non-negative numeric +count+,
3229  * rotates +count+ elements from the beginning to the end:
3230  *
3231  * [0, 1, 2, 3].rotate!(2) # => [2, 3, 0, 1]
3232  [0, 1, 2, 3].rotate!(2.1) # => [2, 3, 0, 1]
3233  *
3234  * If +count+ is large, uses <tt>count % array.size</tt> as the count:
3235  *
3236  * [0, 1, 2, 3].rotate!(21) # => [1, 2, 3, 0]
3237  *
3238  * If +count+ is zero, rotates no elements:
3239  *
3240  * [0, 1, 2, 3].rotate!(0) # => [0, 1, 2, 3]
3241  *
3242  * With a negative numeric +count+, rotates in the opposite direction,
3243  * from end to beginning:
3244  *
3245  * [0, 1, 2, 3].rotate!(-1) # => [3, 0, 1, 2]
3246  *
3247  * If +count+ is small (far from zero), uses <tt>count % array.size</tt> as the count:
3248  *
3249  * [0, 1, 2, 3].rotate!(-21) # => [3, 0, 1, 2]
3250  *
3251  * Related: see {Methods for Assigning}[rdoc-ref:Array@Methods+for+Assigning].
3252  */
3253 
3254 static VALUE
3255 rb_ary_rotate_bang(int argc, VALUE *argv, VALUE ary)
3256 {
3257  long n = (rb_check_arity(argc, 0, 1) ? NUM2LONG(argv[0]) : 1);
3258  rb_ary_rotate(ary, n);
3259  return ary;
3260 }
3261 
3262 /*
3263  * call-seq:
3264  * rotate(count = 1) -> new_array
3265  *
3266  * Returns a new array formed from +self+ with elements
3267  * rotated from one end to the other.
3268  *
3269  * With non-negative numeric +count+,
3270  * rotates elements from the beginning to the end:
3271  *
3272  * [0, 1, 2, 3].rotate(2) # => [2, 3, 0, 1]
3273  * [0, 1, 2, 3].rotate(2.1) # => [2, 3, 0, 1]
3274  *
3275  * If +count+ is large, uses <tt>count % array.size</tt> as the count:
3276  *
3277  * [0, 1, 2, 3].rotate(22) # => [2, 3, 0, 1]
3278  *
3279  * With a +count+ of zero, rotates no elements:
3280  *
3281  * [0, 1, 2, 3].rotate(0) # => [0, 1, 2, 3]
3282  *
3283  * With negative numeric +count+, rotates in the opposite direction,
3284  * from the end to the beginning:
3285  *
3286  * [0, 1, 2, 3].rotate(-1) # => [3, 0, 1, 2]
3287  *
3288  * If +count+ is small (far from zero), uses <tt>count % array.size</tt> as the count:
3289  *
3290  * [0, 1, 2, 3].rotate(-21) # => [3, 0, 1, 2]
3291  *
3292  * Related: see {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching].
3293  */
3294 
3295 static VALUE
3296 rb_ary_rotate_m(int argc, VALUE *argv, VALUE ary)
3297 {
3298  VALUE rotated;
3299  const VALUE *ptr;
3300  long len;
3301  long cnt = (rb_check_arity(argc, 0, 1) ? NUM2LONG(argv[0]) : 1);
3302 
3303  len = RARRAY_LEN(ary);
3304  rotated = rb_ary_new2(len);
3305  if (len > 0) {
3306  cnt = rotate_count(cnt, len);
3308  len -= cnt;
3309  ary_memcpy(rotated, 0, len, ptr + cnt);
3310  ary_memcpy(rotated, len, cnt, ptr);
3311  }
3312  ARY_SET_LEN(rotated, RARRAY_LEN(ary));
3313  return rotated;
3314 }
3315 
3317  VALUE ary;
3318  VALUE receiver;
3319 };
3320 
3321 static VALUE
3322 sort_reentered(VALUE ary)
3323 {
3324  if (RBASIC(ary)->klass) {
3325  rb_raise(rb_eRuntimeError, "sort reentered");
3326  }
3327  return Qnil;
3328 }
3329 
3330 static void
3331 sort_returned(struct ary_sort_data *data)
3332 {
3333  if (rb_obj_frozen_p(data->receiver)) {
3334  rb_raise(rb_eFrozenError, "array frozen during sort");
3335  }
3336  sort_reentered(data->ary);
3337 }
3338 
3339 static int
3340 sort_1(const void *ap, const void *bp, void *dummy)
3341 {
3342  struct ary_sort_data *data = dummy;
3343  VALUE retval = sort_reentered(data->ary);
3344  VALUE a = *(const VALUE *)ap, b = *(const VALUE *)bp;
3345  VALUE args[2];
3346  int n;
3347 
3348  args[0] = a;
3349  args[1] = b;
3350  retval = rb_yield_values2(2, args);
3351  n = rb_cmpint(retval, a, b);
3352  sort_returned(data);
3353  return n;
3354 }
3355 
3356 static int
3357 sort_2(const void *ap, const void *bp, void *dummy)
3358 {
3359  struct ary_sort_data *data = dummy;
3360  VALUE retval = sort_reentered(data->ary);
3361  VALUE a = *(const VALUE *)ap, b = *(const VALUE *)bp;
3362  int n;
3363 
3364  if (FIXNUM_P(a) && FIXNUM_P(b) && CMP_OPTIMIZABLE(INTEGER)) {
3365  if ((long)a > (long)b) return 1;
3366  if ((long)a < (long)b) return -1;
3367  return 0;
3368  }
3369  if (STRING_P(a) && STRING_P(b) && CMP_OPTIMIZABLE(STRING)) {
3370  return rb_str_cmp(a, b);
3371  }
3372  if (RB_FLOAT_TYPE_P(a) && CMP_OPTIMIZABLE(FLOAT)) {
3373  return rb_float_cmp(a, b);
3374  }
3375 
3376  retval = rb_funcallv(a, id_cmp, 1, &b);
3377  n = rb_cmpint(retval, a, b);
3378  sort_returned(data);
3379 
3380  return n;
3381 }
3382 
3383 /*
3384  * call-seq:
3385  * sort! -> self
3386  * sort! {|a, b| ... } -> self
3387  *
3388  * Like Array#sort, but returns +self+ with its elements sorted in place.
3389  *
3390  * Related: see {Methods for Assigning}[rdoc-ref:Array@Methods+for+Assigning].
3391  */
3392 
3393 VALUE
3395 {
3396  rb_ary_modify(ary);
3397  RUBY_ASSERT(!ARY_SHARED_P(ary));
3398  if (RARRAY_LEN(ary) > 1) {
3399  VALUE tmp = ary_make_substitution(ary); /* only ary refers tmp */
3400  struct ary_sort_data data;
3401  long len = RARRAY_LEN(ary);
3402  RBASIC_CLEAR_CLASS(tmp);
3403  data.ary = tmp;
3404  data.receiver = ary;
3405  RARRAY_PTR_USE(tmp, ptr, {
3406  ruby_qsort(ptr, len, sizeof(VALUE),
3407  rb_block_given_p()?sort_1:sort_2, &data);
3408  }); /* WB: no new reference */
3409  rb_ary_modify(ary);
3410  if (ARY_EMBED_P(tmp)) {
3411  if (ARY_SHARED_P(ary)) { /* ary might be destructively operated in the given block */
3412  rb_ary_unshare(ary);
3413  FL_SET_EMBED(ary);
3414  }
3415  if (ARY_EMBED_LEN(tmp) > ARY_CAPA(ary)) {
3416  ary_resize_capa(ary, ARY_EMBED_LEN(tmp));
3417  }
3418  ary_memcpy(ary, 0, ARY_EMBED_LEN(tmp), ARY_EMBED_PTR(tmp));
3419  ARY_SET_LEN(ary, ARY_EMBED_LEN(tmp));
3420  }
3421  else {
3422  if (!ARY_EMBED_P(ary) && ARY_HEAP_PTR(ary) == ARY_HEAP_PTR(tmp)) {
3423  FL_UNSET_SHARED(ary);
3424  ARY_SET_CAPA(ary, RARRAY_LEN(tmp));
3425  }
3426  else {
3427  RUBY_ASSERT(!ARY_SHARED_P(tmp));
3428  if (ARY_EMBED_P(ary)) {
3429  FL_UNSET_EMBED(ary);
3430  }
3431  else if (ARY_SHARED_P(ary)) {
3432  /* ary might be destructively operated in the given block */
3433  rb_ary_unshare(ary);
3434  }
3435  else {
3436  ary_heap_free(ary);
3437  }
3438  ARY_SET_PTR(ary, ARY_HEAP_PTR(tmp));
3439  ARY_SET_HEAP_LEN(ary, len);
3440  ARY_SET_CAPA(ary, ARY_HEAP_LEN(tmp));
3441  }
3442  /* tmp was lost ownership for the ptr */
3443  FL_UNSET(tmp, FL_FREEZE);
3444  FL_SET_EMBED(tmp);
3445  ARY_SET_EMBED_LEN(tmp, 0);
3446  FL_SET(tmp, FL_FREEZE);
3447  }
3448  /* tmp will be GC'ed. */
3449  RBASIC_SET_CLASS_RAW(tmp, rb_cArray); /* rb_cArray must be marked */
3450  }
3451  ary_verify(ary);
3452  return ary;
3453 }
3454 
3455 /*
3456  * call-seq:
3457  * sort -> new_array
3458  * sort {|a, b| ... } -> new_array
3459  *
3460  * Returns a new array containing the elements of +self+, sorted.
3461  *
3462  * With no block given, compares elements using operator <tt>#<=></tt>
3463  * (see Object#<=>):
3464  *
3465  * [0, 2, 3, 1].sort # => [0, 1, 2, 3]
3466  *
3467  * With a block given, calls the block with each combination of pairs of elements from +self+;
3468  * for each pair +a+ and +b+, the block should return a numeric:
3469  *
3470  * - Negative when +b+ is to follow +a+.
3471  * - Zero when +a+ and +b+ are equivalent.
3472  * - Positive when +a+ is to follow +b+.
3473  *
3474  * Example:
3475  *
3476  * a = [3, 2, 0, 1]
3477  * a.sort {|a, b| a <=> b } # => [0, 1, 2, 3]
3478  * a.sort {|a, b| b <=> a } # => [3, 2, 1, 0]
3479  *
3480  * When the block returns zero, the order for +a+ and +b+ is indeterminate,
3481  * and may be unstable.
3482  *
3483  * Related: see {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching].
3484  */
3485 
3486 VALUE
3488 {
3489  ary = rb_ary_dup(ary);
3490  rb_ary_sort_bang(ary);
3491  return ary;
3492 }
3493 
3494 static VALUE rb_ary_bsearch_index(VALUE ary);
3495 
3496 /*
3497  * call-seq:
3498  * bsearch {|element| ... } -> found_element or nil
3499  * bsearch -> new_enumerator
3500  *
3501  * Returns the element from +self+ found by a binary search,
3502  * or +nil+ if the search found no suitable element.
3503  *
3504  * See {Binary Searching}[rdoc-ref:bsearch.rdoc].
3505  *
3506  * Related: see {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching].
3507  */
3508 
3509 static VALUE
3510 rb_ary_bsearch(VALUE ary)
3511 {
3512  VALUE index_result = rb_ary_bsearch_index(ary);
3513 
3514  if (FIXNUM_P(index_result)) {
3515  return rb_ary_entry(ary, FIX2LONG(index_result));
3516  }
3517  return index_result;
3518 }
3519 
3520 /*
3521  * call-seq:
3522  * bsearch_index {|element| ... } -> integer or nil
3523  * bsearch_index -> new_enumerator
3524  *
3525  * Returns the integer index of the element from +self+ found by a binary search,
3526  * or +nil+ if the search found no suitable element.
3527  *
3528  * See {Binary Searching}[rdoc-ref:bsearch.rdoc].
3529  *
3530  * Related: see {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching].
3531  */
3532 
3533 static VALUE
3534 rb_ary_bsearch_index(VALUE ary)
3535 {
3536  long low = 0, high = RARRAY_LEN(ary), mid;
3537  int smaller = 0, satisfied = 0;
3538  VALUE v, val;
3539 
3540  RETURN_ENUMERATOR(ary, 0, 0);
3541  while (low < high) {
3542  mid = low + ((high - low) / 2);
3543  val = rb_ary_entry(ary, mid);
3544  v = rb_yield(val);
3545  if (FIXNUM_P(v)) {
3546  if (v == INT2FIX(0)) return INT2FIX(mid);
3547  smaller = (SIGNED_VALUE)v < 0; /* Fixnum preserves its sign-bit */
3548  }
3549  else if (v == Qtrue) {
3550  satisfied = 1;
3551  smaller = 1;
3552  }
3553  else if (!RTEST(v)) {
3554  smaller = 0;
3555  }
3556  else if (rb_obj_is_kind_of(v, rb_cNumeric)) {
3557  const VALUE zero = INT2FIX(0);
3558  switch (rb_cmpint(rb_funcallv(v, id_cmp, 1, &zero), v, zero)) {
3559  case 0: return INT2FIX(mid);
3560  case 1: smaller = 0; break;
3561  case -1: smaller = 1;
3562  }
3563  }
3564  else {
3565  rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE
3566  " (must be numeric, true, false or nil)",
3567  rb_obj_class(v));
3568  }
3569  if (smaller) {
3570  high = mid;
3571  }
3572  else {
3573  low = mid + 1;
3574  }
3575  }
3576  if (!satisfied) return Qnil;
3577  return INT2FIX(low);
3578 }
3579 
3580 
3581 static VALUE
3582 sort_by_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, dummy))
3583 {
3584  return rb_yield(i);
3585 }
3586 
3587 /*
3588  * call-seq:
3589  * sort_by! {|element| ... } -> self
3590  * sort_by! -> new_enumerator
3591  *
3592  * With a block given, sorts the elements of +self+ in place;
3593  * returns self.
3594  *
3595  * Calls the block with each successive element;
3596  * sorts elements based on the values returned from the block:
3597  *
3598  * a = ['aaaa', 'bbb', 'cc', 'd']
3599  * a.sort_by! {|element| element.size }
3600  * a # => ["d", "cc", "bbb", "aaaa"]
3601  *
3602  * For duplicate values returned by the block, the ordering is indeterminate, and may be unstable.
3603  *
3604  * With no block given, returns a new Enumerator.
3605  *
3606  * Related: see {Methods for Assigning}[rdoc-ref:Array@Methods+for+Assigning].
3607  */
3608 
3609 static VALUE
3610 rb_ary_sort_by_bang(VALUE ary)
3611 {
3612  VALUE sorted;
3613 
3614  RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
3615  rb_ary_modify(ary);
3616  sorted = rb_block_call(ary, rb_intern("sort_by"), 0, 0, sort_by_i, 0);
3617  rb_ary_replace(ary, sorted);
3618  return ary;
3619 }
3620 
3621 
3622 /*
3623  * call-seq:
3624  * collect {|element| ... } -> new_array
3625  * collect -> new_enumerator
3626  * map {|element| ... } -> new_array
3627  * map -> new_enumerator
3628  *
3629  * With a block given, calls the block with each element of +self+;
3630  * returns a new array whose elements are the return values from the block:
3631  *
3632  * a = [:foo, 'bar', 2]
3633  * a1 = a.map {|element| element.class }
3634  * a1 # => [Symbol, String, Integer]
3635  *
3636  * With no block given, returns a new Enumerator.
3637  *
3638  * Related: #collect!;
3639  * see also {Methods for Converting}[rdoc-ref:Array@Methods+for+Converting].
3640  */
3641 
3642 static VALUE
3643 rb_ary_collect(VALUE ary)
3644 {
3645  long i;
3646  VALUE collect;
3647 
3648  RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
3649  collect = rb_ary_new2(RARRAY_LEN(ary));
3650  for (i = 0; i < RARRAY_LEN(ary); i++) {
3651  rb_ary_push(collect, rb_yield(RARRAY_AREF(ary, i)));
3652  }
3653  return collect;
3654 }
3655 
3656 
3657 /*
3658  * call-seq:
3659  * collect! {|element| ... } -> new_array
3660  * collect! -> new_enumerator
3661  * map! {|element| ... } -> new_array
3662  * map! -> new_enumerator
3663  *
3664  * With a block given, calls the block with each element of +self+
3665  * and replaces the element with the block's return value;
3666  * returns +self+:
3667  *
3668  * a = [:foo, 'bar', 2]
3669  * a.map! { |element| element.class } # => [Symbol, String, Integer]
3670  *
3671  * With no block given, returns a new Enumerator.
3672  *
3673  * Related: #collect;
3674  * see also {Methods for Converting}[rdoc-ref:Array@Methods+for+Converting].
3675  */
3676 
3677 static VALUE
3678 rb_ary_collect_bang(VALUE ary)
3679 {
3680  long i;
3681 
3682  RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
3683  rb_ary_modify(ary);
3684  for (i = 0; i < RARRAY_LEN(ary); i++) {
3685  rb_ary_store(ary, i, rb_yield(RARRAY_AREF(ary, i)));
3686  }
3687  return ary;
3688 }
3689 
3690 VALUE
3691 rb_get_values_at(VALUE obj, long olen, int argc, const VALUE *argv, VALUE (*func) (VALUE, long))
3692 {
3693  VALUE result = rb_ary_new2(argc);
3694  long beg, len, i, j;
3695 
3696  for (i=0; i<argc; i++) {
3697  if (FIXNUM_P(argv[i])) {
3698  rb_ary_push(result, (*func)(obj, FIX2LONG(argv[i])));
3699  continue;
3700  }
3701  /* check if idx is Range */
3702  if (rb_range_beg_len(argv[i], &beg, &len, olen, 1)) {
3703  long end = olen < beg+len ? olen : beg+len;
3704  for (j = beg; j < end; j++) {
3705  rb_ary_push(result, (*func)(obj, j));
3706  }
3707  if (beg + len > j)
3708  rb_ary_resize(result, RARRAY_LEN(result) + (beg + len) - j);
3709  continue;
3710  }
3711  rb_ary_push(result, (*func)(obj, NUM2LONG(argv[i])));
3712  }
3713  return result;
3714 }
3715 
3716 static VALUE
3717 append_values_at_single(VALUE result, VALUE ary, long olen, VALUE idx)
3718 {
3719  long beg, len;
3720  if (FIXNUM_P(idx)) {
3721  beg = FIX2LONG(idx);
3722  }
3723  /* check if idx is Range */
3724  else if (rb_range_beg_len(idx, &beg, &len, olen, 1)) {
3725  if (len > 0) {
3726  const VALUE *const src = RARRAY_CONST_PTR(ary);
3727  const long end = beg + len;
3728  const long prevlen = RARRAY_LEN(result);
3729  if (beg < olen) {
3730  rb_ary_cat(result, src + beg, end > olen ? olen-beg : len);
3731  }
3732  if (end > olen) {
3733  rb_ary_store(result, prevlen + len - 1, Qnil);
3734  }
3735  }
3736  return result;
3737  }
3738  else {
3739  beg = NUM2LONG(idx);
3740  }
3741  return rb_ary_push(result, rb_ary_entry(ary, beg));
3742 }
3743 
3744 /*
3745  * call-seq:
3746  * values_at(*specifiers) -> new_array
3747  *
3748  * Returns elements from +self+ in a new array; does not modify +self+.
3749  *
3750  * The objects included in the returned array are the elements of +self+
3751  * selected by the given +specifiers+,
3752  * each of which must be a numeric index or a Range.
3753  *
3754  * In brief:
3755  *
3756  * a = ['a', 'b', 'c', 'd']
3757  *
3758  * # Index specifiers.
3759  * a.values_at(2, 0, 2, 0) # => ["c", "a", "c", "a"] # May repeat.
3760  * a.values_at(-4, -3, -2, -1) # => ["a", "b", "c", "d"] # Counts backwards if negative.
3761  * a.values_at(-50, 50) # => [nil, nil] # Outside of self.
3762  *
3763  * # Range specifiers.
3764  * a.values_at(1..3) # => ["b", "c", "d"] # From range.begin to range.end.
3765  * a.values_at(1...3) # => ["b", "c"] # End excluded.
3766  * a.values_at(3..1) # => [] # No such elements.
3767  *
3768  * a.values_at(-3..3) # => ["b", "c", "d"] # Negative range.begin counts backwards.
3769  * a.values_at(-50..3) # Raises RangeError.
3770  *
3771  * a.values_at(1..-2) # => ["b", "c"] # Negative range.end counts backwards.
3772  * a.values_at(1..-50) # => [] # No such elements.
3773  *
3774  * # Mixture of specifiers.
3775  * a.values_at(2..3, 3, 0..1, 0) # => ["c", "d", "d", "a", "b", "a"]
3776  *
3777  * With no +specifiers+ given, returns a new empty array:
3778  *
3779  * a = ['a', 'b', 'c', 'd']
3780  * a.values_at # => []
3781  *
3782  * For each numeric specifier +index+, includes an element:
3783  *
3784  * - For each non-negative numeric specifier +index+ that is in-range (less than <tt>self.size</tt>),
3785  * includes the element at offset +index+:
3786  *
3787  * a.values_at(0, 2) # => ["a", "c"]
3788  * a.values_at(0.1, 2.9) # => ["a", "c"]
3789  *
3790  * - For each negative numeric +index+ that is in-range (greater than or equal to <tt>- self.size</tt>),
3791  * counts backwards from the end of +self+:
3792  *
3793  * a.values_at(-1, -4) # => ["d", "a"]
3794  *
3795  * The given indexes may be in any order, and may repeat:
3796  *
3797  * a.values_at(2, 0, 1, 0, 2) # => ["c", "a", "b", "a", "c"]
3798  *
3799  * For each +index+ that is out-of-range, includes +nil+:
3800  *
3801  * a.values_at(4, -5) # => [nil, nil]
3802  *
3803  * For each Range specifier +range+, includes elements
3804  * according to <tt>range.begin</tt> and <tt>range.end</tt>:
3805  *
3806  * - If both <tt>range.begin</tt> and <tt>range.end</tt>
3807  * are non-negative and in-range (less than <tt>self.size</tt>),
3808  * includes elements from index <tt>range.begin</tt>
3809  * through <tt>range.end - 1</tt> (if <tt>range.exclude_end?</tt>),
3810  * or through <tt>range.end</tt> (otherwise):
3811  *
3812  * a.values_at(1..2) # => ["b", "c"]
3813  * a.values_at(1...2) # => ["b"]
3814  *
3815  * - If <tt>range.begin</tt> is negative and in-range (greater than or equal to <tt>- self.size</tt>),
3816  * counts backwards from the end of +self+:
3817  *
3818  * a.values_at(-2..3) # => ["c", "d"]
3819  *
3820  * - If <tt>range.begin</tt> is negative and out-of-range, raises an exception:
3821  *
3822  * a.values_at(-5..3) # Raises RangeError.
3823  *
3824  * - If <tt>range.end</tt> is positive and out-of-range,
3825  * extends the returned array with +nil+ elements:
3826  *
3827  * a.values_at(1..5) # => ["b", "c", "d", nil, nil]
3828  *
3829  * - If <tt>range.end</tt> is negative and in-range,
3830  * counts backwards from the end of +self+:
3831  *
3832  * a.values_at(1..-2) # => ["b", "c"]
3833  *
3834  * - If <tt>range.end</tt> is negative and out-of-range,
3835  * returns an empty array:
3836  *
3837  * a.values_at(1..-5) # => []
3838  *
3839  * The given ranges may be in any order and may repeat:
3840  *
3841  * a.values_at(2..3, 0..1, 2..3) # => ["c", "d", "a", "b", "c", "d"]
3842  *
3843  * The given specifiers may be any mixture of indexes and ranges:
3844  *
3845  * a.values_at(3, 1..2, 0, 2..3) # => ["d", "b", "c", "a", "c", "d"]
3846  *
3847  * Related: see {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching].
3848  */
3849 
3850 static VALUE
3851 rb_ary_values_at(int argc, VALUE *argv, VALUE ary)
3852 {
3853  long i, olen = RARRAY_LEN(ary);
3854  VALUE result = rb_ary_new_capa(argc);
3855  for (i = 0; i < argc; ++i) {
3856  append_values_at_single(result, ary, olen, argv[i]);
3857  }
3858  RB_GC_GUARD(ary);
3859  return result;
3860 }
3861 
3862 
3863 /*
3864  * call-seq:
3865  * select {|element| ... } -> new_array
3866  * select -> new_enumerator
3867  * filter {|element| ... } -> new_array
3868  * filter -> new_enumerator
3869  *
3870  * With a block given, calls the block with each element of +self+;
3871  * returns a new array containing those elements of +self+
3872  * for which the block returns a truthy value:
3873  *
3874  * a = [:foo, 'bar', 2, :bam]
3875  * a.select {|element| element.to_s.start_with?('b') }
3876  * # => ["bar", :bam]
3877  *
3878  * With no block given, returns a new Enumerator.
3879  *
3880  * Related: see {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching].
3881  */
3882 
3883 static VALUE
3884 rb_ary_select(VALUE ary)
3885 {
3886  VALUE result;
3887  long i;
3888 
3889  RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
3890  result = rb_ary_new2(RARRAY_LEN(ary));
3891  for (i = 0; i < RARRAY_LEN(ary); i++) {
3892  if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) {
3893  rb_ary_push(result, rb_ary_elt(ary, i));
3894  }
3895  }
3896  return result;
3897 }
3898 
3900  VALUE ary;
3901  long len[2];
3902 };
3903 
3904 static VALUE
3905 select_bang_i(VALUE a)
3906 {
3907  volatile struct select_bang_arg *arg = (void *)a;
3908  VALUE ary = arg->ary;
3909  long i1, i2;
3910 
3911  for (i1 = i2 = 0; i1 < RARRAY_LEN(ary); arg->len[0] = ++i1) {
3912  VALUE v = RARRAY_AREF(ary, i1);
3913  if (!RTEST(rb_yield(v))) continue;
3914  if (i1 != i2) {
3915  rb_ary_store(ary, i2, v);
3916  }
3917  arg->len[1] = ++i2;
3918  }
3919  return (i1 == i2) ? Qnil : ary;
3920 }
3921 
3922 static VALUE
3923 select_bang_ensure(VALUE a)
3924 {
3925  volatile struct select_bang_arg *arg = (void *)a;
3926  VALUE ary = arg->ary;
3927  long len = RARRAY_LEN(ary);
3928  long i1 = arg->len[0], i2 = arg->len[1];
3929 
3930  if (i2 < len && i2 < i1) {
3931  long tail = 0;
3932  rb_ary_modify(ary);
3933  if (i1 < len) {
3934  tail = len - i1;
3935  RARRAY_PTR_USE(ary, ptr, {
3936  MEMMOVE(ptr + i2, ptr + i1, VALUE, tail);
3937  });
3938  }
3939  ARY_SET_LEN(ary, i2 + tail);
3940  }
3941  return ary;
3942 }
3943 
3944 /*
3945  * call-seq:
3946  * select! {|element| ... } -> self or nil
3947  * select! -> new_enumerator
3948  * filter! {|element| ... } -> self or nil
3949  * filter! -> new_enumerator
3950  *
3951  * With a block given, calls the block with each element of +self+;
3952  * removes from +self+ those elements for which the block returns +false+ or +nil+.
3953  *
3954  * Returns +self+ if any elements were removed:
3955  *
3956  * a = [:foo, 'bar', 2, :bam]
3957  * a.select! {|element| element.to_s.start_with?('b') } # => ["bar", :bam]
3958  *
3959  * Returns +nil+ if no elements were removed.
3960  *
3961  * With no block given, returns a new Enumerator.
3962  *
3963  * Related: see {Methods for Deleting}[rdoc-ref:Array@Methods+for+Deleting].
3964  */
3965 
3966 static VALUE
3967 rb_ary_select_bang(VALUE ary)
3968 {
3969  struct select_bang_arg args;
3970 
3971  RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
3972  rb_ary_modify(ary);
3973 
3974  args.ary = ary;
3975  args.len[0] = args.len[1] = 0;
3976  return rb_ensure(select_bang_i, (VALUE)&args, select_bang_ensure, (VALUE)&args);
3977 }
3978 
3979 /*
3980  * call-seq:
3981  * keep_if {|element| ... } -> self
3982  * keep_if -> new_enumerator
3983  *
3984  * With a block given, calls the block with each element of +self+;
3985  * removes the element from +self+ if the block does not return a truthy value:
3986  *
3987  * a = [:foo, 'bar', 2, :bam]
3988  * a.keep_if {|element| element.to_s.start_with?('b') } # => ["bar", :bam]
3989  *
3990  * With no block given, returns a new Enumerator.
3991  *
3992  * Related: see {Methods for Deleting}[rdoc-ref:Array@Methods+for+Deleting].
3993  */
3994 
3995 static VALUE
3996 rb_ary_keep_if(VALUE ary)
3997 {
3998  RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
3999  rb_ary_select_bang(ary);
4000  return ary;
4001 }
4002 
4003 static void
4004 ary_resize_smaller(VALUE ary, long len)
4005 {
4006  rb_ary_modify(ary);
4007  if (RARRAY_LEN(ary) > len) {
4008  ARY_SET_LEN(ary, len);
4009  if (len * 2 < ARY_CAPA(ary) &&
4010  ARY_CAPA(ary) > ARY_DEFAULT_SIZE) {
4011  ary_resize_capa(ary, len * 2);
4012  }
4013  }
4014 }
4015 
4016 /*
4017  * call-seq:
4018  * delete(object) -> last_removed_object
4019  * delete(object) {|element| ... } -> last_removed_object or block_return
4020  *
4021  * Removes zero or more elements from +self+.
4022  *
4023  * With no block given,
4024  * removes from +self+ each element +ele+ such that <tt>ele == object</tt>;
4025  * returns the last removed element:
4026  *
4027  * a = [0, 1, 2, 2.0]
4028  * a.delete(2) # => 2.0
4029  * a # => [0, 1]
4030  *
4031  * Returns +nil+ if no elements removed:
4032  *
4033  * a.delete(2) # => nil
4034  *
4035  * With a block given,
4036  * removes from +self+ each element +ele+ such that <tt>ele == object</tt>.
4037  *
4038  * If any such elements are found, ignores the block
4039  * and returns the last removed element:
4040  *
4041  * a = [0, 1, 2, 2.0]
4042  * a.delete(2) {|element| fail 'Cannot happen' } # => 2.0
4043  * a # => [0, 1]
4044  *
4045  * If no such element is found, returns the block's return value:
4046  *
4047  * a.delete(2) {|element| "Element #{element} not found." }
4048  * # => "Element 2 not found."
4049  *
4050  * Related: see {Methods for Deleting}[rdoc-ref:Array@Methods+for+Deleting].
4051  */
4052 
4053 VALUE
4055 {
4056  VALUE v = item;
4057  long i1, i2;
4058 
4059  for (i1 = i2 = 0; i1 < RARRAY_LEN(ary); i1++) {
4060  VALUE e = RARRAY_AREF(ary, i1);
4061 
4062  if (rb_equal(e, item)) {
4063  v = e;
4064  continue;
4065  }
4066  if (i1 != i2) {
4067  rb_ary_store(ary, i2, e);
4068  }
4069  i2++;
4070  }
4071  if (RARRAY_LEN(ary) == i2) {
4072  if (rb_block_given_p()) {
4073  return rb_yield(item);
4074  }
4075  return Qnil;
4076  }
4077 
4078  ary_resize_smaller(ary, i2);
4079 
4080  ary_verify(ary);
4081  return v;
4082 }
4083 
4084 void
4085 rb_ary_delete_same(VALUE ary, VALUE item)
4086 {
4087  long i1, i2;
4088 
4089  for (i1 = i2 = 0; i1 < RARRAY_LEN(ary); i1++) {
4090  VALUE e = RARRAY_AREF(ary, i1);
4091 
4092  if (e == item) {
4093  continue;
4094  }
4095  if (i1 != i2) {
4096  rb_ary_store(ary, i2, e);
4097  }
4098  i2++;
4099  }
4100  if (RARRAY_LEN(ary) == i2) {
4101  return;
4102  }
4103 
4104  ary_resize_smaller(ary, i2);
4105 }
4106 
4107 VALUE
4108 rb_ary_delete_at(VALUE ary, long pos)
4109 {
4110  long len = RARRAY_LEN(ary);
4111  VALUE del;
4112 
4113  if (pos >= len) return Qnil;
4114  if (pos < 0) {
4115  pos += len;
4116  if (pos < 0) return Qnil;
4117  }
4118 
4119  rb_ary_modify(ary);
4120  del = RARRAY_AREF(ary, pos);
4121  RARRAY_PTR_USE(ary, ptr, {
4122  MEMMOVE(ptr+pos, ptr+pos+1, VALUE, len-pos-1);
4123  });
4124  ARY_INCREASE_LEN(ary, -1);
4125  ary_verify(ary);
4126  return del;
4127 }
4128 
4129 /*
4130  * call-seq:
4131  * delete_at(index) -> removed_object or nil
4132  *
4133  * Removes the element of +self+ at the given +index+, which must be an
4134  * {integer-convertible object}[rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects].
4135  *
4136  * When +index+ is non-negative, deletes the element at offset +index+:
4137  *
4138  * a = [:foo, 'bar', 2]
4139  * a.delete_at(1) # => "bar"
4140  * a # => [:foo, 2]
4141  *
4142  * When +index+ is negative, counts backward from the end of the array:
4143  *
4144  * a = [:foo, 'bar', 2]
4145  * a.delete_at(-2) # => "bar"
4146  * a # => [:foo, 2]
4147  *
4148  * When +index+ is out of range, returns +nil+.
4149  *
4150  * a = [:foo, 'bar', 2]
4151  * a.delete_at(3) # => nil
4152  * a.delete_at(-4) # => nil
4153  *
4154  * Related: see {Methods for Deleting}[rdoc-ref:Array@Methods+for+Deleting].
4155  */
4156 
4157 static VALUE
4158 rb_ary_delete_at_m(VALUE ary, VALUE pos)
4159 {
4160  return rb_ary_delete_at(ary, NUM2LONG(pos));
4161 }
4162 
4163 static VALUE
4164 ary_slice_bang_by_rb_ary_splice(VALUE ary, long pos, long len)
4165 {
4166  const long orig_len = RARRAY_LEN(ary);
4167 
4168  if (len < 0) {
4169  return Qnil;
4170  }
4171  else if (pos < -orig_len) {
4172  return Qnil;
4173  }
4174  else if (pos < 0) {
4175  pos += orig_len;
4176  }
4177  else if (orig_len < pos) {
4178  return Qnil;
4179  }
4180  if (orig_len < pos + len) {
4181  len = orig_len - pos;
4182  }
4183  if (len == 0) {
4184  return rb_ary_new2(0);
4185  }
4186  else {
4187  VALUE arg2 = rb_ary_new4(len, RARRAY_CONST_PTR(ary)+pos);
4188  rb_ary_splice(ary, pos, len, 0, 0);
4189  return arg2;
4190  }
4191 }
4192 
4193 /*
4194  * call-seq:
4195  * slice!(index) -> object or nil
4196  * slice!(start, length) -> new_array or nil
4197  * slice!(range) -> new_array or nil
4198  *
4199  * Removes and returns elements from +self+.
4200  *
4201  * With numeric argument +index+ given,
4202  * removes and returns the element at offset +index+:
4203  *
4204  * a = ['a', 'b', 'c', 'd']
4205  * a.slice!(2) # => "c"
4206  * a # => ["a", "b", "d"]
4207  * a.slice!(2.1) # => "d"
4208  * a # => ["a", "b"]
4209  *
4210  * If +index+ is negative, counts backwards from the end of +self+:
4211  *
4212  * a = ['a', 'b', 'c', 'd']
4213  * a.slice!(-2) # => "c"
4214  * a # => ["a", "b", "d"]
4215  *
4216  * If +index+ is out of range, returns +nil+.
4217  *
4218  * With numeric arguments +start+ and +length+ given,
4219  * removes +length+ elements from +self+ beginning at zero-based offset +start+;
4220  * returns the removed objects in a new array:
4221  *
4222  * a = ['a', 'b', 'c', 'd']
4223  * a.slice!(1, 2) # => ["b", "c"]
4224  * a # => ["a", "d"]
4225  * a.slice!(0.1, 1.1) # => ["a"]
4226  * a # => ["d"]
4227  *
4228  * If +start+ is negative, counts backwards from the end of +self+:
4229  *
4230  * a = ['a', 'b', 'c', 'd']
4231  * a.slice!(-2, 1) # => ["c"]
4232  * a # => ["a", "b", "d"]
4233  *
4234  * If +start+ is out-of-range, returns +nil+:
4235  *
4236  * a = ['a', 'b', 'c', 'd']
4237  * a.slice!(5, 1) # => nil
4238  * a.slice!(-5, 1) # => nil
4239  *
4240  * If <tt>start + length</tt> exceeds the array size,
4241  * removes and returns all elements from offset +start+ to the end:
4242  *
4243  * a = ['a', 'b', 'c', 'd']
4244  * a.slice!(2, 50) # => ["c", "d"]
4245  * a # => ["a", "b"]
4246  *
4247  * If <tt>start == a.size</tt> and +length+ is non-negative,
4248  * returns a new empty array.
4249  *
4250  * If +length+ is negative, returns +nil+.
4251  *
4252  * With Range argument +range+ given,
4253  * treats <tt>range.min</tt> as +start+ (as above)
4254  * and <tt>range.size</tt> as +length+ (as above):
4255  *
4256  * a = ['a', 'b', 'c', 'd']
4257  * a.slice!(1..2) # => ["b", "c"]
4258  * a # => ["a", "d"]
4259  *
4260  * If <tt>range.start == a.size</tt>, returns a new empty array:
4261  *
4262  * a = ['a', 'b', 'c', 'd']
4263  * a.slice!(4..5) # => []
4264  *
4265  * If <tt>range.start</tt> is larger than the array size, returns +nil+:
4266  *
4267  * a = ['a', 'b', 'c', 'd']
4268  a.slice!(5..6) # => nil
4269  *
4270  * If <tt>range.start</tt> is negative,
4271  * calculates the start index by counting backwards from the end of +self+:
4272  *
4273  * a = ['a', 'b', 'c', 'd']
4274  * a.slice!(-2..2) # => ["c"]
4275  *
4276  * If <tt>range.end</tt> is negative,
4277  * calculates the end index by counting backwards from the end of +self+:
4278  *
4279  * a = ['a', 'b', 'c', 'd']
4280  * a.slice!(0..-2) # => ["a", "b", "c"]
4281  *
4282  * Related: see {Methods for Deleting}[rdoc-ref:Array@Methods+for+Deleting].
4283  */
4284 
4285 static VALUE
4286 rb_ary_slice_bang(int argc, VALUE *argv, VALUE ary)
4287 {
4288  VALUE arg1;
4289  long pos, len;
4290 
4291  rb_ary_modify_check(ary);
4292  rb_check_arity(argc, 1, 2);
4293  arg1 = argv[0];
4294 
4295  if (argc == 2) {
4296  pos = NUM2LONG(argv[0]);
4297  len = NUM2LONG(argv[1]);
4298  return ary_slice_bang_by_rb_ary_splice(ary, pos, len);
4299  }
4300 
4301  if (!FIXNUM_P(arg1)) {
4302  switch (rb_range_beg_len(arg1, &pos, &len, RARRAY_LEN(ary), 0)) {
4303  case Qtrue:
4304  /* valid range */
4305  return ary_slice_bang_by_rb_ary_splice(ary, pos, len);
4306  case Qnil:
4307  /* invalid range */
4308  return Qnil;
4309  default:
4310  /* not a range */
4311  break;
4312  }
4313  }
4314 
4315  return rb_ary_delete_at(ary, NUM2LONG(arg1));
4316 }
4317 
4318 static VALUE
4319 ary_reject(VALUE orig, VALUE result)
4320 {
4321  long i;
4322 
4323  for (i = 0; i < RARRAY_LEN(orig); i++) {
4324  VALUE v = RARRAY_AREF(orig, i);
4325 
4326  if (!RTEST(rb_yield(v))) {
4327  rb_ary_push(result, v);
4328  }
4329  }
4330  return result;
4331 }
4332 
4333 static VALUE
4334 reject_bang_i(VALUE a)
4335 {
4336  volatile struct select_bang_arg *arg = (void *)a;
4337  VALUE ary = arg->ary;
4338  long i1, i2;
4339 
4340  for (i1 = i2 = 0; i1 < RARRAY_LEN(ary); arg->len[0] = ++i1) {
4341  VALUE v = RARRAY_AREF(ary, i1);
4342  if (RTEST(rb_yield(v))) continue;
4343  if (i1 != i2) {
4344  rb_ary_store(ary, i2, v);
4345  }
4346  arg->len[1] = ++i2;
4347  }
4348  return (i1 == i2) ? Qnil : ary;
4349 }
4350 
4351 static VALUE
4352 ary_reject_bang(VALUE ary)
4353 {
4354  struct select_bang_arg args;
4355  rb_ary_modify_check(ary);
4356  args.ary = ary;
4357  args.len[0] = args.len[1] = 0;
4358  return rb_ensure(reject_bang_i, (VALUE)&args, select_bang_ensure, (VALUE)&args);
4359 }
4360 
4361 /*
4362  * call-seq:
4363  * reject! {|element| ... } -> self or nil
4364  * reject! -> new_enumerator
4365  *
4366  * With a block given, calls the block with each element of +self+;
4367  * removes each element for which the block returns a truthy value.
4368  *
4369  * Returns +self+ if any elements removed:
4370  *
4371  * a = [:foo, 'bar', 2, 'bat']
4372  * a.reject! {|element| element.to_s.start_with?('b') } # => [:foo, 2]
4373  *
4374  * Returns +nil+ if no elements removed.
4375  *
4376  * With no block given, returns a new Enumerator.
4377  *
4378  * Related: see {Methods for Deleting}[rdoc-ref:Array@Methods+for+Deleting].
4379  */
4380 
4381 static VALUE
4382 rb_ary_reject_bang(VALUE ary)
4383 {
4384  RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
4385  rb_ary_modify(ary);
4386  return ary_reject_bang(ary);
4387 }
4388 
4389 /*
4390  * call-seq:
4391  * reject {|element| ... } -> new_array
4392  * reject -> new_enumerator
4393  *
4394  * With a block given, returns a new array whose elements are all those from +self+
4395  * for which the block returns +false+ or +nil+:
4396  *
4397  * a = [:foo, 'bar', 2, 'bat']
4398  * a1 = a.reject {|element| element.to_s.start_with?('b') }
4399  * a1 # => [:foo, 2]
4400  *
4401  * With no block given, returns a new Enumerator.
4402  *
4403  * Related: {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching].
4404  */
4405 
4406 static VALUE
4407 rb_ary_reject(VALUE ary)
4408 {
4409  VALUE rejected_ary;
4410 
4411  RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
4412  rejected_ary = rb_ary_new();
4413  ary_reject(ary, rejected_ary);
4414  return rejected_ary;
4415 }
4416 
4417 /*
4418  * call-seq:
4419  * delete_if {|element| ... } -> self
4420  * delete_if -> new_numerator
4421  *
4422  * With a block given, calls the block with each element of +self+;
4423  * removes the element if the block returns a truthy value;
4424  * returns +self+:
4425  *
4426  * a = [:foo, 'bar', 2, 'bat']
4427  * a.delete_if {|element| element.to_s.start_with?('b') } # => [:foo, 2]
4428  *
4429  * With no block given, returns a new Enumerator.
4430  *
4431  * Related: see {Methods for Deleting}[rdoc-ref:Array@Methods+for+Deleting].
4432  */
4433 
4434 static VALUE
4435 rb_ary_delete_if(VALUE ary)
4436 {
4437  ary_verify(ary);
4438  RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
4439  ary_reject_bang(ary);
4440  return ary;
4441 }
4442 
4443 static VALUE
4444 take_i(RB_BLOCK_CALL_FUNC_ARGLIST(val, cbarg))
4445 {
4446  VALUE *args = (VALUE *)cbarg;
4447  if (argc > 1) val = rb_ary_new4(argc, argv);
4448  rb_ary_push(args[0], val);
4449  if (--args[1] == 0) rb_iter_break();
4450  return Qnil;
4451 }
4452 
4453 static VALUE
4454 take_items(VALUE obj, long n)
4455 {
4456  VALUE result = rb_check_array_type(obj);
4457  VALUE args[2];
4458 
4459  if (n == 0) return result;
4460  if (!NIL_P(result)) return rb_ary_subseq(result, 0, n);
4461  result = rb_ary_new2(n);
4462  args[0] = result; args[1] = (VALUE)n;
4463  if (UNDEF_P(rb_check_block_call(obj, idEach, 0, 0, take_i, (VALUE)args)))
4464  rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (must respond to :each)",
4465  rb_obj_class(obj));
4466  return result;
4467 }
4468 
4469 
4470 /*
4471  * call-seq:
4472  * zip(*other_arrays) -> new_array
4473  * zip(*other_arrays) {|other_array| ... } -> nil
4474  *
4475  * With no block given, combines +self+ with the collection of +other_arrays+;
4476  * returns a new array of sub-arrays:
4477  *
4478  * [0, 1].zip(['zero', 'one'], [:zero, :one])
4479  * # => [[0, "zero", :zero], [1, "one", :one]]
4480  *
4481  * Returned:
4482  *
4483  * - The outer array is of size <tt>self.size</tt>.
4484  * - Each sub-array is of size <tt>other_arrays.size + 1</tt>.
4485  * - The _nth_ sub-array contains (in order):
4486  *
4487  * - The _nth_ element of +self+.
4488  * - The _nth_ element of each of the other arrays, as available.
4489  *
4490  * Example:
4491  *
4492  * a = [0, 1]
4493  * zipped = a.zip(['zero', 'one'], [:zero, :one])
4494  * # => [[0, "zero", :zero], [1, "one", :one]]
4495  * zipped.size # => 2 # Same size as a.
4496  * zipped.first.size # => 3 # Size of other arrays plus 1.
4497  *
4498  * When the other arrays are all the same size as +self+,
4499  * the returned sub-arrays are a rearrangement containing exactly elements of all the arrays
4500  * (including +self+), with no omissions or additions:
4501  *
4502  * a = [:a0, :a1, :a2, :a3]
4503  * b = [:b0, :b1, :b2, :b3]
4504  * c = [:c0, :c1, :c2, :c3]
4505  * d = a.zip(b, c)
4506  * pp d
4507  * # =>
4508  * [[:a0, :b0, :c0],
4509  * [:a1, :b1, :c1],
4510  * [:a2, :b2, :c2],
4511  * [:a3, :b3, :c3]]
4512  *
4513  * When one of the other arrays is smaller than +self+,
4514  * pads the corresponding sub-array with +nil+ elements:
4515  *
4516  * a = [:a0, :a1, :a2, :a3]
4517  * b = [:b0, :b1, :b2]
4518  * c = [:c0, :c1]
4519  * d = a.zip(b, c)
4520  * pp d
4521  * # =>
4522  * [[:a0, :b0, :c0],
4523  * [:a1, :b1, :c1],
4524  * [:a2, :b2, nil],
4525  * [:a3, nil, nil]]
4526  *
4527  * When one of the other arrays is larger than +self+,
4528  * _ignores_ its trailing elements:
4529  *
4530  * a = [:a0, :a1, :a2, :a3]
4531  * b = [:b0, :b1, :b2, :b3, :b4]
4532  * c = [:c0, :c1, :c2, :c3, :c4, :c5]
4533  * d = a.zip(b, c)
4534  * pp d
4535  * # =>
4536  * [[:a0, :b0, :c0],
4537  * [:a1, :b1, :c1],
4538  * [:a2, :b2, :c2],
4539  * [:a3, :b3, :c3]]
4540  *
4541  * With a block given, calls the block with each of the other arrays;
4542  * returns +nil+:
4543  *
4544  * d = []
4545  * a = [:a0, :a1, :a2, :a3]
4546  * b = [:b0, :b1, :b2, :b3]
4547  * c = [:c0, :c1, :c2, :c3]
4548  * a.zip(b, c) {|sub_array| d.push(sub_array.reverse) } # => nil
4549  * pp d
4550  * # =>
4551  * [[:c0, :b0, :a0],
4552  * [:c1, :b1, :a1],
4553  * [:c2, :b2, :a2],
4554  * [:c3, :b3, :a3]]
4555  *
4556  * For an *object* in *other_arrays* that is not actually an array,
4557  * forms the the "other array" as <tt>object.to_ary</tt>, if defined,
4558  * or as <tt>object.each.to_a</tt> otherwise.
4559  *
4560  * Related: see {Methods for Converting}[rdoc-ref:Array@Methods+for+Converting].
4561  */
4562 
4563 static VALUE
4564 rb_ary_zip(int argc, VALUE *argv, VALUE ary)
4565 {
4566  int i, j;
4567  long len = RARRAY_LEN(ary);
4568  VALUE result = Qnil;
4569 
4570  for (i=0; i<argc; i++) {
4571  argv[i] = take_items(argv[i], len);
4572  }
4573 
4574  if (rb_block_given_p()) {
4575  int arity = rb_block_arity();
4576 
4577  if (arity > 1) {
4578  VALUE work, *tmp;
4579 
4580  tmp = ALLOCV_N(VALUE, work, argc+1);
4581 
4582  for (i=0; i<RARRAY_LEN(ary); i++) {
4583  tmp[0] = RARRAY_AREF(ary, i);
4584  for (j=0; j<argc; j++) {
4585  tmp[j+1] = rb_ary_elt(argv[j], i);
4586  }
4587  rb_yield_values2(argc+1, tmp);
4588  }
4589 
4590  if (work) ALLOCV_END(work);
4591  }
4592  else {
4593  for (i=0; i<RARRAY_LEN(ary); i++) {
4594  VALUE tmp = rb_ary_new2(argc+1);
4595 
4596  rb_ary_push(tmp, RARRAY_AREF(ary, i));
4597  for (j=0; j<argc; j++) {
4598  rb_ary_push(tmp, rb_ary_elt(argv[j], i));
4599  }
4600  rb_yield(tmp);
4601  }
4602  }
4603  }
4604  else {
4605  result = rb_ary_new_capa(len);
4606 
4607  for (i=0; i<len; i++) {
4608  VALUE tmp = rb_ary_new_capa(argc+1);
4609 
4610  rb_ary_push(tmp, RARRAY_AREF(ary, i));
4611  for (j=0; j<argc; j++) {
4612  rb_ary_push(tmp, rb_ary_elt(argv[j], i));
4613  }
4614  rb_ary_push(result, tmp);
4615  }
4616  }
4617 
4618  return result;
4619 }
4620 
4621 /*
4622  * call-seq:
4623  * transpose -> new_array
4624  *
4625  * Returns a new array that is +self+
4626  * as a {transposed matrix}[https://en.wikipedia.org/wiki/Transpose]:
4627  *
4628  * a = [[:a0, :a1], [:b0, :b1], [:c0, :c1]]
4629  * a.transpose # => [[:a0, :b0, :c0], [:a1, :b1, :c1]]
4630  *
4631  * The elements of +self+ must all be the same size.
4632  *
4633  * Related: see {Methods for Converting}[rdoc-ref:Array@Methods+for+Converting].
4634  */
4635 
4636 static VALUE
4637 rb_ary_transpose(VALUE ary)
4638 {
4639  long elen = -1, alen, i, j;
4640  VALUE tmp, result = 0;
4641 
4642  alen = RARRAY_LEN(ary);
4643  if (alen == 0) return rb_ary_dup(ary);
4644  for (i=0; i<alen; i++) {
4645  tmp = to_ary(rb_ary_elt(ary, i));
4646  if (elen < 0) { /* first element */
4647  elen = RARRAY_LEN(tmp);
4648  result = rb_ary_new2(elen);
4649  for (j=0; j<elen; j++) {
4650  rb_ary_store(result, j, rb_ary_new2(alen));
4651  }
4652  }
4653  else if (elen != RARRAY_LEN(tmp)) {
4654  rb_raise(rb_eIndexError, "element size differs (%ld should be %ld)",
4655  RARRAY_LEN(tmp), elen);
4656  }
4657  for (j=0; j<elen; j++) {
4658  rb_ary_store(rb_ary_elt(result, j), i, rb_ary_elt(tmp, j));
4659  }
4660  }
4661  return result;
4662 }
4663 
4664 /*
4665  * call-seq:
4666  * initialize_copy(other_array) -> self
4667  * replace(other_array) -> self
4668  *
4669  * Replaces the elements of +self+ with the elements of +other_array+, which must be an
4670  * {array-convertible object}[rdoc-ref:implicit_conversion.rdoc@Array-Convertible+Objects];
4671  * returns +self+:
4672  *
4673  * a = ['a', 'b', 'c'] # => ["a", "b", "c"]
4674  * a.replace(['d', 'e']) # => ["d", "e"]
4675  *
4676  * Related: see {Methods for Assigning}[rdoc-ref:Array@Methods+for+Assigning].
4677  */
4678 
4679 VALUE
4681 {
4682  rb_ary_modify_check(copy);
4683  orig = to_ary(orig);
4684  if (copy == orig) return copy;
4685 
4686  rb_ary_reset(copy);
4687 
4688  /* orig has enough space to embed the contents of orig. */
4689  if (RARRAY_LEN(orig) <= ary_embed_capa(copy)) {
4690  RUBY_ASSERT(ARY_EMBED_P(copy));
4691  ary_memcpy(copy, 0, RARRAY_LEN(orig), RARRAY_CONST_PTR(orig));
4692  ARY_SET_EMBED_LEN(copy, RARRAY_LEN(orig));
4693  }
4694  /* orig is embedded but copy does not have enough space to embed the
4695  * contents of orig. */
4696  else if (ARY_EMBED_P(orig)) {
4697  long len = ARY_EMBED_LEN(orig);
4698  VALUE *ptr = ary_heap_alloc_buffer(len);
4699 
4700  FL_UNSET_EMBED(copy);
4701  ARY_SET_PTR(copy, ptr);
4702  ARY_SET_LEN(copy, len);
4703  ARY_SET_CAPA(copy, len);
4704 
4705  // No allocation and exception expected that could leave `copy` in a
4706  // bad state from the edits above.
4707  ary_memcpy(copy, 0, len, RARRAY_CONST_PTR(orig));
4708  }
4709  /* Otherwise, orig is on heap and copy does not have enough space to embed
4710  * the contents of orig. */
4711  else {
4712  VALUE shared_root = ary_make_shared(orig);
4713  FL_UNSET_EMBED(copy);
4714  ARY_SET_PTR(copy, ARY_HEAP_PTR(orig));
4715  ARY_SET_LEN(copy, ARY_HEAP_LEN(orig));
4716  rb_ary_set_shared(copy, shared_root);
4717  }
4718  ary_verify(copy);
4719  return copy;
4720 }
4721 
4722 /*
4723  * call-seq:
4724  * clear -> self
4725  *
4726  * Removes all elements from +self+; returns +self+:
4727  *
4728  * a = [:foo, 'bar', 2]
4729  * a.clear # => []
4730  *
4731  * Related: see {Methods for Deleting}[rdoc-ref:Array@Methods+for+Deleting].
4732  */
4733 
4734 VALUE
4736 {
4737  rb_ary_modify_check(ary);
4738  if (ARY_SHARED_P(ary)) {
4739  rb_ary_unshare(ary);
4740  FL_SET_EMBED(ary);
4741  ARY_SET_EMBED_LEN(ary, 0);
4742  }
4743  else {
4744  ARY_SET_LEN(ary, 0);
4745  if (ARY_DEFAULT_SIZE * 2 < ARY_CAPA(ary)) {
4746  ary_resize_capa(ary, ARY_DEFAULT_SIZE * 2);
4747  }
4748  }
4749  ary_verify(ary);
4750  return ary;
4751 }
4752 
4753 /*
4754  * call-seq:
4755  * fill(object, start = nil, count = nil) -> new_array
4756  * fill(object, range) -> new_array
4757  * fill(start = nil, count = nil) {|element| ... } -> new_array
4758  * fill(range) {|element| ... } -> new_array
4759  *
4760  * Replaces selected elements in +self+;
4761  * may add elements to +self+;
4762  * always returns +self+ (never a new array).
4763  *
4764  * In brief:
4765  *
4766  * # Non-negative start.
4767  * ['a', 'b', 'c', 'd'].fill('-', 1, 2) # => ["a", "-", "-", "d"]
4768  * ['a', 'b', 'c', 'd'].fill(1, 2) {|e| e.to_s } # => ["a", "1", "2", "d"]
4769  *
4770  * # Extends with specified values if necessary.
4771  * ['a', 'b', 'c', 'd'].fill('-', 3, 2) # => ["a", "b", "c", "-", "-"]
4772  * ['a', 'b', 'c', 'd'].fill(3, 2) {|e| e.to_s } # => ["a", "b", "c", "3", "4"]
4773  *
4774  * # Fills with nils if necessary.
4775  * ['a', 'b', 'c', 'd'].fill('-', 6, 2) # => ["a", "b", "c", "d", nil, nil, "-", "-"]
4776  * ['a', 'b', 'c', 'd'].fill(6, 2) {|e| e.to_s } # => ["a", "b", "c", "d", nil, nil, "6", "7"]
4777  *
4778  * # For negative start, counts backwards from the end.
4779  * ['a', 'b', 'c', 'd'].fill('-', -3, 3) # => ["a", "-", "-", "-"]
4780  * ['a', 'b', 'c', 'd'].fill(-3, 3) {|e| e.to_s } # => ["a", "1", "2", "3"]
4781  *
4782  * # Range.
4783  * ['a', 'b', 'c', 'd'].fill('-', 1..2) # => ["a", "-", "-", "d"]
4784  * ['a', 'b', 'c', 'd'].fill(1..2) {|e| e.to_s } # => ["a", "1", "2", "d"]
4785  *
4786  * When arguments +start+ and +count+ are given,
4787  * they select the elements of +self+ to be replaced;
4788  * each must be an
4789  * {integer-convertible object}[rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects]
4790  * (or +nil+):
4791  *
4792  * - +start+ specifies the zero-based offset of the first element to be replaced;
4793  * +nil+ means zero.
4794  * - +count+ is the number of consecutive elements to be replaced;
4795  * +nil+ means "all the rest."
4796  *
4797  * With argument +object+ given,
4798  * that one object is used for all replacements:
4799  *
4800  * o = Object.new # => #<Object:0x0000014e7bff7600>
4801  * a = ['a', 'b', 'c', 'd'] # => ["a", "b", "c", "d"]
4802  * a.fill(o, 1, 2)
4803  * # => ["a", #<Object:0x0000014e7bff7600>, #<Object:0x0000014e7bff7600>, "d"]
4804  *
4805  * With a block given, the block is called once for each element to be replaced;
4806  * the value passed to the block is the _index_ of the element to be replaced
4807  * (not the element itself);
4808  * the block's return value replaces the element:
4809  *
4810  * a = ['a', 'b', 'c', 'd'] # => ["a", "b", "c", "d"]
4811  * a.fill(1, 2) {|element| element.to_s } # => ["a", "1", "2", "d"]
4812  *
4813  * For arguments +start+ and +count+:
4814  *
4815  * - If +start+ is non-negative,
4816  * replaces +count+ elements beginning at offset +start+:
4817  *
4818  * ['a', 'b', 'c', 'd'].fill('-', 0, 2) # => ["-", "-", "c", "d"]
4819  * ['a', 'b', 'c', 'd'].fill('-', 1, 2) # => ["a", "-", "-", "d"]
4820  * ['a', 'b', 'c', 'd'].fill('-', 2, 2) # => ["a", "b", "-", "-"]
4821  *
4822  * ['a', 'b', 'c', 'd'].fill(0, 2) {|e| e.to_s } # => ["0", "1", "c", "d"]
4823  * ['a', 'b', 'c', 'd'].fill(1, 2) {|e| e.to_s } # => ["a", "1", "2", "d"]
4824  * ['a', 'b', 'c', 'd'].fill(2, 2) {|e| e.to_s } # => ["a", "b", "2", "3"]
4825  *
4826  * Extends +self+ if necessary:
4827  *
4828  * ['a', 'b', 'c', 'd'].fill('-', 3, 2) # => ["a", "b", "c", "-", "-"]
4829  * ['a', 'b', 'c', 'd'].fill('-', 4, 2) # => ["a", "b", "c", "d", "-", "-"]
4830  *
4831  * ['a', 'b', 'c', 'd'].fill(3, 2) {|e| e.to_s } # => ["a", "b", "c", "3", "4"]
4832  * ['a', 'b', 'c', 'd'].fill(4, 2) {|e| e.to_s } # => ["a", "b", "c", "d", "4", "5"]
4833  *
4834  * Fills with +nil+ if necessary:
4835  *
4836  * ['a', 'b', 'c', 'd'].fill('-', 5, 2) # => ["a", "b", "c", "d", nil, "-", "-"]
4837  * ['a', 'b', 'c', 'd'].fill('-', 6, 2) # => ["a", "b", "c", "d", nil, nil, "-", "-"]
4838  *
4839  * ['a', 'b', 'c', 'd'].fill(5, 2) {|e| e.to_s } # => ["a", "b", "c", "d", nil, "5", "6"]
4840  * ['a', 'b', 'c', 'd'].fill(6, 2) {|e| e.to_s } # => ["a", "b", "c", "d", nil, nil, "6", "7"]
4841  *
4842  * Does nothing if +count+ is non-positive:
4843  *
4844  * ['a', 'b', 'c', 'd'].fill('-', 2, 0) # => ["a", "b", "c", "d"]
4845  * ['a', 'b', 'c', 'd'].fill('-', 2, -100) # => ["a", "b", "c", "d"]
4846  * ['a', 'b', 'c', 'd'].fill('-', 6, -100) # => ["a", "b", "c", "d"]
4847  *
4848  * ['a', 'b', 'c', 'd'].fill(2, 0) {|e| fail 'Cannot happen' } # => ["a", "b", "c", "d"]
4849  * ['a', 'b', 'c', 'd'].fill(2, -100) {|e| fail 'Cannot happen' } # => ["a", "b", "c", "d"]
4850  * ['a', 'b', 'c', 'd'].fill(6, -100) {|e| fail 'Cannot happen' } # => ["a", "b", "c", "d"]
4851  *
4852  * - If +start+ is negative, counts backwards from the end of +self+:
4853  *
4854  * ['a', 'b', 'c', 'd'].fill('-', -4, 3) # => ["-", "-", "-", "d"]
4855  * ['a', 'b', 'c', 'd'].fill('-', -3, 3) # => ["a", "-", "-", "-"]
4856  *
4857  * ['a', 'b', 'c', 'd'].fill(-4, 3) {|e| e.to_s } # => ["0", "1", "2", "d"]
4858  * ['a', 'b', 'c', 'd'].fill(-3, 3) {|e| e.to_s } # => ["a", "1", "2", "3"]
4859  *
4860  * Extends +self+ if necessary:
4861  *
4862  * ['a', 'b', 'c', 'd'].fill('-', -2, 3) # => ["a", "b", "-", "-", "-"]
4863  * ['a', 'b', 'c', 'd'].fill('-', -1, 3) # => ["a", "b", "c", "-", "-", "-"]
4864  *
4865  * ['a', 'b', 'c', 'd'].fill(-2, 3) {|e| e.to_s } # => ["a", "b", "2", "3", "4"]
4866  * ['a', 'b', 'c', 'd'].fill(-1, 3) {|e| e.to_s } # => ["a", "b", "c", "3", "4", "5"]
4867  *
4868  * Starts at the beginning of +self+ if +start+ is negative and out-of-range:
4869  *
4870  * ['a', 'b', 'c', 'd'].fill('-', -5, 2) # => ["-", "-", "c", "d"]
4871  * ['a', 'b', 'c', 'd'].fill('-', -6, 2) # => ["-", "-", "c", "d"]
4872  *
4873  * ['a', 'b', 'c', 'd'].fill(-5, 2) {|e| e.to_s } # => ["0", "1", "c", "d"]
4874  * ['a', 'b', 'c', 'd'].fill(-6, 2) {|e| e.to_s } # => ["0", "1", "c", "d"]
4875  *
4876  * Does nothing if +count+ is non-positive:
4877  *
4878  * ['a', 'b', 'c', 'd'].fill('-', -2, 0) # => ["a", "b", "c", "d"]
4879  * ['a', 'b', 'c', 'd'].fill('-', -2, -1) # => ["a", "b", "c", "d"]
4880  *
4881  * ['a', 'b', 'c', 'd'].fill(-2, 0) {|e| fail 'Cannot happen' } # => ["a", "b", "c", "d"]
4882  * ['a', 'b', 'c', 'd'].fill(-2, -1) {|e| fail 'Cannot happen' } # => ["a", "b", "c", "d"]
4883  *
4884  * When argument +range+ is given,
4885  * it must be a Range object whose members are numeric;
4886  * its +begin+ and +end+ values determine the elements of +self+
4887  * to be replaced:
4888  *
4889  * - If both +begin+ and +end+ are positive, they specify the first and last elements
4890  * to be replaced:
4891  *
4892  * ['a', 'b', 'c', 'd'].fill('-', 1..2) # => ["a", "-", "-", "d"]
4893  * ['a', 'b', 'c', 'd'].fill(1..2) {|e| e.to_s } # => ["a", "1", "2", "d"]
4894  *
4895  * If +end+ is smaller than +begin+, replaces no elements:
4896  *
4897  * ['a', 'b', 'c', 'd'].fill('-', 2..1) # => ["a", "b", "c", "d"]
4898  * ['a', 'b', 'c', 'd'].fill(2..1) {|e| e.to_s } # => ["a", "b", "c", "d"]
4899  *
4900  * - If either is negative (or both are negative), counts backwards from the end of +self+:
4901  *
4902  * ['a', 'b', 'c', 'd'].fill('-', -3..2) # => ["a", "-", "-", "d"]
4903  * ['a', 'b', 'c', 'd'].fill('-', 1..-2) # => ["a", "-", "-", "d"]
4904  * ['a', 'b', 'c', 'd'].fill('-', -3..-2) # => ["a", "-", "-", "d"]
4905  *
4906  * ['a', 'b', 'c', 'd'].fill(-3..2) {|e| e.to_s } # => ["a", "1", "2", "d"]
4907  * ['a', 'b', 'c', 'd'].fill(1..-2) {|e| e.to_s } # => ["a", "1", "2", "d"]
4908  * ['a', 'b', 'c', 'd'].fill(-3..-2) {|e| e.to_s } # => ["a", "1", "2", "d"]
4909  *
4910  * - If the +end+ value is excluded (see Range#exclude_end?), omits the last replacement:
4911  *
4912  * ['a', 'b', 'c', 'd'].fill('-', 1...2) # => ["a", "-", "c", "d"]
4913  * ['a', 'b', 'c', 'd'].fill('-', 1...-2) # => ["a", "-", "c", "d"]
4914  *
4915  * ['a', 'b', 'c', 'd'].fill(1...2) {|e| e.to_s } # => ["a", "1", "c", "d"]
4916  * ['a', 'b', 'c', 'd'].fill(1...-2) {|e| e.to_s } # => ["a", "1", "c", "d"]
4917  *
4918  * - If the range is endless (see {Endless Ranges}[rdoc-ref:Range@Endless+Ranges]),
4919  * replaces elements to the end of +self+:
4920  *
4921  * ['a', 'b', 'c', 'd'].fill('-', 1..) # => ["a", "-", "-", "-"]
4922  * ['a', 'b', 'c', 'd'].fill(1..) {|e| e.to_s } # => ["a", "1", "2", "3"]
4923  *
4924  * - If the range is beginless (see {Beginless Ranges}[rdoc-ref:Range@Beginless+Ranges]),
4925  * replaces elements from the beginning of +self+:
4926  *
4927  * ['a', 'b', 'c', 'd'].fill('-', ..2) # => ["-", "-", "-", "d"]
4928  * ['a', 'b', 'c', 'd'].fill(..2) {|e| e.to_s } # => ["0", "1", "2", "d"]
4929  *
4930  * Related: see {Methods for Assigning}[rdoc-ref:Array@Methods+for+Assigning].
4931  */
4932 
4933 static VALUE
4934 rb_ary_fill(int argc, VALUE *argv, VALUE ary)
4935 {
4936  VALUE item = Qundef, arg1, arg2;
4937  long beg = 0, end = 0, len = 0;
4938 
4939  if (rb_block_given_p()) {
4940  rb_scan_args(argc, argv, "02", &arg1, &arg2);
4941  argc += 1; /* hackish */
4942  }
4943  else {
4944  rb_scan_args(argc, argv, "12", &item, &arg1, &arg2);
4945  }
4946  switch (argc) {
4947  case 1:
4948  beg = 0;
4949  len = RARRAY_LEN(ary);
4950  break;
4951  case 2:
4952  if (rb_range_beg_len(arg1, &beg, &len, RARRAY_LEN(ary), 1)) {
4953  break;
4954  }
4955  /* fall through */
4956  case 3:
4957  beg = NIL_P(arg1) ? 0 : NUM2LONG(arg1);
4958  if (beg < 0) {
4959  beg = RARRAY_LEN(ary) + beg;
4960  if (beg < 0) beg = 0;
4961  }
4962  len = NIL_P(arg2) ? RARRAY_LEN(ary) - beg : NUM2LONG(arg2);
4963  break;
4964  }
4965  rb_ary_modify(ary);
4966  if (len < 0) {
4967  return ary;
4968  }
4969  if (beg >= ARY_MAX_SIZE || len > ARY_MAX_SIZE - beg) {
4970  rb_raise(rb_eArgError, "argument too big");
4971  }
4972  end = beg + len;
4973  if (RARRAY_LEN(ary) < end) {
4974  if (end >= ARY_CAPA(ary)) {
4975  ary_resize_capa(ary, end);
4976  }
4977  ary_mem_clear(ary, RARRAY_LEN(ary), end - RARRAY_LEN(ary));
4978  ARY_SET_LEN(ary, end);
4979  }
4980 
4981  if (UNDEF_P(item)) {
4982  VALUE v;
4983  long i;
4984 
4985  for (i=beg; i<end; i++) {
4986  v = rb_yield(LONG2NUM(i));
4987  if (i>=RARRAY_LEN(ary)) break;
4988  ARY_SET(ary, i, v);
4989  }
4990  }
4991  else {
4992  ary_memfill(ary, beg, len, item);
4993  }
4994  return ary;
4995 }
4996 
4997 /*
4998  * call-seq:
4999  * self + other_array -> new_array
5000  *
5001  * Returns a new array containing all elements of +self+
5002  * followed by all elements of +other_array+:
5003  *
5004  * a = [0, 1] + [2, 3]
5005  * a # => [0, 1, 2, 3]
5006  *
5007  * Related: see {Methods for Combining}[rdoc-ref:Array@Methods+for+Combining].
5008  */
5009 
5010 VALUE
5012 {
5013  VALUE z;
5014  long len, xlen, ylen;
5015 
5016  y = to_ary(y);
5017  xlen = RARRAY_LEN(x);
5018  ylen = RARRAY_LEN(y);
5019  len = xlen + ylen;
5020  z = rb_ary_new2(len);
5021 
5022  ary_memcpy(z, 0, xlen, RARRAY_CONST_PTR(x));
5023  ary_memcpy(z, xlen, ylen, RARRAY_CONST_PTR(y));
5024  ARY_SET_LEN(z, len);
5025  return z;
5026 }
5027 
5028 static VALUE
5029 ary_append(VALUE x, VALUE y)
5030 {
5031  long n = RARRAY_LEN(y);
5032  if (n > 0) {
5033  rb_ary_splice(x, RARRAY_LEN(x), 0, RARRAY_CONST_PTR(y), n);
5034  }
5035  RB_GC_GUARD(y);
5036  return x;
5037 }
5038 
5039 /*
5040  * call-seq:
5041  * concat(*other_arrays) -> self
5042  *
5043  * Adds to +self+ all elements from each array in +other_arrays+; returns +self+:
5044  *
5045  * a = [0, 1]
5046  * a.concat(['two', 'three'], [:four, :five], a)
5047  * # => [0, 1, "two", "three", :four, :five, 0, 1]
5048  *
5049  * Related: see {Methods for Assigning}[rdoc-ref:Array@Methods+for+Assigning].
5050  */
5051 
5052 static VALUE
5053 rb_ary_concat_multi(int argc, VALUE *argv, VALUE ary)
5054 {
5055  rb_ary_modify_check(ary);
5056 
5057  if (argc == 1) {
5058  rb_ary_concat(ary, argv[0]);
5059  }
5060  else if (argc > 1) {
5061  int i;
5062  VALUE args = rb_ary_hidden_new(argc);
5063  for (i = 0; i < argc; i++) {
5064  rb_ary_concat(args, argv[i]);
5065  }
5066  ary_append(ary, args);
5067  }
5068 
5069  ary_verify(ary);
5070  return ary;
5071 }
5072 
5073 VALUE
5075 {
5076  return ary_append(x, to_ary(y));
5077 }
5078 
5079 /*
5080  * call-seq:
5081  * self * n -> new_array
5082  * self * string_separator -> new_string
5083  *
5084  * When non-negative integer argument +n+ is given,
5085  * returns a new array built by concatenating +n+ copies of +self+:
5086  *
5087  * a = ['x', 'y']
5088  * a * 3 # => ["x", "y", "x", "y", "x", "y"]
5089  *
5090  * When string argument +string_separator+ is given,
5091  * equivalent to <tt>self.join(string_separator)</tt>:
5092  *
5093  * [0, [0, 1], {foo: 0}] * ', ' # => "0, 0, 1, {:foo=>0}"
5094  *
5095  */
5096 
5097 static VALUE
5098 rb_ary_times(VALUE ary, VALUE times)
5099 {
5100  VALUE ary2, tmp;
5101  const VALUE *ptr;
5102  long t, len;
5103 
5104  tmp = rb_check_string_type(times);
5105  if (!NIL_P(tmp)) {
5106  return rb_ary_join(ary, tmp);
5107  }
5108 
5109  len = NUM2LONG(times);
5110  if (len == 0) {
5111  ary2 = ary_new(rb_cArray, 0);
5112  goto out;
5113  }
5114  if (len < 0) {
5115  rb_raise(rb_eArgError, "negative argument");
5116  }
5117  if (ARY_MAX_SIZE/len < RARRAY_LEN(ary)) {
5118  rb_raise(rb_eArgError, "argument too big");
5119  }
5120  len *= RARRAY_LEN(ary);
5121 
5122  ary2 = ary_new(rb_cArray, len);
5123  ARY_SET_LEN(ary2, len);
5124 
5125  ptr = RARRAY_CONST_PTR(ary);
5126  t = RARRAY_LEN(ary);
5127  if (0 < t) {
5128  ary_memcpy(ary2, 0, t, ptr);
5129  while (t <= len/2) {
5130  ary_memcpy(ary2, t, t, RARRAY_CONST_PTR(ary2));
5131  t *= 2;
5132  }
5133  if (t < len) {
5134  ary_memcpy(ary2, t, len-t, RARRAY_CONST_PTR(ary2));
5135  }
5136  }
5137  out:
5138  return ary2;
5139 }
5140 
5141 /*
5142  * call-seq:
5143  * assoc(object) -> found_array or nil
5144  *
5145  * Returns the first element +ele+ in +self+ such that +ele+ is an array
5146  * and <tt>ele[0] == object</tt>:
5147  *
5148  * a = [{foo: 0}, [2, 4], [4, 5, 6], [4, 5]]
5149  * a.assoc(4) # => [4, 5, 6]
5150  *
5151  * Returns +nil+ if no such element is found.
5152  *
5153  * Related: Array#rassoc;
5154  * see also {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching].
5155  */
5156 
5157 VALUE
5159 {
5160  long i;
5161  VALUE v;
5162 
5163  for (i = 0; i < RARRAY_LEN(ary); ++i) {
5164  v = rb_check_array_type(RARRAY_AREF(ary, i));
5165  if (!NIL_P(v) && RARRAY_LEN(v) > 0 &&
5166  rb_equal(RARRAY_AREF(v, 0), key))
5167  return v;
5168  }
5169  return Qnil;
5170 }
5171 
5172 /*
5173  * call-seq:
5174  * rassoc(object) -> found_array or nil
5175  *
5176  * Returns the first element +ele+ in +self+ such that +ele+ is an array
5177  * and <tt>ele[1] == object</tt>:
5178  *
5179  * a = [{foo: 0}, [2, 4], [4, 5, 6], [4, 5]]
5180  * a.rassoc(4) # => [2, 4]
5181  * a.rassoc(5) # => [4, 5, 6]
5182  *
5183  * Returns +nil+ if no such element is found.
5184  *
5185  * Related: Array#assoc;
5186  * see also {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching].
5187  */
5188 
5189 VALUE
5191 {
5192  long i;
5193  VALUE v;
5194 
5195  for (i = 0; i < RARRAY_LEN(ary); ++i) {
5196  v = rb_check_array_type(RARRAY_AREF(ary, i));
5197  if (RB_TYPE_P(v, T_ARRAY) &&
5198  RARRAY_LEN(v) > 1 &&
5199  rb_equal(RARRAY_AREF(v, 1), value))
5200  return v;
5201  }
5202  return Qnil;
5203 }
5204 
5205 static VALUE
5206 recursive_equal(VALUE ary1, VALUE ary2, int recur)
5207 {
5208  long i, len1;
5209  const VALUE *p1, *p2;
5210 
5211  if (recur) return Qtrue; /* Subtle! */
5212 
5213  /* rb_equal() can evacuate ptrs */
5214  p1 = RARRAY_CONST_PTR(ary1);
5215  p2 = RARRAY_CONST_PTR(ary2);
5216  len1 = RARRAY_LEN(ary1);
5217 
5218  for (i = 0; i < len1; i++) {
5219  if (*p1 != *p2) {
5220  if (rb_equal(*p1, *p2)) {
5221  len1 = RARRAY_LEN(ary1);
5222  if (len1 != RARRAY_LEN(ary2))
5223  return Qfalse;
5224  if (len1 < i)
5225  return Qtrue;
5226  p1 = RARRAY_CONST_PTR(ary1) + i;
5227  p2 = RARRAY_CONST_PTR(ary2) + i;
5228  }
5229  else {
5230  return Qfalse;
5231  }
5232  }
5233  p1++;
5234  p2++;
5235  }
5236  return Qtrue;
5237 }
5238 
5239 /*
5240  * call-seq:
5241  * self == other_array -> true or false
5242  *
5243  * Returns whether both:
5244  *
5245  * - +self+ and +other_array+ are the same size.
5246  * - Their corresponding elements are the same;
5247  * that is, for each index +i+ in <tt>(0...self.size)</tt>,
5248  * <tt>self[i] == other_array[i]</tt>.
5249  *
5250  * Examples:
5251  *
5252  * [:foo, 'bar', 2] == [:foo, 'bar', 2] # => true
5253  * [:foo, 'bar', 2] == [:foo, 'bar', 2.0] # => true
5254  * [:foo, 'bar', 2] == [:foo, 'bar'] # => false # Different sizes.
5255  * [:foo, 'bar', 2] == [:foo, 'bar', 3] # => false # Different elements.
5256  *
5257  * This method is different from method Array#eql?,
5258  * which compares elements using <tt>Object#eql?</tt>.
5259  *
5260  * Related: see {Methods for Comparing}[rdoc-ref:Array@Methods+for+Comparing].
5261  */
5262 
5263 static VALUE
5264 rb_ary_equal(VALUE ary1, VALUE ary2)
5265 {
5266  if (ary1 == ary2) return Qtrue;
5267  if (!RB_TYPE_P(ary2, T_ARRAY)) {
5268  if (!rb_respond_to(ary2, idTo_ary)) {
5269  return Qfalse;
5270  }
5271  return rb_equal(ary2, ary1);
5272  }
5273  if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return Qfalse;
5274  if (RARRAY_CONST_PTR(ary1) == RARRAY_CONST_PTR(ary2)) return Qtrue;
5275  return rb_exec_recursive_paired(recursive_equal, ary1, ary2, ary2);
5276 }
5277 
5278 static VALUE
5279 recursive_eql(VALUE ary1, VALUE ary2, int recur)
5280 {
5281  long i;
5282 
5283  if (recur) return Qtrue; /* Subtle! */
5284  for (i=0; i<RARRAY_LEN(ary1); i++) {
5285  if (!rb_eql(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
5286  return Qfalse;
5287  }
5288  return Qtrue;
5289 }
5290 
5291 /*
5292  * call-seq:
5293  * eql?(other_array) -> true or false
5294  *
5295  * Returns +true+ if +self+ and +other_array+ are the same size,
5296  * and if, for each index +i+ in +self+, <tt>self[i].eql?(other_array[i])</tt>:
5297  *
5298  * a0 = [:foo, 'bar', 2]
5299  * a1 = [:foo, 'bar', 2]
5300  * a1.eql?(a0) # => true
5301  *
5302  * Otherwise, returns +false+.
5303  *
5304  * This method is different from method Array#==,
5305  * which compares using method <tt>Object#==</tt>.
5306  *
5307  * Related: see {Methods for Querying}[rdoc-ref:Array@Methods+for+Querying].
5308  */
5309 
5310 static VALUE
5311 rb_ary_eql(VALUE ary1, VALUE ary2)
5312 {
5313  if (ary1 == ary2) return Qtrue;
5314  if (!RB_TYPE_P(ary2, T_ARRAY)) return Qfalse;
5315  if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return Qfalse;
5316  if (RARRAY_CONST_PTR(ary1) == RARRAY_CONST_PTR(ary2)) return Qtrue;
5317  return rb_exec_recursive_paired(recursive_eql, ary1, ary2, ary2);
5318 }
5319 
5320 VALUE
5321 rb_ary_hash_values(long len, const VALUE *elements)
5322 {
5323  long i;
5324  st_index_t h;
5325  VALUE n;
5326 
5327  h = rb_hash_start(len);
5328  h = rb_hash_uint(h, (st_index_t)rb_ary_hash_values);
5329  for (i=0; i<len; i++) {
5330  n = rb_hash(elements[i]);
5331  h = rb_hash_uint(h, NUM2LONG(n));
5332  }
5333  h = rb_hash_end(h);
5334  return ST2FIX(h);
5335 }
5336 
5337 /*
5338  * call-seq:
5339  * hash -> integer
5340  *
5341  * Returns the integer hash value for +self+.
5342  *
5343  * Two arrays with the same content will have the same hash value
5344  * (and will compare using eql?):
5345  *
5346  * ['a', 'b'].hash == ['a', 'b'].hash # => true
5347  * ['a', 'b'].hash == ['a', 'c'].hash # => false
5348  * ['a', 'b'].hash == ['a'].hash # => false
5349  *
5350  */
5351 
5352 static VALUE
5353 rb_ary_hash(VALUE ary)
5354 {
5355  return rb_ary_hash_values(RARRAY_LEN(ary), RARRAY_CONST_PTR(ary));
5356 }
5357 
5358 /*
5359  * call-seq:
5360  * include?(object) -> true or false
5361  *
5362  * Returns whether for some element +element+ in +self+,
5363  * <tt>object == element</tt>:
5364  *
5365  * [0, 1, 2].include?(2) # => true
5366  * [0, 1, 2].include?(2.0) # => true
5367  * [0, 1, 2].include?(2.1) # => false
5368  *
5369  * Related: see {Methods for Querying}[rdoc-ref:Array@Methods+for+Querying].
5370  */
5371 
5372 VALUE
5374 {
5375  long i;
5376  VALUE e;
5377 
5378  for (i=0; i<RARRAY_LEN(ary); i++) {
5379  e = RARRAY_AREF(ary, i);
5380  if (rb_equal(e, item)) {
5381  return Qtrue;
5382  }
5383  }
5384  return Qfalse;
5385 }
5386 
5387 static VALUE
5388 rb_ary_includes_by_eql(VALUE ary, VALUE item)
5389 {
5390  long i;
5391  VALUE e;
5392 
5393  for (i=0; i<RARRAY_LEN(ary); i++) {
5394  e = RARRAY_AREF(ary, i);
5395  if (rb_eql(item, e)) {
5396  return Qtrue;
5397  }
5398  }
5399  return Qfalse;
5400 }
5401 
5402 static VALUE
5403 recursive_cmp(VALUE ary1, VALUE ary2, int recur)
5404 {
5405  long i, len;
5406 
5407  if (recur) return Qundef; /* Subtle! */
5408  len = RARRAY_LEN(ary1);
5409  if (len > RARRAY_LEN(ary2)) {
5410  len = RARRAY_LEN(ary2);
5411  }
5412  for (i=0; i<len; i++) {
5413  VALUE e1 = rb_ary_elt(ary1, i), e2 = rb_ary_elt(ary2, i);
5414  VALUE v = rb_funcallv(e1, id_cmp, 1, &e2);
5415  if (v != INT2FIX(0)) {
5416  return v;
5417  }
5418  }
5419  return Qundef;
5420 }
5421 
5422 /*
5423  * call-seq:
5424  * self <=> other_array -> -1, 0, or 1
5425  *
5426  * Returns -1, 0, or 1 as +self+ is determined
5427  * to be less than, equal to, or greater than +other_array+.
5428  *
5429  * Iterates over each index +i+ in <tt>(0...self.size)</tt>:
5430  *
5431  * - Computes <tt>result[i]</tt> as <tt>self[i] <=> other_array[i]</tt>.
5432  * - Immediately returns 1 if <tt>result[i]</tt> is 1:
5433  *
5434  * [0, 1, 2] <=> [0, 0, 2] # => 1
5435  *
5436  * - Immediately returns -1 if <tt>result[i]</tt> is -1:
5437  *
5438  * [0, 1, 2] <=> [0, 2, 2] # => -1
5439  *
5440  * - Continues if <tt>result[i]</tt> is 0.
5441  *
5442  * When every +result+ is 0,
5443  * returns <tt>self.size <=> other_array.size</tt>
5444  * (see Integer#<=>):
5445  *
5446  * [0, 1, 2] <=> [0, 1] # => 1
5447  * [0, 1, 2] <=> [0, 1, 2] # => 0
5448  * [0, 1, 2] <=> [0, 1, 2, 3] # => -1
5449  *
5450  * Note that when +other_array+ is larger than +self+,
5451  * its trailing elements do not affect the result:
5452  *
5453  * [0, 1, 2] <=> [0, 1, 2, -3] # => -1
5454  * [0, 1, 2] <=> [0, 1, 2, 0] # => -1
5455  * [0, 1, 2] <=> [0, 1, 2, 3] # => -1
5456  *
5457  * Related: see {Methods for Comparing}[rdoc-ref:Array@Methods+for+Comparing].
5458  */
5459 
5460 VALUE
5462 {
5463  long len;
5464  VALUE v;
5465 
5466  ary2 = rb_check_array_type(ary2);
5467  if (NIL_P(ary2)) return Qnil;
5468  if (ary1 == ary2) return INT2FIX(0);
5469  v = rb_exec_recursive_paired(recursive_cmp, ary1, ary2, ary2);
5470  if (!UNDEF_P(v)) return v;
5471  len = RARRAY_LEN(ary1) - RARRAY_LEN(ary2);
5472  if (len == 0) return INT2FIX(0);
5473  if (len > 0) return INT2FIX(1);
5474  return INT2FIX(-1);
5475 }
5476 
5477 static VALUE
5478 ary_add_hash(VALUE hash, VALUE ary)
5479 {
5480  long i;
5481 
5482  for (i=0; i<RARRAY_LEN(ary); i++) {
5483  VALUE elt = RARRAY_AREF(ary, i);
5484  rb_hash_add_new_element(hash, elt, elt);
5485  }
5486  return hash;
5487 }
5488 
5489 static inline VALUE
5490 ary_tmp_hash_new(VALUE ary)
5491 {
5492  long size = RARRAY_LEN(ary);
5493  VALUE hash = rb_hash_new_with_size(size);
5494 
5495  RBASIC_CLEAR_CLASS(hash);
5496  return hash;
5497 }
5498 
5499 static VALUE
5500 ary_make_hash(VALUE ary)
5501 {
5502  VALUE hash = ary_tmp_hash_new(ary);
5503  return ary_add_hash(hash, ary);
5504 }
5505 
5506 static VALUE
5507 ary_add_hash_by(VALUE hash, VALUE ary)
5508 {
5509  long i;
5510 
5511  for (i = 0; i < RARRAY_LEN(ary); ++i) {
5512  VALUE v = rb_ary_elt(ary, i), k = rb_yield(v);
5513  rb_hash_add_new_element(hash, k, v);
5514  }
5515  return hash;
5516 }
5517 
5518 static VALUE
5519 ary_make_hash_by(VALUE ary)
5520 {
5521  VALUE hash = ary_tmp_hash_new(ary);
5522  return ary_add_hash_by(hash, ary);
5523 }
5524 
5525 /*
5526  * call-seq:
5527  * self - other_array -> new_array
5528  *
5529  * Returns a new array containing only those elements of +self+
5530  * that are not found in +other_array+;
5531  * the order from +self+ is preserved:
5532  *
5533  * [0, 1, 1, 2, 1, 1, 3, 1, 1] - [1] # => [0, 2, 3]
5534  * [0, 1, 1, 2, 1, 1, 3, 1, 1] - [3, 2, 0, :foo] # => [1, 1, 1, 1, 1, 1]
5535  * [0, 1, 2] - [:foo] # => [0, 1, 2]
5536  *
5537  * Element are compared using method <tt>#eql?</tt>
5538  * (as defined in each element of +self+).
5539  *
5540  * Related: see {Methods for Combining}[rdoc-ref:Array@Methods+for+Combining].
5541  */
5542 
5543 VALUE
5544 rb_ary_diff(VALUE ary1, VALUE ary2)
5545 {
5546  VALUE ary3;
5547  VALUE hash;
5548  long i;
5549 
5550  ary2 = to_ary(ary2);
5551  if (RARRAY_LEN(ary2) == 0) { return ary_make_shared_copy(ary1); }
5552  ary3 = rb_ary_new();
5553 
5554  if (RARRAY_LEN(ary1) <= SMALL_ARRAY_LEN || RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
5555  for (i=0; i<RARRAY_LEN(ary1); i++) {
5556  VALUE elt = rb_ary_elt(ary1, i);
5557  if (rb_ary_includes_by_eql(ary2, elt)) continue;
5558  rb_ary_push(ary3, elt);
5559  }
5560  return ary3;
5561  }
5562 
5563  hash = ary_make_hash(ary2);
5564  for (i=0; i<RARRAY_LEN(ary1); i++) {
5565  if (rb_hash_stlike_lookup(hash, RARRAY_AREF(ary1, i), NULL)) continue;
5566  rb_ary_push(ary3, rb_ary_elt(ary1, i));
5567  }
5568 
5569  return ary3;
5570 }
5571 
5572 /*
5573  * call-seq:
5574  * difference(*other_arrays = []) -> new_array
5575  *
5576  * Returns a new array containing only those elements from +self+
5577  * that are not found in any of the given +other_arrays+;
5578  * items are compared using <tt>eql?</tt>; order from +self+ is preserved:
5579  *
5580  * [0, 1, 1, 2, 1, 1, 3, 1, 1].difference([1]) # => [0, 2, 3]
5581  * [0, 1, 2, 3].difference([3, 0], [1, 3]) # => [2]
5582  * [0, 1, 2].difference([4]) # => [0, 1, 2]
5583  * [0, 1, 2].difference # => [0, 1, 2]
5584  *
5585  * Returns a copy of +self+ if no arguments are given.
5586  *
5587  * Related: Array#-;
5588  * see also {Methods for Combining}[rdoc-ref:Array@Methods+for+Combining].
5589  */
5590 
5591 static VALUE
5592 rb_ary_difference_multi(int argc, VALUE *argv, VALUE ary)
5593 {
5594  VALUE ary_diff;
5595  long i, length;
5596  volatile VALUE t0;
5597  bool *is_hash = ALLOCV_N(bool, t0, argc);
5598  ary_diff = rb_ary_new();
5599  length = RARRAY_LEN(ary);
5600 
5601  for (i = 0; i < argc; i++) {
5602  argv[i] = to_ary(argv[i]);
5603  is_hash[i] = (length > SMALL_ARRAY_LEN && RARRAY_LEN(argv[i]) > SMALL_ARRAY_LEN);
5604  if (is_hash[i]) argv[i] = ary_make_hash(argv[i]);
5605  }
5606 
5607  for (i = 0; i < RARRAY_LEN(ary); i++) {
5608  int j;
5609  VALUE elt = rb_ary_elt(ary, i);
5610  for (j = 0; j < argc; j++) {
5611  if (is_hash[j]) {
5612  if (rb_hash_stlike_lookup(argv[j], RARRAY_AREF(ary, i), NULL))
5613  break;
5614  }
5615  else {
5616  if (rb_ary_includes_by_eql(argv[j], elt)) break;
5617  }
5618  }
5619  if (j == argc) rb_ary_push(ary_diff, elt);
5620  }
5621 
5622  ALLOCV_END(t0);
5623 
5624  return ary_diff;
5625 }
5626 
5627 
5628 /*
5629  * call-seq:
5630  * self & other_array -> new_array
5631  *
5632  * Returns a new array containing the _intersection_ of +self+ and +other_array+;
5633  * that is, containing those elements found in both +self+ and +other_array+:
5634  *
5635  * [0, 1, 2, 3] & [1, 2] # => [1, 2]
5636  *
5637  * Omits duplicates:
5638  *
5639  * [0, 1, 1, 0] & [0, 1] # => [0, 1]
5640  *
5641  * Preserves order from +self+:
5642  *
5643  * [0, 1, 2] & [3, 2, 1, 0] # => [0, 1, 2]
5644  *
5645  * Identifies common elements using method <tt>#eql?</tt>
5646  * (as defined in each element of +self+).
5647  *
5648  * Related: see {Methods for Combining}[rdoc-ref:Array@Methods+for+Combining].
5649  */
5650 
5651 
5652 static VALUE
5653 rb_ary_and(VALUE ary1, VALUE ary2)
5654 {
5655  VALUE hash, ary3, v;
5656  st_data_t vv;
5657  long i;
5658 
5659  ary2 = to_ary(ary2);
5660  ary3 = rb_ary_new();
5661  if (RARRAY_LEN(ary1) == 0 || RARRAY_LEN(ary2) == 0) return ary3;
5662 
5663  if (RARRAY_LEN(ary1) <= SMALL_ARRAY_LEN && RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
5664  for (i=0; i<RARRAY_LEN(ary1); i++) {
5665  v = RARRAY_AREF(ary1, i);
5666  if (!rb_ary_includes_by_eql(ary2, v)) continue;
5667  if (rb_ary_includes_by_eql(ary3, v)) continue;
5668  rb_ary_push(ary3, v);
5669  }
5670  return ary3;
5671  }
5672 
5673  hash = ary_make_hash(ary2);
5674 
5675  for (i=0; i<RARRAY_LEN(ary1); i++) {
5676  v = RARRAY_AREF(ary1, i);
5677  vv = (st_data_t)v;
5678  if (rb_hash_stlike_delete(hash, &vv, 0)) {
5679  rb_ary_push(ary3, v);
5680  }
5681  }
5682 
5683  return ary3;
5684 }
5685 
5686 /*
5687  * call-seq:
5688  * intersection(*other_arrays) -> new_array
5689  *
5690  * Returns a new array containing each element in +self+ that is +#eql?+
5691  * to at least one element in each of the given +other_arrays+;
5692  * duplicates are omitted:
5693  *
5694  * [0, 0, 1, 1, 2, 3].intersection([0, 1, 2], [0, 1, 3]) # => [0, 1]
5695  *
5696  * Each element must correctly implement method <tt>#hash</tt>.
5697  *
5698  * Order from +self+ is preserved:
5699  *
5700  * [0, 1, 2].intersection([2, 1, 0]) # => [0, 1, 2]
5701  *
5702  * Returns a copy of +self+ if no arguments are given.
5703  *
5704  * Related: see {Methods for Combining}[rdoc-ref:Array@Methods+for+Combining].
5705  */
5706 
5707 static VALUE
5708 rb_ary_intersection_multi(int argc, VALUE *argv, VALUE ary)
5709 {
5710  VALUE result = rb_ary_dup(ary);
5711  int i;
5712 
5713  for (i = 0; i < argc; i++) {
5714  result = rb_ary_and(result, argv[i]);
5715  }
5716 
5717  return result;
5718 }
5719 
5720 static int
5721 ary_hash_orset(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
5722 {
5723  if (existing) return ST_STOP;
5724  *key = *value = (VALUE)arg;
5725  return ST_CONTINUE;
5726 }
5727 
5728 static void
5729 rb_ary_union(VALUE ary_union, VALUE ary)
5730 {
5731  long i;
5732  for (i = 0; i < RARRAY_LEN(ary); i++) {
5733  VALUE elt = rb_ary_elt(ary, i);
5734  if (rb_ary_includes_by_eql(ary_union, elt)) continue;
5735  rb_ary_push(ary_union, elt);
5736  }
5737 }
5738 
5739 static void
5740 rb_ary_union_hash(VALUE hash, VALUE ary2)
5741 {
5742  long i;
5743  for (i = 0; i < RARRAY_LEN(ary2); i++) {
5744  VALUE elt = RARRAY_AREF(ary2, i);
5745  if (!rb_hash_stlike_update(hash, (st_data_t)elt, ary_hash_orset, (st_data_t)elt)) {
5746  RB_OBJ_WRITTEN(hash, Qundef, elt);
5747  }
5748  }
5749 }
5750 
5751 /*
5752  * call-seq:
5753  * self | other_array -> new_array
5754  *
5755  * Returns the union of +self+ and +other_array+;
5756  * duplicates are removed; order is preserved;
5757  * items are compared using <tt>eql?</tt>:
5758  *
5759  * [0, 1] | [2, 3] # => [0, 1, 2, 3]
5760  * [0, 1, 1] | [2, 2, 3] # => [0, 1, 2, 3]
5761  * [0, 1, 2] | [3, 2, 1, 0] # => [0, 1, 2, 3]
5762  *
5763  * Related: see {Methods for Combining}[rdoc-ref:Array@Methods+for+Combining].
5764  */
5765 
5766 static VALUE
5767 rb_ary_or(VALUE ary1, VALUE ary2)
5768 {
5769  VALUE hash;
5770 
5771  ary2 = to_ary(ary2);
5772  if (RARRAY_LEN(ary1) + RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
5773  VALUE ary3 = rb_ary_new();
5774  rb_ary_union(ary3, ary1);
5775  rb_ary_union(ary3, ary2);
5776  return ary3;
5777  }
5778 
5779  hash = ary_make_hash(ary1);
5780  rb_ary_union_hash(hash, ary2);
5781 
5782  return rb_hash_values(hash);
5783 }
5784 
5785 /*
5786  * call-seq:
5787  * union(*other_arrays) -> new_array
5788  *
5789  * Returns a new array that is the union of the elements of +self+
5790  * and all given arrays +other_arrays+;
5791  * items are compared using <tt>eql?</tt>:
5792  *
5793  * [0, 1, 2, 3].union([4, 5], [6, 7]) # => [0, 1, 2, 3, 4, 5, 6, 7]
5794  *
5795  * Removes duplicates (preserving the first found):
5796  *
5797  * [0, 1, 1].union([2, 1], [3, 1]) # => [0, 1, 2, 3]
5798  *
5799  * Preserves order (preserving the position of the first found):
5800  *
5801  * [3, 2, 1, 0].union([5, 3], [4, 2]) # => [3, 2, 1, 0, 5, 4]
5802  *
5803  * With no arguments given, returns a copy of +self+.
5804  *
5805  * Related: see {Methods for Combining}[rdoc-ref:Array@Methods+for+Combining].
5806  */
5807 
5808 static VALUE
5809 rb_ary_union_multi(int argc, VALUE *argv, VALUE ary)
5810 {
5811  int i;
5812  long sum;
5813  VALUE hash;
5814 
5815  sum = RARRAY_LEN(ary);
5816  for (i = 0; i < argc; i++) {
5817  argv[i] = to_ary(argv[i]);
5818  sum += RARRAY_LEN(argv[i]);
5819  }
5820 
5821  if (sum <= SMALL_ARRAY_LEN) {
5822  VALUE ary_union = rb_ary_new();
5823 
5824  rb_ary_union(ary_union, ary);
5825  for (i = 0; i < argc; i++) rb_ary_union(ary_union, argv[i]);
5826 
5827  return ary_union;
5828  }
5829 
5830  hash = ary_make_hash(ary);
5831  for (i = 0; i < argc; i++) rb_ary_union_hash(hash, argv[i]);
5832 
5833  return rb_hash_values(hash);
5834 }
5835 
5836 /*
5837  * call-seq:
5838  * intersect?(other_array) -> true or false
5839  *
5840  * Returns whether +other_array+ has at least one element that is +#eql?+ to some element of +self+:
5841  *
5842  * [1, 2, 3].intersect?([3, 4, 5]) # => true
5843  * [1, 2, 3].intersect?([4, 5, 6]) # => false
5844  *
5845  * Each element must correctly implement method <tt>#hash</tt>.
5846  *
5847  * Related: see {Methods for Querying}[rdoc-ref:Array@Methods+for+Querying].
5848  */
5849 
5850 static VALUE
5851 rb_ary_intersect_p(VALUE ary1, VALUE ary2)
5852 {
5853  VALUE hash, v, result, shorter, longer;
5854  st_data_t vv;
5855  long i;
5856 
5857  ary2 = to_ary(ary2);
5858  if (RARRAY_LEN(ary1) == 0 || RARRAY_LEN(ary2) == 0) return Qfalse;
5859 
5860  if (RARRAY_LEN(ary1) <= SMALL_ARRAY_LEN && RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
5861  for (i=0; i<RARRAY_LEN(ary1); i++) {
5862  v = RARRAY_AREF(ary1, i);
5863  if (rb_ary_includes_by_eql(ary2, v)) return Qtrue;
5864  }
5865  return Qfalse;
5866  }
5867 
5868  shorter = ary1;
5869  longer = ary2;
5870  if (RARRAY_LEN(ary1) > RARRAY_LEN(ary2)) {
5871  longer = ary1;
5872  shorter = ary2;
5873  }
5874 
5875  hash = ary_make_hash(shorter);
5876  result = Qfalse;
5877 
5878  for (i=0; i<RARRAY_LEN(longer); i++) {
5879  v = RARRAY_AREF(longer, i);
5880  vv = (st_data_t)v;
5881  if (rb_hash_stlike_lookup(hash, vv, 0)) {
5882  result = Qtrue;
5883  break;
5884  }
5885  }
5886 
5887  return result;
5888 }
5889 
5890 static VALUE
5891 ary_max_generic(VALUE ary, long i, VALUE vmax)
5892 {
5893  RUBY_ASSERT(i > 0 && i < RARRAY_LEN(ary));
5894 
5895  VALUE v;
5896  for (; i < RARRAY_LEN(ary); ++i) {
5897  v = RARRAY_AREF(ary, i);
5898 
5899  if (rb_cmpint(rb_funcallv(vmax, id_cmp, 1, &v), vmax, v) < 0) {
5900  vmax = v;
5901  }
5902  }
5903 
5904  return vmax;
5905 }
5906 
5907 static VALUE
5908 ary_max_opt_fixnum(VALUE ary, long i, VALUE vmax)
5909 {
5910  const long n = RARRAY_LEN(ary);
5911  RUBY_ASSERT(i > 0 && i < n);
5912  RUBY_ASSERT(FIXNUM_P(vmax));
5913 
5914  VALUE v;
5915  for (; i < n; ++i) {
5916  v = RARRAY_AREF(ary, i);
5917 
5918  if (FIXNUM_P(v)) {
5919  if ((long)vmax < (long)v) {
5920  vmax = v;
5921  }
5922  }
5923  else {
5924  return ary_max_generic(ary, i, vmax);
5925  }
5926  }
5927 
5928  return vmax;
5929 }
5930 
5931 static VALUE
5932 ary_max_opt_float(VALUE ary, long i, VALUE vmax)
5933 {
5934  const long n = RARRAY_LEN(ary);
5935  RUBY_ASSERT(i > 0 && i < n);
5937 
5938  VALUE v;
5939  for (; i < n; ++i) {
5940  v = RARRAY_AREF(ary, i);
5941 
5942  if (RB_FLOAT_TYPE_P(v)) {
5943  if (rb_float_cmp(vmax, v) < 0) {
5944  vmax = v;
5945  }
5946  }
5947  else {
5948  return ary_max_generic(ary, i, vmax);
5949  }
5950  }
5951 
5952  return vmax;
5953 }
5954 
5955 static VALUE
5956 ary_max_opt_string(VALUE ary, long i, VALUE vmax)
5957 {
5958  const long n = RARRAY_LEN(ary);
5959  RUBY_ASSERT(i > 0 && i < n);
5960  RUBY_ASSERT(STRING_P(vmax));
5961 
5962  VALUE v;
5963  for (; i < n; ++i) {
5964  v = RARRAY_AREF(ary, i);
5965 
5966  if (STRING_P(v)) {
5967  if (rb_str_cmp(vmax, v) < 0) {
5968  vmax = v;
5969  }
5970  }
5971  else {
5972  return ary_max_generic(ary, i, vmax);
5973  }
5974  }
5975 
5976  return vmax;
5977 }
5978 
5979 /*
5980  * call-seq:
5981  * max -> element
5982  * max(n) -> new_array
5983  * max {|a, b| ... } -> element
5984  * max(n) {|a, b| ... } -> new_array
5985  *
5986  * Returns one of the following:
5987  *
5988  * - The maximum-valued element from +self+.
5989  * - A new array of maximum-valued elements from +self+.
5990  *
5991  * Does not modify +self+.
5992  *
5993  * With no block given, each element in +self+ must respond to method <tt>#<=></tt>
5994  * with a numeric.
5995  *
5996  * With no argument and no block, returns the element in +self+
5997  * having the maximum value per method <tt>#<=></tt>:
5998  *
5999  * [1, 0, 3, 2].max # => 3
6000  *
6001  * With non-negative numeric argument +n+ and no block,
6002  * returns a new array with at most +n+ elements,
6003  * in descending order, per method <tt>#<=></tt>:
6004  *
6005  * [1, 0, 3, 2].max(3) # => [3, 2, 1]
6006  * [1, 0, 3, 2].max(3.0) # => [3, 2, 1]
6007  * [1, 0, 3, 2].max(9) # => [3, 2, 1, 0]
6008  * [1, 0, 3, 2].max(0) # => []
6009  *
6010  * With a block given, the block must return a numeric.
6011  *
6012  * With a block and no argument, calls the block <tt>self.size - 1</tt> times to compare elements;
6013  * returns the element having the maximum value per the block:
6014  *
6015  * ['0', '', '000', '00'].max {|a, b| a.size <=> b.size }
6016  * # => "000"
6017  *
6018  * With non-negative numeric argument +n+ and a block,
6019  * returns a new array with at most +n+ elements,
6020  * in descending order, per the block:
6021  *
6022  * ['0', '', '000', '00'].max(2) {|a, b| a.size <=> b.size }
6023  * # => ["000", "00"]
6024  *
6025  * Related: see {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching].
6026  */
6027 static VALUE
6028 rb_ary_max(int argc, VALUE *argv, VALUE ary)
6029 {
6030  VALUE result = Qundef, v;
6031  VALUE num;
6032  long i;
6033 
6034  if (rb_check_arity(argc, 0, 1) && !NIL_P(num = argv[0]))
6035  return rb_nmin_run(ary, num, 0, 1, 1);
6036 
6037  const long n = RARRAY_LEN(ary);
6038  if (rb_block_given_p()) {
6039  for (i = 0; i < RARRAY_LEN(ary); i++) {
6040  v = RARRAY_AREF(ary, i);
6041  if (UNDEF_P(result) || rb_cmpint(rb_yield_values(2, v, result), v, result) > 0) {
6042  result = v;
6043  }
6044  }
6045  }
6046  else if (n > 0) {
6047  result = RARRAY_AREF(ary, 0);
6048  if (n > 1) {
6049  if (FIXNUM_P(result) && CMP_OPTIMIZABLE(INTEGER)) {
6050  return ary_max_opt_fixnum(ary, 1, result);
6051  }
6052  else if (STRING_P(result) && CMP_OPTIMIZABLE(STRING)) {
6053  return ary_max_opt_string(ary, 1, result);
6054  }
6055  else if (RB_FLOAT_TYPE_P(result) && CMP_OPTIMIZABLE(FLOAT)) {
6056  return ary_max_opt_float(ary, 1, result);
6057  }
6058  else {
6059  return ary_max_generic(ary, 1, result);
6060  }
6061  }
6062  }
6063  if (UNDEF_P(result)) return Qnil;
6064  return result;
6065 }
6066 
6067 static VALUE
6068 ary_min_generic(VALUE ary, long i, VALUE vmin)
6069 {
6070  RUBY_ASSERT(i > 0 && i < RARRAY_LEN(ary));
6071 
6072  VALUE v;
6073  for (; i < RARRAY_LEN(ary); ++i) {
6074  v = RARRAY_AREF(ary, i);
6075 
6076  if (rb_cmpint(rb_funcallv(vmin, id_cmp, 1, &v), vmin, v) > 0) {
6077  vmin = v;
6078  }
6079  }
6080 
6081  return vmin;
6082 }
6083 
6084 static VALUE
6085 ary_min_opt_fixnum(VALUE ary, long i, VALUE vmin)
6086 {
6087  const long n = RARRAY_LEN(ary);
6088  RUBY_ASSERT(i > 0 && i < n);
6089  RUBY_ASSERT(FIXNUM_P(vmin));
6090 
6091  VALUE a;
6092  for (; i < n; ++i) {
6093  a = RARRAY_AREF(ary, i);
6094 
6095  if (FIXNUM_P(a)) {
6096  if ((long)vmin > (long)a) {
6097  vmin = a;
6098  }
6099  }
6100  else {
6101  return ary_min_generic(ary, i, vmin);
6102  }
6103  }
6104 
6105  return vmin;
6106 }
6107 
6108 static VALUE
6109 ary_min_opt_float(VALUE ary, long i, VALUE vmin)
6110 {
6111  const long n = RARRAY_LEN(ary);
6112  RUBY_ASSERT(i > 0 && i < n);
6114 
6115  VALUE a;
6116  for (; i < n; ++i) {
6117  a = RARRAY_AREF(ary, i);
6118 
6119  if (RB_FLOAT_TYPE_P(a)) {
6120  if (rb_float_cmp(vmin, a) > 0) {
6121  vmin = a;
6122  }
6123  }
6124  else {
6125  return ary_min_generic(ary, i, vmin);
6126  }
6127  }
6128 
6129  return vmin;
6130 }
6131 
6132 static VALUE
6133 ary_min_opt_string(VALUE ary, long i, VALUE vmin)
6134 {
6135  const long n = RARRAY_LEN(ary);
6136  RUBY_ASSERT(i > 0 && i < n);
6137  RUBY_ASSERT(STRING_P(vmin));
6138 
6139  VALUE a;
6140  for (; i < n; ++i) {
6141  a = RARRAY_AREF(ary, i);
6142 
6143  if (STRING_P(a)) {
6144  if (rb_str_cmp(vmin, a) > 0) {
6145  vmin = a;
6146  }
6147  }
6148  else {
6149  return ary_min_generic(ary, i, vmin);
6150  }
6151  }
6152 
6153  return vmin;
6154 }
6155 
6156 /*
6157  * call-seq:
6158  * min -> element
6159  * min(n) -> new_array
6160  * min {|a, b| ... } -> element
6161  * min(n) {|a, b| ... } -> new_array
6162  *
6163  * Returns one of the following:
6164  *
6165  * - The minimum-valued element from +self+.
6166  * - A new array of minimum-valued elements from +self+.
6167  *
6168  * Does not modify +self+.
6169  *
6170  * With no block given, each element in +self+ must respond to method <tt>#<=></tt>
6171  * with a numeric.
6172  *
6173  * With no argument and no block, returns the element in +self+
6174  * having the minimum value per method <tt>#<=></tt>:
6175  *
6176  * [1, 0, 3, 2].min # => 0
6177  *
6178  * With non-negative numeric argument +n+ and no block,
6179  * returns a new array with at most +n+ elements,
6180  * in ascending order, per method <tt>#<=></tt>:
6181  *
6182  * [1, 0, 3, 2].min(3) # => [0, 1, 2]
6183  * [1, 0, 3, 2].min(3.0) # => [0, 1, 2]
6184  * [1, 0, 3, 2].min(9) # => [0, 1, 2, 3]
6185  * [1, 0, 3, 2].min(0) # => []
6186  *
6187  * With a block given, the block must return a numeric.
6188  *
6189  * With a block and no argument, calls the block <tt>self.size - 1</tt> times to compare elements;
6190  * returns the element having the minimum value per the block:
6191  *
6192  * ['0', '', '000', '00'].min {|a, b| a.size <=> b.size }
6193  * # => ""
6194  *
6195  * With non-negative numeric argument +n+ and a block,
6196  * returns a new array with at most +n+ elements,
6197  * in ascending order, per the block:
6198  *
6199  * ['0', '', '000', '00'].min(2) {|a, b| a.size <=> b.size }
6200  * # => ["", "0"]
6201  *
6202  * Related: see {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching].
6203  */
6204 static VALUE
6205 rb_ary_min(int argc, VALUE *argv, VALUE ary)
6206 {
6207  VALUE result = Qundef, v;
6208  VALUE num;
6209  long i;
6210 
6211  if (rb_check_arity(argc, 0, 1) && !NIL_P(num = argv[0]))
6212  return rb_nmin_run(ary, num, 0, 0, 1);
6213 
6214  const long n = RARRAY_LEN(ary);
6215  if (rb_block_given_p()) {
6216  for (i = 0; i < RARRAY_LEN(ary); i++) {
6217  v = RARRAY_AREF(ary, i);
6218  if (UNDEF_P(result) || rb_cmpint(rb_yield_values(2, v, result), v, result) < 0) {
6219  result = v;
6220  }
6221  }
6222  }
6223  else if (n > 0) {
6224  result = RARRAY_AREF(ary, 0);
6225  if (n > 1) {
6226  if (FIXNUM_P(result) && CMP_OPTIMIZABLE(INTEGER)) {
6227  return ary_min_opt_fixnum(ary, 1, result);
6228  }
6229  else if (STRING_P(result) && CMP_OPTIMIZABLE(STRING)) {
6230  return ary_min_opt_string(ary, 1, result);
6231  }
6232  else if (RB_FLOAT_TYPE_P(result) && CMP_OPTIMIZABLE(FLOAT)) {
6233  return ary_min_opt_float(ary, 1, result);
6234  }
6235  else {
6236  return ary_min_generic(ary, 1, result);
6237  }
6238  }
6239  }
6240  if (UNDEF_P(result)) return Qnil;
6241  return result;
6242 }
6243 
6244 /*
6245  * call-seq:
6246  * minmax -> array
6247  * minmax {|a, b| ... } -> array
6248  *
6249  * Returns a 2-element array containing the minimum-valued and maximum-valued
6250  * elements from +self+;
6251  * does not modify +self+.
6252  *
6253  * With no block given, the minimum and maximum values are determined using method <tt>#<=></tt>:
6254  *
6255  * [1, 0, 3, 2].minmax # => [0, 3]
6256  *
6257  * With a block given, the block must return a numeric;
6258  * the block is called <tt>self.size - 1</tt> times to compare elements;
6259  * returns the elements having the minimum and maximum values per the block:
6260  *
6261  * ['0', '', '000', '00'].minmax {|a, b| a.size <=> b.size }
6262  * # => ["", "000"]
6263  *
6264  * Related: see {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching].
6265  */
6266 static VALUE
6267 rb_ary_minmax(VALUE ary)
6268 {
6269  if (rb_block_given_p()) {
6270  return rb_call_super(0, NULL);
6271  }
6272  return rb_assoc_new(rb_ary_min(0, 0, ary), rb_ary_max(0, 0, ary));
6273 }
6274 
6275 static int
6276 push_value(st_data_t key, st_data_t val, st_data_t ary)
6277 {
6278  rb_ary_push((VALUE)ary, (VALUE)val);
6279  return ST_CONTINUE;
6280 }
6281 
6282 /*
6283  * call-seq:
6284  * uniq! -> self or nil
6285  * uniq! {|element| ... } -> self or nil
6286  *
6287  * Removes duplicate elements from +self+, the first occurrence always being retained;
6288  * returns +self+ if any elements removed, +nil+ otherwise.
6289  *
6290  * With no block given, identifies and removes elements using method <tt>eql?</tt>
6291  * to compare elements:
6292  *
6293  * a = [0, 0, 1, 1, 2, 2]
6294  * a.uniq! # => [0, 1, 2]
6295  * a.uniq! # => nil
6296  *
6297  * With a block given, calls the block for each element;
6298  * identifies and omits "duplicate" elements using method <tt>eql?</tt>
6299  * to compare <i>block return values</i>;
6300  * that is, an element is a duplicate if its block return value
6301  * is the same as that of a previous element:
6302  *
6303  * a = ['a', 'aa', 'aaa', 'b', 'bb', 'bbb']
6304  * a.uniq! {|element| element.size } # => ["a", "aa", "aaa"]
6305  * a.uniq! {|element| element.size } # => nil
6306  *
6307  * Related: see {Methods for Deleting}[rdoc-ref:Array@Methods+for+Deleting].
6308  */
6309 static VALUE
6310 rb_ary_uniq_bang(VALUE ary)
6311 {
6312  VALUE hash;
6313  long hash_size;
6314 
6315  rb_ary_modify_check(ary);
6316  if (RARRAY_LEN(ary) <= 1)
6317  return Qnil;
6318  if (rb_block_given_p())
6319  hash = ary_make_hash_by(ary);
6320  else
6321  hash = ary_make_hash(ary);
6322 
6323  hash_size = RHASH_SIZE(hash);
6324  if (RARRAY_LEN(ary) == hash_size) {
6325  return Qnil;
6326  }
6327  rb_ary_modify_check(ary);
6328  ARY_SET_LEN(ary, 0);
6329  if (ARY_SHARED_P(ary)) {
6330  rb_ary_unshare(ary);
6331  FL_SET_EMBED(ary);
6332  }
6333  ary_resize_capa(ary, hash_size);
6334  rb_hash_foreach(hash, push_value, ary);
6335 
6336  return ary;
6337 }
6338 
6339 /*
6340  * call-seq:
6341  * uniq -> new_array
6342  * uniq {|element| ... } -> new_array
6343  *
6344  * Returns a new array containing those elements from +self+ that are not duplicates,
6345  * the first occurrence always being retained.
6346  *
6347  * With no block given, identifies and omits duplicate elements using method <tt>eql?</tt>
6348  * to compare elements:
6349  *
6350  * a = [0, 0, 1, 1, 2, 2]
6351  * a.uniq # => [0, 1, 2]
6352  *
6353  * With a block given, calls the block for each element;
6354  * identifies and omits "duplicate" elements using method <tt>eql?</tt>
6355  * to compare <i>block return values</i>;
6356  * that is, an element is a duplicate if its block return value
6357  * is the same as that of a previous element:
6358  *
6359  * a = ['a', 'aa', 'aaa', 'b', 'bb', 'bbb']
6360  * a.uniq {|element| element.size } # => ["a", "aa", "aaa"]
6361  *
6362  * Related: {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching].
6363  */
6364 
6365 static VALUE
6366 rb_ary_uniq(VALUE ary)
6367 {
6368  VALUE hash, uniq;
6369 
6370  if (RARRAY_LEN(ary) <= 1) {
6371  hash = 0;
6372  uniq = rb_ary_dup(ary);
6373  }
6374  else if (rb_block_given_p()) {
6375  hash = ary_make_hash_by(ary);
6376  uniq = rb_hash_values(hash);
6377  }
6378  else {
6379  hash = ary_make_hash(ary);
6380  uniq = rb_hash_values(hash);
6381  }
6382 
6383  return uniq;
6384 }
6385 
6386 /*
6387  * call-seq:
6388  * compact! -> self or nil
6389  *
6390  * Removes all +nil+ elements from +self+;
6391  * Returns +self+ if any elements are removed, +nil+ otherwise:
6392  *
6393  * a = [nil, 0, nil, false, nil, '', nil, [], nil, {}]
6394  * a.compact! # => [0, false, "", [], {}]
6395  * a # => [0, false, "", [], {}]
6396  * a.compact! # => nil
6397  *
6398  * Related: Array#compact;
6399  * see also {Methods for Deleting}[rdoc-ref:Array@Methods+for+Deleting].
6400  */
6401 
6402 static VALUE
6403 rb_ary_compact_bang(VALUE ary)
6404 {
6405  VALUE *p, *t, *end;
6406  long n;
6407 
6408  rb_ary_modify(ary);
6409  p = t = (VALUE *)RARRAY_CONST_PTR(ary); /* WB: no new reference */
6410  end = p + RARRAY_LEN(ary);
6411 
6412  while (t < end) {
6413  if (NIL_P(*t)) t++;
6414  else *p++ = *t++;
6415  }
6416  n = p - RARRAY_CONST_PTR(ary);
6417  if (RARRAY_LEN(ary) == n) {
6418  return Qnil;
6419  }
6420  ary_resize_smaller(ary, n);
6421 
6422  return ary;
6423 }
6424 
6425 /*
6426  * call-seq:
6427  * compact -> new_array
6428  *
6429  * Returns a new array containing only the non-+nil+ elements from +self+;
6430  * element order is preserved:
6431  *
6432  * a = [nil, 0, nil, false, nil, '', nil, [], nil, {}]
6433  * a.compact # => [0, false, "", [], {}]
6434  *
6435  * Related: Array#compact!;
6436  * see also {Methods for Deleting}[rdoc-ref:Array@Methods+for+Deleting].
6437  */
6438 
6439 static VALUE
6440 rb_ary_compact(VALUE ary)
6441 {
6442  ary = rb_ary_dup(ary);
6443  rb_ary_compact_bang(ary);
6444  return ary;
6445 }
6446 
6447 /*
6448  * call-seq:
6449  * count -> integer
6450  * count(object) -> integer
6451  * count {|element| ... } -> integer
6452  *
6453  * Returns a count of specified elements.
6454  *
6455  * With no argument and no block, returns the count of all elements:
6456  *
6457  * [0, :one, 'two', 3, 3.0].count # => 5
6458  *
6459  * With argument +object+ given, returns the count of elements <tt>==</tt> to +object+:
6460  *
6461  * [0, :one, 'two', 3, 3.0].count(3) # => 2
6462  *
6463  * With no argument and a block given, calls the block with each element;
6464  * returns the count of elements for which the block returns a truthy value:
6465  *
6466  * [0, 1, 2, 3].count {|element| element > 1 } # => 2
6467  *
6468  * With argument +object+ and a block given, issues a warning, ignores the block,
6469  * and returns the count of elements <tt>==</tt> to +object+.
6470  *
6471  * Related: see {Methods for Querying}[rdoc-ref:Array@Methods+for+Querying].
6472  */
6473 
6474 static VALUE
6475 rb_ary_count(int argc, VALUE *argv, VALUE ary)
6476 {
6477  long i, n = 0;
6478 
6479  if (rb_check_arity(argc, 0, 1) == 0) {
6480  VALUE v;
6481 
6482  if (!rb_block_given_p())
6483  return LONG2NUM(RARRAY_LEN(ary));
6484 
6485  for (i = 0; i < RARRAY_LEN(ary); i++) {
6486  v = RARRAY_AREF(ary, i);
6487  if (RTEST(rb_yield(v))) n++;
6488  }
6489  }
6490  else {
6491  VALUE obj = argv[0];
6492 
6493  if (rb_block_given_p()) {
6494  rb_warn("given block not used");
6495  }
6496  for (i = 0; i < RARRAY_LEN(ary); i++) {
6497  if (rb_equal(RARRAY_AREF(ary, i), obj)) n++;
6498  }
6499  }
6500 
6501  return LONG2NUM(n);
6502 }
6503 
6504 static VALUE
6505 flatten(VALUE ary, int level)
6506 {
6507  long i;
6508  VALUE stack, result, tmp = 0, elt;
6509  VALUE memo = Qfalse;
6510 
6511  for (i = 0; i < RARRAY_LEN(ary); i++) {
6512  elt = RARRAY_AREF(ary, i);
6513  tmp = rb_check_array_type(elt);
6514  if (!NIL_P(tmp)) {
6515  break;
6516  }
6517  }
6518  if (i == RARRAY_LEN(ary)) {
6519  return ary;
6520  }
6521 
6522  result = ary_new(0, RARRAY_LEN(ary));
6523  ary_memcpy(result, 0, i, RARRAY_CONST_PTR(ary));
6524  ARY_SET_LEN(result, i);
6525 
6526  stack = ary_new(0, ARY_DEFAULT_SIZE);
6527  rb_ary_push(stack, ary);
6528  rb_ary_push(stack, LONG2NUM(i + 1));
6529 
6530  if (level < 0) {
6531  memo = rb_obj_hide(rb_ident_hash_new());
6532  rb_hash_aset(memo, ary, Qtrue);
6533  rb_hash_aset(memo, tmp, Qtrue);
6534  }
6535 
6536  ary = tmp;
6537  i = 0;
6538 
6539  while (1) {
6540  while (i < RARRAY_LEN(ary)) {
6541  elt = RARRAY_AREF(ary, i++);
6542  if (level >= 0 && RARRAY_LEN(stack) / 2 >= level) {
6543  rb_ary_push(result, elt);
6544  continue;
6545  }
6546  tmp = rb_check_array_type(elt);
6547  if (RBASIC(result)->klass) {
6548  if (RTEST(memo)) {
6549  rb_hash_clear(memo);
6550  }
6551  rb_raise(rb_eRuntimeError, "flatten reentered");
6552  }
6553  if (NIL_P(tmp)) {
6554  rb_ary_push(result, elt);
6555  }
6556  else {
6557  if (memo) {
6558  if (rb_hash_aref(memo, tmp) == Qtrue) {
6559  rb_hash_clear(memo);
6560  rb_raise(rb_eArgError, "tried to flatten recursive array");
6561  }
6562  rb_hash_aset(memo, tmp, Qtrue);
6563  }
6564  rb_ary_push(stack, ary);
6565  rb_ary_push(stack, LONG2NUM(i));
6566  ary = tmp;
6567  i = 0;
6568  }
6569  }
6570  if (RARRAY_LEN(stack) == 0) {
6571  break;
6572  }
6573  if (memo) {
6574  rb_hash_delete(memo, ary);
6575  }
6576  tmp = rb_ary_pop(stack);
6577  i = NUM2LONG(tmp);
6578  ary = rb_ary_pop(stack);
6579  }
6580 
6581  if (memo) {
6582  rb_hash_clear(memo);
6583  }
6584 
6585  RBASIC_SET_CLASS(result, rb_cArray);
6586  return result;
6587 }
6588 
6589 /*
6590  * call-seq:
6591  * flatten!(depth = nil) -> self or nil
6592  *
6593  * Returns +self+ as a recursively flattening of +self+ to +depth+ levels of recursion;
6594  * +depth+ must be an
6595  * {integer-convertible object}[rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects],
6596  * or +nil+.
6597  * At each level of recursion:
6598  *
6599  * - Each element that is an array is "flattened"
6600  * (that is, replaced by its individual array elements).
6601  * - Each element that is not an array is unchanged
6602  * (even if the element is an object that has instance method +flatten+).
6603  *
6604  * Returns +nil+ if no elements were flattened.
6605  *
6606  * With non-negative integer argument +depth+, flattens recursively through +depth+ levels:
6607  *
6608  * a = [ 0, [ 1, [2, 3], 4 ], 5, {foo: 0}, Set.new([6, 7]) ]
6609  * a # => [0, [1, [2, 3], 4], 5, {:foo=>0}, #<Set: {6, 7}>]
6610  * a.dup.flatten!(1) # => [0, 1, [2, 3], 4, 5, {:foo=>0}, #<Set: {6, 7}>]
6611  * a.dup.flatten!(1.1) # => [0, 1, [2, 3], 4, 5, {:foo=>0}, #<Set: {6, 7}>]
6612  * a.dup.flatten!(2) # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>]
6613  * a.dup.flatten!(3) # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>]
6614  *
6615  * With +nil+ or negative argument +depth+, flattens all levels:
6616  *
6617  * a.dup.flatten! # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>]
6618  * a.dup.flatten!(-1) # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>]
6619  *
6620  * Related: Array#flatten;
6621  * see also {Methods for Assigning}[rdoc-ref:Array@Methods+for+Assigning].
6622  */
6623 
6624 static VALUE
6625 rb_ary_flatten_bang(int argc, VALUE *argv, VALUE ary)
6626 {
6627  int mod = 0, level = -1;
6628  VALUE result, lv;
6629 
6630  lv = (rb_check_arity(argc, 0, 1) ? argv[0] : Qnil);
6631  rb_ary_modify_check(ary);
6632  if (!NIL_P(lv)) level = NUM2INT(lv);
6633  if (level == 0) return Qnil;
6634 
6635  result = flatten(ary, level);
6636  if (result == ary) {
6637  return Qnil;
6638  }
6639  if (!(mod = ARY_EMBED_P(result))) rb_ary_freeze(result);
6640  rb_ary_replace(ary, result);
6641  if (mod) ARY_SET_EMBED_LEN(result, 0);
6642 
6643  return ary;
6644 }
6645 
6646 /*
6647  * call-seq:
6648  * flatten(depth = nil) -> new_array
6649  *
6650  * Returns a new array that is a recursive flattening of +self+
6651  * to +depth+ levels of recursion;
6652  * +depth+ must be an
6653  * {integer-convertible object}[rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects]
6654  * or +nil+.
6655  * At each level of recursion:
6656  *
6657  * - Each element that is an array is "flattened"
6658  * (that is, replaced by its individual array elements).
6659  * - Each element that is not an array is unchanged
6660  * (even if the element is an object that has instance method +flatten+).
6661  *
6662  * With non-negative integer argument +depth+, flattens recursively through +depth+ levels:
6663  *
6664  * a = [ 0, [ 1, [2, 3], 4 ], 5, {foo: 0}, Set.new([6, 7]) ]
6665  * a # => [0, [1, [2, 3], 4], 5, {:foo=>0}, #<Set: {6, 7}>]
6666  * a.flatten(0) # => [0, [1, [2, 3], 4], 5, {:foo=>0}, #<Set: {6, 7}>]
6667  * a.flatten(1 ) # => [0, 1, [2, 3], 4, 5, {:foo=>0}, #<Set: {6, 7}>]
6668  * a.flatten(1.1) # => [0, 1, [2, 3], 4, 5, {:foo=>0}, #<Set: {6, 7}>]
6669  * a.flatten(2) # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>]
6670  * a.flatten(3) # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>]
6671  *
6672  * With +nil+ or negative +depth+, flattens all levels.
6673  *
6674  * a.flatten # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>]
6675  * a.flatten(-1) # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>]
6676  *
6677  * Related: Array#flatten!;
6678  * see also {Methods for Converting}[rdoc-ref:Array@Methods+for+Converting].
6679  */
6680 
6681 static VALUE
6682 rb_ary_flatten(int argc, VALUE *argv, VALUE ary)
6683 {
6684  int level = -1;
6685  VALUE result;
6686 
6687  if (rb_check_arity(argc, 0, 1) && !NIL_P(argv[0])) {
6688  level = NUM2INT(argv[0]);
6689  if (level == 0) return ary_make_shared_copy(ary);
6690  }
6691 
6692  result = flatten(ary, level);
6693  if (result == ary) {
6694  result = ary_make_shared_copy(ary);
6695  }
6696 
6697  return result;
6698 }
6699 
6700 #define RAND_UPTO(max) (long)rb_random_ulong_limited((randgen), (max)-1)
6701 
6702 static VALUE
6703 rb_ary_shuffle_bang(rb_execution_context_t *ec, VALUE ary, VALUE randgen)
6704 {
6705  long i, len;
6706 
6707  rb_ary_modify(ary);
6708  i = len = RARRAY_LEN(ary);
6709  RARRAY_PTR_USE(ary, ptr, {
6710  while (i) {
6711  long j = RAND_UPTO(i);
6712  VALUE tmp;
6713  if (len != RARRAY_LEN(ary) || ptr != RARRAY_CONST_PTR(ary)) {
6714  rb_raise(rb_eRuntimeError, "modified during shuffle");
6715  }
6716  tmp = ptr[--i];
6717  ptr[i] = ptr[j];
6718  ptr[j] = tmp;
6719  }
6720  }); /* WB: no new reference */
6721  return ary;
6722 }
6723 
6724 static VALUE
6725 rb_ary_shuffle(rb_execution_context_t *ec, VALUE ary, VALUE randgen)
6726 {
6727  ary = rb_ary_dup(ary);
6728  rb_ary_shuffle_bang(ec, ary, randgen);
6729  return ary;
6730 }
6731 
6732 static const rb_data_type_t ary_sample_memo_type = {
6733  .wrap_struct_name = "ary_sample_memo",
6734  .function = {
6735  .dfree = (RUBY_DATA_FUNC)st_free_table,
6736  },
6737  .flags = RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY
6738 };
6739 
6740 static VALUE
6741 ary_sample(rb_execution_context_t *ec, VALUE ary, VALUE randgen, VALUE nv, VALUE to_array)
6742 {
6743  VALUE result;
6744  long n, len, i, j, k, idx[10];
6745  long rnds[numberof(idx)];
6746  long memo_threshold;
6747 
6748  len = RARRAY_LEN(ary);
6749  if (!to_array) {
6750  if (len < 2)
6751  i = 0;
6752  else
6753  i = RAND_UPTO(len);
6754 
6755  return rb_ary_elt(ary, i);
6756  }
6757  n = NUM2LONG(nv);
6758  if (n < 0) rb_raise(rb_eArgError, "negative sample number");
6759  if (n > len) n = len;
6760  if (n <= numberof(idx)) {
6761  for (i = 0; i < n; ++i) {
6762  rnds[i] = RAND_UPTO(len - i);
6763  }
6764  }
6765  k = len;
6766  len = RARRAY_LEN(ary);
6767  if (len < k && n <= numberof(idx)) {
6768  for (i = 0; i < n; ++i) {
6769  if (rnds[i] >= len) return rb_ary_new_capa(0);
6770  }
6771  }
6772  if (n > len) n = len;
6773  switch (n) {
6774  case 0:
6775  return rb_ary_new_capa(0);
6776  case 1:
6777  i = rnds[0];
6778  return rb_ary_new_from_args(1, RARRAY_AREF(ary, i));
6779  case 2:
6780  i = rnds[0];
6781  j = rnds[1];
6782  if (j >= i) j++;
6783  return rb_ary_new_from_args(2, RARRAY_AREF(ary, i), RARRAY_AREF(ary, j));
6784  case 3:
6785  i = rnds[0];
6786  j = rnds[1];
6787  k = rnds[2];
6788  {
6789  long l = j, g = i;
6790  if (j >= i) l = i, g = ++j;
6791  if (k >= l && (++k >= g)) ++k;
6792  }
6793  return rb_ary_new_from_args(3, RARRAY_AREF(ary, i), RARRAY_AREF(ary, j), RARRAY_AREF(ary, k));
6794  }
6795  memo_threshold =
6796  len < 2560 ? len / 128 :
6797  len < 5120 ? len / 64 :
6798  len < 10240 ? len / 32 :
6799  len / 16;
6800  if (n <= numberof(idx)) {
6801  long sorted[numberof(idx)];
6802  sorted[0] = idx[0] = rnds[0];
6803  for (i=1; i<n; i++) {
6804  k = rnds[i];
6805  for (j = 0; j < i; ++j) {
6806  if (k < sorted[j]) break;
6807  ++k;
6808  }
6809  memmove(&sorted[j+1], &sorted[j], sizeof(sorted[0])*(i-j));
6810  sorted[j] = idx[i] = k;
6811  }
6812  result = rb_ary_new_capa(n);
6813  RARRAY_PTR_USE(result, ptr_result, {
6814  for (i=0; i<n; i++) {
6815  ptr_result[i] = RARRAY_AREF(ary, idx[i]);
6816  }
6817  });
6818  }
6819  else if (n <= memo_threshold / 2) {
6820  long max_idx = 0;
6821  VALUE vmemo = TypedData_Wrap_Struct(0, &ary_sample_memo_type, 0);
6822  st_table *memo = st_init_numtable_with_size(n);
6823  RTYPEDDATA_DATA(vmemo) = memo;
6824  result = rb_ary_new_capa(n);
6825  RARRAY_PTR_USE(result, ptr_result, {
6826  for (i=0; i<n; i++) {
6827  long r = RAND_UPTO(len-i) + i;
6828  ptr_result[i] = r;
6829  if (r > max_idx) max_idx = r;
6830  }
6831  len = RARRAY_LEN(ary);
6832  if (len <= max_idx) n = 0;
6833  else if (n > len) n = len;
6834  RARRAY_PTR_USE(ary, ptr_ary, {
6835  for (i=0; i<n; i++) {
6836  long j2 = j = ptr_result[i];
6837  long i2 = i;
6838  st_data_t value;
6839  if (st_lookup(memo, (st_data_t)i, &value)) i2 = (long)value;
6840  if (st_lookup(memo, (st_data_t)j, &value)) j2 = (long)value;
6841  st_insert(memo, (st_data_t)j, (st_data_t)i2);
6842  ptr_result[i] = ptr_ary[j2];
6843  }
6844  });
6845  });
6846  RTYPEDDATA_DATA(vmemo) = 0;
6847  st_free_table(memo);
6848  RB_GC_GUARD(vmemo);
6849  }
6850  else {
6851  result = rb_ary_dup(ary);
6852  RBASIC_CLEAR_CLASS(result);
6853  RB_GC_GUARD(ary);
6854  RARRAY_PTR_USE(result, ptr_result, {
6855  for (i=0; i<n; i++) {
6856  j = RAND_UPTO(len-i) + i;
6857  nv = ptr_result[j];
6858  ptr_result[j] = ptr_result[i];
6859  ptr_result[i] = nv;
6860  }
6861  });
6862  RBASIC_SET_CLASS_RAW(result, rb_cArray);
6863  }
6864  ARY_SET_LEN(result, n);
6865 
6866  return result;
6867 }
6868 
6869 static VALUE
6870 ary_sized_alloc(rb_execution_context_t *ec, VALUE self)
6871 {
6872  return rb_ary_new2(RARRAY_LEN(self));
6873 }
6874 
6875 static VALUE
6876 ary_sample0(rb_execution_context_t *ec, VALUE ary)
6877 {
6878  return ary_sample(ec, ary, rb_cRandom, Qfalse, Qfalse);
6879 }
6880 
6881 static VALUE
6882 rb_ary_cycle_size(VALUE self, VALUE args, VALUE eobj)
6883 {
6884  long mul;
6885  VALUE n = Qnil;
6886  if (args && (RARRAY_LEN(args) > 0)) {
6887  n = RARRAY_AREF(args, 0);
6888  }
6889  if (RARRAY_LEN(self) == 0) return INT2FIX(0);
6890  if (NIL_P(n)) return DBL2NUM(HUGE_VAL);
6891  mul = NUM2LONG(n);
6892  if (mul <= 0) return INT2FIX(0);
6893  n = LONG2FIX(mul);
6894  return rb_fix_mul_fix(rb_ary_length(self), n);
6895 }
6896 
6897 /*
6898  * call-seq:
6899  * cycle(count = nil) {|element| ... } -> nil
6900  * cycle(count = nil) -> new_enumerator
6901  *
6902  * With a block given, may call the block, depending on the value of argument +count+;
6903  * +count+ must be an
6904  * {integer-convertible object}[rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects],
6905  * or +nil+.
6906  *
6907  * When +count+ is positive,
6908  * calls the block with each element, then does so repeatedly,
6909  * until it has done so +count+ times; returns +nil+:
6910  *
6911  * output = []
6912  * [0, 1].cycle(2) {|element| output.push(element) } # => nil
6913  * output # => [0, 1, 0, 1]
6914  *
6915  * When +count+ is zero or negative, does not call the block:
6916  *
6917  * [0, 1].cycle(0) {|element| fail 'Cannot happen' } # => nil
6918  * [0, 1].cycle(-1) {|element| fail 'Cannot happen' } # => nil
6919  *
6920  * When +count+ is +nil+, cycles forever:
6921  *
6922  * # Prints 0 and 1 forever.
6923  * [0, 1].cycle {|element| puts element }
6924  * [0, 1].cycle(nil) {|element| puts element }
6925  *
6926  * With no block given, returns a new Enumerator.
6927  *
6928  * Related: see {Methods for Iterating}[rdoc-ref:Array@Methods+for+Iterating].
6929  */
6930 static VALUE
6931 rb_ary_cycle(int argc, VALUE *argv, VALUE ary)
6932 {
6933  long n, i;
6934 
6935  rb_check_arity(argc, 0, 1);
6936 
6937  RETURN_SIZED_ENUMERATOR(ary, argc, argv, rb_ary_cycle_size);
6938  if (argc == 0 || NIL_P(argv[0])) {
6939  n = -1;
6940  }
6941  else {
6942  n = NUM2LONG(argv[0]);
6943  if (n <= 0) return Qnil;
6944  }
6945 
6946  while (RARRAY_LEN(ary) > 0 && (n < 0 || 0 < n--)) {
6947  for (i=0; i<RARRAY_LEN(ary); i++) {
6948  rb_yield(RARRAY_AREF(ary, i));
6949  }
6950  }
6951  return Qnil;
6952 }
6953 
6954 /*
6955  * Build a ruby array of the corresponding values and yield it to the
6956  * associated block.
6957  * Return the class of +values+ for reentry check.
6958  */
6959 static int
6960 yield_indexed_values(const VALUE values, const long r, const long *const p)
6961 {
6962  const VALUE result = rb_ary_new2(r);
6963  long i;
6964 
6965  for (i = 0; i < r; i++) ARY_SET(result, i, RARRAY_AREF(values, p[i]));
6966  ARY_SET_LEN(result, r);
6967  rb_yield(result);
6968  return !RBASIC(values)->klass;
6969 }
6970 
6971 /*
6972  * Compute permutations of +r+ elements of the set <code>[0..n-1]</code>.
6973  *
6974  * When we have a complete permutation of array indices, copy the values
6975  * at those indices into a new array and yield that array.
6976  *
6977  * n: the size of the set
6978  * r: the number of elements in each permutation
6979  * p: the array (of size r) that we're filling in
6980  * used: an array of booleans: whether a given index is already used
6981  * values: the Ruby array that holds the actual values to permute
6982  */
6983 static void
6984 permute0(const long n, const long r, long *const p, char *const used, const VALUE values)
6985 {
6986  long i = 0, index = 0;
6987 
6988  for (;;) {
6989  const char *const unused = memchr(&used[i], 0, n-i);
6990  if (!unused) {
6991  if (!index) break;
6992  i = p[--index]; /* pop index */
6993  used[i++] = 0; /* index unused */
6994  }
6995  else {
6996  i = unused - used;
6997  p[index] = i;
6998  used[i] = 1; /* mark index used */
6999  ++index;
7000  if (index < r-1) { /* if not done yet */
7001  p[index] = i = 0;
7002  continue;
7003  }
7004  for (i = 0; i < n; ++i) {
7005  if (used[i]) continue;
7006  p[index] = i;
7007  if (!yield_indexed_values(values, r, p)) {
7008  rb_raise(rb_eRuntimeError, "permute reentered");
7009  }
7010  }
7011  i = p[--index]; /* pop index */
7012  used[i] = 0; /* index unused */
7013  p[index] = ++i;
7014  }
7015  }
7016 }
7017 
7018 /*
7019  * Returns the product of from, from-1, ..., from - how_many + 1.
7020  * https://en.wikipedia.org/wiki/Pochhammer_symbol
7021  */
7022 static VALUE
7023 descending_factorial(long from, long how_many)
7024 {
7025  VALUE cnt;
7026  if (how_many > 0) {
7027  cnt = LONG2FIX(from);
7028  while (--how_many > 0) {
7029  long v = --from;
7030  cnt = rb_int_mul(cnt, LONG2FIX(v));
7031  }
7032  }
7033  else {
7034  cnt = LONG2FIX(how_many == 0);
7035  }
7036  return cnt;
7037 }
7038 
7039 static VALUE
7040 binomial_coefficient(long comb, long size)
7041 {
7042  VALUE r;
7043  long i;
7044  if (comb > size-comb) {
7045  comb = size-comb;
7046  }
7047  if (comb < 0) {
7048  return LONG2FIX(0);
7049  }
7050  else if (comb == 0) {
7051  return LONG2FIX(1);
7052  }
7053  r = LONG2FIX(size);
7054  for (i = 1; i < comb; ++i) {
7055  r = rb_int_mul(r, LONG2FIX(size - i));
7056  r = rb_int_idiv(r, LONG2FIX(i + 1));
7057  }
7058  return r;
7059 }
7060 
7061 static VALUE
7062 rb_ary_permutation_size(VALUE ary, VALUE args, VALUE eobj)
7063 {
7064  long n = RARRAY_LEN(ary);
7065  long k = (args && (RARRAY_LEN(args) > 0)) ? NUM2LONG(RARRAY_AREF(args, 0)) : n;
7066 
7067  return descending_factorial(n, k);
7068 }
7069 
7070 /*
7071  * call-seq:
7072  * permutation(n = self.size) {|permutation| ... } -> self
7073  * permutation(n = self.size) -> new_enumerator
7074  *
7075  * Iterates over permutations of the elements of +self+;
7076  * the order of permutations is indeterminate.
7077  *
7078  * With a block and an in-range positive integer argument +n+ (<tt>0 < n <= self.size</tt>) given,
7079  * calls the block with each +n+-tuple permutations of +self+;
7080  * returns +self+:
7081  *
7082  * a = [0, 1, 2]
7083  * perms = []
7084  * a.permutation(1) {|perm| perms.push(perm) }
7085  * perms # => [[0], [1], [2]]
7086  *
7087  * perms = []
7088  * a.permutation(2) {|perm| perms.push(perm) }
7089  * perms # => [[0, 1], [0, 2], [1, 0], [1, 2], [2, 0], [2, 1]]
7090  *
7091  * perms = []
7092  * a.permutation(3) {|perm| perms.push(perm) }
7093  * perms # => [[0, 1, 2], [0, 2, 1], [1, 0, 2], [1, 2, 0], [2, 0, 1], [2, 1, 0]]
7094  *
7095  * When +n+ is zero, calls the block once with a new empty array:
7096  *
7097  * perms = []
7098  * a.permutation(0) {|perm| perms.push(perm) }
7099  * perms # => [[]]
7100  *
7101  * When +n+ is out of range (negative or larger than <tt>self.size</tt>),
7102  * does not call the block:
7103  *
7104  * a.permutation(-1) {|permutation| fail 'Cannot happen' }
7105  * a.permutation(4) {|permutation| fail 'Cannot happen' }
7106  *
7107  * With no block given, returns a new Enumerator.
7108  *
7109  * Related: {Methods for Iterating}[rdoc-ref:Array@Methods+for+Iterating].
7110  */
7111 
7112 static VALUE
7113 rb_ary_permutation(int argc, VALUE *argv, VALUE ary)
7114 {
7115  long r, n, i;
7116 
7117  n = RARRAY_LEN(ary); /* Array length */
7118  RETURN_SIZED_ENUMERATOR(ary, argc, argv, rb_ary_permutation_size); /* Return enumerator if no block */
7119  r = n;
7120  if (rb_check_arity(argc, 0, 1) && !NIL_P(argv[0]))
7121  r = NUM2LONG(argv[0]); /* Permutation size from argument */
7122 
7123  if (r < 0 || n < r) {
7124  /* no permutations: yield nothing */
7125  }
7126  else if (r == 0) { /* exactly one permutation: the zero-length array */
7127  rb_yield(rb_ary_new2(0));
7128  }
7129  else if (r == 1) { /* this is a special, easy case */
7130  for (i = 0; i < RARRAY_LEN(ary); i++) {
7131  rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
7132  }
7133  }
7134  else { /* this is the general case */
7135  volatile VALUE t0;
7136  long *p = ALLOCV_N(long, t0, r+roomof(n, sizeof(long)));
7137  char *used = (char*)(p + r);
7138  VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
7139  RBASIC_CLEAR_CLASS(ary0);
7140 
7141  MEMZERO(used, char, n); /* initialize array */
7142 
7143  permute0(n, r, p, used, ary0); /* compute and yield permutations */
7144  ALLOCV_END(t0);
7145  RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
7146  }
7147  return ary;
7148 }
7149 
7150 static void
7151 combinate0(const long len, const long n, long *const stack, const VALUE values)
7152 {
7153  long lev = 0;
7154 
7155  MEMZERO(stack+1, long, n);
7156  stack[0] = -1;
7157  for (;;) {
7158  for (lev++; lev < n; lev++) {
7159  stack[lev+1] = stack[lev]+1;
7160  }
7161  if (!yield_indexed_values(values, n, stack+1)) {
7162  rb_raise(rb_eRuntimeError, "combination reentered");
7163  }
7164  do {
7165  if (lev == 0) return;
7166  stack[lev--]++;
7167  } while (stack[lev+1]+n == len+lev+1);
7168  }
7169 }
7170 
7171 static VALUE
7172 rb_ary_combination_size(VALUE ary, VALUE args, VALUE eobj)
7173 {
7174  long n = RARRAY_LEN(ary);
7175  long k = NUM2LONG(RARRAY_AREF(args, 0));
7176 
7177  return binomial_coefficient(k, n);
7178 }
7179 
7180 /*
7181  * call-seq:
7182  * combination(n) {|element| ... } -> self
7183  * combination(n) -> new_enumerator
7184  *
7185  * When a block and a positive
7186  * {integer-convertible object}[rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects]
7187  * argument +n+ (<tt>0 < n <= self.size</tt>)
7188  * are given, calls the block with all +n+-tuple combinations of +self+;
7189  * returns +self+:
7190  *
7191  * a = %w[a b c] # => ["a", "b", "c"]
7192  * a.combination(2) {|combination| p combination } # => ["a", "b", "c"]
7193  *
7194  * Output:
7195  *
7196  * ["a", "b"]
7197  * ["a", "c"]
7198  * ["b", "c"]
7199  *
7200  * The order of the yielded combinations is not guaranteed.
7201  *
7202  * When +n+ is zero, calls the block once with a new empty array:
7203  *
7204  * a.combination(0) {|combination| p combination }
7205  * [].combination(0) {|combination| p combination }
7206  *
7207  * Output:
7208  *
7209  * []
7210  * []
7211  *
7212  * When +n+ is negative or larger than +self.size+ and +self+ is non-empty,
7213  * does not call the block:
7214  *
7215  * a.combination(-1) {|combination| fail 'Cannot happen' } # => ["a", "b", "c"]
7216  * a.combination(4) {|combination| fail 'Cannot happen' } # => ["a", "b", "c"]
7217  *
7218  * With no block given, returns a new Enumerator.
7219  *
7220  * Related: Array#permutation;
7221  * see also {Methods for Iterating}[rdoc-ref:Array@Methods+for+Iterating].
7222  */
7223 
7224 static VALUE
7225 rb_ary_combination(VALUE ary, VALUE num)
7226 {
7227  long i, n, len;
7228 
7229  n = NUM2LONG(num);
7230  RETURN_SIZED_ENUMERATOR(ary, 1, &num, rb_ary_combination_size);
7231  len = RARRAY_LEN(ary);
7232  if (n < 0 || len < n) {
7233  /* yield nothing */
7234  }
7235  else if (n == 0) {
7236  rb_yield(rb_ary_new2(0));
7237  }
7238  else if (n == 1) {
7239  for (i = 0; i < RARRAY_LEN(ary); i++) {
7240  rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
7241  }
7242  }
7243  else {
7244  VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
7245  volatile VALUE t0;
7246  long *stack = ALLOCV_N(long, t0, n+1);
7247 
7248  RBASIC_CLEAR_CLASS(ary0);
7249  combinate0(len, n, stack, ary0);
7250  ALLOCV_END(t0);
7251  RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
7252  }
7253  return ary;
7254 }
7255 
7256 /*
7257  * Compute repeated permutations of +r+ elements of the set
7258  * <code>[0..n-1]</code>.
7259  *
7260  * When we have a complete repeated permutation of array indices, copy the
7261  * values at those indices into a new array and yield that array.
7262  *
7263  * n: the size of the set
7264  * r: the number of elements in each permutation
7265  * p: the array (of size r) that we're filling in
7266  * values: the Ruby array that holds the actual values to permute
7267  */
7268 static void
7269 rpermute0(const long n, const long r, long *const p, const VALUE values)
7270 {
7271  long i = 0, index = 0;
7272 
7273  p[index] = i;
7274  for (;;) {
7275  if (++index < r-1) {
7276  p[index] = i = 0;
7277  continue;
7278  }
7279  for (i = 0; i < n; ++i) {
7280  p[index] = i;
7281  if (!yield_indexed_values(values, r, p)) {
7282  rb_raise(rb_eRuntimeError, "repeated permute reentered");
7283  }
7284  }
7285  do {
7286  if (index <= 0) return;
7287  } while ((i = ++p[--index]) >= n);
7288  }
7289 }
7290 
7291 static VALUE
7292 rb_ary_repeated_permutation_size(VALUE ary, VALUE args, VALUE eobj)
7293 {
7294  long n = RARRAY_LEN(ary);
7295  long k = NUM2LONG(RARRAY_AREF(args, 0));
7296 
7297  if (k < 0) {
7298  return LONG2FIX(0);
7299  }
7300  if (n <= 0) {
7301  return LONG2FIX(!k);
7302  }
7303  return rb_int_positive_pow(n, (unsigned long)k);
7304 }
7305 
7306 /*
7307  * call-seq:
7308  * repeated_permutation(size) {|permutation| ... } -> self
7309  * repeated_permutation(size) -> new_enumerator
7310  *
7311  * With a block given, calls the block with each repeated permutation of length +size+
7312  * of the elements of +self+;
7313  * each permutation is an array;
7314  * returns +self+. The order of the permutations is indeterminate.
7315  *
7316  * If a positive integer argument +size+ is given,
7317  * calls the block with each +size+-tuple repeated permutation of the elements of +self+.
7318  * The number of permutations is <tt>self.size**size</tt>.
7319  *
7320  * Examples:
7321  *
7322  * - +size+ is 1:
7323  *
7324  * p = []
7325  * [0, 1, 2].repeated_permutation(1) {|permutation| p.push(permutation) }
7326  * p # => [[0], [1], [2]]
7327  *
7328  * - +size+ is 2:
7329  *
7330  * p = []
7331  * [0, 1, 2].repeated_permutation(2) {|permutation| p.push(permutation) }
7332  * p # => [[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2]]
7333  *
7334  * If +size+ is zero, calls the block once with an empty array.
7335  *
7336  * If +size+ is negative, does not call the block:
7337  *
7338  * [0, 1, 2].repeated_permutation(-1) {|permutation| fail 'Cannot happen' }
7339  *
7340  * With no block given, returns a new Enumerator.
7341  *
7342  * Related: see {Methods for Combining}[rdoc-ref:Array@Methods+for+Combining].
7343  */
7344 static VALUE
7345 rb_ary_repeated_permutation(VALUE ary, VALUE num)
7346 {
7347  long r, n, i;
7348 
7349  n = RARRAY_LEN(ary); /* Array length */
7350  RETURN_SIZED_ENUMERATOR(ary, 1, &num, rb_ary_repeated_permutation_size); /* Return Enumerator if no block */
7351  r = NUM2LONG(num); /* Permutation size from argument */
7352 
7353  if (r < 0) {
7354  /* no permutations: yield nothing */
7355  }
7356  else if (r == 0) { /* exactly one permutation: the zero-length array */
7357  rb_yield(rb_ary_new2(0));
7358  }
7359  else if (r == 1) { /* this is a special, easy case */
7360  for (i = 0; i < RARRAY_LEN(ary); i++) {
7361  rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
7362  }
7363  }
7364  else { /* this is the general case */
7365  volatile VALUE t0;
7366  long *p = ALLOCV_N(long, t0, r);
7367  VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
7368  RBASIC_CLEAR_CLASS(ary0);
7369 
7370  rpermute0(n, r, p, ary0); /* compute and yield repeated permutations */
7371  ALLOCV_END(t0);
7372  RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
7373  }
7374  return ary;
7375 }
7376 
7377 static void
7378 rcombinate0(const long n, const long r, long *const p, const long rest, const VALUE values)
7379 {
7380  long i = 0, index = 0;
7381 
7382  p[index] = i;
7383  for (;;) {
7384  if (++index < r-1) {
7385  p[index] = i;
7386  continue;
7387  }
7388  for (; i < n; ++i) {
7389  p[index] = i;
7390  if (!yield_indexed_values(values, r, p)) {
7391  rb_raise(rb_eRuntimeError, "repeated combination reentered");
7392  }
7393  }
7394  do {
7395  if (index <= 0) return;
7396  } while ((i = ++p[--index]) >= n);
7397  }
7398 }
7399 
7400 static VALUE
7401 rb_ary_repeated_combination_size(VALUE ary, VALUE args, VALUE eobj)
7402 {
7403  long n = RARRAY_LEN(ary);
7404  long k = NUM2LONG(RARRAY_AREF(args, 0));
7405  if (k == 0) {
7406  return LONG2FIX(1);
7407  }
7408  return binomial_coefficient(k, n + k - 1);
7409 }
7410 
7411 /*
7412  * call-seq:
7413  * repeated_combination(size) {|combination| ... } -> self
7414  * repeated_combination(size) -> new_enumerator
7415  *
7416  * With a block given, calls the block with each repeated combination of length +size+
7417  * of the elements of +self+;
7418  * each combination is an array;
7419  * returns +self+. The order of the combinations is indeterminate.
7420  *
7421  * If a positive integer argument +size+ is given,
7422  * calls the block with each +size+-tuple repeated combination of the elements of +self+.
7423  * The number of combinations is <tt>(size+1)(size+2)/2</tt>.
7424  *
7425  * Examples:
7426  *
7427  * - +size+ is 1:
7428  *
7429  * c = []
7430  * [0, 1, 2].repeated_combination(1) {|combination| c.push(combination) }
7431  * c # => [[0], [1], [2]]
7432  *
7433  * - +size+ is 2:
7434  *
7435  * c = []
7436  * [0, 1, 2].repeated_combination(2) {|combination| c.push(combination) }
7437  * c # => [[0, 0], [0, 1], [0, 2], [1, 1], [1, 2], [2, 2]]
7438  *
7439  * If +size+ is zero, calls the block once with an empty array.
7440  *
7441  * If +size+ is negative, does not call the block:
7442  *
7443  * [0, 1, 2].repeated_combination(-1) {|combination| fail 'Cannot happen' }
7444  *
7445  * With no block given, returns a new Enumerator.
7446  *
7447  * Related: see {Methods for Combining}[rdoc-ref:Array@Methods+for+Combining].
7448  */
7449 
7450 static VALUE
7451 rb_ary_repeated_combination(VALUE ary, VALUE num)
7452 {
7453  long n, i, len;
7454 
7455  n = NUM2LONG(num); /* Combination size from argument */
7456  RETURN_SIZED_ENUMERATOR(ary, 1, &num, rb_ary_repeated_combination_size); /* Return enumerator if no block */
7457  len = RARRAY_LEN(ary);
7458  if (n < 0) {
7459  /* yield nothing */
7460  }
7461  else if (n == 0) {
7462  rb_yield(rb_ary_new2(0));
7463  }
7464  else if (n == 1) {
7465  for (i = 0; i < RARRAY_LEN(ary); i++) {
7466  rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
7467  }
7468  }
7469  else if (len == 0) {
7470  /* yield nothing */
7471  }
7472  else {
7473  volatile VALUE t0;
7474  long *p = ALLOCV_N(long, t0, n);
7475  VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
7476  RBASIC_CLEAR_CLASS(ary0);
7477 
7478  rcombinate0(len, n, p, n, ary0); /* compute and yield repeated combinations */
7479  ALLOCV_END(t0);
7480  RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
7481  }
7482  return ary;
7483 }
7484 
7485 /*
7486  * call-seq:
7487  * product(*other_arrays) -> new_array
7488  * product(*other_arrays) {|combination| ... } -> self
7489  *
7490  * Computes all combinations of elements from all the arrays,
7491  * including both +self+ and +other_arrays+:
7492  *
7493  * - The number of combinations is the product of the sizes of all the arrays,
7494  * including both +self+ and +other_arrays+.
7495  * - The order of the returned combinations is indeterminate.
7496  *
7497  * With no block given, returns the combinations as an array of arrays:
7498  *
7499  * p = [0, 1].product([2, 3])
7500  * # => [[0, 2], [0, 3], [1, 2], [1, 3]]
7501  * p.size # => 4
7502  * p = [0, 1].product([2, 3], [4, 5])
7503  * # => [[0, 2, 4], [0, 2, 5], [0, 3, 4], [0, 3, 5], [1, 2, 4], [1, 2, 5], [1, 3, 4], [1, 3,...
7504  * p.size # => 8
7505  *
7506  * If +self+ or any argument is empty, returns an empty array:
7507  *
7508  * [].product([2, 3], [4, 5]) # => []
7509  * [0, 1].product([2, 3], []) # => []
7510  *
7511  * If no argument is given, returns an array of 1-element arrays,
7512  * each containing an element of +self+:
7513  *
7514  * a.product # => [[0], [1], [2]]
7515  *
7516  * With a block given, calls the block with each combination; returns +self+:
7517  *
7518  * p = []
7519  * [0, 1].product([2, 3]) {|combination| p.push(combination) }
7520  * p # => [[0, 2], [0, 3], [1, 2], [1, 3]]
7521  *
7522  * If +self+ or any argument is empty, does not call the block:
7523  *
7524  * [].product([2, 3], [4, 5]) {|combination| fail 'Cannot happen' }
7525  * # => []
7526  * [0, 1].product([2, 3], []) {|combination| fail 'Cannot happen' }
7527  * # => [0, 1]
7528  *
7529  * If no argument is given, calls the block with each element of +self+ as a 1-element array:
7530  *
7531  * p = []
7532  * [0, 1].product {|combination| p.push(combination) }
7533  * p # => [[0], [1]]
7534  *
7535  * Related: see {Methods for Combining}[rdoc-ref:Array@Methods+for+Combining].
7536  */
7537 
7538 static VALUE
7539 rb_ary_product(int argc, VALUE *argv, VALUE ary)
7540 {
7541  int n = argc+1; /* How many arrays we're operating on */
7542  volatile VALUE t0 = rb_ary_hidden_new(n);
7543  volatile VALUE t1 = Qundef;
7544  VALUE *arrays = RARRAY_PTR(t0); /* The arrays we're computing the product of */
7545  int *counters = ALLOCV_N(int, t1, n); /* The current position in each one */
7546  VALUE result = Qnil; /* The array we'll be returning, when no block given */
7547  long i,j;
7548  long resultlen = 1;
7549 
7550  RBASIC_CLEAR_CLASS(t0);
7551 
7552  /* initialize the arrays of arrays */
7553  ARY_SET_LEN(t0, n);
7554  arrays[0] = ary;
7555  for (i = 1; i < n; i++) arrays[i] = Qnil;
7556  for (i = 1; i < n; i++) arrays[i] = to_ary(argv[i-1]);
7557 
7558  /* initialize the counters for the arrays */
7559  for (i = 0; i < n; i++) counters[i] = 0;
7560 
7561  /* Otherwise, allocate and fill in an array of results */
7562  if (rb_block_given_p()) {
7563  /* Make defensive copies of arrays; exit if any is empty */
7564  for (i = 0; i < n; i++) {
7565  if (RARRAY_LEN(arrays[i]) == 0) goto done;
7566  arrays[i] = ary_make_shared_copy(arrays[i]);
7567  }
7568  }
7569  else {
7570  /* Compute the length of the result array; return [] if any is empty */
7571  for (i = 0; i < n; i++) {
7572  long k = RARRAY_LEN(arrays[i]);
7573  if (k == 0) {
7574  result = rb_ary_new2(0);
7575  goto done;
7576  }
7577  if (MUL_OVERFLOW_LONG_P(resultlen, k))
7578  rb_raise(rb_eRangeError, "too big to product");
7579  resultlen *= k;
7580  }
7581  result = rb_ary_new2(resultlen);
7582  }
7583  for (;;) {
7584  int m;
7585  /* fill in one subarray */
7586  VALUE subarray = rb_ary_new2(n);
7587  for (j = 0; j < n; j++) {
7588  rb_ary_push(subarray, rb_ary_entry(arrays[j], counters[j]));
7589  }
7590 
7591  /* put it on the result array */
7592  if (NIL_P(result)) {
7593  FL_SET(t0, RARRAY_SHARED_ROOT_FLAG);
7594  rb_yield(subarray);
7595  if (!FL_TEST(t0, RARRAY_SHARED_ROOT_FLAG)) {
7596  rb_raise(rb_eRuntimeError, "product reentered");
7597  }
7598  else {
7599  FL_UNSET(t0, RARRAY_SHARED_ROOT_FLAG);
7600  }
7601  }
7602  else {
7603  rb_ary_push(result, subarray);
7604  }
7605 
7606  /*
7607  * Increment the last counter. If it overflows, reset to 0
7608  * and increment the one before it.
7609  */
7610  m = n-1;
7611  counters[m]++;
7612  while (counters[m] == RARRAY_LEN(arrays[m])) {
7613  counters[m] = 0;
7614  /* If the first counter overflows, we are done */
7615  if (--m < 0) goto done;
7616  counters[m]++;
7617  }
7618  }
7619 
7620 done:
7621  ALLOCV_END(t1);
7622 
7623  return NIL_P(result) ? ary : result;
7624 }
7625 
7626 /*
7627  * call-seq:
7628  * take(count) -> new_array
7629  *
7630  * Returns a new array containing the first +count+ element of +self+
7631  * (as available);
7632  * +count+ must be a non-negative numeric;
7633  * does not modify +self+:
7634  *
7635  * a = ['a', 'b', 'c', 'd']
7636  * a.take(2) # => ["a", "b"]
7637  * a.take(2.1) # => ["a", "b"]
7638  * a.take(50) # => ["a", "b", "c", "d"]
7639  * a.take(0) # => []
7640  *
7641  * Related: see {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching].
7642  */
7643 
7644 static VALUE
7645 rb_ary_take(VALUE obj, VALUE n)
7646 {
7647  long len = NUM2LONG(n);
7648  if (len < 0) {
7649  rb_raise(rb_eArgError, "attempt to take negative size");
7650  }
7651  return rb_ary_subseq(obj, 0, len);
7652 }
7653 
7654 /*
7655  * call-seq:
7656  * take_while {|element| ... } -> new_array
7657  * take_while -> new_enumerator
7658  *
7659  * With a block given, calls the block with each successive element of +self+;
7660  * stops iterating if the block returns +false+ or +nil+;
7661  * returns a new array containing those elements for which the block returned a truthy value:
7662  *
7663  * a = [0, 1, 2, 3, 4, 5]
7664  * a.take_while {|element| element < 3 } # => [0, 1, 2]
7665  * a.take_while {|element| true } # => [0, 1, 2, 3, 4, 5]
7666  * a.take_while {|element| false } # => []
7667  *
7668  * With no block given, returns a new Enumerator.
7669  *
7670  * Does not modify +self+.
7671  *
7672  * Related: see {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching].
7673  */
7674 
7675 static VALUE
7676 rb_ary_take_while(VALUE ary)
7677 {
7678  long i;
7679 
7680  RETURN_ENUMERATOR(ary, 0, 0);
7681  for (i = 0; i < RARRAY_LEN(ary); i++) {
7682  if (!RTEST(rb_yield(RARRAY_AREF(ary, i)))) break;
7683  }
7684  return rb_ary_take(ary, LONG2FIX(i));
7685 }
7686 
7687 /*
7688  * call-seq:
7689  * drop(n) -> new_array
7690  *
7691  * Returns a new array containing all but the first +n+ element of +self+,
7692  * where +n+ is a non-negative Integer;
7693  * does not modify +self+.
7694  *
7695  * Examples:
7696  *
7697  * a = [0, 1, 2, 3, 4, 5]
7698  * a.drop(0) # => [0, 1, 2, 3, 4, 5]
7699  * a.drop(1) # => [1, 2, 3, 4, 5]
7700  * a.drop(2) # => [2, 3, 4, 5]
7701  * a.drop(9) # => []
7702  *
7703  * Related: see {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching].
7704  */
7705 
7706 static VALUE
7707 rb_ary_drop(VALUE ary, VALUE n)
7708 {
7709  VALUE result;
7710  long pos = NUM2LONG(n);
7711  if (pos < 0) {
7712  rb_raise(rb_eArgError, "attempt to drop negative size");
7713  }
7714 
7715  result = rb_ary_subseq(ary, pos, RARRAY_LEN(ary));
7716  if (NIL_P(result)) result = rb_ary_new();
7717  return result;
7718 }
7719 
7720 /*
7721  * call-seq:
7722  * drop_while {|element| ... } -> new_array
7723  * drop_while -> new_enumerator
7724  *
7725  * With a block given, calls the block with each successive element of +self+;
7726  * stops if the block returns +false+ or +nil+;
7727  * returns a new array _omitting_ those elements for which the block returned a truthy value;
7728  * does not modify +self+:
7729  *
7730  * a = [0, 1, 2, 3, 4, 5]
7731  * a.drop_while {|element| element < 3 } # => [3, 4, 5]
7732  *
7733  * With no block given, returns a new Enumerator.
7734  *
7735  * Related: see {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching].
7736  */
7737 
7738 static VALUE
7739 rb_ary_drop_while(VALUE ary)
7740 {
7741  long i;
7742 
7743  RETURN_ENUMERATOR(ary, 0, 0);
7744  for (i = 0; i < RARRAY_LEN(ary); i++) {
7745  if (!RTEST(rb_yield(RARRAY_AREF(ary, i)))) break;
7746  }
7747  return rb_ary_drop(ary, LONG2FIX(i));
7748 }
7749 
7750 /*
7751  * call-seq:
7752  * any? -> true or false
7753  * any?(object) -> true or false
7754  * any? {|element| ... } -> true or false
7755  *
7756  * Returns whether for any element of +self+, a given criterion is satisfied.
7757  *
7758  * With no block and no argument, returns whether any element of +self+ is truthy:
7759  *
7760  * [nil, false, []].any? # => true # Array object is truthy.
7761  * [nil, false, {}].any? # => true # Hash object is truthy.
7762  * [nil, false, ''].any? # => true # String object is truthy.
7763  * [nil, false].any? # => false # Nil and false are not truthy.
7764  *
7765  * With argument +object+ given,
7766  * returns whether <tt>object === ele</tt> for any element +ele+ in +self+:
7767  *
7768  * [nil, false, 0].any?(0) # => true
7769  * [nil, false, 1].any?(0) # => false
7770  * [nil, false, 'food'].any?(/foo/) # => true
7771  * [nil, false, 'food'].any?(/bar/) # => false
7772  *
7773  * With a block given,
7774  * calls the block with each element in +self+;
7775  * returns whether the block returns any truthy value:
7776  *
7777  * [0, 1, 2].any? {|ele| ele < 1 } # => true
7778  * [0, 1, 2].any? {|ele| ele < 0 } # => false
7779  *
7780  * With both a block and argument +object+ given,
7781  * ignores the block and uses +object+ as above.
7782  *
7783  * <b>Special case</b>: returns +false+ if +self+ is empty
7784  * (regardless of any given argument or block).
7785  *
7786  * Related: see {Methods for Querying}[rdoc-ref:Array@Methods+for+Querying].
7787  */
7788 
7789 static VALUE
7790 rb_ary_any_p(int argc, VALUE *argv, VALUE ary)
7791 {
7792  long i, len = RARRAY_LEN(ary);
7793 
7794  rb_check_arity(argc, 0, 1);
7795  if (!len) return Qfalse;
7796  if (argc) {
7797  if (rb_block_given_p()) {
7798  rb_warn("given block not used");
7799  }
7800  for (i = 0; i < RARRAY_LEN(ary); ++i) {
7801  if (RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) return Qtrue;
7802  }
7803  }
7804  else if (!rb_block_given_p()) {
7805  for (i = 0; i < len; ++i) {
7806  if (RTEST(RARRAY_AREF(ary, i))) return Qtrue;
7807  }
7808  }
7809  else {
7810  for (i = 0; i < RARRAY_LEN(ary); ++i) {
7811  if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) return Qtrue;
7812  }
7813  }
7814  return Qfalse;
7815 }
7816 
7817 /*
7818  * call-seq:
7819  * all? -> true or false
7820  * all?(object) -> true or false
7821  * all? {|element| ... } -> true or false
7822  *
7823  * Returns whether for every element of +self+,
7824  * a given criterion is satisfied.
7825  *
7826  * With no block and no argument,
7827  * returns whether every element of +self+ is truthy:
7828  *
7829  * [[], {}, '', 0, 0.0, Object.new].all? # => true # All truthy objects.
7830  * [[], {}, '', 0, 0.0, nil].all? # => false # nil is not truthy.
7831  * [[], {}, '', 0, 0.0, false].all? # => false # false is not truthy.
7832  *
7833  * With argument +object+ given, returns whether <tt>object === ele</tt>
7834  * for every element +ele+ in +self+:
7835  *
7836  * [0, 0, 0].all?(0) # => true
7837  * [0, 1, 2].all?(1) # => false
7838  * ['food', 'fool', 'foot'].all?(/foo/) # => true
7839  * ['food', 'drink'].all?(/foo/) # => false
7840  *
7841  * With a block given, calls the block with each element in +self+;
7842  * returns whether the block returns only truthy values:
7843  *
7844  * [0, 1, 2].all? { |ele| ele < 3 } # => true
7845  * [0, 1, 2].all? { |ele| ele < 2 } # => false
7846  *
7847  * With both a block and argument +object+ given,
7848  * ignores the block and uses +object+ as above.
7849  *
7850  * <b>Special case</b>: returns +true+ if +self+ is empty
7851  * (regardless of any given argument or block).
7852  *
7853  * Related: see {Methods for Querying}[rdoc-ref:Array@Methods+for+Querying].
7854  */
7855 
7856 static VALUE
7857 rb_ary_all_p(int argc, VALUE *argv, VALUE ary)
7858 {
7859  long i, len = RARRAY_LEN(ary);
7860 
7861  rb_check_arity(argc, 0, 1);
7862  if (!len) return Qtrue;
7863  if (argc) {
7864  if (rb_block_given_p()) {
7865  rb_warn("given block not used");
7866  }
7867  for (i = 0; i < RARRAY_LEN(ary); ++i) {
7868  if (!RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) return Qfalse;
7869  }
7870  }
7871  else if (!rb_block_given_p()) {
7872  for (i = 0; i < len; ++i) {
7873  if (!RTEST(RARRAY_AREF(ary, i))) return Qfalse;
7874  }
7875  }
7876  else {
7877  for (i = 0; i < RARRAY_LEN(ary); ++i) {
7878  if (!RTEST(rb_yield(RARRAY_AREF(ary, i)))) return Qfalse;
7879  }
7880  }
7881  return Qtrue;
7882 }
7883 
7884 /*
7885  * call-seq:
7886  * none? -> true or false
7887  * none?(object) -> true or false
7888  * none? {|element| ... } -> true or false
7889  *
7890  * Returns +true+ if no element of +self+ meets a given criterion, +false+ otherwise.
7891  *
7892  * With no block given and no argument, returns +true+ if +self+ has no truthy elements,
7893  * +false+ otherwise:
7894  *
7895  * [nil, false].none? # => true
7896  * [nil, 0, false].none? # => false
7897  * [].none? # => true
7898  *
7899  * With argument +object+ given, returns +false+ if for any element +element+,
7900  * <tt>object === element</tt>; +true+ otherwise:
7901  *
7902  * ['food', 'drink'].none?(/bar/) # => true
7903  * ['food', 'drink'].none?(/foo/) # => false
7904  * [].none?(/foo/) # => true
7905  * [0, 1, 2].none?(3) # => true
7906  * [0, 1, 2].none?(1) # => false
7907  *
7908  * With a block given, calls the block with each element in +self+;
7909  * returns +true+ if the block returns no truthy value, +false+ otherwise:
7910  *
7911  * [0, 1, 2].none? {|element| element > 3 } # => true
7912  * [0, 1, 2].none? {|element| element > 1 } # => false
7913  *
7914  * Related: see {Methods for Querying}[rdoc-ref:Array@Methods+for+Querying].
7915  */
7916 
7917 static VALUE
7918 rb_ary_none_p(int argc, VALUE *argv, VALUE ary)
7919 {
7920  long i, len = RARRAY_LEN(ary);
7921 
7922  rb_check_arity(argc, 0, 1);
7923  if (!len) return Qtrue;
7924  if (argc) {
7925  if (rb_block_given_p()) {
7926  rb_warn("given block not used");
7927  }
7928  for (i = 0; i < RARRAY_LEN(ary); ++i) {
7929  if (RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) return Qfalse;
7930  }
7931  }
7932  else if (!rb_block_given_p()) {
7933  for (i = 0; i < len; ++i) {
7934  if (RTEST(RARRAY_AREF(ary, i))) return Qfalse;
7935  }
7936  }
7937  else {
7938  for (i = 0; i < RARRAY_LEN(ary); ++i) {
7939  if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) return Qfalse;
7940  }
7941  }
7942  return Qtrue;
7943 }
7944 
7945 /*
7946  * call-seq:
7947  * one? -> true or false
7948  * one? {|element| ... } -> true or false
7949  * one?(object) -> true or false
7950  *
7951  * Returns +true+ if exactly one element of +self+ meets a given criterion.
7952  *
7953  * With no block given and no argument, returns +true+ if +self+ has exactly one truthy element,
7954  * +false+ otherwise:
7955  *
7956  * [nil, 0].one? # => true
7957  * [0, 0].one? # => false
7958  * [nil, nil].one? # => false
7959  * [].one? # => false
7960  *
7961  * With a block given, calls the block with each element in +self+;
7962  * returns +true+ if the block a truthy value for exactly one element, +false+ otherwise:
7963  *
7964  * [0, 1, 2].one? {|element| element > 0 } # => false
7965  * [0, 1, 2].one? {|element| element > 1 } # => true
7966  * [0, 1, 2].one? {|element| element > 2 } # => false
7967  *
7968  * With argument +object+ given, returns +true+ if for exactly one element +element+, <tt>object === element</tt>;
7969  * +false+ otherwise:
7970  *
7971  * [0, 1, 2].one?(0) # => true
7972  * [0, 0, 1].one?(0) # => false
7973  * [1, 1, 2].one?(0) # => false
7974  * ['food', 'drink'].one?(/bar/) # => false
7975  * ['food', 'drink'].one?(/foo/) # => true
7976  * [].one?(/foo/) # => false
7977  *
7978  * Related: see {Methods for Querying}[rdoc-ref:Array@Methods+for+Querying].
7979  */
7980 
7981 static VALUE
7982 rb_ary_one_p(int argc, VALUE *argv, VALUE ary)
7983 {
7984  long i, len = RARRAY_LEN(ary);
7985  VALUE result = Qfalse;
7986 
7987  rb_check_arity(argc, 0, 1);
7988  if (!len) return Qfalse;
7989  if (argc) {
7990  if (rb_block_given_p()) {
7991  rb_warn("given block not used");
7992  }
7993  for (i = 0; i < RARRAY_LEN(ary); ++i) {
7994  if (RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) {
7995  if (result) return Qfalse;
7996  result = Qtrue;
7997  }
7998  }
7999  }
8000  else if (!rb_block_given_p()) {
8001  for (i = 0; i < len; ++i) {
8002  if (RTEST(RARRAY_AREF(ary, i))) {
8003  if (result) return Qfalse;
8004  result = Qtrue;
8005  }
8006  }
8007  }
8008  else {
8009  for (i = 0; i < RARRAY_LEN(ary); ++i) {
8010  if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) {
8011  if (result) return Qfalse;
8012  result = Qtrue;
8013  }
8014  }
8015  }
8016  return result;
8017 }
8018 
8019 /*
8020  * call-seq:
8021  * array.dig(index, *identifiers) -> object
8022  *
8023  * Finds and returns the object in nested object
8024  * specified by +index+ and +identifiers+;
8025  * the nested objects may be instances of various classes.
8026  * See {Dig Methods}[rdoc-ref:dig_methods.rdoc].
8027  *
8028  * Examples:
8029  *
8030  * a = [:foo, [:bar, :baz, [:bat, :bam]]]
8031  * a.dig(1) # => [:bar, :baz, [:bat, :bam]]
8032  * a.dig(1, 2) # => [:bat, :bam]
8033  * a.dig(1, 2, 0) # => :bat
8034  * a.dig(1, 2, 3) # => nil
8035  *
8036  * Related: see {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching].
8037  */
8038 
8039 static VALUE
8040 rb_ary_dig(int argc, VALUE *argv, VALUE self)
8041 {
8043  self = rb_ary_at(self, *argv);
8044  if (!--argc) return self;
8045  ++argv;
8046  return rb_obj_dig(argc, argv, self, Qnil);
8047 }
8048 
8049 static inline VALUE
8050 finish_exact_sum(long n, VALUE r, VALUE v, int z)
8051 {
8052  if (n != 0)
8053  v = rb_fix_plus(LONG2FIX(n), v);
8054  if (!UNDEF_P(r)) {
8055  v = rb_rational_plus(r, v);
8056  }
8057  else if (!n && z) {
8058  v = rb_fix_plus(LONG2FIX(0), v);
8059  }
8060  return v;
8061 }
8062 
8063 /*
8064  * call-seq:
8065  * sum(init = 0) -> object
8066  * sum(init = 0) {|element| ... } -> object
8067  *
8068  * With no block given, returns the sum of +init+ and all elements of +self+;
8069  * for array +array+ and value +init+, equivalent to:
8070  *
8071  * sum = init
8072  * array.each {|element| sum += element }
8073  * sum
8074  *
8075  * For example, <tt>[e0, e1, e2].sum</tt> returns <tt>init + e0 + e1 + e2</tt>.
8076  *
8077  * Examples:
8078  *
8079  * [0, 1, 2, 3].sum # => 6
8080  * [0, 1, 2, 3].sum(100) # => 106
8081  * ['abc', 'def', 'ghi'].sum('jkl') # => "jklabcdefghi"
8082  * [[:foo, :bar], ['foo', 'bar']].sum([2, 3])
8083  * # => [2, 3, :foo, :bar, "foo", "bar"]
8084  *
8085  * The +init+ value and elements need not be numeric, but must all be <tt>+</tt>-compatible:
8086  *
8087  * # Raises TypeError: Array can't be coerced into Integer.
8088  * [[:foo, :bar], ['foo', 'bar']].sum(2)
8089  *
8090  * With a block given, calls the block with each element of +self+;
8091  * the block's return value (instead of the element itself) is used as the addend:
8092  *
8093  * ['zero', 1, :two].sum('Coerced and concatenated: ') {|element| element.to_s }
8094  * # => "Coerced and concatenated: zero1two"
8095  *
8096  * Notes:
8097  *
8098  * - Array#join and Array#flatten may be faster than Array#sum
8099  * for an array of strings or an array of arrays.
8100  * - Array#sum method may not respect method redefinition of "+" methods such as Integer#+.
8101  *
8102  */
8103 
8104 static VALUE
8105 rb_ary_sum(int argc, VALUE *argv, VALUE ary)
8106 {
8107  VALUE e, v, r;
8108  long i, n;
8109  int block_given;
8110 
8111  v = (rb_check_arity(argc, 0, 1) ? argv[0] : LONG2FIX(0));
8112 
8113  block_given = rb_block_given_p();
8114 
8115  if (RARRAY_LEN(ary) == 0)
8116  return v;
8117 
8118  n = 0;
8119  r = Qundef;
8120 
8121  if (!FIXNUM_P(v) && !RB_BIGNUM_TYPE_P(v) && !RB_TYPE_P(v, T_RATIONAL)) {
8122  i = 0;
8123  goto init_is_a_value;
8124  }
8125 
8126  for (i = 0; i < RARRAY_LEN(ary); i++) {
8127  e = RARRAY_AREF(ary, i);
8128  if (block_given)
8129  e = rb_yield(e);
8130  if (FIXNUM_P(e)) {
8131  n += FIX2LONG(e); /* should not overflow long type */
8132  if (!FIXABLE(n)) {
8133  v = rb_big_plus(LONG2NUM(n), v);
8134  n = 0;
8135  }
8136  }
8137  else if (RB_BIGNUM_TYPE_P(e))
8138  v = rb_big_plus(e, v);
8139  else if (RB_TYPE_P(e, T_RATIONAL)) {
8140  if (UNDEF_P(r))
8141  r = e;
8142  else
8143  r = rb_rational_plus(r, e);
8144  }
8145  else
8146  goto not_exact;
8147  }
8148  v = finish_exact_sum(n, r, v, argc!=0);
8149  return v;
8150 
8151  not_exact:
8152  v = finish_exact_sum(n, r, v, i!=0);
8153 
8154  if (RB_FLOAT_TYPE_P(e)) {
8155  /*
8156  * Kahan-Babuska balancing compensated summation algorithm
8157  * See https://link.springer.com/article/10.1007/s00607-005-0139-x
8158  */
8159  double f, c;
8160  double x, t;
8161 
8162  f = NUM2DBL(v);
8163  c = 0.0;
8164  goto has_float_value;
8165  for (; i < RARRAY_LEN(ary); i++) {
8166  e = RARRAY_AREF(ary, i);
8167  if (block_given)
8168  e = rb_yield(e);
8169  if (RB_FLOAT_TYPE_P(e))
8170  has_float_value:
8171  x = RFLOAT_VALUE(e);
8172  else if (FIXNUM_P(e))
8173  x = FIX2LONG(e);
8174  else if (RB_BIGNUM_TYPE_P(e))
8175  x = rb_big2dbl(e);
8176  else if (RB_TYPE_P(e, T_RATIONAL))
8177  x = rb_num2dbl(e);
8178  else
8179  goto not_float;
8180 
8181  if (isnan(f)) continue;
8182  if (isnan(x)) {
8183  f = x;
8184  continue;
8185  }
8186  if (isinf(x)) {
8187  if (isinf(f) && signbit(x) != signbit(f))
8188  f = NAN;
8189  else
8190  f = x;
8191  continue;
8192  }
8193  if (isinf(f)) continue;
8194 
8195  t = f + x;
8196  if (fabs(f) >= fabs(x))
8197  c += ((f - t) + x);
8198  else
8199  c += ((x - t) + f);
8200  f = t;
8201  }
8202  f += c;
8203  return DBL2NUM(f);
8204 
8205  not_float:
8206  v = DBL2NUM(f);
8207  }
8208 
8209  goto has_some_value;
8210  init_is_a_value:
8211  for (; i < RARRAY_LEN(ary); i++) {
8212  e = RARRAY_AREF(ary, i);
8213  if (block_given)
8214  e = rb_yield(e);
8215  has_some_value:
8216  v = rb_funcall(v, idPLUS, 1, e);
8217  }
8218  return v;
8219 }
8220 
8221 /* :nodoc: */
8222 static VALUE
8223 rb_ary_deconstruct(VALUE ary)
8224 {
8225  return ary;
8226 }
8227 
8228 /*
8229  * An \Array object is an ordered, integer-indexed collection of objects,
8230  * called _elements_;
8231  * the object represents
8232  * an {array data structure}[https://en.wikipedia.org/wiki/Array_(data_structure)].
8233  *
8234  * An element may be any object (even another array);
8235  * elements may be any mixture of objects of different types.
8236  *
8237  * Important data structures that use arrays include:
8238  *
8239  * - {Coordinate vector}[https://en.wikipedia.org/wiki/Coordinate_vector].
8240  * - {Matrix}[https://en.wikipedia.org/wiki/Matrix_(mathematics)].
8241  * - {Heap}[https://en.wikipedia.org/wiki/Heap_(data_structure)].
8242  * - {Hash table}[https://en.wikipedia.org/wiki/Hash_table].
8243  * - {Deque (double-ended queue)}[https://en.wikipedia.org/wiki/Double-ended_queue].
8244  * - {Queue}[https://en.wikipedia.org/wiki/Queue_(abstract_data_type)].
8245  * - {Stack}[https://en.wikipedia.org/wiki/Stack_(abstract_data_type)].
8246  *
8247  * There are also array-like data structures:
8248  *
8249  * - {Associative array}[https://en.wikipedia.org/wiki/Associative_array] (see Hash).
8250  * - {Directory}[https://en.wikipedia.org/wiki/Directory_(computing)] (see Dir).
8251  * - {Environment}[https://en.wikipedia.org/wiki/Environment_variable] (see ENV).
8252  * - {Set}[https://en.wikipedia.org/wiki/Set_(abstract_data_type)] (see Set).
8253  * - {String}[https://en.wikipedia.org/wiki/String_(computer_science)] (see String).
8254  *
8255  * == \Array Indexes
8256  *
8257  * \Array indexing starts at 0, as in C or Java.
8258  *
8259  * A non-negative index is an offset from the first element:
8260  *
8261  * - Index 0 indicates the first element.
8262  * - Index 1 indicates the second element.
8263  * - ...
8264  *
8265  * A negative index is an offset, backwards, from the end of the array:
8266  *
8267  * - Index -1 indicates the last element.
8268  * - Index -2 indicates the next-to-last element.
8269  * - ...
8270  *
8271  *
8272  * === In-Range and Out-of-Range Indexes
8273  *
8274  * A non-negative index is <i>in range</i> if and only if it is smaller than
8275  * the size of the array. For a 3-element array:
8276  *
8277  * - Indexes 0 through 2 are in range.
8278  * - Index 3 is out of range.
8279  *
8280  * A negative index is <i>in range</i> if and only if its absolute value is
8281  * not larger than the size of the array. For a 3-element array:
8282  *
8283  * - Indexes -1 through -3 are in range.
8284  * - Index -4 is out of range.
8285  *
8286  * === Effective Index
8287  *
8288  * Although the effective index into an array is always an integer,
8289  * some methods (both within class \Array and elsewhere)
8290  * accept one or more non-integer arguments that are
8291  * {integer-convertible objects}[rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects].
8292  *
8293  * == Creating Arrays
8294  *
8295  * You can create an \Array object explicitly with:
8296  *
8297  * - An {array literal}[rdoc-ref:literals.rdoc@Array+Literals]:
8298  *
8299  * [1, 'one', :one, [2, 'two', :two]]
8300  *
8301  * - A {%w or %W: string-array Literal}[rdoc-ref:literals.rdoc@25w+and+-25W-3A+String-Array+Literals]:
8302  *
8303  * %w[foo bar baz] # => ["foo", "bar", "baz"]
8304  * %w[1 % *] # => ["1", "%", "*"]
8305  *
8306  * - A {%i pr %I: symbol-array Literal}[rdoc-ref:literals.rdoc@25i+and+-25I-3A+Symbol-Array+Literals]:
8307  *
8308  * %i[foo bar baz] # => [:foo, :bar, :baz]
8309  * %i[1 % *] # => [:"1", :%, :*]
8310  *
8311  * - \Method Kernel#Array:
8312  *
8313  * Array(["a", "b"]) # => ["a", "b"]
8314  * Array(1..5) # => [1, 2, 3, 4, 5]
8315  * Array(key: :value) # => [[:key, :value]]
8316  * Array(nil) # => []
8317  * Array(1) # => [1]
8318  * Array({:a => "a", :b => "b"}) # => [[:a, "a"], [:b, "b"]]
8319  *
8320  * - \Method Array.new:
8321  *
8322  * Array.new # => []
8323  * Array.new(3) # => [nil, nil, nil]
8324  * Array.new(4) {Hash.new} # => [{}, {}, {}, {}]
8325  * Array.new(3, true) # => [true, true, true]
8326  *
8327  * Note that the last example above populates the array
8328  * with references to the same object.
8329  * This is recommended only in cases where that object is a natively immutable object
8330  * such as a symbol, a numeric, +nil+, +true+, or +false+.
8331  *
8332  * Another way to create an array with various objects, using a block;
8333  * this usage is safe for mutable objects such as hashes, strings or
8334  * other arrays:
8335  *
8336  * Array.new(4) {|i| i.to_s } # => ["0", "1", "2", "3"]
8337  *
8338  * Here is a way to create a multi-dimensional array:
8339  *
8340  * Array.new(3) {Array.new(3)}
8341  * # => [[nil, nil, nil], [nil, nil, nil], [nil, nil, nil]]
8342  *
8343  * A number of Ruby methods, both in the core and in the standard library,
8344  * provide instance method +to_a+, which converts an object to an array.
8345  *
8346  * - ARGF#to_a
8347  * - Array#to_a
8348  * - Enumerable#to_a
8349  * - Hash#to_a
8350  * - MatchData#to_a
8351  * - NilClass#to_a
8352  * - OptionParser#to_a
8353  * - Range#to_a
8354  * - Set#to_a
8355  * - Struct#to_a
8356  * - Time#to_a
8357  * - Benchmark::Tms#to_a
8358  * - CSV::Table#to_a
8359  * - Enumerator::Lazy#to_a
8360  * - Gem::List#to_a
8361  * - Gem::NameTuple#to_a
8362  * - Gem::Platform#to_a
8363  * - Gem::RequestSet::Lockfile::Tokenizer#to_a
8364  * - Gem::SourceList#to_a
8365  * - OpenSSL::X509::Extension#to_a
8366  * - OpenSSL::X509::Name#to_a
8367  * - Racc::ISet#to_a
8368  * - Rinda::RingFinger#to_a
8369  * - Ripper::Lexer::Elem#to_a
8370  * - RubyVM::InstructionSequence#to_a
8371  * - YAML::DBM#to_a
8372  *
8373  * == Example Usage
8374  *
8375  * In addition to the methods it mixes in through the Enumerable module, the
8376  * +Array+ class has proprietary methods for accessing, searching and otherwise
8377  * manipulating arrays.
8378  *
8379  * Some of the more common ones are illustrated below.
8380  *
8381  * == Accessing Elements
8382  *
8383  * Elements in an array can be retrieved using the Array#[] method. It can
8384  * take a single integer argument (a numeric index), a pair of arguments
8385  * (start and length) or a range. Negative indices start counting from the end,
8386  * with -1 being the last element.
8387  *
8388  * arr = [1, 2, 3, 4, 5, 6]
8389  * arr[2] #=> 3
8390  * arr[100] #=> nil
8391  * arr[-3] #=> 4
8392  * arr[2, 3] #=> [3, 4, 5]
8393  * arr[1..4] #=> [2, 3, 4, 5]
8394  * arr[1..-3] #=> [2, 3, 4]
8395  *
8396  * Another way to access a particular array element is by using the #at method
8397  *
8398  * arr.at(0) #=> 1
8399  *
8400  * The #slice method works in an identical manner to Array#[].
8401  *
8402  * To raise an error for indices outside of the array bounds or else to
8403  * provide a default value when that happens, you can use #fetch.
8404  *
8405  * arr = ['a', 'b', 'c', 'd', 'e', 'f']
8406  * arr.fetch(100) #=> IndexError: index 100 outside of array bounds: -6...6
8407  * arr.fetch(100, "oops") #=> "oops"
8408  *
8409  * The special methods #first and #last will return the first and last
8410  * elements of an array, respectively.
8411  *
8412  * arr.first #=> 1
8413  * arr.last #=> 6
8414  *
8415  * To return the first +n+ elements of an array, use #take
8416  *
8417  * arr.take(3) #=> [1, 2, 3]
8418  *
8419  * #drop does the opposite of #take, by returning the elements after +n+
8420  * elements have been dropped:
8421  *
8422  * arr.drop(3) #=> [4, 5, 6]
8423  *
8424  * == Obtaining Information about an +Array+
8425  *
8426  * Arrays keep track of their own length at all times. To query an array
8427  * about the number of elements it contains, use #length, #count or #size.
8428  *
8429  * browsers = ['Chrome', 'Firefox', 'Safari', 'Opera', 'IE']
8430  * browsers.length #=> 5
8431  * browsers.count #=> 5
8432  *
8433  * To check whether an array contains any elements at all
8434  *
8435  * browsers.empty? #=> false
8436  *
8437  * To check whether a particular item is included in the array
8438  *
8439  * browsers.include?('Konqueror') #=> false
8440  *
8441  * == Adding Items to Arrays
8442  *
8443  * Items can be added to the end of an array by using either #push or #<<
8444  *
8445  * arr = [1, 2, 3, 4]
8446  * arr.push(5) #=> [1, 2, 3, 4, 5]
8447  * arr << 6 #=> [1, 2, 3, 4, 5, 6]
8448  *
8449  * #unshift will add a new item to the beginning of an array.
8450  *
8451  * arr.unshift(0) #=> [0, 1, 2, 3, 4, 5, 6]
8452  *
8453  * With #insert you can add a new element to an array at any position.
8454  *
8455  * arr.insert(3, 'apple') #=> [0, 1, 2, 'apple', 3, 4, 5, 6]
8456  *
8457  * Using the #insert method, you can also insert multiple values at once:
8458  *
8459  * arr.insert(3, 'orange', 'pear', 'grapefruit')
8460  * #=> [0, 1, 2, "orange", "pear", "grapefruit", "apple", 3, 4, 5, 6]
8461  *
8462  * == Removing Items from an +Array+
8463  *
8464  * The method #pop removes the last element in an array and returns it:
8465  *
8466  * arr = [1, 2, 3, 4, 5, 6]
8467  * arr.pop #=> 6
8468  * arr #=> [1, 2, 3, 4, 5]
8469  *
8470  * To retrieve and at the same time remove the first item, use #shift:
8471  *
8472  * arr.shift #=> 1
8473  * arr #=> [2, 3, 4, 5]
8474  *
8475  * To delete an element at a particular index:
8476  *
8477  * arr.delete_at(2) #=> 4
8478  * arr #=> [2, 3, 5]
8479  *
8480  * To delete a particular element anywhere in an array, use #delete:
8481  *
8482  * arr = [1, 2, 2, 3]
8483  * arr.delete(2) #=> 2
8484  * arr #=> [1,3]
8485  *
8486  * A useful method if you need to remove +nil+ values from an array is
8487  * #compact:
8488  *
8489  * arr = ['foo', 0, nil, 'bar', 7, 'baz', nil]
8490  * arr.compact #=> ['foo', 0, 'bar', 7, 'baz']
8491  * arr #=> ['foo', 0, nil, 'bar', 7, 'baz', nil]
8492  * arr.compact! #=> ['foo', 0, 'bar', 7, 'baz']
8493  * arr #=> ['foo', 0, 'bar', 7, 'baz']
8494  *
8495  * Another common need is to remove duplicate elements from an array.
8496  *
8497  * It has the non-destructive #uniq, and destructive method #uniq!
8498  *
8499  * arr = [2, 5, 6, 556, 6, 6, 8, 9, 0, 123, 556]
8500  * arr.uniq #=> [2, 5, 6, 556, 8, 9, 0, 123]
8501  *
8502  * == Iterating over Arrays
8503  *
8504  * Like all classes that include the Enumerable module, +Array+ has an each
8505  * method, which defines what elements should be iterated over and how. In
8506  * case of Array's #each, all elements in the +Array+ instance are yielded to
8507  * the supplied block in sequence.
8508  *
8509  * Note that this operation leaves the array unchanged.
8510  *
8511  * arr = [1, 2, 3, 4, 5]
8512  * arr.each {|a| print a -= 10, " "}
8513  * # prints: -9 -8 -7 -6 -5
8514  * #=> [1, 2, 3, 4, 5]
8515  *
8516  * Another sometimes useful iterator is #reverse_each which will iterate over
8517  * the elements in the array in reverse order.
8518  *
8519  * words = %w[first second third fourth fifth sixth]
8520  * str = ""
8521  * words.reverse_each {|word| str += "#{word} "}
8522  * p str #=> "sixth fifth fourth third second first "
8523  *
8524  * The #map method can be used to create a new array based on the original
8525  * array, but with the values modified by the supplied block:
8526  *
8527  * arr.map {|a| 2*a} #=> [2, 4, 6, 8, 10]
8528  * arr #=> [1, 2, 3, 4, 5]
8529  * arr.map! {|a| a**2} #=> [1, 4, 9, 16, 25]
8530  * arr #=> [1, 4, 9, 16, 25]
8531  *
8532  *
8533  * == Selecting Items from an +Array+
8534  *
8535  * Elements can be selected from an array according to criteria defined in a
8536  * block. The selection can happen in a destructive or a non-destructive
8537  * manner. While the destructive operations will modify the array they were
8538  * called on, the non-destructive methods usually return a new array with the
8539  * selected elements, but leave the original array unchanged.
8540  *
8541  * === Non-destructive Selection
8542  *
8543  * arr = [1, 2, 3, 4, 5, 6]
8544  * arr.select {|a| a > 3} #=> [4, 5, 6]
8545  * arr.reject {|a| a < 3} #=> [3, 4, 5, 6]
8546  * arr.drop_while {|a| a < 4} #=> [4, 5, 6]
8547  * arr #=> [1, 2, 3, 4, 5, 6]
8548  *
8549  * === Destructive Selection
8550  *
8551  * #select! and #reject! are the corresponding destructive methods to #select
8552  * and #reject
8553  *
8554  * Similar to #select vs. #reject, #delete_if and #keep_if have the exact
8555  * opposite result when supplied with the same block:
8556  *
8557  * arr.delete_if {|a| a < 4} #=> [4, 5, 6]
8558  * arr #=> [4, 5, 6]
8559  *
8560  * arr = [1, 2, 3, 4, 5, 6]
8561  * arr.keep_if {|a| a < 4} #=> [1, 2, 3]
8562  * arr #=> [1, 2, 3]
8563  *
8564  * == What's Here
8565  *
8566  * First, what's elsewhere. \Class +Array+:
8567  *
8568  * - Inherits from {class Object}[rdoc-ref:Object@What-27s+Here].
8569  * - Includes {module Enumerable}[rdoc-ref:Enumerable@What-27s+Here],
8570  * which provides dozens of additional methods.
8571  *
8572  * Here, class +Array+ provides methods that are useful for:
8573  *
8574  * - {Creating an Array}[rdoc-ref:Array@Methods+for+Creating+an+Array]
8575  * - {Querying}[rdoc-ref:Array@Methods+for+Querying]
8576  * - {Comparing}[rdoc-ref:Array@Methods+for+Comparing]
8577  * - {Fetching}[rdoc-ref:Array@Methods+for+Fetching]
8578  * - {Assigning}[rdoc-ref:Array@Methods+for+Assigning]
8579  * - {Deleting}[rdoc-ref:Array@Methods+for+Deleting]
8580  * - {Combining}[rdoc-ref:Array@Methods+for+Combining]
8581  * - {Iterating}[rdoc-ref:Array@Methods+for+Iterating]
8582  * - {Converting}[rdoc-ref:Array@Methods+for+Converting]
8583  * - {And more....}[rdoc-ref:Array@Other+Methods]
8584  *
8585  * === Methods for Creating an +Array+
8586  *
8587  * - ::[]: Returns a new array populated with given objects.
8588  * - ::new: Returns a new array.
8589  * - ::try_convert: Returns a new array created from a given object.
8590  *
8591  * See also {Creating Arrays}[rdoc-ref:Array@Creating+Arrays].
8592  *
8593  * === Methods for Querying
8594  *
8595  * - #all?: Returns whether all elements meet a given criterion.
8596  * - #any?: Returns whether any element meets a given criterion.
8597  * - #count: Returns the count of elements that meet a given criterion.
8598  * - #empty?: Returns whether there are no elements.
8599  * - #find_index (aliased as #index): Returns the index of the first element that meets a given criterion.
8600  * - #hash: Returns the integer hash code.
8601  * - #include?: Returns whether any element <tt>==</tt> a given object.
8602  * - #length (aliased as #size): Returns the count of elements.
8603  * - #none?: Returns whether no element <tt>==</tt> a given object.
8604  * - #one?: Returns whether exactly one element <tt>==</tt> a given object.
8605  * - #rindex: Returns the index of the last element that meets a given criterion.
8606  *
8607  * === Methods for Comparing
8608  *
8609  * - #<=>: Returns -1, 0, or 1, as +self+ is less than, equal to, or greater than a given object.
8610  * - #==: Returns whether each element in +self+ is <tt>==</tt> to the corresponding element in a given object.
8611  * - #eql?: Returns whether each element in +self+ is <tt>eql?</tt> to the corresponding element in a given object.
8612 
8613  * === Methods for Fetching
8614  *
8615  * These methods do not modify +self+.
8616  *
8617  * - #[] (aliased as #slice): Returns consecutive elements as determined by a given argument.
8618  * - #assoc: Returns the first element that is an array whose first element <tt>==</tt> a given object.
8619  * - #at: Returns the element at a given offset.
8620  * - #bsearch: Returns an element selected via a binary search as determined by a given block.
8621  * - #bsearch_index: Returns the index of an element selected via a binary search as determined by a given block.
8622  * - #compact: Returns an array containing all non-+nil+ elements.
8623  * - #dig: Returns the object in nested objects that is specified by a given index and additional arguments.
8624  * - #drop: Returns trailing elements as determined by a given index.
8625  * - #drop_while: Returns trailing elements as determined by a given block.
8626  * - #fetch: Returns the element at a given offset.
8627  * - #fetch_values: Returns elements at given offsets.
8628  * - #first: Returns one or more leading elements.
8629  * - #last: Returns one or more trailing elements.
8630  * - #max: Returns one or more maximum-valued elements, as determined by <tt>#<=></tt> or a given block.
8631  * - #min: Returns one or more minimum-valued elements, as determined by <tt>#<=></tt> or a given block.
8632  * - #minmax: Returns the minimum-valued and maximum-valued elements, as determined by <tt>#<=></tt> or a given block.
8633  * - #rassoc: Returns the first element that is an array whose second element <tt>==</tt> a given object.
8634  * - #reject: Returns an array containing elements not rejected by a given block.
8635  * - #reverse: Returns all elements in reverse order.
8636  * - #rotate: Returns all elements with some rotated from one end to the other.
8637  * - #sample: Returns one or more random elements.
8638  * - #select (aliased as #filter): Returns an array containing elements selected by a given block.
8639  * - #shuffle: Returns elements in a random order.
8640  * - #sort: Returns all elements in an order determined by <tt>#<=></tt> or a given block.
8641  * - #take: Returns leading elements as determined by a given index.
8642  * - #take_while: Returns leading elements as determined by a given block.
8643  * - #uniq: Returns an array containing non-duplicate elements.
8644  * - #values_at: Returns the elements at given offsets.
8645  *
8646  * === Methods for Assigning
8647  *
8648  * These methods add, replace, or reorder elements in +self+.
8649  *
8650  * - #<<: Appends an element.
8651  * - #[]=: Assigns specified elements with a given object.
8652  * - #concat: Appends all elements from given arrays.
8653  * - #fill: Replaces specified elements with specified objects.
8654  * - #flatten!: Replaces each nested array in +self+ with the elements from that array.
8655  * - #initialize_copy (aliased as #replace): Replaces the content of +self+ with the content of a given array.
8656  * - #insert: Inserts given objects at a given offset; does not replace elements.
8657  * - #push (aliased as #append): Appends elements.
8658  * - #reverse!: Replaces +self+ with its elements reversed.
8659  * - #rotate!: Replaces +self+ with its elements rotated.
8660  * - #shuffle!: Replaces +self+ with its elements in random order.
8661  * - #sort!: Replaces +self+ with its elements sorted, as determined by <tt>#<=></tt> or a given block.
8662  * - #sort_by!: Replaces +self+ with its elements sorted, as determined by a given block.
8663  * - #unshift (aliased as #prepend): Prepends leading elements.
8664  *
8665  * === Methods for Deleting
8666  *
8667  * Each of these methods removes elements from +self+:
8668  *
8669  * - #clear: Removes all elements.
8670  * - #compact!: Removes all +nil+ elements.
8671  * - #delete: Removes elements equal to a given object.
8672  * - #delete_at: Removes the element at a given offset.
8673  * - #delete_if: Removes elements specified by a given block.
8674  * - #keep_if: Removes elements not specified by a given block.
8675  * - #pop: Removes and returns the last element.
8676  * - #reject!: Removes elements specified by a given block.
8677  * - #select! (aliased as #filter!): Removes elements not specified by a given block.
8678  * - #shift: Removes and returns the first element.
8679  * - #slice!: Removes and returns a sequence of elements.
8680  * - #uniq!: Removes duplicates.
8681  *
8682  * === Methods for Combining
8683  *
8684  * - #&: Returns an array containing elements found both in +self+ and a given array.
8685  * - #+: Returns an array containing all elements of +self+ followed by all elements of a given array.
8686  * - #-: Returns an array containing all elements of +self+ that are not found in a given array.
8687  * - #difference: Returns an array containing all elements of +self+ that are not found in any of the given arrays..
8688  * - #intersection: Returns an array containing elements found both in +self+ and in each given array.
8689  * - #product: Returns or yields all combinations of elements from +self+ and given arrays.
8690  * - #reverse: Returns an array containing all elements of +self+ in reverse order.
8691  * - #union: Returns an array containing all elements of +self+ and all elements of given arrays, duplicates removed.
8692  * - #|: Returns an array containing all elements of +self+ and all elements of a given array, duplicates removed.
8693  *
8694  * === Methods for Iterating
8695  *
8696  * - #combination: Calls a given block with combinations of elements of +self+; a combination does not use the same element more than once.
8697  * - #cycle: Calls a given block with each element, then does so again, for a specified number of times, or forever.
8698  * - #each: Passes each element to a given block.
8699  * - #each_index: Passes each element index to a given block.
8700  * - #permutation: Calls a given block with permutations of elements of +self+; a permutation does not use the same element more than once.
8701  * - #repeated_combination: Calls a given block with combinations of elements of +self+; a combination may use the same element more than once.
8702  * - #repeated_permutation: Calls a given block with permutations of elements of +self+; a permutation may use the same element more than once.
8703  * - #reverse_each: Passes each element, in reverse order, to a given block.
8704  *
8705  * === Methods for Converting
8706  *
8707  * - #collect (aliased as #map): Returns an array containing the block return-value for each element.
8708  * - #collect! (aliased as #map!): Replaces each element with a block return-value.
8709  * - #flatten: Returns an array that is a recursive flattening of +self+.
8710  * - #inspect (aliased as #to_s): Returns a new String containing the elements.
8711  * - #join: Returns a newsString containing the elements joined by the field separator.
8712  * - #to_a: Returns +self+ or a new array containing all elements.
8713  * - #to_ary: Returns +self+.
8714  * - #to_h: Returns a new hash formed from the elements.
8715  * - #transpose: Transposes +self+, which must be an array of arrays.
8716  * - #zip: Returns a new array of arrays containing +self+ and given arrays.
8717  *
8718  * === Other Methods
8719  *
8720  * - #*: Returns one of the following:
8721  *
8722  * - With integer argument +n+, a new array that is the concatenation
8723  * of +n+ copies of +self+.
8724  * - With string argument +field_separator+, a new string that is equivalent to
8725  * <tt>join(field_separator)</tt>.
8726  *
8727  * - #pack: Packs the elements into a binary sequence.
8728  * - #sum: Returns a sum of elements according to either <tt>+</tt> or a given block.
8729  */
8730 
8731 void
8732 Init_Array(void)
8733 {
8734  fake_ary_flags = init_fake_ary_flags();
8735 
8736  rb_cArray = rb_define_class("Array", rb_cObject);
8738 
8739  rb_define_alloc_func(rb_cArray, empty_ary_alloc);
8740  rb_define_singleton_method(rb_cArray, "new", rb_ary_s_new, -1);
8741  rb_define_singleton_method(rb_cArray, "[]", rb_ary_s_create, -1);
8742  rb_define_singleton_method(rb_cArray, "try_convert", rb_ary_s_try_convert, 1);
8743  rb_define_method(rb_cArray, "initialize", rb_ary_initialize, -1);
8744  rb_define_method(rb_cArray, "initialize_copy", rb_ary_replace, 1);
8745 
8746  rb_define_method(rb_cArray, "inspect", rb_ary_inspect, 0);
8747  rb_define_alias(rb_cArray, "to_s", "inspect");
8748  rb_define_method(rb_cArray, "to_a", rb_ary_to_a, 0);
8749  rb_define_method(rb_cArray, "to_h", rb_ary_to_h, 0);
8750  rb_define_method(rb_cArray, "to_ary", rb_ary_to_ary_m, 0);
8751 
8752  rb_define_method(rb_cArray, "==", rb_ary_equal, 1);
8753  rb_define_method(rb_cArray, "eql?", rb_ary_eql, 1);
8754  rb_define_method(rb_cArray, "hash", rb_ary_hash, 0);
8755 
8757  rb_define_method(rb_cArray, "[]=", rb_ary_aset, -1);
8758  rb_define_method(rb_cArray, "at", rb_ary_at, 1);
8759  rb_define_method(rb_cArray, "fetch", rb_ary_fetch, -1);
8760  rb_define_method(rb_cArray, "concat", rb_ary_concat_multi, -1);
8761  rb_define_method(rb_cArray, "union", rb_ary_union_multi, -1);
8762  rb_define_method(rb_cArray, "difference", rb_ary_difference_multi, -1);
8763  rb_define_method(rb_cArray, "intersection", rb_ary_intersection_multi, -1);
8764  rb_define_method(rb_cArray, "intersect?", rb_ary_intersect_p, 1);
8766  rb_define_method(rb_cArray, "push", rb_ary_push_m, -1);
8767  rb_define_alias(rb_cArray, "append", "push");
8768  rb_define_method(rb_cArray, "pop", rb_ary_pop_m, -1);
8769  rb_define_method(rb_cArray, "shift", rb_ary_shift_m, -1);
8770  rb_define_method(rb_cArray, "unshift", rb_ary_unshift_m, -1);
8771  rb_define_alias(rb_cArray, "prepend", "unshift");
8772  rb_define_method(rb_cArray, "insert", rb_ary_insert, -1);
8773  rb_define_method(rb_cArray, "each", rb_ary_each, 0);
8774  rb_define_method(rb_cArray, "each_index", rb_ary_each_index, 0);
8775  rb_define_method(rb_cArray, "reverse_each", rb_ary_reverse_each, 0);
8776  rb_define_method(rb_cArray, "length", rb_ary_length, 0);
8777  rb_define_method(rb_cArray, "size", rb_ary_length, 0);
8778  rb_define_method(rb_cArray, "empty?", rb_ary_empty_p, 0);
8779  rb_define_method(rb_cArray, "find_index", rb_ary_index, -1);
8780  rb_define_method(rb_cArray, "index", rb_ary_index, -1);
8781  rb_define_method(rb_cArray, "rindex", rb_ary_rindex, -1);
8782  rb_define_method(rb_cArray, "join", rb_ary_join_m, -1);
8783  rb_define_method(rb_cArray, "reverse", rb_ary_reverse_m, 0);
8784  rb_define_method(rb_cArray, "reverse!", rb_ary_reverse_bang, 0);
8785  rb_define_method(rb_cArray, "rotate", rb_ary_rotate_m, -1);
8786  rb_define_method(rb_cArray, "rotate!", rb_ary_rotate_bang, -1);
8787  rb_define_method(rb_cArray, "sort", rb_ary_sort, 0);
8789  rb_define_method(rb_cArray, "sort_by!", rb_ary_sort_by_bang, 0);
8790  rb_define_method(rb_cArray, "collect", rb_ary_collect, 0);
8791  rb_define_method(rb_cArray, "collect!", rb_ary_collect_bang, 0);
8792  rb_define_method(rb_cArray, "map", rb_ary_collect, 0);
8793  rb_define_method(rb_cArray, "map!", rb_ary_collect_bang, 0);
8794  rb_define_method(rb_cArray, "select", rb_ary_select, 0);
8795  rb_define_method(rb_cArray, "select!", rb_ary_select_bang, 0);
8796  rb_define_method(rb_cArray, "filter", rb_ary_select, 0);
8797  rb_define_method(rb_cArray, "filter!", rb_ary_select_bang, 0);
8798  rb_define_method(rb_cArray, "keep_if", rb_ary_keep_if, 0);
8799  rb_define_method(rb_cArray, "values_at", rb_ary_values_at, -1);
8800  rb_define_method(rb_cArray, "delete", rb_ary_delete, 1);
8801  rb_define_method(rb_cArray, "delete_at", rb_ary_delete_at_m, 1);
8802  rb_define_method(rb_cArray, "delete_if", rb_ary_delete_if, 0);
8803  rb_define_method(rb_cArray, "reject", rb_ary_reject, 0);
8804  rb_define_method(rb_cArray, "reject!", rb_ary_reject_bang, 0);
8805  rb_define_method(rb_cArray, "zip", rb_ary_zip, -1);
8806  rb_define_method(rb_cArray, "transpose", rb_ary_transpose, 0);
8807  rb_define_method(rb_cArray, "replace", rb_ary_replace, 1);
8808  rb_define_method(rb_cArray, "clear", rb_ary_clear, 0);
8809  rb_define_method(rb_cArray, "fill", rb_ary_fill, -1);
8810  rb_define_method(rb_cArray, "include?", rb_ary_includes, 1);
8812 
8813  rb_define_method(rb_cArray, "slice", rb_ary_aref, -1);
8814  rb_define_method(rb_cArray, "slice!", rb_ary_slice_bang, -1);
8815 
8816  rb_define_method(rb_cArray, "assoc", rb_ary_assoc, 1);
8817  rb_define_method(rb_cArray, "rassoc", rb_ary_rassoc, 1);
8818 
8820  rb_define_method(rb_cArray, "*", rb_ary_times, 1);
8821 
8822  rb_define_method(rb_cArray, "-", rb_ary_diff, 1);
8823  rb_define_method(rb_cArray, "&", rb_ary_and, 1);
8824  rb_define_method(rb_cArray, "|", rb_ary_or, 1);
8825 
8826  rb_define_method(rb_cArray, "max", rb_ary_max, -1);
8827  rb_define_method(rb_cArray, "min", rb_ary_min, -1);
8828  rb_define_method(rb_cArray, "minmax", rb_ary_minmax, 0);
8829 
8830  rb_define_method(rb_cArray, "uniq", rb_ary_uniq, 0);
8831  rb_define_method(rb_cArray, "uniq!", rb_ary_uniq_bang, 0);
8832  rb_define_method(rb_cArray, "compact", rb_ary_compact, 0);
8833  rb_define_method(rb_cArray, "compact!", rb_ary_compact_bang, 0);
8834  rb_define_method(rb_cArray, "flatten", rb_ary_flatten, -1);
8835  rb_define_method(rb_cArray, "flatten!", rb_ary_flatten_bang, -1);
8836  rb_define_method(rb_cArray, "count", rb_ary_count, -1);
8837  rb_define_method(rb_cArray, "cycle", rb_ary_cycle, -1);
8838  rb_define_method(rb_cArray, "permutation", rb_ary_permutation, -1);
8839  rb_define_method(rb_cArray, "combination", rb_ary_combination, 1);
8840  rb_define_method(rb_cArray, "repeated_permutation", rb_ary_repeated_permutation, 1);
8841  rb_define_method(rb_cArray, "repeated_combination", rb_ary_repeated_combination, 1);
8842  rb_define_method(rb_cArray, "product", rb_ary_product, -1);
8843 
8844  rb_define_method(rb_cArray, "take", rb_ary_take, 1);
8845  rb_define_method(rb_cArray, "take_while", rb_ary_take_while, 0);
8846  rb_define_method(rb_cArray, "drop", rb_ary_drop, 1);
8847  rb_define_method(rb_cArray, "drop_while", rb_ary_drop_while, 0);
8848  rb_define_method(rb_cArray, "bsearch", rb_ary_bsearch, 0);
8849  rb_define_method(rb_cArray, "bsearch_index", rb_ary_bsearch_index, 0);
8850  rb_define_method(rb_cArray, "any?", rb_ary_any_p, -1);
8851  rb_define_method(rb_cArray, "all?", rb_ary_all_p, -1);
8852  rb_define_method(rb_cArray, "none?", rb_ary_none_p, -1);
8853  rb_define_method(rb_cArray, "one?", rb_ary_one_p, -1);
8854  rb_define_method(rb_cArray, "dig", rb_ary_dig, -1);
8855  rb_define_method(rb_cArray, "sum", rb_ary_sum, -1);
8856  rb_define_method(rb_cArray, "freeze", rb_ary_freeze, 0);
8857 
8858  rb_define_method(rb_cArray, "deconstruct", rb_ary_deconstruct, 0);
8859 
8860  rb_cArray_empty_frozen = rb_ary_freeze(rb_ary_new());
8861  rb_vm_register_global_object(rb_cArray_empty_frozen);
8862 }
8863 
8864 #include "array.rbinc"
#define RUBY_ASSERT_ALWAYS(expr,...)
A variant of RUBY_ASSERT that does not interface with RUBY_DEBUG.
Definition: assert.h:199
#define RUBY_ASSERT(...)
Asserts that the given expression is truthy if and only if RUBY_DEBUG is truthy.
Definition: assert.h:219
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
Definition: cxxanyargs.hpp:685
void rb_include_module(VALUE klass, VALUE module)
Includes a module to a class.
Definition: class.c:1187
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:980
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition: class.c:2345
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.
Definition: class.c:2635
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a method.
Definition: class.c:2142
int rb_block_given_p(void)
Determines if the current method is given a block.
Definition: eval.c:916
#define FL_UNSET_RAW
Old name of RB_FL_UNSET_RAW.
Definition: fl_type.h:134
#define RFLOAT_VALUE
Old name of rb_float_value.
Definition: double.h:28
#define T_STRING
Old name of RUBY_T_STRING.
Definition: value_type.h:78
#define Qundef
Old name of RUBY_Qundef.
#define INT2FIX
Old name of RB_INT2FIX.
Definition: long.h:48
#define OBJ_FROZEN
Old name of RB_OBJ_FROZEN.
Definition: fl_type.h:137
#define rb_str_buf_new2
Old name of rb_str_buf_new_cstr.
Definition: string.h:1679
#define rb_ary_new4
Old name of rb_ary_new_from_values.
Definition: array.h:659
#define FIXABLE
Old name of RB_FIXABLE.
Definition: fixnum.h:25
#define LONG2FIX
Old name of RB_INT2FIX.
Definition: long.h:49
#define T_RATIONAL
Old name of RUBY_T_RATIONAL.
Definition: value_type.h:76
#define ALLOC_N
Old name of RB_ALLOC_N.
Definition: memory.h:394
#define NUM2DBL
Old name of rb_num2dbl.
Definition: double.h:27
#define FL_SET
Old name of RB_FL_SET.
Definition: fl_type.h:129
#define rb_ary_new3
Old name of rb_ary_new_from_args.
Definition: array.h:658
#define LONG2NUM
Old name of RB_LONG2NUM.
Definition: long.h:50
#define rb_usascii_str_new2
Old name of rb_usascii_str_new_cstr.
Definition: string.h:1680
#define Qtrue
Old name of RUBY_Qtrue.
#define ST2FIX
Old name of RB_ST2FIX.
Definition: st_data_t.h:33
#define NUM2INT
Old name of RB_NUM2INT.
Definition: int.h:44
#define Qnil
Old name of RUBY_Qnil.
#define Qfalse
Old name of RUBY_Qfalse.
#define FIX2LONG
Old name of RB_FIX2LONG.
Definition: long.h:46
#define T_ARRAY
Old name of RUBY_T_ARRAY.
Definition: value_type.h:56
#define NIL_P
Old name of RB_NIL_P.
#define ALLOCV_N
Old name of RB_ALLOCV_N.
Definition: memory.h:400
#define FL_WB_PROTECTED
Old name of RUBY_FL_WB_PROTECTED.
Definition: fl_type.h:59
#define DBL2NUM
Old name of rb_float_new.
Definition: double.h:29
#define FL_TEST
Old name of RB_FL_TEST.
Definition: fl_type.h:131
#define FL_FREEZE
Old name of RUBY_FL_FREEZE.
Definition: fl_type.h:67
#define NUM2LONG
Old name of RB_NUM2LONG.
Definition: long.h:51
#define FL_UNSET
Old name of RB_FL_UNSET.
Definition: fl_type.h:133
#define FIXNUM_P
Old name of RB_FIXNUM_P.
#define rb_ary_new2
Old name of rb_ary_new_capa.
Definition: array.h:657
#define FL_SET_RAW
Old name of RB_FL_SET_RAW.
Definition: fl_type.h:130
#define ALLOCV_END
Old name of RB_ALLOCV_END.
Definition: memory.h:401
void rb_category_warn(rb_warning_category_t category, const char *fmt,...)
Identical to rb_category_warning(), except it reports unless $VERBOSE is nil.
Definition: error.c:476
void rb_raise(VALUE exc, const char *fmt,...)
Exception entry point.
Definition: error.c:3635
void rb_bug(const char *fmt,...)
Interpreter panic switch.
Definition: error.c:1089
void rb_iter_break(void)
Breaks from a block.
Definition: vm.c:2075
VALUE rb_eFrozenError
FrozenError exception.
Definition: error.c:1407
VALUE rb_eRangeError
RangeError exception.
Definition: error.c:1412
VALUE rb_eTypeError
TypeError exception.
Definition: error.c:1408
VALUE rb_eRuntimeError
RuntimeError exception.
Definition: error.c:1406
void rb_warn(const char *fmt,...)
Identical to rb_warning(), except it reports unless $VERBOSE is nil.
Definition: error.c:466
VALUE rb_eArgError
ArgumentError exception.
Definition: error.c:1409
VALUE rb_eIndexError
IndexError exception.
Definition: error.c:1410
VALUE rb_ensure(VALUE(*b_proc)(VALUE), VALUE data1, VALUE(*e_proc)(VALUE), VALUE data2)
An equivalent to ensure clause.
Definition: eval.c:1045
void rb_warning(const char *fmt,...)
Issues a warning.
Definition: error.c:497
@ RB_WARN_CATEGORY_DEPRECATED
Warning is for deprecated features.
Definition: error.h:48
VALUE rb_cArray
Array class.
Definition: array.c:40
VALUE rb_mEnumerable
Enumerable module.
Definition: enum.c:27
VALUE rb_obj_hide(VALUE obj)
Make the object invisible from Ruby code.
Definition: object.c:104
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 ...
Definition: object.c:2111
VALUE rb_obj_frozen_p(VALUE obj)
Just calls RB_OBJ_FROZEN() inside.
Definition: object.c:1272
int rb_eql(VALUE lhs, VALUE rhs)
Checks for equality of the passed objects, in terms of Object#eql?.
Definition: object.c:192
VALUE rb_cNumeric
Numeric class.
Definition: numeric.c:196
VALUE rb_cRandom
Random class.
Definition: random.c:236
VALUE rb_obj_class(VALUE obj)
Queries the class of an object.
Definition: object.c:247
VALUE rb_inspect(VALUE obj)
Generates a human-readable textual representation of the given object.
Definition: object.c:680
double rb_num2dbl(VALUE num)
Converts an instance of rb_cNumeric into C's double.
Definition: object.c:3686
VALUE rb_equal(VALUE lhs, VALUE rhs)
This function is an optimised version of calling #==.
Definition: object.c:179
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.
Definition: object.c:865
VALUE rb_obj_freeze(VALUE obj)
Just calls rb_obj_freeze_inline() inside.
Definition: object.c:1260
#define RB_OBJ_WRITTEN(old, oldv, young)
Identical to RB_OBJ_WRITE(), except it doesn't write any values, but only a WB declaration.
Definition: gc.h:615
#define RB_OBJ_WRITE(old, slot, young)
Declaration of a "back" pointer.
Definition: gc.h:603
Encoding relates APIs.
VALUE rb_enc_associate(VALUE obj, rb_encoding *enc)
Identical to rb_enc_associate_index(), except it takes an encoding itself instead of its index.
Definition: encoding.c:1022
rb_encoding * rb_usascii_encoding(void)
Queries the encoding that represents US-ASCII.
Definition: encoding.c:1487
void rb_enc_copy(VALUE dst, VALUE src)
Destructively copies the encoding of the latter object to that of former one.
Definition: encoding.c:1149
VALUE rb_funcall(VALUE recv, ID mid, int n,...)
Calls a method.
Definition: vm_eval.c:1099
VALUE rb_funcallv(VALUE recv, ID mid, int argc, const VALUE *argv)
Identical to rb_funcall(), except it takes the method arguments as a C array.
Definition: vm_eval.c:1058
VALUE rb_call_super(int argc, const VALUE *argv)
This resembles ruby's super.
Definition: vm_eval.c:362
#define RGENGC_WB_PROTECTED_ARRAY
This is a compile-time flag to enable/disable write barrier for struct RArray.
Definition: gc.h:446
Defines RBIMPL_HAS_BUILTIN.
VALUE rb_ary_rotate(VALUE ary, long rot)
Destructively rotates the passed array in-place to towards its end.
Definition: array.c:3208
VALUE rb_ary_new_from_values(long n, const VALUE *elts)
Identical to rb_ary_new_from_args(), except how objects are passed.
Definition: array.c:786
VALUE rb_ary_cmp(VALUE lhs, VALUE rhs)
Recursively compares each elements of the two arrays one-by-one using <=>.
Definition: array.c:5461
VALUE rb_ary_rassoc(VALUE alist, VALUE key)
Identical to rb_ary_assoc(), except it scans the passed array from the opposite direction.
Definition: array.c:5190
VALUE rb_ary_concat(VALUE lhs, VALUE rhs)
Destructively appends the contents of latter into the end of former.
Definition: array.c:5074
VALUE rb_ary_assoc(VALUE alist, VALUE key)
Looks up the passed key, assuming the passed array is an alist.
Definition: array.c:5158
VALUE rb_ary_reverse(VALUE ary)
Destructively reverses the passed array in-place.
Definition: array.c:3119
VALUE rb_ary_shared_with_p(VALUE lhs, VALUE rhs)
Queries if the passed two arrays share the same backend storage.
Definition: array.c:669
VALUE rb_ary_shift(VALUE ary)
Destructively deletes an element from the beginning of the passed array and returns what was deleted.
Definition: array.c:1496
VALUE rb_ary_sort(VALUE ary)
Creates a copy of the passed array, whose elements are sorted according to their <=> result.
Definition: array.c:3487
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...
Definition: array.c:2790
VALUE rb_ary_dup(VALUE ary)
Duplicates an array.
Definition: array.c:2777
VALUE rb_ary_includes(VALUE ary, VALUE elem)
Queries if the passed array has the passed entry.
Definition: array.c:5373
VALUE rb_ary_aref(int argc, const VALUE *argv, VALUE ary)
Queries element(s) of an array.
Definition: array.c:1895
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.
Definition: array.c:875
VALUE rb_ary_each(VALUE ary)
Iteratively yields each element of the passed array to the implicitly passed block if any.
Definition: array.c:2641
VALUE rb_ary_delete_at(VALUE ary, long pos)
Destructively removes an element which resides at the specific index of the passed array.
Definition: array.c:4108
VALUE rb_ary_unshift(VALUE ary, VALUE elem)
Destructively prepends the passed item at the beginning of the passed array.
Definition: array.c:1719
VALUE rb_ary_plus(VALUE lhs, VALUE rhs)
Creates a new array, concatenating the former to the latter.
Definition: array.c:5011
VALUE rb_ary_cat(VALUE ary, const VALUE *train, long len)
Destructively appends multiple elements at the end of the array.
Definition: array.c:1397
void rb_ary_modify(VALUE ary)
Declares that the array is about to be modified.
Definition: array.c:576
VALUE rb_ary_replace(VALUE copy, VALUE orig)
Replaces the contents of the former object with the contents of the latter.
Definition: array.c:4680
VALUE rb_check_array_type(VALUE obj)
Try converting an object to its array representation using its to_ary method, if any.
Definition: array.c:1014
VALUE rb_ary_to_ary(VALUE obj)
Force converts an object to an array.
Definition: array.c:2197
VALUE rb_ary_new(void)
Allocates a new, empty array.
Definition: array.c:747
VALUE rb_ary_new_capa(long capa)
Identical to rb_ary_new(), except it additionally specifies how many rooms of objects it should alloc...
Definition: array.c:741
VALUE rb_ary_resize(VALUE ary, long len)
Expands or shrinks the passed array to the passed length.
Definition: array.c:2296
VALUE rb_ary_pop(VALUE ary)
Destructively deletes an element from the end of the passed array and returns what was deleted.
Definition: array.c:1431
VALUE rb_ary_hidden_new(long capa)
Allocates a hidden (no class) empty array.
Definition: array.c:859
VALUE rb_ary_clear(VALUE ary)
Destructively removes everything form an array.
Definition: array.c:4735
VALUE rb_ary_subseq(VALUE ary, long beg, long len)
Obtains a part of the passed array.
Definition: array.c:1765
VALUE rb_ary_push(VALUE ary, VALUE elem)
Special case of rb_ary_cat() that it adds only one element.
Definition: array.c:1384
VALUE rb_ary_freeze(VALUE obj)
Freeze an array, preventing further modifications.
Definition: array.c:648
VALUE rb_ary_to_s(VALUE ary)
Converts an array into a human-readable string.
Definition: array.c:3013
VALUE rb_ary_new_from_args(long n,...)
Constructs an array from the passed objects.
Definition: array.c:753
VALUE rb_ary_entry(VALUE ary, long off)
Queries an element of an array.
Definition: array.c:1737
VALUE rb_ary_sort_bang(VALUE ary)
Destructively sorts the passed array in-place, according to each elements' <=> result.
Definition: array.c:3394
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Identical to rb_ary_new_from_values(), except it expects exactly two parameters.
Definition: array.c:1001
void rb_mem_clear(VALUE *buf, long len)
Fills the memory region with a series of RUBY_Qnil.
Definition: array.c:294
VALUE rb_ary_delete(VALUE ary, VALUE elem)
Destructively removes elements from the passed array, so that there would be no elements inside that ...
Definition: array.c:4054
VALUE rb_ary_join(VALUE ary, VALUE sep)
Recursively stringises the elements of the passed array, flattens that result, then joins the sequenc...
Definition: array.c:2891
void rb_ary_store(VALUE ary, long key, VALUE val)
Destructively stores the passed value to the passed array's passed index.
Definition: array.c:1207
VALUE rb_big_plus(VALUE x, VALUE y)
Performs addition of the passed two objects.
Definition: bignum.c:5852
double rb_big2dbl(VALUE x)
Converts a bignum into C's double.
Definition: bignum.c:5346
int rb_cmpint(VALUE val, VALUE a, VALUE b)
Canonicalises the passed val, which is the return value of a <=> b, into C's {-1, 0,...
Definition: bignum.c:2965
VALUE rb_arithmetic_sequence_beg_len_step(VALUE as, long *begp, long *lenp, long *stepp, long len, int err)
Identical to rb_range_beg_len(), except it takes an instance of Enumerator::ArithmericSequence.
Definition: enumerator.c:3848
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn)
This roughly resembles return enum_for(__callee__) unless block_given?.
Definition: enumerator.h:206
#define RETURN_ENUMERATOR(obj, argc, argv)
Identical to RETURN_SIZED_ENUMERATOR(), except its size is unknown.
Definition: enumerator.h:239
#define UNLIMITED_ARGUMENTS
This macro is used in conjunction with rb_check_arity().
Definition: error.h:35
static int rb_check_arity(int argc, int min, int max)
Ensures that the passed integer is in the passed range.
Definition: error.h:284
void rb_obj_call_init_kw(VALUE, int, const VALUE *, int)
Identical to rb_obj_call_init(), except you can specify how to handle the last element of the given a...
Definition: eval.c:1728
void rb_hash_foreach(VALUE hash, int(*func)(VALUE key, VALUE val, VALUE arg), VALUE arg)
Iterates over a hash.
VALUE rb_hash_delete(VALUE hash, VALUE key)
Deletes the passed key from the passed hash table, if any.
Definition: hash.c:2353
VALUE rb_hash_aref(VALUE hash, VALUE key)
Queries the given key in the given hash table.
Definition: hash.c:2073
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
Inserts or replaces ("upsert"s) the objects into the given hash table.
Definition: hash.c:2893
VALUE rb_hash(VALUE obj)
Calculates a message authentication code of the passed object.
Definition: hash.c:267
VALUE rb_hash_clear(VALUE hash)
Swipes everything out of the passed hash table.
Definition: hash.c:2820
VALUE rb_output_fs
The field separator character for outputs, or the $,.
Definition: io.c:204
VALUE rb_int_positive_pow(long x, unsigned long y)
Raises the passed x to the power of y.
Definition: numeric.c:4559
VALUE rb_range_beg_len(VALUE range, long *begp, long *lenp, long len, int err)
Deconstructs a numerical range.
Definition: range.c:1842
#define rb_hash_uint(h, i)
Just another name of st_hash_uint.
Definition: string.h:942
#define rb_hash_end(h)
Just another name of st_hash_end.
Definition: string.h:945
VALUE rb_usascii_str_new(const char *ptr, long len)
Identical to rb_str_new(), except it generates a string of "US ASCII" encoding.
Definition: string.c:1056
VALUE rb_usascii_str_new_cstr(const char *ptr)
Identical to rb_str_new_cstr(), except it generates a string of "US ASCII" encoding.
Definition: string.c:1086
VALUE rb_str_buf_cat2(VALUE, const char *)
Just another name of rb_str_cat_cstr.
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.
Definition: string.c:3643
void rb_str_set_len(VALUE str, long len)
Overwrites the length of the string.
Definition: string.c:3269
st_index_t rb_hash_start(st_index_t i)
Starts a series of hashing.
Definition: random.c:1746
int rb_str_cmp(VALUE lhs, VALUE rhs)
Compares two strings, as in strcmp(3).
Definition: string.c:4102
VALUE rb_str_new(const char *ptr, long len)
Allocates an instance of rb_cString.
Definition: string.c:1050
VALUE rb_check_string_type(VALUE obj)
Try converting an object to its stringised representation using its to_str method,...
Definition: string.c:2854
VALUE rb_str_buf_new(long capa)
Allocates a "string buffer".
Definition: string.c:1643
VALUE rb_obj_as_string(VALUE obj)
Try converting an object to its stringised representation using its to_s method, if any.
Definition: string.c:1786
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.
Definition: vm_method.c:2955
void rb_define_alloc_func(VALUE klass, rb_alloc_func_t func)
Sets the allocator function of a class.
ID rb_intern(const char *name)
Finds or creates a symbol of the given name.
Definition: symbol.c:823
int capa
Designed capacity of the buffer.
Definition: io.h:11
char * ptr
Pointer to the underlying memory region, of at least capa bytes.
Definition: io.h:2
int len
Length of the buffer.
Definition: io.h:8
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.
Definition: iterator.h:58
VALUE rb_block_call(VALUE obj, ID mid, int argc, const VALUE *argv, rb_block_call_func_t proc, VALUE data2)
Identical to rb_funcallv(), except it additionally passes a function as a block.
Definition: vm_eval.c:1534
VALUE rb_yield_values(int n,...)
Identical to rb_yield(), except it takes variadic number of parameters and pass them to the block.
Definition: vm_eval.c:1366
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...
Definition: vm_eval.c:1388
VALUE rb_yield(VALUE val)
Yields the block.
Definition: vm_eval.c:1354
#define RBIMPL_ATTR_MAYBE_UNUSED()
Wraps (or simulates) [[maybe_unused]]
Definition: maybe_unused.h:33
#define MEMCPY(p1, p2, type, n)
Handy macro to call memcpy.
Definition: memory.h:367
#define MEMZERO(p, type, n)
Handy macro to erase a region of memory.
Definition: memory.h:355
#define RB_GC_GUARD(v)
Prevents premature destruction of local objects.
Definition: memory.h:162
#define MEMMOVE(p1, p2, type, n)
Handy macro to call memmove.
Definition: memory.h:379
static VALUE * RARRAY_PTR(VALUE ary)
Wild use of a C pointer.
Definition: rarray.h:366
#define RARRAY_LEN
Just another name of rb_array_len.
Definition: rarray.h:51
#define RARRAY(obj)
Convenient casting macro.
Definition: rarray.h:44
static void RARRAY_ASET(VALUE ary, long i, VALUE v)
Assigns an object in an array.
Definition: rarray.h:386
#define RARRAY_PTR_USE(ary, ptr_name, expr)
Declares a section of code where raw pointers are used.
Definition: rarray.h:348
#define RARRAY_AREF(a, i)
Definition: rarray.h:403
#define RARRAY_CONST_PTR
Just another name of rb_array_const_ptr.
Definition: rarray.h:52
#define RBASIC(obj)
Convenient casting macro.
Definition: rbasic.h:40
void(* RUBY_DATA_FUNC)(void *)
This is the type of callbacks registered to RData.
Definition: rdata.h:104
#define RHASH_SIZE(h)
Queries the size of the hash.
Definition: rhash.h:69
#define StringValue(v)
Ensures that the parameter object is a String.
Definition: rstring.h:66
static long RSTRING_LEN(VALUE str)
Queries the length of the string.
Definition: rstring.h:367
#define RTYPEDDATA_DATA(v)
Convenient getter macro.
Definition: rtypeddata.h:102
#define TypedData_Wrap_Struct(klass, data_type, sval)
Converts sval, a pointer to your struct, into a Ruby object.
Definition: rtypeddata.h:449
#define RB_PASS_CALLED_KEYWORDS
Pass keywords if current method is called with keywords, useful for argument delegation.
Definition: scan_args.h:78
#define RTEST
This is an old name of RB_TEST.
Ruby's array.
Definition: rarray.h:128
struct RArray::@43::@44 heap
Arrays that use separated memory region for elements use this pattern.
struct RBasic basic
Basic part, including flags and class.
Definition: rarray.h:131
const VALUE shared_root
Parent of the array.
Definition: rarray.h:166
const VALUE ary[1]
Embedded elements.
Definition: rarray.h:188
union RArray::@43 as
Array's specific fields.
VALUE flags
Per-object flags.
Definition: rbasic.h:75
This is the struct that holds necessary info for a struct.
Definition: rtypeddata.h:200
const char * wrap_struct_name
Name of structs of this kind.
Definition: rtypeddata.h:207
Definition: st.h:79
intptr_t SIGNED_VALUE
A signed integer type that has the same width with VALUE.
Definition: value.h:63
uintptr_t VALUE
Type that represents a Ruby object.
Definition: value.h:40
static bool RB_FLOAT_TYPE_P(VALUE obj)
Queries if the object is an instance of rb_cFloat.
Definition: value_type.h:264
static bool RB_TYPE_P(VALUE obj, enum ruby_value_type t)
Queries if the given object is of given type.
Definition: value_type.h:376