Ruby  2.7.1p83(2020-03-31revisiona0c7c23c9cec0d0ffcba012279cd652d28ad5bf3)
array.c
Go to the documentation of this file.
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 #include "ruby/encoding.h"
14 #include "ruby/util.h"
15 #include "ruby/st.h"
16 #include "probes.h"
17 #include "id.h"
18 #include "debug_counter.h"
19 #include "transient_heap.h"
20 #include "internal.h"
21 
22 #if !ARRAY_DEBUG
23 # define NDEBUG
24 #endif
25 #include "ruby_assert.h"
26 
28 
29 /* for OPTIMIZED_CMP: */
30 #define id_cmp idCmp
31 
32 #define ARY_DEFAULT_SIZE 16
33 #define ARY_MAX_SIZE (LONG_MAX / (int)sizeof(VALUE))
34 #define SMALL_ARRAY_LEN 16
35 
36 static int
37 should_be_T_ARRAY(VALUE ary)
38 {
39  return RB_TYPE_P(ary, T_ARRAY);
40 }
41 
42 static int
43 should_not_be_shared_and_embedded(VALUE ary)
44 {
45  return !FL_TEST((ary), ELTS_SHARED) || !FL_TEST((ary), RARRAY_EMBED_FLAG);
46 }
47 
48 #define ARY_SHARED_P(ary) \
49  (assert(should_be_T_ARRAY((VALUE)(ary))), \
50  assert(should_not_be_shared_and_embedded((VALUE)ary)), \
51  FL_TEST_RAW((ary),ELTS_SHARED)!=0)
52 
53 #define ARY_EMBED_P(ary) \
54  (assert(should_be_T_ARRAY((VALUE)(ary))), \
55  assert(should_not_be_shared_and_embedded((VALUE)ary)), \
56  FL_TEST_RAW((ary), RARRAY_EMBED_FLAG) != 0)
57 
58 #define ARY_HEAP_PTR(a) (assert(!ARY_EMBED_P(a)), RARRAY(a)->as.heap.ptr)
59 #define ARY_HEAP_LEN(a) (assert(!ARY_EMBED_P(a)), RARRAY(a)->as.heap.len)
60 #define ARY_HEAP_CAPA(a) (assert(!ARY_EMBED_P(a)), assert(!ARY_SHARED_ROOT_P(a)), \
61  RARRAY(a)->as.heap.aux.capa)
62 
63 #define ARY_EMBED_PTR(a) (assert(ARY_EMBED_P(a)), RARRAY(a)->as.ary)
64 #define ARY_EMBED_LEN(a) \
65  (assert(ARY_EMBED_P(a)), \
66  (long)((RBASIC(a)->flags >> RARRAY_EMBED_LEN_SHIFT) & \
67  (RARRAY_EMBED_LEN_MASK >> RARRAY_EMBED_LEN_SHIFT)))
68 #define ARY_HEAP_SIZE(a) (assert(!ARY_EMBED_P(a)), assert(ARY_OWNS_HEAP_P(a)), ARY_CAPA(a) * sizeof(VALUE))
69 
70 #define ARY_OWNS_HEAP_P(a) (assert(should_be_T_ARRAY((VALUE)(a))), \
71  !FL_TEST_RAW((a), ELTS_SHARED|RARRAY_EMBED_FLAG))
72 
73 #define FL_SET_EMBED(a) do { \
74  assert(!ARY_SHARED_P(a)); \
75  FL_SET((a), RARRAY_EMBED_FLAG); \
76  RARY_TRANSIENT_UNSET(a); \
77  ary_verify(a); \
78 } while (0)
79 
80 #define FL_UNSET_EMBED(ary) FL_UNSET((ary), RARRAY_EMBED_FLAG|RARRAY_EMBED_LEN_MASK)
81 #define FL_SET_SHARED(ary) do { \
82  assert(!ARY_EMBED_P(ary)); \
83  FL_SET((ary), ELTS_SHARED); \
84 } while (0)
85 #define FL_UNSET_SHARED(ary) FL_UNSET((ary), ELTS_SHARED)
86 
87 #define ARY_SET_PTR(ary, p) do { \
88  assert(!ARY_EMBED_P(ary)); \
89  assert(!OBJ_FROZEN(ary)); \
90  RARRAY(ary)->as.heap.ptr = (p); \
91 } while (0)
92 #define ARY_SET_EMBED_LEN(ary, n) do { \
93  long tmp_n = (n); \
94  assert(ARY_EMBED_P(ary)); \
95  assert(!OBJ_FROZEN(ary)); \
96  RBASIC(ary)->flags &= ~RARRAY_EMBED_LEN_MASK; \
97  RBASIC(ary)->flags |= (tmp_n) << RARRAY_EMBED_LEN_SHIFT; \
98 } while (0)
99 #define ARY_SET_HEAP_LEN(ary, n) do { \
100  assert(!ARY_EMBED_P(ary)); \
101  RARRAY(ary)->as.heap.len = (n); \
102 } while (0)
103 #define ARY_SET_LEN(ary, n) do { \
104  if (ARY_EMBED_P(ary)) { \
105  ARY_SET_EMBED_LEN((ary), (n)); \
106  } \
107  else { \
108  ARY_SET_HEAP_LEN((ary), (n)); \
109  } \
110  assert(RARRAY_LEN(ary) == (n)); \
111 } while (0)
112 #define ARY_INCREASE_PTR(ary, n) do { \
113  assert(!ARY_EMBED_P(ary)); \
114  assert(!OBJ_FROZEN(ary)); \
115  RARRAY(ary)->as.heap.ptr += (n); \
116 } while (0)
117 #define ARY_INCREASE_LEN(ary, n) do { \
118  assert(!OBJ_FROZEN(ary)); \
119  if (ARY_EMBED_P(ary)) { \
120  ARY_SET_EMBED_LEN((ary), RARRAY_LEN(ary)+(n)); \
121  } \
122  else { \
123  RARRAY(ary)->as.heap.len += (n); \
124  } \
125 } while (0)
126 
127 #define ARY_CAPA(ary) (ARY_EMBED_P(ary) ? RARRAY_EMBED_LEN_MAX : \
128  ARY_SHARED_ROOT_P(ary) ? RARRAY_LEN(ary) : ARY_HEAP_CAPA(ary))
129 #define ARY_SET_CAPA(ary, n) do { \
130  assert(!ARY_EMBED_P(ary)); \
131  assert(!ARY_SHARED_P(ary)); \
132  assert(!OBJ_FROZEN(ary)); \
133  RARRAY(ary)->as.heap.aux.capa = (n); \
134 } while (0)
135 
136 #define ARY_SHARED_ROOT(ary) (assert(ARY_SHARED_P(ary)), RARRAY(ary)->as.heap.aux.shared_root)
137 #define ARY_SET_SHARED(ary, value) do { \
138  const VALUE _ary_ = (ary); \
139  const VALUE _value_ = (value); \
140  assert(!ARY_EMBED_P(_ary_)); \
141  assert(ARY_SHARED_P(_ary_)); \
142  assert(ARY_SHARED_ROOT_P(_value_)); \
143  RB_OBJ_WRITE(_ary_, &RARRAY(_ary_)->as.heap.aux.shared_root, _value_); \
144 } while (0)
145 #define RARRAY_SHARED_ROOT_FLAG FL_USER5
146 #define ARY_SHARED_ROOT_P(ary) (assert(should_be_T_ARRAY((VALUE)(ary))), \
147  FL_TEST_RAW((ary), RARRAY_SHARED_ROOT_FLAG))
148 #define ARY_SHARED_ROOT_REFCNT(ary) \
149  (assert(ARY_SHARED_ROOT_P(ary)), RARRAY(ary)->as.heap.aux.capa)
150 #define ARY_SHARED_ROOT_OCCUPIED(ary) (ARY_SHARED_ROOT_REFCNT(ary) == 1)
151 #define ARY_SET_SHARED_ROOT_REFCNT(ary, value) do { \
152  assert(ARY_SHARED_ROOT_P(ary)); \
153  RARRAY(ary)->as.heap.aux.capa = (value); \
154 } while (0)
155 #define FL_SET_SHARED_ROOT(ary) do { \
156  assert(!ARY_EMBED_P(ary)); \
157  assert(!RARRAY_TRANSIENT_P(ary)); \
158  FL_SET((ary), RARRAY_SHARED_ROOT_FLAG); \
159 } while (0)
160 
161 static inline void
162 ARY_SET(VALUE a, long i, VALUE v)
163 {
164  assert(!ARY_SHARED_P(a));
165  assert(!OBJ_FROZEN(a));
166 
167  RARRAY_ASET(a, i, v);
168 }
169 #undef RARRAY_ASET
170 
171 
172 #if ARRAY_DEBUG
173 #define ary_verify(ary) ary_verify_(ary, __FILE__, __LINE__)
174 
175 static VALUE
176 ary_verify_(VALUE ary, const char *file, int line)
177 {
178  assert(RB_TYPE_P(ary, T_ARRAY));
179 
180  if (FL_TEST(ary, ELTS_SHARED)) {
181  VALUE root = RARRAY(ary)->as.heap.aux.shared_root;
182  const VALUE *ptr = ARY_HEAP_PTR(ary);
183  const VALUE *root_ptr = RARRAY_CONST_PTR_TRANSIENT(root);
184  long len = ARY_HEAP_LEN(ary), root_len = RARRAY_LEN(root);
186  assert(root_ptr <= ptr && ptr + len <= root_ptr + root_len);
187  ary_verify(root);
188  }
189  else if (ARY_EMBED_P(ary)) {
190  assert(!RARRAY_TRANSIENT_P(ary));
191  assert(!ARY_SHARED_P(ary));
193  }
194  else {
195 #if 1
196  const VALUE *ptr = RARRAY_CONST_PTR_TRANSIENT(ary);
197  long i, len = RARRAY_LEN(ary);
198  volatile VALUE v;
199  if (len > 1) len = 1; /* check only HEAD */
200  for (i=0; i<len; i++) {
201  v = ptr[i]; /* access check */
202  }
203  v = v;
204 #endif
205  }
206 
207  if (RARRAY_TRANSIENT_P(ary)) {
209  }
210 
212 
213  return ary;
214 }
215 
216 void
217 rb_ary_verify(VALUE ary)
218 {
219  ary_verify(ary);
220 }
221 #else
222 #define ary_verify(ary) ((void)0)
223 #endif
224 
225 VALUE *
227 {
228 #if ARRAY_DEBUG
230 #endif
231  return (VALUE *)RARRAY_CONST_PTR_TRANSIENT(ary);
232 }
233 
234 void
236 {
237 #if ARRAY_DEBUG
239 #endif
240 }
241 
242 void
244 {
245  while (size--) {
246  *mem++ = Qnil;
247  }
248 }
249 
250 static void
251 ary_mem_clear(VALUE ary, long beg, long size)
252 {
254  rb_mem_clear(ptr + beg, size);
255  });
256 }
257 
258 static inline void
259 memfill(register VALUE *mem, register long size, register VALUE val)
260 {
261  while (size--) {
262  *mem++ = val;
263  }
264 }
265 
266 static void
267 ary_memfill(VALUE ary, long beg, long size, VALUE val)
268 {
270  memfill(ptr + beg, size, val);
271  RB_OBJ_WRITTEN(ary, Qundef, val);
272  });
273 }
274 
275 static void
276 ary_memcpy0(VALUE ary, long beg, long argc, const VALUE *argv, VALUE buff_owner_ary)
277 {
278  assert(!ARY_SHARED_P(buff_owner_ary));
279 
280  if (argc > (int)(128/sizeof(VALUE)) /* is magic number (cache line size) */) {
281  rb_gc_writebarrier_remember(buff_owner_ary);
283  MEMCPY(ptr+beg, argv, VALUE, argc);
284  });
285  }
286  else {
287  int i;
289  for (i=0; i<argc; i++) {
290  RB_OBJ_WRITE(buff_owner_ary, &ptr[i+beg], argv[i]);
291  }
292  });
293  }
294 }
295 
296 static void
297 ary_memcpy(VALUE ary, long beg, long argc, const VALUE *argv)
298 {
299  ary_memcpy0(ary, beg, argc, argv, ary);
300 }
301 
302 static VALUE *
303 ary_heap_alloc(VALUE ary, size_t capa)
304 {
305  VALUE *ptr = rb_transient_heap_alloc(ary, sizeof(VALUE) * capa);
306 
307  if (ptr != NULL) {
308  RARY_TRANSIENT_SET(ary);
309  }
310  else {
312  ptr = ALLOC_N(VALUE, capa);
313  }
314 
315  return ptr;
316 }
317 
318 static void
319 ary_heap_free_ptr(VALUE ary, const VALUE *ptr, long size)
320 {
321  if (RARRAY_TRANSIENT_P(ary)) {
322  /* ignore it */
323  }
324  else {
325  ruby_sized_xfree((void *)ptr, size);
326  }
327 }
328 
329 static void
330 ary_heap_free(VALUE ary)
331 {
332  if (RARRAY_TRANSIENT_P(ary)) {
334  }
335  else {
336  ary_heap_free_ptr(ary, ARY_HEAP_PTR(ary), ARY_HEAP_SIZE(ary));
337  }
338 }
339 
340 static void
341 ary_heap_realloc(VALUE ary, size_t new_capa)
342 {
343  size_t old_capa = ARY_HEAP_CAPA(ary);
344 
345  if (RARRAY_TRANSIENT_P(ary)) {
346  if (new_capa <= old_capa) {
347  /* do nothing */
348  }
349  else {
350  VALUE *new_ptr = rb_transient_heap_alloc(ary, sizeof(VALUE) * new_capa);
351 
352  if (new_ptr == NULL) {
353  new_ptr = ALLOC_N(VALUE, new_capa);
355  }
356 
357  MEMCPY(new_ptr, ARY_HEAP_PTR(ary), VALUE, old_capa);
358  ARY_SET_PTR(ary, new_ptr);
359  }
360  }
361  else {
362  SIZED_REALLOC_N(RARRAY(ary)->as.heap.ptr, VALUE, new_capa, old_capa);
363  }
364  ary_verify(ary);
365 }
366 
367 #if USE_TRANSIENT_HEAP
368 static inline void
369 rb_ary_transient_heap_evacuate_(VALUE ary, int transient, int promote)
370 {
371  if (transient) {
372  VALUE *new_ptr;
373  const VALUE *old_ptr = ARY_HEAP_PTR(ary);
374  long capa = ARY_HEAP_CAPA(ary);
375  long len = ARY_HEAP_LEN(ary);
376 
377  if (ARY_SHARED_ROOT_P(ary)) {
378  capa = len;
379  }
380 
381  assert(ARY_OWNS_HEAP_P(ary));
383  assert(!ARY_PTR_USING_P(ary));
384 
385  if (promote) {
386  new_ptr = ALLOC_N(VALUE, capa);
388  }
389  else {
390  new_ptr = ary_heap_alloc(ary, capa);
391  }
392 
393  MEMCPY(new_ptr, old_ptr, VALUE, capa);
394  /* do not use ARY_SET_PTR() because they assert !frozen */
395  RARRAY(ary)->as.heap.ptr = new_ptr;
396  }
397 
398  ary_verify(ary);
399 }
400 
401 void
403 {
404  rb_ary_transient_heap_evacuate_(ary, RARRAY_TRANSIENT_P(ary), promote);
405 }
406 
407 void
409 {
411  rb_ary_transient_heap_evacuate_(ary, TRUE, TRUE);
412 }
413 #else
414 void
416 {
417  /* do nothing */
418 }
419 #endif
420 
421 static void
422 ary_resize_capa(VALUE ary, long capacity)
423 {
424  assert(RARRAY_LEN(ary) <= capacity);
425  assert(!OBJ_FROZEN(ary));
426  assert(!ARY_SHARED_P(ary));
427 
428  if (capacity > RARRAY_EMBED_LEN_MAX) {
429  if (ARY_EMBED_P(ary)) {
430  long len = ARY_EMBED_LEN(ary);
431  VALUE *ptr = ary_heap_alloc(ary, capacity);
432 
433  MEMCPY(ptr, ARY_EMBED_PTR(ary), VALUE, len);
434  FL_UNSET_EMBED(ary);
435  ARY_SET_PTR(ary, ptr);
436  ARY_SET_HEAP_LEN(ary, len);
437  }
438  else {
439  ary_heap_realloc(ary, capacity);
440  }
441  ARY_SET_CAPA(ary, capacity);
442  }
443  else {
444  if (!ARY_EMBED_P(ary)) {
445  long len = ARY_HEAP_LEN(ary);
446  long old_capa = ARY_HEAP_CAPA(ary);
447  const VALUE *ptr = ARY_HEAP_PTR(ary);
448 
449  if (len > capacity) len = capacity;
450  MEMCPY((VALUE *)RARRAY(ary)->as.ary, ptr, VALUE, len);
451  ary_heap_free_ptr(ary, ptr, old_capa);
452 
453  FL_SET_EMBED(ary);
454  ARY_SET_LEN(ary, len);
455  }
456  }
457 
458  ary_verify(ary);
459 }
460 
461 static inline void
462 ary_shrink_capa(VALUE ary)
463 {
464  long capacity = ARY_HEAP_LEN(ary);
465  long old_capa = ARY_HEAP_CAPA(ary);
466  assert(!ARY_SHARED_P(ary));
467  assert(old_capa >= capacity);
468  if (old_capa > capacity) ary_heap_realloc(ary, capacity);
469 
470  ary_verify(ary);
471 }
472 
473 static void
474 ary_double_capa(VALUE ary, long min)
475 {
476  long new_capa = ARY_CAPA(ary) / 2;
477 
478  if (new_capa < ARY_DEFAULT_SIZE) {
479  new_capa = ARY_DEFAULT_SIZE;
480  }
481  if (new_capa >= ARY_MAX_SIZE - min) {
482  new_capa = (ARY_MAX_SIZE - min) / 2;
483  }
484  new_capa += min;
485  ary_resize_capa(ary, new_capa);
486 
487  ary_verify(ary);
488 }
489 
490 static void
491 rb_ary_decrement_share(VALUE shared_root)
492 {
493  if (shared_root) {
494  long num = ARY_SHARED_ROOT_REFCNT(shared_root) - 1;
495  if (num == 0) {
496  rb_ary_free(shared_root);
497  rb_gc_force_recycle(shared_root);
498  }
499  else if (num > 0) {
500  ARY_SET_SHARED_ROOT_REFCNT(shared_root, num);
501  }
502  }
503 }
504 
505 static void
506 rb_ary_unshare(VALUE ary)
507 {
508  VALUE shared_root = RARRAY(ary)->as.heap.aux.shared_root;
509  rb_ary_decrement_share(shared_root);
510  FL_UNSET_SHARED(ary);
511 }
512 
513 static inline void
514 rb_ary_unshare_safe(VALUE ary)
515 {
516  if (ARY_SHARED_P(ary) && !ARY_EMBED_P(ary)) {
517  rb_ary_unshare(ary);
518  }
519 }
520 
521 static VALUE
522 rb_ary_increment_share(VALUE shared_root)
523 {
524  long num = ARY_SHARED_ROOT_REFCNT(shared_root);
525  if (num >= 0) {
526  ARY_SET_SHARED_ROOT_REFCNT(shared_root, num + 1);
527  }
528  return shared_root;
529 }
530 
531 static void
532 rb_ary_set_shared(VALUE ary, VALUE shared_root)
533 {
534  rb_ary_increment_share(shared_root);
535  FL_SET_SHARED(ary);
536  RB_DEBUG_COUNTER_INC(obj_ary_shared_create);
537  ARY_SET_SHARED(ary, shared_root);
538 }
539 
540 static inline void
541 rb_ary_modify_check(VALUE ary)
542 {
543  rb_check_frozen(ary);
544  ary_verify(ary);
545 }
546 
547 void
549 {
550  rb_ary_modify_check(ary);
551  if (ARY_SHARED_P(ary)) {
552  long shared_len, len = RARRAY_LEN(ary);
553  VALUE shared_root = ARY_SHARED_ROOT(ary);
554 
555  ary_verify(shared_root);
556 
557  if (len <= RARRAY_EMBED_LEN_MAX) {
558  const VALUE *ptr = ARY_HEAP_PTR(ary);
559  FL_UNSET_SHARED(ary);
560  FL_SET_EMBED(ary);
561  MEMCPY((VALUE *)ARY_EMBED_PTR(ary), ptr, VALUE, len);
562  rb_ary_decrement_share(shared_root);
563  ARY_SET_EMBED_LEN(ary, len);
564  }
565  else if (ARY_SHARED_ROOT_OCCUPIED(shared_root) && len > ((shared_len = RARRAY_LEN(shared_root))>>1)) {
566  long shift = RARRAY_CONST_PTR_TRANSIENT(ary) - RARRAY_CONST_PTR_TRANSIENT(shared_root);
567  FL_UNSET_SHARED(ary);
568  ARY_SET_PTR(ary, RARRAY_CONST_PTR_TRANSIENT(shared_root));
569  ARY_SET_CAPA(ary, shared_len);
571  MEMMOVE(ptr, ptr+shift, VALUE, len);
572  });
573  FL_SET_EMBED(shared_root);
574  rb_ary_decrement_share(shared_root);
575  }
576  else {
577  VALUE *ptr = ary_heap_alloc(ary, len);
578  MEMCPY(ptr, ARY_HEAP_PTR(ary), VALUE, len);
579  rb_ary_unshare(ary);
580  ARY_SET_CAPA(ary, len);
581  ARY_SET_PTR(ary, ptr);
582  }
583 
585  }
586  ary_verify(ary);
587 }
588 
589 static VALUE
590 ary_ensure_room_for_push(VALUE ary, long add_len)
591 {
592  long old_len = RARRAY_LEN(ary);
593  long new_len = old_len + add_len;
594  long capa;
595 
596  if (old_len > ARY_MAX_SIZE - add_len) {
597  rb_raise(rb_eIndexError, "index %ld too big", new_len);
598  }
599  if (ARY_SHARED_P(ary)) {
600  if (new_len > RARRAY_EMBED_LEN_MAX) {
601  VALUE shared_root = ARY_SHARED_ROOT(ary);
602  if (ARY_SHARED_ROOT_OCCUPIED(shared_root)) {
603  if (ARY_HEAP_PTR(ary) - RARRAY_CONST_PTR_TRANSIENT(shared_root) + new_len <= RARRAY_LEN(shared_root)) {
604  rb_ary_modify_check(ary);
605 
606  ary_verify(ary);
607  ary_verify(shared_root);
608  return shared_root;
609  }
610  else {
611  /* if array is shared, then it is likely it participate in push/shift pattern */
612  rb_ary_modify(ary);
613  capa = ARY_CAPA(ary);
614  if (new_len > capa - (capa >> 6)) {
615  ary_double_capa(ary, new_len);
616  }
617  ary_verify(ary);
618  return ary;
619  }
620  }
621  }
622  ary_verify(ary);
623  rb_ary_modify(ary);
624  }
625  else {
626  rb_ary_modify_check(ary);
627  }
628  capa = ARY_CAPA(ary);
629  if (new_len > capa) {
630  ary_double_capa(ary, new_len);
631  }
632 
633  ary_verify(ary);
634  return ary;
635 }
636 
637 /*
638  * call-seq:
639  * ary.freeze -> ary
640  *
641  * Calls Object#freeze on +ary+ to prevent any further
642  * modification. A RuntimeError will be raised if a modification
643  * attempt is made.
644  *
645  */
646 
647 VALUE
649 {
650  return rb_obj_freeze(ary);
651 }
652 
653 /* This can be used to take a snapshot of an array (with
654  e.g. rb_ary_replace) and check later whether the array has been
655  modified from the snapshot. The snapshot is cheap, though if
656  something does modify the array it will pay the cost of copying
657  it. If Array#pop or Array#shift has been called, the array will
658  be still shared with the snapshot, but the array length will
659  differ. */
660 VALUE
662 {
663  if (!ARY_EMBED_P(ary1) && ARY_SHARED_P(ary1) &&
664  !ARY_EMBED_P(ary2) && ARY_SHARED_P(ary2) &&
665  RARRAY(ary1)->as.heap.aux.shared_root == RARRAY(ary2)->as.heap.aux.shared_root &&
666  RARRAY(ary1)->as.heap.len == RARRAY(ary2)->as.heap.len) {
667  return Qtrue;
668  }
669  return Qfalse;
670 }
671 
672 static VALUE
673 ary_alloc(VALUE klass)
674 {
676  /* Created array is:
677  * FL_SET_EMBED((VALUE)ary);
678  * ARY_SET_EMBED_LEN((VALUE)ary, 0);
679  */
680  return (VALUE)ary;
681 }
682 
683 static VALUE
684 empty_ary_alloc(VALUE klass)
685 {
686  RUBY_DTRACE_CREATE_HOOK(ARRAY, 0);
687  return ary_alloc(klass);
688 }
689 
690 static VALUE
691 ary_new(VALUE klass, long capa)
692 {
693  VALUE ary,*ptr;
694 
695  if (capa < 0) {
696  rb_raise(rb_eArgError, "negative array size (or size too big)");
697  }
698  if (capa > ARY_MAX_SIZE) {
699  rb_raise(rb_eArgError, "array size too big");
700  }
701 
702  RUBY_DTRACE_CREATE_HOOK(ARRAY, capa);
703 
704  ary = ary_alloc(klass);
705  if (capa > RARRAY_EMBED_LEN_MAX) {
706  ptr = ary_heap_alloc(ary, capa);
707  FL_UNSET_EMBED(ary);
708  ARY_SET_PTR(ary, ptr);
709  ARY_SET_CAPA(ary, capa);
710  ARY_SET_HEAP_LEN(ary, 0);
711  }
712 
713  return ary;
714 }
715 
716 VALUE
717 rb_ary_new_capa(long capa)
718 {
719  return ary_new(rb_cArray, capa);
720 }
721 
722 VALUE
724 {
726 }
727 
728 VALUE
730 {
731  va_list ar;
732  VALUE ary;
733  long i;
734 
735  ary = rb_ary_new2(n);
736 
737  va_start(ar, n);
738  for (i=0; i<n; i++) {
739  ARY_SET(ary, i, va_arg(ar, VALUE));
740  }
741  va_end(ar);
742 
743  ARY_SET_LEN(ary, n);
744  return ary;
745 }
746 
749 {
750  VALUE ary;
751 
752  ary = ary_new(klass, n);
753  if (n > 0 && elts) {
754  ary_memcpy(ary, 0, n, elts);
755  ARY_SET_LEN(ary, n);
756  }
757 
758  return ary;
759 }
760 
761 VALUE
762 rb_ary_new_from_values(long n, const VALUE *elts)
763 {
764  return rb_ary_tmp_new_from_values(rb_cArray, n, elts);
765 }
766 
767 VALUE
768 rb_ary_tmp_new(long capa)
769 {
770  VALUE ary = ary_new(0, capa);
772  return ary;
773 }
774 
775 VALUE
777 {
778  VALUE ary = ary_new(0, capa);
779  ary_memfill(ary, 0, capa, Qnil);
780  ARY_SET_LEN(ary, capa);
782  return ary;
783 }
784 
785 void
787 {
788  if (ARY_OWNS_HEAP_P(ary)) {
789  if (USE_DEBUG_COUNTER &&
790  !ARY_SHARED_ROOT_P(ary) &&
791  ARY_HEAP_CAPA(ary) > RARRAY_LEN(ary)) {
792  RB_DEBUG_COUNTER_INC(obj_ary_extracapa);
793  }
794 
795  if (RARRAY_TRANSIENT_P(ary)) {
796  RB_DEBUG_COUNTER_INC(obj_ary_transient);
797  }
798  else {
799  RB_DEBUG_COUNTER_INC(obj_ary_ptr);
800  ary_heap_free(ary);
801  }
802  }
803  else {
804  RB_DEBUG_COUNTER_INC(obj_ary_embed);
805  }
806 
807  if (ARY_SHARED_P(ary)) {
808  RB_DEBUG_COUNTER_INC(obj_ary_shared);
809  }
810  if (ARY_SHARED_ROOT_P(ary) && ARY_SHARED_ROOT_OCCUPIED(ary)) {
811  RB_DEBUG_COUNTER_INC(obj_ary_shared_root_occupied);
812  }
813 }
814 
815 RUBY_FUNC_EXPORTED size_t
817 {
818  if (ARY_OWNS_HEAP_P(ary)) {
819  return ARY_CAPA(ary) * sizeof(VALUE);
820  }
821  else {
822  return 0;
823  }
824 }
825 
826 static inline void
827 ary_discard(VALUE ary)
828 {
829  rb_ary_free(ary);
830  RBASIC(ary)->flags |= RARRAY_EMBED_FLAG;
832 }
833 
834 static VALUE
835 ary_make_shared(VALUE ary)
836 {
837  assert(!ARY_EMBED_P(ary));
838  ary_verify(ary);
839 
840  if (ARY_SHARED_P(ary)) {
841  return ARY_SHARED_ROOT(ary);
842  }
843  else if (ARY_SHARED_ROOT_P(ary)) {
844  return ary;
845  }
846  else if (OBJ_FROZEN(ary)) {
848  ary_shrink_capa(ary);
849  FL_SET_SHARED_ROOT(ary);
851  return ary;
852  }
853  else {
854  long capa = ARY_CAPA(ary), len = RARRAY_LEN(ary);
855  const VALUE *ptr;
856  NEWOBJ_OF(shared, struct RArray, 0, T_ARRAY | (RGENGC_WB_PROTECTED_ARRAY ? FL_WB_PROTECTED : 0));
857 
859  ptr = ARY_HEAP_PTR(ary);
860 
861  FL_UNSET_EMBED(shared);
862  ARY_SET_LEN((VALUE)shared, capa);
863  ARY_SET_PTR((VALUE)shared, ptr);
864  ary_mem_clear((VALUE)shared, len, capa - len);
865  FL_SET_SHARED_ROOT(shared);
866  ARY_SET_SHARED_ROOT_REFCNT((VALUE)shared, 1);
867  FL_SET_SHARED(ary);
868  RB_DEBUG_COUNTER_INC(obj_ary_shared_create);
869  ARY_SET_SHARED(ary, (VALUE)shared);
870  OBJ_FREEZE(shared);
871 
872  ary_verify((VALUE)shared);
873  ary_verify(ary);
874 
875  return (VALUE)shared;
876  }
877 }
878 
879 static VALUE
880 ary_make_substitution(VALUE ary)
881 {
882  long len = RARRAY_LEN(ary);
883 
884  if (len <= RARRAY_EMBED_LEN_MAX) {
885  VALUE subst = rb_ary_new2(len);
886  ary_memcpy(subst, 0, len, RARRAY_CONST_PTR_TRANSIENT(ary));
887  ARY_SET_EMBED_LEN(subst, len);
888  return subst;
889  }
890  else {
891  return rb_ary_increment_share(ary_make_shared(ary));
892  }
893 }
894 
895 VALUE
897 {
898  return rb_ary_new3(2, car, cdr);
899 }
900 
901 VALUE
903 {
904  return rb_convert_type_with_id(ary, T_ARRAY, "Array", idTo_ary);
905 }
906 #define to_ary rb_to_array_type
907 
908 VALUE
910 {
911  return rb_check_convert_type_with_id(ary, T_ARRAY, "Array", idTo_ary);
912 }
913 
916 {
917  return rb_check_convert_type_with_id(ary, T_ARRAY, "Array", idTo_a);
918 }
919 
920 /*
921  * call-seq:
922  * Array.try_convert(obj) -> array or nil
923  *
924  * Tries to convert +obj+ into an array, using the +to_ary+ method. Returns
925  * the converted array or +nil+ if +obj+ cannot be converted.
926  * This method can be used to check if an argument is an array.
927  *
928  * Array.try_convert([1]) #=> [1]
929  * Array.try_convert("1") #=> nil
930  *
931  * if tmp = Array.try_convert(arg)
932  * # the argument is an array
933  * elsif tmp = String.try_convert(arg)
934  * # the argument is a string
935  * end
936  *
937  */
938 
939 static VALUE
940 rb_ary_s_try_convert(VALUE dummy, VALUE ary)
941 {
942  return rb_check_array_type(ary);
943 }
944 
945 /*
946  * call-seq:
947  * Array.new(size=0, default=nil)
948  * Array.new(array)
949  * Array.new(size) {|index| block }
950  *
951  * Returns a new array.
952  *
953  * In the first form, if no arguments are sent, the new array will be empty.
954  * When a +size+ and an optional +default+ are sent, an array is created with
955  * +size+ copies of +default+. Take notice that all elements will reference the
956  * same object +default+.
957  *
958  * The second form creates a copy of the array passed as a parameter (the
959  * array is generated by calling to_ary on the parameter).
960  *
961  * first_array = ["Matz", "Guido"]
962  *
963  * second_array = Array.new(first_array) #=> ["Matz", "Guido"]
964  *
965  * first_array.equal? second_array #=> false
966  *
967  * In the last form, an array of the given size is created. Each element in
968  * this array is created by passing the element's index to the given block
969  * and storing the return value.
970  *
971  * Array.new(3) {|index| index ** 2}
972  * # => [0, 1, 4]
973  *
974  * == Common gotchas
975  *
976  * When sending the second parameter, the same object will be used as the
977  * value for all the array elements:
978  *
979  * a = Array.new(2, Hash.new)
980  * # => [{}, {}]
981  *
982  * a[0]['cat'] = 'feline'
983  * a # => [{"cat"=>"feline"}, {"cat"=>"feline"}]
984  *
985  * a[1]['cat'] = 'Felix'
986  * a # => [{"cat"=>"Felix"}, {"cat"=>"Felix"}]
987  *
988  * Since all the Array elements store the same hash, changes to one of them
989  * will affect them all.
990  *
991  * If multiple copies are what you want, you should use the block
992  * version which uses the result of that block each time an element
993  * of the array needs to be initialized:
994  *
995  * a = Array.new(2) {Hash.new}
996  * a[0]['cat'] = 'feline'
997  * a # => [{"cat"=>"feline"}, {}]
998  *
999  */
1000 
1001 static VALUE
1002 rb_ary_initialize(int argc, VALUE *argv, VALUE ary)
1003 {
1004  long len;
1005  VALUE size, val;
1006 
1007  rb_ary_modify(ary);
1008  if (argc == 0) {
1009  if (ARY_OWNS_HEAP_P(ary) && ARY_HEAP_PTR(ary) != NULL) {
1010  ary_heap_free(ary);
1011  }
1012  rb_ary_unshare_safe(ary);
1013  FL_SET_EMBED(ary);
1014  ARY_SET_EMBED_LEN(ary, 0);
1015  if (rb_block_given_p()) {
1016  rb_warning("given block not used");
1017  }
1018  return ary;
1019  }
1020  rb_scan_args(argc, argv, "02", &size, &val);
1021  if (argc == 1 && !FIXNUM_P(size)) {
1022  val = rb_check_array_type(size);
1023  if (!NIL_P(val)) {
1024  rb_ary_replace(ary, val);
1025  return ary;
1026  }
1027  }
1028 
1029  len = NUM2LONG(size);
1030  /* NUM2LONG() may call size.to_int, ary can be frozen, modified, etc */
1031  if (len < 0) {
1032  rb_raise(rb_eArgError, "negative array size");
1033  }
1034  if (len > ARY_MAX_SIZE) {
1035  rb_raise(rb_eArgError, "array size too big");
1036  }
1037  /* recheck after argument conversion */
1038  rb_ary_modify(ary);
1039  ary_resize_capa(ary, len);
1040  if (rb_block_given_p()) {
1041  long i;
1042 
1043  if (argc == 2) {
1044  rb_warn("block supersedes default value argument");
1045  }
1046  for (i=0; i<len; i++) {
1047  rb_ary_store(ary, i, rb_yield(LONG2NUM(i)));
1048  ARY_SET_LEN(ary, i + 1);
1049  }
1050  }
1051  else {
1052  ary_memfill(ary, 0, len, val);
1053  ARY_SET_LEN(ary, len);
1054  }
1055  return ary;
1056 }
1057 
1058 /*
1059  * Returns a new array populated with the given objects.
1060  *
1061  * Array.[]( 1, 'a', /^A/) # => [1, "a", /^A/]
1062  * Array[ 1, 'a', /^A/ ] # => [1, "a", /^A/]
1063  * [ 1, 'a', /^A/ ] # => [1, "a", /^A/]
1064  */
1065 
1066 static VALUE
1067 rb_ary_s_create(int argc, VALUE *argv, VALUE klass)
1068 {
1069  VALUE ary = ary_new(klass, argc);
1070  if (argc > 0 && argv) {
1071  ary_memcpy(ary, 0, argc, argv);
1072  ARY_SET_LEN(ary, argc);
1073  }
1074 
1075  return ary;
1076 }
1077 
1078 void
1079 rb_ary_store(VALUE ary, long idx, VALUE val)
1080 {
1081  long len = RARRAY_LEN(ary);
1082 
1083  if (idx < 0) {
1084  idx += len;
1085  if (idx < 0) {
1086  rb_raise(rb_eIndexError, "index %ld too small for array; minimum: %ld",
1087  idx - len, -len);
1088  }
1089  }
1090  else if (idx >= ARY_MAX_SIZE) {
1091  rb_raise(rb_eIndexError, "index %ld too big", idx);
1092  }
1093 
1094  rb_ary_modify(ary);
1095  if (idx >= ARY_CAPA(ary)) {
1096  ary_double_capa(ary, idx);
1097  }
1098  if (idx > len) {
1099  ary_mem_clear(ary, len, idx - len + 1);
1100  }
1101 
1102  if (idx >= len) {
1103  ARY_SET_LEN(ary, idx + 1);
1104  }
1105  ARY_SET(ary, idx, val);
1106 }
1107 
1108 static VALUE
1109 ary_make_partial(VALUE ary, VALUE klass, long offset, long len)
1110 {
1111  assert(offset >= 0);
1112  assert(len >= 0);
1113  assert(offset+len <= RARRAY_LEN(ary));
1114 
1115  if (len <= RARRAY_EMBED_LEN_MAX) {
1116  VALUE result = ary_alloc(klass);
1117  ary_memcpy(result, 0, len, RARRAY_CONST_PTR_TRANSIENT(ary) + offset);
1118  ARY_SET_EMBED_LEN(result, len);
1119  return result;
1120  }
1121  else {
1122  VALUE shared, result = ary_alloc(klass);
1123  FL_UNSET_EMBED(result);
1124 
1125  shared = ary_make_shared(ary);
1127  ARY_SET_LEN(result, RARRAY_LEN(ary));
1128  rb_ary_set_shared(result, shared);
1129 
1130  ARY_INCREASE_PTR(result, offset);
1131  ARY_SET_LEN(result, len);
1132 
1133  ary_verify(shared);
1134  ary_verify(result);
1135  return result;
1136  }
1137 }
1138 
1139 static VALUE
1140 ary_make_shared_copy(VALUE ary)
1141 {
1142  return ary_make_partial(ary, rb_obj_class(ary), 0, RARRAY_LEN(ary));
1143 }
1144 
1146 {
1149 };
1150 
1151 static VALUE
1152 ary_take_first_or_last(int argc, const VALUE *argv, VALUE ary, enum ary_take_pos_flags last)
1153 {
1154  long n;
1155  long len;
1156  long offset = 0;
1157 
1158  argc = rb_check_arity(argc, 0, 1);
1159  /* the case optional argument is omitted should be handled in
1160  * callers of this function. if another arity case is added,
1161  * this arity check needs to rewrite. */
1162  RUBY_ASSERT_ALWAYS(argc == 1);
1163 
1164  n = NUM2LONG(argv[0]);
1165  len = RARRAY_LEN(ary);
1166  if (n > len) {
1167  n = len;
1168  }
1169  else if (n < 0) {
1170  rb_raise(rb_eArgError, "negative array size");
1171  }
1172  if (last) {
1173  offset = len - n;
1174  }
1175  return ary_make_partial(ary, rb_cArray, offset, n);
1176 }
1177 
1178 /*
1179  * call-seq:
1180  * ary << obj -> ary
1181  *
1182  * Append---Pushes the given object on to the end of this array. This
1183  * expression returns the array itself, so several appends
1184  * may be chained together.
1185  *
1186  * a = [ 1, 2 ]
1187  * a << "c" << "d" << [ 3, 4 ]
1188  * #=> [ 1, 2, "c", "d", [ 3, 4 ] ]
1189  * a
1190  * #=> [ 1, 2, "c", "d", [ 3, 4 ] ]
1191  *
1192  */
1193 
1194 VALUE
1196 {
1197  long idx = RARRAY_LEN((ary_verify(ary), ary));
1198  VALUE target_ary = ary_ensure_room_for_push(ary, 1);
1200  RB_OBJ_WRITE(target_ary, &ptr[idx], item);
1201  });
1202  ARY_SET_LEN(ary, idx + 1);
1203  ary_verify(ary);
1204  return ary;
1205 }
1206 
1207 VALUE
1208 rb_ary_cat(VALUE ary, const VALUE *argv, long len)
1209 {
1210  long oldlen = RARRAY_LEN(ary);
1211  VALUE target_ary = ary_ensure_room_for_push(ary, len);
1212  ary_memcpy0(ary, oldlen, len, argv, target_ary);
1213  ARY_SET_LEN(ary, oldlen + len);
1214  return ary;
1215 }
1216 
1217 /*
1218  * call-seq:
1219  * ary.push(obj, ...) -> ary
1220  * ary.append(obj, ...) -> ary
1221  *
1222  * Append --- Pushes the given object(s) on to the end of this array. This
1223  * expression returns the array itself, so several appends
1224  * may be chained together. See also Array#pop for the opposite
1225  * effect.
1226  *
1227  * a = [ "a", "b", "c" ]
1228  * a.push("d", "e", "f")
1229  * #=> ["a", "b", "c", "d", "e", "f"]
1230  * [1, 2, 3].push(4).push(5)
1231  * #=> [1, 2, 3, 4, 5]
1232  */
1233 
1234 static VALUE
1235 rb_ary_push_m(int argc, VALUE *argv, VALUE ary)
1236 {
1237  return rb_ary_cat(ary, argv, argc);
1238 }
1239 
1240 VALUE
1242 {
1243  long n;
1244  rb_ary_modify_check(ary);
1245  n = RARRAY_LEN(ary);
1246  if (n == 0) return Qnil;
1247  if (ARY_OWNS_HEAP_P(ary) &&
1248  n * 3 < ARY_CAPA(ary) &&
1249  ARY_CAPA(ary) > ARY_DEFAULT_SIZE)
1250  {
1251  ary_resize_capa(ary, n * 2);
1252  }
1253  --n;
1254  ARY_SET_LEN(ary, n);
1255  ary_verify(ary);
1256  return RARRAY_AREF(ary, n);
1257 }
1258 
1259 /*
1260  * call-seq:
1261  * ary.pop -> obj or nil
1262  * ary.pop(n) -> new_ary
1263  *
1264  * Removes the last element from +self+ and returns it, or
1265  * +nil+ if the array is empty.
1266  *
1267  * If a number +n+ is given, returns an array of the last +n+ elements
1268  * (or less) just like <code>array.slice!(-n, n)</code> does. See also
1269  * Array#push for the opposite effect.
1270  *
1271  * a = [ "a", "b", "c", "d" ]
1272  * a.pop #=> "d"
1273  * a.pop(2) #=> ["b", "c"]
1274  * a #=> ["a"]
1275  */
1276 
1277 static VALUE
1278 rb_ary_pop_m(int argc, VALUE *argv, VALUE ary)
1279 {
1280  VALUE result;
1281 
1282  if (argc == 0) {
1283  return rb_ary_pop(ary);
1284  }
1285 
1286  rb_ary_modify_check(ary);
1287  result = ary_take_first_or_last(argc, argv, ary, ARY_TAKE_LAST);
1288  ARY_INCREASE_LEN(ary, -RARRAY_LEN(result));
1289  ary_verify(ary);
1290  return result;
1291 }
1292 
1293 VALUE
1295 {
1296  VALUE top;
1297  long len = RARRAY_LEN(ary);
1298 
1299  rb_ary_modify_check(ary);
1300  if (len == 0) return Qnil;
1301  top = RARRAY_AREF(ary, 0);
1302  if (!ARY_SHARED_P(ary)) {
1303  if (len < ARY_DEFAULT_SIZE) {
1305  MEMMOVE(ptr, ptr+1, VALUE, len-1);
1306  }); /* WB: no new reference */
1307  ARY_INCREASE_LEN(ary, -1);
1308  ary_verify(ary);
1309  return top;
1310  }
1311  assert(!ARY_EMBED_P(ary)); /* ARY_EMBED_LEN_MAX < ARY_DEFAULT_SIZE */
1312 
1313  ARY_SET(ary, 0, Qnil);
1314  ary_make_shared(ary);
1315  }
1316  else if (ARY_SHARED_ROOT_OCCUPIED(ARY_SHARED_ROOT(ary))) {
1317  RARRAY_PTR_USE_TRANSIENT(ary, ptr, ptr[0] = Qnil);
1318  }
1319  ARY_INCREASE_PTR(ary, 1); /* shift ptr */
1320  ARY_INCREASE_LEN(ary, -1);
1321 
1322  ary_verify(ary);
1323 
1324  return top;
1325 }
1326 
1327 /*
1328  * call-seq:
1329  * ary.shift -> obj or nil
1330  * ary.shift(n) -> new_ary
1331  *
1332  * Removes the first element of +self+ and returns it (shifting all
1333  * other elements down by one). Returns +nil+ if the array
1334  * is empty.
1335  *
1336  * If a number +n+ is given, returns an array of the first +n+ elements
1337  * (or less) just like <code>array.slice!(0, n)</code> does. With +ary+
1338  * containing only the remainder elements, not including what was shifted to
1339  * +new_ary+. See also Array#unshift for the opposite effect.
1340  *
1341  * args = [ "-m", "-q", "filename" ]
1342  * args.shift #=> "-m"
1343  * args #=> ["-q", "filename"]
1344  *
1345  * args = [ "-m", "-q", "filename" ]
1346  * args.shift(2) #=> ["-m", "-q"]
1347  * args #=> ["filename"]
1348  */
1349 
1350 static VALUE
1351 rb_ary_shift_m(int argc, VALUE *argv, VALUE ary)
1352 {
1353  VALUE result;
1354  long n;
1355 
1356  if (argc == 0) {
1357  return rb_ary_shift(ary);
1358  }
1359 
1360  rb_ary_modify_check(ary);
1361  result = ary_take_first_or_last(argc, argv, ary, ARY_TAKE_FIRST);
1362  n = RARRAY_LEN(result);
1363  rb_ary_behead(ary,n);
1364 
1365  return result;
1366 }
1367 
1370 {
1371  if (n<=0) return ary;
1372 
1373  rb_ary_modify_check(ary);
1374  if (ARY_SHARED_P(ary)) {
1376  setup_occupied_shared:
1377  ary_mem_clear(ary, 0, n);
1378  }
1379  ARY_INCREASE_PTR(ary, n);
1380  }
1381  else {
1382  if (RARRAY_LEN(ary) < ARY_DEFAULT_SIZE) {
1384  MEMMOVE(ptr, ptr+n, VALUE, RARRAY_LEN(ary)-n);
1385  }); /* WB: no new reference */
1386  }
1387  else {
1388  ary_make_shared(ary);
1389  goto setup_occupied_shared;
1390  }
1391  }
1392  ARY_INCREASE_LEN(ary, -n);
1393 
1394  ary_verify(ary);
1395  return ary;
1396 }
1397 
1398 static VALUE
1399 ary_ensure_room_for_unshift(VALUE ary, int argc)
1400 {
1401  long len = RARRAY_LEN(ary);
1402  long new_len = len + argc;
1403  long capa;
1404  const VALUE *head, *sharedp;
1405 
1406  if (len > ARY_MAX_SIZE - argc) {
1407  rb_raise(rb_eIndexError, "index %ld too big", new_len);
1408  }
1409 
1410  if (ARY_SHARED_P(ary)) {
1411  VALUE shared_root = ARY_SHARED_ROOT(ary);
1412  capa = RARRAY_LEN(shared_root);
1413  if (ARY_SHARED_ROOT_OCCUPIED(shared_root) && capa > new_len) {
1414  rb_ary_modify_check(ary);
1415  head = RARRAY_CONST_PTR_TRANSIENT(ary);
1416  sharedp = RARRAY_CONST_PTR_TRANSIENT(shared_root);
1417  goto makeroom_if_need;
1418  }
1419  }
1420 
1421  rb_ary_modify(ary);
1422  capa = ARY_CAPA(ary);
1423  if (capa - (capa >> 6) <= new_len) {
1424  ary_double_capa(ary, new_len);
1425  }
1426 
1427  /* use shared array for big "queues" */
1428  if (new_len > ARY_DEFAULT_SIZE * 4) {
1429  ary_verify(ary);
1430 
1431  /* make a room for unshifted items */
1432  capa = ARY_CAPA(ary);
1433  ary_make_shared(ary);
1434 
1435  head = sharedp = RARRAY_CONST_PTR_TRANSIENT(ary);
1436  goto makeroom;
1437  makeroom_if_need:
1438  if (head - sharedp < argc) {
1439  long room;
1440  makeroom:
1441  room = capa - new_len;
1442  room -= room >> 4;
1443  MEMMOVE((VALUE *)sharedp + argc + room, head, VALUE, len);
1444  head = sharedp + argc + room;
1445  }
1446  ARY_SET_PTR(ary, head - argc);
1448 
1449  ary_verify(ary);
1450  return ARY_SHARED_ROOT(ary);
1451  }
1452  else {
1453  /* sliding items */
1455  MEMMOVE(ptr + argc, ptr, VALUE, len);
1456  });
1457 
1458  ary_verify(ary);
1459  return ary;
1460  }
1461 }
1462 
1463 /*
1464  * call-seq:
1465  * ary.unshift(obj, ...) -> ary
1466  * ary.prepend(obj, ...) -> ary
1467  *
1468  * Prepends objects to the front of +self+, moving other elements upwards.
1469  * See also Array#shift for the opposite effect.
1470  *
1471  * a = [ "b", "c", "d" ]
1472  * a.unshift("a") #=> ["a", "b", "c", "d"]
1473  * a.unshift(1, 2) #=> [ 1, 2, "a", "b", "c", "d"]
1474  */
1475 
1476 static VALUE
1477 rb_ary_unshift_m(int argc, VALUE *argv, VALUE ary)
1478 {
1479  long len = RARRAY_LEN(ary);
1480  VALUE target_ary;
1481 
1482  if (argc == 0) {
1483  rb_ary_modify_check(ary);
1484  return ary;
1485  }
1486 
1487  target_ary = ary_ensure_room_for_unshift(ary, argc);
1488  ary_memcpy0(ary, 0, argc, argv, target_ary);
1489  ARY_SET_LEN(ary, len + argc);
1490  return ary;
1491 }
1492 
1493 VALUE
1495 {
1496  return rb_ary_unshift_m(1,&item,ary);
1497 }
1498 
1499 /* faster version - use this if you don't need to treat negative offset */
1500 static inline VALUE
1501 rb_ary_elt(VALUE ary, long offset)
1502 {
1503  long len = RARRAY_LEN(ary);
1504  if (len == 0) return Qnil;
1505  if (offset < 0 || len <= offset) {
1506  return Qnil;
1507  }
1508  return RARRAY_AREF(ary, offset);
1509 }
1510 
1511 VALUE
1512 rb_ary_entry(VALUE ary, long offset)
1513 {
1514  return rb_ary_entry_internal(ary, offset);
1515 }
1516 
1517 VALUE
1518 rb_ary_subseq(VALUE ary, long beg, long len)
1519 {
1520  VALUE klass;
1521  long alen = RARRAY_LEN(ary);
1522 
1523  if (beg > alen) return Qnil;
1524  if (beg < 0 || len < 0) return Qnil;
1525 
1526  if (alen < len || alen < beg + len) {
1527  len = alen - beg;
1528  }
1529  klass = rb_obj_class(ary);
1530  if (len == 0) return ary_new(klass, 0);
1531 
1532  return ary_make_partial(ary, klass, beg, len);
1533 }
1534 
1535 static VALUE rb_ary_aref2(VALUE ary, VALUE b, VALUE e);
1536 
1537 /*
1538  * call-seq:
1539  * ary[index] -> obj or nil
1540  * ary[start, length] -> new_ary or nil
1541  * ary[range] -> new_ary or nil
1542  * ary.slice(index) -> obj or nil
1543  * ary.slice(start, length) -> new_ary or nil
1544  * ary.slice(range) -> new_ary or nil
1545  *
1546  * Element Reference --- Returns the element at +index+, or returns a
1547  * subarray starting at the +start+ index and continuing for +length+
1548  * elements, or returns a subarray specified by +range+ of indices.
1549  *
1550  * Negative indices count backward from the end of the array (-1 is the last
1551  * element). For +start+ and +range+ cases the starting index is just before
1552  * an element. Additionally, an empty array is returned when the starting
1553  * index for an element range is at the end of the array.
1554  *
1555  * Returns +nil+ if the index (or starting index) are out of range.
1556  *
1557  * a = [ "a", "b", "c", "d", "e" ]
1558  * a[2] + a[0] + a[1] #=> "cab"
1559  * a[6] #=> nil
1560  * a[1, 2] #=> [ "b", "c" ]
1561  * a[1..3] #=> [ "b", "c", "d" ]
1562  * a[4..7] #=> [ "e" ]
1563  * a[6..10] #=> nil
1564  * a[-3, 3] #=> [ "c", "d", "e" ]
1565  * # special cases
1566  * a[5] #=> nil
1567  * a[6, 1] #=> nil
1568  * a[5, 1] #=> []
1569  * a[5..10] #=> []
1570  *
1571  */
1572 
1573 VALUE
1574 rb_ary_aref(int argc, const VALUE *argv, VALUE ary)
1575 {
1576  rb_check_arity(argc, 1, 2);
1577  if (argc == 2) {
1578  return rb_ary_aref2(ary, argv[0], argv[1]);
1579  }
1580  return rb_ary_aref1(ary, argv[0]);
1581 }
1582 
1583 VALUE
1584 rb_ary_aref2(VALUE ary, VALUE b, VALUE e)
1585 {
1586  long beg = NUM2LONG(b);
1587  long len = NUM2LONG(e);
1588  if (beg < 0) {
1589  beg += RARRAY_LEN(ary);
1590  }
1591  return rb_ary_subseq(ary, beg, len);
1592 }
1593 
1596 {
1597  long beg, len;
1598 
1599  /* special case - speeding up */
1600  if (FIXNUM_P(arg)) {
1601  return rb_ary_entry(ary, FIX2LONG(arg));
1602  }
1603  /* check if idx is Range */
1604  switch (rb_range_beg_len(arg, &beg, &len, RARRAY_LEN(ary), 0)) {
1605  case Qfalse:
1606  break;
1607  case Qnil:
1608  return Qnil;
1609  default:
1610  return rb_ary_subseq(ary, beg, len);
1611  }
1612  return rb_ary_entry(ary, NUM2LONG(arg));
1613 }
1614 
1615 /*
1616  * call-seq:
1617  * ary.at(index) -> obj or nil
1618  *
1619  * Returns the element at +index+. A negative index counts from the end of
1620  * +self+. Returns +nil+ if the index is out of range. See also
1621  * Array#[].
1622  *
1623  * a = [ "a", "b", "c", "d", "e" ]
1624  * a.at(0) #=> "a"
1625  * a.at(-1) #=> "e"
1626  */
1627 
1628 VALUE
1630 {
1631  return rb_ary_entry(ary, NUM2LONG(pos));
1632 }
1633 
1634 /*
1635  * call-seq:
1636  * ary.first -> obj or nil
1637  * ary.first(n) -> new_ary
1638  *
1639  * Returns the first element, or the first +n+ elements, of the array.
1640  * If the array is empty, the first form returns +nil+, and the
1641  * second form returns an empty array. See also Array#last for
1642  * the opposite effect.
1643  *
1644  * a = [ "q", "r", "s", "t" ]
1645  * a.first #=> "q"
1646  * a.first(2) #=> ["q", "r"]
1647  */
1648 
1649 static VALUE
1650 rb_ary_first(int argc, VALUE *argv, VALUE ary)
1651 {
1652  if (argc == 0) {
1653  if (RARRAY_LEN(ary) == 0) return Qnil;
1654  return RARRAY_AREF(ary, 0);
1655  }
1656  else {
1657  return ary_take_first_or_last(argc, argv, ary, ARY_TAKE_FIRST);
1658  }
1659 }
1660 
1661 /*
1662  * call-seq:
1663  * ary.last -> obj or nil
1664  * ary.last(n) -> new_ary
1665  *
1666  * Returns the last element(s) of +self+. If the array is empty,
1667  * the first form returns +nil+.
1668  *
1669  * See also Array#first for the opposite effect.
1670  *
1671  * a = [ "w", "x", "y", "z" ]
1672  * a.last #=> "z"
1673  * a.last(2) #=> ["y", "z"]
1674  */
1675 
1676 VALUE
1677 rb_ary_last(int argc, const VALUE *argv, VALUE ary)
1678 {
1679  if (argc == 0) {
1680  long len = RARRAY_LEN(ary);
1681  if (len == 0) return Qnil;
1682  return RARRAY_AREF(ary, len-1);
1683  }
1684  else {
1685  return ary_take_first_or_last(argc, argv, ary, ARY_TAKE_LAST);
1686  }
1687 }
1688 
1689 /*
1690  * call-seq:
1691  * ary.fetch(index) -> obj
1692  * ary.fetch(index, default) -> obj
1693  * ary.fetch(index) {|index| block} -> obj
1694  *
1695  * Tries to return the element at position +index+, but throws an IndexError
1696  * exception if the referenced +index+ lies outside of the array bounds. This
1697  * error can be prevented by supplying a second argument, which will act as a
1698  * +default+ value.
1699  *
1700  * Alternatively, if a block is given it will only be executed when an
1701  * invalid +index+ is referenced.
1702  *
1703  * Negative values of +index+ count from the end of the array.
1704  *
1705  * a = [ 11, 22, 33, 44 ]
1706  * a.fetch(1) #=> 22
1707  * a.fetch(-1) #=> 44
1708  * a.fetch(4, 'cat') #=> "cat"
1709  * a.fetch(100) {|i| puts "#{i} is out of bounds"}
1710  * #=> "100 is out of bounds"
1711  */
1712 
1713 static VALUE
1714 rb_ary_fetch(int argc, VALUE *argv, VALUE ary)
1715 {
1716  VALUE pos, ifnone;
1717  long block_given;
1718  long idx;
1719 
1720  rb_scan_args(argc, argv, "11", &pos, &ifnone);
1721  block_given = rb_block_given_p();
1722  if (block_given && argc == 2) {
1723  rb_warn("block supersedes default value argument");
1724  }
1725  idx = NUM2LONG(pos);
1726 
1727  if (idx < 0) {
1728  idx += RARRAY_LEN(ary);
1729  }
1730  if (idx < 0 || RARRAY_LEN(ary) <= idx) {
1731  if (block_given) return rb_yield(pos);
1732  if (argc == 1) {
1733  rb_raise(rb_eIndexError, "index %ld outside of array bounds: %ld...%ld",
1734  idx - (idx < 0 ? RARRAY_LEN(ary) : 0), -RARRAY_LEN(ary), RARRAY_LEN(ary));
1735  }
1736  return ifnone;
1737  }
1738  return RARRAY_AREF(ary, idx);
1739 }
1740 
1741 /*
1742  * call-seq:
1743  * ary.find_index(obj) -> int or nil
1744  * ary.find_index {|item| block} -> int or nil
1745  * ary.find_index -> Enumerator
1746  * ary.index(obj) -> int or nil
1747  * ary.index {|item| block} -> int or nil
1748  * ary.index -> Enumerator
1749  *
1750  * Returns the _index_ of the first object in +ary+ such that the object is
1751  * <code>==</code> to +obj+.
1752  *
1753  * If a block is given instead of an argument, returns the _index_ of the
1754  * first object for which the block returns +true+. Returns +nil+ if no
1755  * match is found.
1756  *
1757  * See also Array#rindex.
1758  *
1759  * An Enumerator is returned if neither a block nor argument is given.
1760  *
1761  * a = [ "a", "b", "c" ]
1762  * a.index("b") #=> 1
1763  * a.index("z") #=> nil
1764  * a.index {|x| x == "b"} #=> 1
1765  */
1766 
1767 static VALUE
1768 rb_ary_index(int argc, VALUE *argv, VALUE ary)
1769 {
1770  VALUE val;
1771  long i;
1772 
1773  if (argc == 0) {
1774  RETURN_ENUMERATOR(ary, 0, 0);
1775  for (i=0; i<RARRAY_LEN(ary); i++) {
1776  if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) {
1777  return LONG2NUM(i);
1778  }
1779  }
1780  return Qnil;
1781  }
1782  rb_check_arity(argc, 0, 1);
1783  val = argv[0];
1784  if (rb_block_given_p())
1785  rb_warn("given block not used");
1786  for (i=0; i<RARRAY_LEN(ary); i++) {
1787  VALUE e = RARRAY_AREF(ary, i);
1788  if (rb_equal(e, val)) {
1789  return LONG2NUM(i);
1790  }
1791  }
1792  return Qnil;
1793 }
1794 
1795 /*
1796  * call-seq:
1797  * ary.rindex(obj) -> int or nil
1798  * ary.rindex {|item| block} -> int or nil
1799  * ary.rindex -> Enumerator
1800  *
1801  * Returns the _index_ of the last object in +self+ <code>==</code> to +obj+.
1802  *
1803  * If a block is given instead of an argument, returns the _index_ of the
1804  * first object for which the block returns +true+, starting from the last
1805  * object.
1806  *
1807  * Returns +nil+ if no match is found.
1808  *
1809  * See also Array#index.
1810  *
1811  * If neither block nor argument is given, an Enumerator is returned instead.
1812  *
1813  * a = [ "a", "b", "b", "b", "c" ]
1814  * a.rindex("b") #=> 3
1815  * a.rindex("z") #=> nil
1816  * a.rindex {|x| x == "b"} #=> 3
1817  */
1818 
1819 static VALUE
1820 rb_ary_rindex(int argc, VALUE *argv, VALUE ary)
1821 {
1822  VALUE val;
1823  long i = RARRAY_LEN(ary), len;
1824 
1825  if (argc == 0) {
1826  RETURN_ENUMERATOR(ary, 0, 0);
1827  while (i--) {
1828  if (RTEST(rb_yield(RARRAY_AREF(ary, i))))
1829  return LONG2NUM(i);
1830  if (i > (len = RARRAY_LEN(ary))) {
1831  i = len;
1832  }
1833  }
1834  return Qnil;
1835  }
1836  rb_check_arity(argc, 0, 1);
1837  val = argv[0];
1838  if (rb_block_given_p())
1839  rb_warn("given block not used");
1840  while (i--) {
1841  VALUE e = RARRAY_AREF(ary, i);
1842  if (rb_equal(e, val)) {
1843  return LONG2NUM(i);
1844  }
1845  if (i > RARRAY_LEN(ary)) {
1846  break;
1847  }
1848  }
1849  return Qnil;
1850 }
1851 
1852 VALUE
1854 {
1855  VALUE tmp = rb_check_array_type(obj);
1856 
1857  if (!NIL_P(tmp)) return tmp;
1858  return rb_ary_new3(1, obj);
1859 }
1860 
1861 static void
1862 rb_ary_splice(VALUE ary, long beg, long len, const VALUE *rptr, long rlen)
1863 {
1864  long olen;
1865  long rofs;
1866 
1867  if (len < 0) rb_raise(rb_eIndexError, "negative length (%ld)", len);
1868  olen = RARRAY_LEN(ary);
1869  if (beg < 0) {
1870  beg += olen;
1871  if (beg < 0) {
1872  rb_raise(rb_eIndexError, "index %ld too small for array; minimum: %ld",
1873  beg - olen, -olen);
1874  }
1875  }
1876  if (olen < len || olen < beg + len) {
1877  len = olen - beg;
1878  }
1879 
1880  {
1881  const VALUE *optr = RARRAY_CONST_PTR_TRANSIENT(ary);
1882  rofs = (rptr >= optr && rptr < optr + olen) ? rptr - optr : -1;
1883  }
1884 
1885  if (beg >= olen) {
1886  VALUE target_ary;
1887  if (beg > ARY_MAX_SIZE - rlen) {
1888  rb_raise(rb_eIndexError, "index %ld too big", beg);
1889  }
1890  target_ary = ary_ensure_room_for_push(ary, rlen-len); /* len is 0 or negative */
1891  len = beg + rlen;
1892  ary_mem_clear(ary, olen, beg - olen);
1893  if (rlen > 0) {
1894  if (rofs != -1) rptr = RARRAY_CONST_PTR_TRANSIENT(ary) + rofs;
1895  ary_memcpy0(ary, beg, rlen, rptr, target_ary);
1896  }
1897  ARY_SET_LEN(ary, len);
1898  }
1899  else {
1900  long alen;
1901 
1902  if (olen - len > ARY_MAX_SIZE - rlen) {
1903  rb_raise(rb_eIndexError, "index %ld too big", olen + rlen - len);
1904  }
1905  rb_ary_modify(ary);
1906  alen = olen + rlen - len;
1907  if (alen >= ARY_CAPA(ary)) {
1908  ary_double_capa(ary, alen);
1909  }
1910 
1911  if (len != rlen) {
1913  MEMMOVE(ptr + beg + rlen, ptr + beg + len,
1914  VALUE, olen - (beg + len)));
1915  ARY_SET_LEN(ary, alen);
1916  }
1917  if (rlen > 0) {
1918  if (rofs != -1) rptr = RARRAY_CONST_PTR_TRANSIENT(ary) + rofs;
1919  /* give up wb-protected ary */
1920  RB_OBJ_WB_UNPROTECT_FOR(ARRAY, ary);
1921 
1922  /* do not use RARRAY_PTR() because it can causes GC.
1923  * ary can contain T_NONE object because it is not cleared.
1924  */
1926  MEMMOVE(ptr + beg, rptr, VALUE, rlen));
1927  }
1928  }
1929 }
1930 
1931 void
1933 {
1934  long capa;
1935 
1936  rb_ary_modify_check(ary);
1937  if (ARY_SHARED_P(ary)) {
1938  rb_raise(rb_eRuntimeError, "can't set length of shared ");
1939  }
1940  if (len > (capa = (long)ARY_CAPA(ary))) {
1941  rb_bug("probable buffer overflow: %ld for %ld", len, capa);
1942  }
1943  ARY_SET_LEN(ary, len);
1944 }
1945 
1954 VALUE
1956 {
1957  long olen;
1958 
1959  rb_ary_modify(ary);
1960  olen = RARRAY_LEN(ary);
1961  if (len == olen) return ary;
1962  if (len > ARY_MAX_SIZE) {
1963  rb_raise(rb_eIndexError, "index %ld too big", len);
1964  }
1965  if (len > olen) {
1966  if (len >= ARY_CAPA(ary)) {
1967  ary_double_capa(ary, len);
1968  }
1969  ary_mem_clear(ary, olen, len - olen);
1970  ARY_SET_LEN(ary, len);
1971  }
1972  else if (ARY_EMBED_P(ary)) {
1973  ARY_SET_EMBED_LEN(ary, len);
1974  }
1975  else if (len <= RARRAY_EMBED_LEN_MAX) {
1977  MEMCPY(tmp, ARY_HEAP_PTR(ary), VALUE, len);
1978  ary_discard(ary);
1979  MEMCPY((VALUE *)ARY_EMBED_PTR(ary), tmp, VALUE, len); /* WB: no new reference */
1980  ARY_SET_EMBED_LEN(ary, len);
1981  }
1982  else {
1983  if (olen > len + ARY_DEFAULT_SIZE) {
1984  ary_heap_realloc(ary, len);
1985  ARY_SET_CAPA(ary, len);
1986  }
1987  ARY_SET_HEAP_LEN(ary, len);
1988  }
1989  ary_verify(ary);
1990  return ary;
1991 }
1992 
1993 /*
1994  * call-seq:
1995  * ary[index] = obj -> obj
1996  * ary[start, length] = obj or other_ary or nil -> obj or other_ary or nil
1997  * ary[range] = obj or other_ary or nil -> obj or other_ary or nil
1998  *
1999  * Element Assignment --- Sets the element at +index+, or replaces a subarray
2000  * from the +start+ index for +length+ elements, or replaces a subarray
2001  * specified by the +range+ of indices.
2002  *
2003  * If indices are greater than the current capacity of the array, the array
2004  * grows automatically. Elements are inserted into the array at +start+ if
2005  * +length+ is zero.
2006  *
2007  * Negative indices will count backward from the end of the array. For
2008  * +start+ and +range+ cases the starting index is just before an element.
2009  *
2010  * An IndexError is raised if a negative index points past the beginning of
2011  * the array.
2012  *
2013  * See also Array#push, and Array#unshift.
2014  *
2015  * a = Array.new
2016  * a[4] = "4"; #=> [nil, nil, nil, nil, "4"]
2017  * a[0, 3] = [ 'a', 'b', 'c' ] #=> ["a", "b", "c", nil, "4"]
2018  * a[1..2] = [ 1, 2 ] #=> ["a", 1, 2, nil, "4"]
2019  * a[0, 2] = "?" #=> ["?", 2, nil, "4"]
2020  * a[0..2] = "A" #=> ["A", "4"]
2021  * a[-1] = "Z" #=> ["A", "Z"]
2022  * a[1..-1] = nil #=> ["A", nil]
2023  * a[1..-1] = [] #=> ["A"]
2024  * a[0, 0] = [ 1, 2 ] #=> [1, 2, "A"]
2025  * a[3, 0] = "B" #=> [1, 2, "A", "B"]
2026  */
2027 
2028 static VALUE
2029 rb_ary_aset(int argc, VALUE *argv, VALUE ary)
2030 {
2031  long offset, beg, len;
2032  VALUE rpl;
2033 
2034  if (argc == 3) {
2035  rb_ary_modify_check(ary);
2036  beg = NUM2LONG(argv[0]);
2037  len = NUM2LONG(argv[1]);
2038  goto range;
2039  }
2040  rb_check_arity(argc, 2, 2);
2041  rb_ary_modify_check(ary);
2042  if (FIXNUM_P(argv[0])) {
2043  offset = FIX2LONG(argv[0]);
2044  goto fixnum;
2045  }
2046  if (rb_range_beg_len(argv[0], &beg, &len, RARRAY_LEN(ary), 1)) {
2047  /* check if idx is Range */
2048  range:
2049  rpl = rb_ary_to_ary(argv[argc-1]);
2050  rb_ary_splice(ary, beg, len, RARRAY_CONST_PTR_TRANSIENT(rpl), RARRAY_LEN(rpl));
2051  RB_GC_GUARD(rpl);
2052  return argv[argc-1];
2053  }
2054 
2055  offset = NUM2LONG(argv[0]);
2056 fixnum:
2057  rb_ary_store(ary, offset, argv[1]);
2058  return argv[1];
2059 }
2060 
2061 /*
2062  * call-seq:
2063  * ary.insert(index, obj...) -> ary
2064  *
2065  * Inserts the given values before the element with the given +index+.
2066  *
2067  * Negative indices count backwards from the end of the array, where +-1+ is
2068  * the last element. If a negative index is used, the given values will be
2069  * inserted after that element, so using an index of +-1+ will insert the
2070  * values at the end of the array.
2071  *
2072  * a = %w{ a b c d }
2073  * a.insert(2, 99) #=> ["a", "b", 99, "c", "d"]
2074  * a.insert(-2, 1, 2, 3) #=> ["a", "b", 99, "c", 1, 2, 3, "d"]
2075  */
2076 
2077 static VALUE
2078 rb_ary_insert(int argc, VALUE *argv, VALUE ary)
2079 {
2080  long pos;
2081 
2083  rb_ary_modify_check(ary);
2084  pos = NUM2LONG(argv[0]);
2085  if (argc == 1) return ary;
2086  if (pos == -1) {
2087  pos = RARRAY_LEN(ary);
2088  }
2089  else if (pos < 0) {
2090  long minpos = -RARRAY_LEN(ary) - 1;
2091  if (pos < minpos) {
2092  rb_raise(rb_eIndexError, "index %ld too small for array; minimum: %ld",
2093  pos, minpos);
2094  }
2095  pos++;
2096  }
2097  rb_ary_splice(ary, pos, 0, argv + 1, argc - 1);
2098  return ary;
2099 }
2100 
2101 static VALUE
2102 rb_ary_length(VALUE ary);
2103 
2104 static VALUE
2105 ary_enum_length(VALUE ary, VALUE args, VALUE eobj)
2106 {
2107  return rb_ary_length(ary);
2108 }
2109 
2110 /*
2111  * call-seq:
2112  * ary.each {|item| block} -> ary
2113  * ary.each -> Enumerator
2114  *
2115  * Calls the given block once for each element in +self+, passing that element
2116  * as a parameter. Returns the array itself.
2117  *
2118  * If no block is given, an Enumerator is returned.
2119  *
2120  * a = [ "a", "b", "c" ]
2121  * a.each {|x| print x, " -- " }
2122  *
2123  * produces:
2124  *
2125  * a -- b -- c --
2126  */
2127 
2128 VALUE
2130 {
2131  long i;
2132  ary_verify(ary);
2133  RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
2134  for (i=0; i<RARRAY_LEN(ary); i++) {
2135  rb_yield(RARRAY_AREF(ary, i));
2136  }
2137  return ary;
2138 }
2139 
2140 /*
2141  * call-seq:
2142  * ary.each_index {|index| block} -> ary
2143  * ary.each_index -> Enumerator
2144  *
2145  * Same as Array#each, but passes the +index+ of the element instead of the
2146  * element itself.
2147  *
2148  * An Enumerator is returned if no block is given.
2149  *
2150  * a = [ "a", "b", "c" ]
2151  * a.each_index {|x| print x, " -- " }
2152  *
2153  * produces:
2154  *
2155  * 0 -- 1 -- 2 --
2156  */
2157 
2158 static VALUE
2159 rb_ary_each_index(VALUE ary)
2160 {
2161  long i;
2162  RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
2163 
2164  for (i=0; i<RARRAY_LEN(ary); i++) {
2165  rb_yield(LONG2NUM(i));
2166  }
2167  return ary;
2168 }
2169 
2170 /*
2171  * call-seq:
2172  * ary.reverse_each {|item| block} -> ary
2173  * ary.reverse_each -> Enumerator
2174  *
2175  * Same as Array#each, but traverses +self+ in reverse order.
2176  *
2177  * a = [ "a", "b", "c" ]
2178  * a.reverse_each {|x| print x, " " }
2179  *
2180  * produces:
2181  *
2182  * c b a
2183  */
2184 
2185 static VALUE
2186 rb_ary_reverse_each(VALUE ary)
2187 {
2188  long len;
2189 
2190  RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
2191  len = RARRAY_LEN(ary);
2192  while (len--) {
2193  long nlen;
2194  rb_yield(RARRAY_AREF(ary, len));
2195  nlen = RARRAY_LEN(ary);
2196  if (nlen < len) {
2197  len = nlen;
2198  }
2199  }
2200  return ary;
2201 }
2202 
2203 /*
2204  * call-seq:
2205  * ary.length -> int
2206  *
2207  * Returns the number of elements in +self+. May be zero.
2208  *
2209  * [ 1, 2, 3, 4, 5 ].length #=> 5
2210  * [].length #=> 0
2211  */
2212 
2213 static VALUE
2214 rb_ary_length(VALUE ary)
2215 {
2216  long len = RARRAY_LEN(ary);
2217  return LONG2NUM(len);
2218 }
2219 
2220 /*
2221  * call-seq:
2222  * ary.empty? -> true or false
2223  *
2224  * Returns +true+ if +self+ contains no elements.
2225  *
2226  * [].empty? #=> true
2227  */
2228 
2229 static VALUE
2230 rb_ary_empty_p(VALUE ary)
2231 {
2232  if (RARRAY_LEN(ary) == 0)
2233  return Qtrue;
2234  return Qfalse;
2235 }
2236 
2237 VALUE
2239 {
2240  long len = RARRAY_LEN(ary);
2241  VALUE dup = rb_ary_new2(len);
2242  ary_memcpy(dup, 0, len, RARRAY_CONST_PTR_TRANSIENT(ary));
2243  ARY_SET_LEN(dup, len);
2244 
2245  ary_verify(ary);
2246  ary_verify(dup);
2247  return dup;
2248 }
2249 
2250 VALUE
2252 {
2253  return ary_make_partial(ary, rb_cArray, 0, RARRAY_LEN(ary));
2254 }
2255 
2256 extern VALUE rb_output_fs;
2257 
2258 static void ary_join_1(VALUE obj, VALUE ary, VALUE sep, long i, VALUE result, int *first);
2259 
2260 static VALUE
2261 recursive_join(VALUE obj, VALUE argp, int recur)
2262 {
2263  VALUE *arg = (VALUE *)argp;
2264  VALUE ary = arg[0];
2265  VALUE sep = arg[1];
2266  VALUE result = arg[2];
2267  int *first = (int *)arg[3];
2268 
2269  if (recur) {
2270  rb_raise(rb_eArgError, "recursive array join");
2271  }
2272  else {
2273  ary_join_1(obj, ary, sep, 0, result, first);
2274  }
2275  return Qnil;
2276 }
2277 
2278 static void
2279 ary_join_0(VALUE ary, VALUE sep, long max, VALUE result)
2280 {
2281  long i;
2282  VALUE val;
2283 
2284  if (max > 0) rb_enc_copy(result, RARRAY_AREF(ary, 0));
2285  for (i=0; i<max; i++) {
2286  val = RARRAY_AREF(ary, i);
2287  if (i > 0 && !NIL_P(sep))
2288  rb_str_buf_append(result, sep);
2289  rb_str_buf_append(result, val);
2290  }
2291 }
2292 
2293 static void
2294 ary_join_1(VALUE obj, VALUE ary, VALUE sep, long i, VALUE result, int *first)
2295 {
2296  VALUE val, tmp;
2297 
2298  for (; i<RARRAY_LEN(ary); i++) {
2299  if (i > 0 && !NIL_P(sep))
2300  rb_str_buf_append(result, sep);
2301 
2302  val = RARRAY_AREF(ary, i);
2303  if (RB_TYPE_P(val, T_STRING)) {
2304  str_join:
2305  rb_str_buf_append(result, val);
2306  if (*first) {
2307  rb_enc_copy(result, val);
2308  *first = FALSE;
2309  }
2310  }
2311  else if (RB_TYPE_P(val, T_ARRAY)) {
2312  obj = val;
2313  ary_join:
2314  if (val == ary) {
2315  rb_raise(rb_eArgError, "recursive array join");
2316  }
2317  else {
2318  VALUE args[4];
2319 
2320  *first = FALSE;
2321  args[0] = val;
2322  args[1] = sep;
2323  args[2] = result;
2324  args[3] = (VALUE)first;
2325  rb_exec_recursive(recursive_join, obj, (VALUE)args);
2326  }
2327  }
2328  else {
2329  tmp = rb_check_string_type(val);
2330  if (!NIL_P(tmp)) {
2331  val = tmp;
2332  goto str_join;
2333  }
2334  tmp = rb_check_array_type(val);
2335  if (!NIL_P(tmp)) {
2336  obj = val;
2337  val = tmp;
2338  goto ary_join;
2339  }
2340  val = rb_obj_as_string(val);
2341  goto str_join;
2342  }
2343  }
2344 }
2345 
2346 VALUE
2348 {
2349  long len = 1, i;
2350  VALUE val, tmp, result;
2351 
2352  if (RARRAY_LEN(ary) == 0) return rb_usascii_str_new(0, 0);
2353 
2354  if (!NIL_P(sep)) {
2355  StringValue(sep);
2356  len += RSTRING_LEN(sep) * (RARRAY_LEN(ary) - 1);
2357  }
2358  for (i=0; i<RARRAY_LEN(ary); i++) {
2359  val = RARRAY_AREF(ary, i);
2360  tmp = rb_check_string_type(val);
2361 
2362  if (NIL_P(tmp) || tmp != val) {
2363  int first;
2364  result = rb_str_buf_new(len + (RARRAY_LEN(ary)-i)*10);
2366  ary_join_0(ary, sep, i, result);
2367  first = i == 0;
2368  ary_join_1(ary, ary, sep, i, result, &first);
2369  return result;
2370  }
2371 
2372  len += RSTRING_LEN(tmp);
2373  }
2374 
2375  result = rb_str_new(0, len);
2376  rb_str_set_len(result, 0);
2377 
2378  ary_join_0(ary, sep, RARRAY_LEN(ary), result);
2379 
2380  return result;
2381 }
2382 
2383 /*
2384  * call-seq:
2385  * ary.join(separator=$,) -> str
2386  *
2387  * Returns a string created by converting each element of the array to
2388  * a string, separated by the given +separator+.
2389  * If the +separator+ is +nil+, it uses current <code>$,</code>.
2390  * If both the +separator+ and <code>$,</code> are +nil+,
2391  * it uses an empty string.
2392  *
2393  * [ "a", "b", "c" ].join #=> "abc"
2394  * [ "a", "b", "c" ].join("-") #=> "a-b-c"
2395  *
2396  * For nested arrays, join is applied recursively:
2397  *
2398  * [ "a", [1, 2, [:x, :y]], "b" ].join("-") #=> "a-1-2-x-y-b"
2399  */
2400 
2401 static VALUE
2402 rb_ary_join_m(int argc, VALUE *argv, VALUE ary)
2403 {
2404  VALUE sep;
2405 
2406  if (rb_check_arity(argc, 0, 1) == 0 || NIL_P(sep = argv[0])) {
2407  sep = rb_output_fs;
2408  if (!NIL_P(sep)) {
2409  rb_warn("$, is set to non-nil value");
2410  }
2411  }
2412 
2413  return rb_ary_join(ary, sep);
2414 }
2415 
2416 static VALUE
2417 inspect_ary(VALUE ary, VALUE dummy, int recur)
2418 {
2419  long i;
2420  VALUE s, str;
2421 
2422  if (recur) return rb_usascii_str_new_cstr("[...]");
2423  str = rb_str_buf_new2("[");
2424  for (i=0; i<RARRAY_LEN(ary); i++) {
2425  s = rb_inspect(RARRAY_AREF(ary, i));
2426  if (i > 0) rb_str_buf_cat2(str, ", ");
2427  else rb_enc_copy(str, s);
2428  rb_str_buf_append(str, s);
2429  }
2430  rb_str_buf_cat2(str, "]");
2431  return str;
2432 }
2433 
2434 /*
2435  * call-seq:
2436  * ary.inspect -> string
2437  * ary.to_s -> string
2438  *
2439  * Creates a string representation of +self+, by calling #inspect
2440  * on each element.
2441  *
2442  * [ "a", "b", "c" ].to_s #=> "[\"a\", \"b\", \"c\"]"
2443  */
2444 
2445 static VALUE
2446 rb_ary_inspect(VALUE ary)
2447 {
2448  if (RARRAY_LEN(ary) == 0) return rb_usascii_str_new2("[]");
2449  return rb_exec_recursive(inspect_ary, ary, 0);
2450 }
2451 
2452 VALUE
2454 {
2455  return rb_ary_inspect(ary);
2456 }
2457 
2458 /*
2459  * call-seq:
2460  * ary.to_a -> ary
2461  *
2462  * Returns +self+.
2463  *
2464  * If called on a subclass of Array, converts the receiver to an Array object.
2465  */
2466 
2467 static VALUE
2468 rb_ary_to_a(VALUE ary)
2469 {
2470  if (rb_obj_class(ary) != rb_cArray) {
2471  VALUE dup = rb_ary_new2(RARRAY_LEN(ary));
2472  rb_ary_replace(dup, ary);
2473  return dup;
2474  }
2475  return ary;
2476 }
2477 
2478 /*
2479  * call-seq:
2480  * ary.to_h -> hash
2481  * ary.to_h {|item| block } -> hash
2482  *
2483  * Returns the result of interpreting <i>ary</i> as an array of
2484  * <tt>[key, value]</tt> pairs.
2485  *
2486  * [[:foo, :bar], [1, 2]].to_h
2487  * # => {:foo => :bar, 1 => 2}
2488  *
2489  * If a block is given, the results of the block on each element of
2490  * the array will be used as pairs.
2491  *
2492  * ["foo", "bar"].to_h {|s| [s.ord, s]}
2493  * # => {102=>"foo", 98=>"bar"}
2494  */
2495 
2496 static VALUE
2497 rb_ary_to_h(VALUE ary)
2498 {
2499  long i;
2500  VALUE hash = rb_hash_new_with_size(RARRAY_LEN(ary));
2501  int block_given = rb_block_given_p();
2502 
2503  for (i=0; i<RARRAY_LEN(ary); i++) {
2504  const VALUE e = rb_ary_elt(ary, i);
2505  const VALUE elt = block_given ? rb_yield_force_blockarg(e) : e;
2506  const VALUE key_value_pair = rb_check_array_type(elt);
2507  if (NIL_P(key_value_pair)) {
2508  rb_raise(rb_eTypeError, "wrong element type %"PRIsVALUE" at %ld (expected array)",
2509  rb_obj_class(elt), i);
2510  }
2511  if (RARRAY_LEN(key_value_pair) != 2) {
2512  rb_raise(rb_eArgError, "wrong array length at %ld (expected 2, was %ld)",
2513  i, RARRAY_LEN(key_value_pair));
2514  }
2515  rb_hash_aset(hash, RARRAY_AREF(key_value_pair, 0), RARRAY_AREF(key_value_pair, 1));
2516  }
2517  return hash;
2518 }
2519 
2520 /*
2521  * call-seq:
2522  * ary.to_ary -> ary
2523  *
2524  * Returns +self+.
2525  */
2526 
2527 static VALUE
2528 rb_ary_to_ary_m(VALUE ary)
2529 {
2530  return ary;
2531 }
2532 
2533 static void
2534 ary_reverse(VALUE *p1, VALUE *p2)
2535 {
2536  while (p1 < p2) {
2537  VALUE tmp = *p1;
2538  *p1++ = *p2;
2539  *p2-- = tmp;
2540  }
2541 }
2542 
2543 VALUE
2545 {
2546  VALUE *p2;
2547  long len = RARRAY_LEN(ary);
2548 
2549  rb_ary_modify(ary);
2550  if (len > 1) {
2551  RARRAY_PTR_USE_TRANSIENT(ary, p1, {
2552  p2 = p1 + len - 1; /* points last item */
2553  ary_reverse(p1, p2);
2554  }); /* WB: no new reference */
2555  }
2556  return ary;
2557 }
2558 
2559 /*
2560  * call-seq:
2561  * ary.reverse! -> ary
2562  *
2563  * Reverses +self+ in place.
2564  *
2565  * a = [ "a", "b", "c" ]
2566  * a.reverse! #=> ["c", "b", "a"]
2567  * a #=> ["c", "b", "a"]
2568  */
2569 
2570 static VALUE
2571 rb_ary_reverse_bang(VALUE ary)
2572 {
2573  return rb_ary_reverse(ary);
2574 }
2575 
2576 /*
2577  * call-seq:
2578  * ary.reverse -> new_ary
2579  *
2580  * Returns a new array containing +self+'s elements in reverse order.
2581  *
2582  * [ "a", "b", "c" ].reverse #=> ["c", "b", "a"]
2583  * [ 1 ].reverse #=> [1]
2584  */
2585 
2586 static VALUE
2587 rb_ary_reverse_m(VALUE ary)
2588 {
2589  long len = RARRAY_LEN(ary);
2590  VALUE dup = rb_ary_new2(len);
2591 
2592  if (len > 0) {
2593  const VALUE *p1 = RARRAY_CONST_PTR_TRANSIENT(ary);
2594  VALUE *p2 = (VALUE *)RARRAY_CONST_PTR_TRANSIENT(dup) + len - 1;
2595  do *p2-- = *p1++; while (--len > 0);
2596  }
2597  ARY_SET_LEN(dup, RARRAY_LEN(ary));
2598  return dup;
2599 }
2600 
2601 static inline long
2602 rotate_count(long cnt, long len)
2603 {
2604  return (cnt < 0) ? (len - (~cnt % len) - 1) : (cnt % len);
2605 }
2606 
2607 static void
2608 ary_rotate_ptr(VALUE *ptr, long len, long cnt)
2609 {
2610  --len;
2611  if (cnt < len) ary_reverse(ptr + cnt, ptr + len);
2612  if (--cnt > 0) ary_reverse(ptr, ptr + cnt);
2613  if (len > 0) ary_reverse(ptr, ptr + len);
2614 }
2615 
2616 VALUE
2618 {
2619  rb_ary_modify(ary);
2620 
2621  if (cnt != 0) {
2622  long len = RARRAY_LEN(ary);
2623  if (len > 0 && (cnt = rotate_count(cnt, len)) > 0) {
2624  RARRAY_PTR_USE_TRANSIENT(ary, ptr, ary_rotate_ptr(ptr, len, cnt));
2625  return ary;
2626  }
2627  }
2628  return Qnil;
2629 }
2630 
2631 /*
2632  * call-seq:
2633  * ary.rotate!(count=1) -> ary
2634  *
2635  * Rotates +self+ in place so that the element at +count+ comes first, and
2636  * returns +self+.
2637  *
2638  * If +count+ is negative then it rotates in the opposite direction, starting
2639  * from the end of the array where +-1+ is the last element.
2640  *
2641  * a = [ "a", "b", "c", "d" ]
2642  * a.rotate! #=> ["b", "c", "d", "a"]
2643  * a #=> ["b", "c", "d", "a"]
2644  * a.rotate!(2) #=> ["d", "a", "b", "c"]
2645  * a.rotate!(-3) #=> ["a", "b", "c", "d"]
2646  */
2647 
2648 static VALUE
2649 rb_ary_rotate_bang(int argc, VALUE *argv, VALUE ary)
2650 {
2651  long n = (rb_check_arity(argc, 0, 1) ? NUM2LONG(argv[0]) : 1);
2652  rb_ary_rotate(ary, n);
2653  return ary;
2654 }
2655 
2656 /*
2657  * call-seq:
2658  * ary.rotate(count=1) -> new_ary
2659  *
2660  * Returns a new array by rotating +self+ so that the element at +count+ is
2661  * the first element of the new array.
2662  *
2663  * If +count+ is negative then it rotates in the opposite direction, starting
2664  * from the end of +self+ where +-1+ is the last element.
2665  *
2666  * a = [ "a", "b", "c", "d" ]
2667  * a.rotate #=> ["b", "c", "d", "a"]
2668  * a #=> ["a", "b", "c", "d"]
2669  * a.rotate(2) #=> ["c", "d", "a", "b"]
2670  * a.rotate(-3) #=> ["b", "c", "d", "a"]
2671  */
2672 
2673 static VALUE
2674 rb_ary_rotate_m(int argc, VALUE *argv, VALUE ary)
2675 {
2676  VALUE rotated;
2677  const VALUE *ptr;
2678  long len;
2679  long cnt = (rb_check_arity(argc, 0, 1) ? NUM2LONG(argv[0]) : 1);
2680 
2681  len = RARRAY_LEN(ary);
2682  rotated = rb_ary_new2(len);
2683  if (len > 0) {
2684  cnt = rotate_count(cnt, len);
2686  len -= cnt;
2687  ary_memcpy(rotated, 0, len, ptr + cnt);
2688  ary_memcpy(rotated, len, cnt, ptr);
2689  }
2690  ARY_SET_LEN(rotated, RARRAY_LEN(ary));
2691  return rotated;
2692 }
2693 
2697 };
2698 
2699 static VALUE
2700 sort_reentered(VALUE ary)
2701 {
2702  if (RBASIC(ary)->klass) {
2703  rb_raise(rb_eRuntimeError, "sort reentered");
2704  }
2705  return Qnil;
2706 }
2707 
2708 static int
2709 sort_1(const void *ap, const void *bp, void *dummy)
2710 {
2711  struct ary_sort_data *data = dummy;
2712  VALUE retval = sort_reentered(data->ary);
2713  VALUE a = *(const VALUE *)ap, b = *(const VALUE *)bp;
2714  VALUE args[2];
2715  int n;
2716 
2717  args[0] = a;
2718  args[1] = b;
2719  retval = rb_yield_values2(2, args);
2720  n = rb_cmpint(retval, a, b);
2721  sort_reentered(data->ary);
2722  return n;
2723 }
2724 
2725 static int
2726 sort_2(const void *ap, const void *bp, void *dummy)
2727 {
2728  struct ary_sort_data *data = dummy;
2729  VALUE retval = sort_reentered(data->ary);
2730  VALUE a = *(const VALUE *)ap, b = *(const VALUE *)bp;
2731  int n;
2732 
2733  if (FIXNUM_P(a) && FIXNUM_P(b) && CMP_OPTIMIZABLE(data->cmp_opt, Fixnum)) {
2734  if ((long)a > (long)b) return 1;
2735  if ((long)a < (long)b) return -1;
2736  return 0;
2737  }
2738  if (STRING_P(a) && STRING_P(b) && CMP_OPTIMIZABLE(data->cmp_opt, String)) {
2739  return rb_str_cmp(a, b);
2740  }
2741  if (RB_FLOAT_TYPE_P(a) && CMP_OPTIMIZABLE(data->cmp_opt, Float)) {
2742  return rb_float_cmp(a, b);
2743  }
2744 
2745  retval = rb_funcallv(a, id_cmp, 1, &b);
2746  n = rb_cmpint(retval, a, b);
2747  sort_reentered(data->ary);
2748 
2749  return n;
2750 }
2751 
2752 /*
2753  * call-seq:
2754  * ary.sort! -> ary
2755  * ary.sort! {|a, b| block} -> ary
2756  *
2757  * Sorts +self+ in place.
2758  *
2759  * Comparisons for the sort will be done using the <code><=></code> operator
2760  * or using an optional code block.
2761  *
2762  * The block must implement a comparison between +a+ and +b+ and return
2763  * an integer less than 0 when +b+ follows +a+, +0+ when +a+ and +b+
2764  * are equivalent, or an integer greater than 0 when +a+ follows +b+.
2765  *
2766  * The result is not guaranteed to be stable. When the comparison of two
2767  * elements returns +0+, the order of the elements is unpredictable.
2768  *
2769  * ary = [ "d", "a", "e", "c", "b" ]
2770  * ary.sort! #=> ["a", "b", "c", "d", "e"]
2771  * ary.sort! {|a, b| b <=> a} #=> ["e", "d", "c", "b", "a"]
2772  *
2773  * See also Enumerable#sort_by.
2774  */
2775 
2776 VALUE
2778 {
2779  rb_ary_modify(ary);
2780  assert(!ARY_SHARED_P(ary));
2781  if (RARRAY_LEN(ary) > 1) {
2782  VALUE tmp = ary_make_substitution(ary); /* only ary refers tmp */
2783  struct ary_sort_data data;
2784  long len = RARRAY_LEN(ary);
2785  RBASIC_CLEAR_CLASS(tmp);
2786  data.ary = tmp;
2787  data.cmp_opt.opt_methods = 0;
2788  data.cmp_opt.opt_inited = 0;
2789  RARRAY_PTR_USE(tmp, ptr, {
2790  ruby_qsort(ptr, len, sizeof(VALUE),
2791  rb_block_given_p()?sort_1:sort_2, &data);
2792  }); /* WB: no new reference */
2793  rb_ary_modify(ary);
2794  if (ARY_EMBED_P(tmp)) {
2795  if (ARY_SHARED_P(ary)) { /* ary might be destructively operated in the given block */
2796  rb_ary_unshare(ary);
2797  FL_SET_EMBED(ary);
2798  }
2799  ary_memcpy(ary, 0, ARY_EMBED_LEN(tmp), ARY_EMBED_PTR(tmp));
2800  ARY_SET_LEN(ary, ARY_EMBED_LEN(tmp));
2801  }
2802  else {
2803  if (!ARY_EMBED_P(ary) && ARY_HEAP_PTR(ary) == ARY_HEAP_PTR(tmp)) {
2805  ARY_SET_CAPA(ary, RARRAY_LEN(tmp));
2806  }
2807  else {
2808  assert(!ARY_SHARED_P(tmp));
2809  if (ARY_EMBED_P(ary)) {
2811  }
2812  else if (ARY_SHARED_P(ary)) {
2813  /* ary might be destructively operated in the given block */
2814  rb_ary_unshare(ary);
2815  }
2816  else {
2817  ary_heap_free(ary);
2818  }
2819  ARY_SET_PTR(ary, ARY_HEAP_PTR(tmp));
2821  ARY_SET_CAPA(ary, ARY_HEAP_LEN(tmp));
2822  }
2823  /* tmp was lost ownership for the ptr */
2824  FL_UNSET(tmp, FL_FREEZE);
2825  FL_SET_EMBED(tmp);
2826  ARY_SET_EMBED_LEN(tmp, 0);
2827  FL_SET(tmp, FL_FREEZE);
2828  }
2829  /* tmp will be GC'ed. */
2830  RBASIC_SET_CLASS_RAW(tmp, rb_cArray); /* rb_cArray must be marked */
2831  }
2832  ary_verify(ary);
2833  return ary;
2834 }
2835 
2836 /*
2837  * call-seq:
2838  * ary.sort -> new_ary
2839  * ary.sort {|a, b| block} -> new_ary
2840  *
2841  * Returns a new array created by sorting +self+.
2842  *
2843  * Comparisons for the sort will be done using the <code><=></code> operator
2844  * or using an optional code block.
2845  *
2846  * The block must implement a comparison between +a+ and +b+ and return
2847  * an integer less than 0 when +b+ follows +a+, +0+ when +a+ and +b+
2848  * are equivalent, or an integer greater than 0 when +a+ follows +b+.
2849  *
2850  * The result is not guaranteed to be stable. When the comparison of two
2851  * elements returns +0+, the order of the elements is unpredictable.
2852  *
2853  * ary = [ "d", "a", "e", "c", "b" ]
2854  * ary.sort #=> ["a", "b", "c", "d", "e"]
2855  * ary.sort {|a, b| b <=> a} #=> ["e", "d", "c", "b", "a"]
2856  *
2857  * To produce the reverse order, the following can also be used
2858  * (and may be faster):
2859  *
2860  * ary.sort.reverse! #=> ["e", "d", "c", "b", "a"]
2861  *
2862  * See also Enumerable#sort_by.
2863  */
2864 
2865 VALUE
2867 {
2868  ary = rb_ary_dup(ary);
2870  return ary;
2871 }
2872 
2873 static VALUE rb_ary_bsearch_index(VALUE ary);
2874 
2875 /*
2876  * call-seq:
2877  * ary.bsearch {|x| block } -> elem
2878  *
2879  * By using binary search, finds a value from this array which meets
2880  * the given condition in O(log n) where n is the size of the array.
2881  *
2882  * You can use this method in two modes: a find-minimum mode and
2883  * a find-any mode. In either case, the elements of the array must be
2884  * monotone (or sorted) with respect to the block.
2885  *
2886  * In find-minimum mode (this is a good choice for typical use cases),
2887  * the block must always return true or false, and there must be an index i
2888  * (0 <= i <= ary.size) so that:
2889  *
2890  * - the block returns false for any element whose index is less than
2891  * i, and
2892  * - the block returns true for any element whose index is greater
2893  * than or equal to i.
2894  *
2895  * This method returns the i-th element. If i is equal to ary.size,
2896  * it returns nil.
2897  *
2898  * ary = [0, 4, 7, 10, 12]
2899  * ary.bsearch {|x| x >= 4 } #=> 4
2900  * ary.bsearch {|x| x >= 6 } #=> 7
2901  * ary.bsearch {|x| x >= -1 } #=> 0
2902  * ary.bsearch {|x| x >= 100 } #=> nil
2903  *
2904  * In find-any mode (this behaves like libc's bsearch(3)), the block
2905  * must always return a number, and there must be two indices i and j
2906  * (0 <= i <= j <= ary.size) so that:
2907  *
2908  * - the block returns a positive number for ary[k] if 0 <= k < i,
2909  * - the block returns zero for ary[k] if i <= k < j, and
2910  * - the block returns a negative number for ary[k] if
2911  * j <= k < ary.size.
2912  *
2913  * Under this condition, this method returns any element whose index
2914  * is within i...j. If i is equal to j (i.e., there is no element
2915  * that satisfies the block), this method returns nil.
2916  *
2917  * ary = [0, 4, 7, 10, 12]
2918  * # try to find v such that 4 <= v < 8
2919  * ary.bsearch {|x| 1 - x / 4 } #=> 4 or 7
2920  * # try to find v such that 8 <= v < 10
2921  * ary.bsearch {|x| 4 - x / 2 } #=> nil
2922  *
2923  * You must not mix the two modes at a time; the block must always
2924  * return either true/false, or always return a number. It is
2925  * undefined which value is actually picked up at each iteration.
2926  */
2927 
2928 static VALUE
2929 rb_ary_bsearch(VALUE ary)
2930 {
2931  VALUE index_result = rb_ary_bsearch_index(ary);
2932 
2933  if (FIXNUM_P(index_result)) {
2934  return rb_ary_entry(ary, FIX2LONG(index_result));
2935  }
2936  return index_result;
2937 }
2938 
2939 /*
2940  * call-seq:
2941  * ary.bsearch_index {|x| block } -> int or nil
2942  *
2943  * By using binary search, finds an index of a value from this array which
2944  * meets the given condition in O(log n) where n is the size of the array.
2945  *
2946  * It supports two modes, depending on the nature of the block. They are
2947  * exactly the same as in the case of the #bsearch method, with the only difference
2948  * being that this method returns the index of the element instead of the
2949  * element itself. For more details consult the documentation for #bsearch.
2950  */
2951 
2952 static VALUE
2953 rb_ary_bsearch_index(VALUE ary)
2954 {
2955  long low = 0, high = RARRAY_LEN(ary), mid;
2956  int smaller = 0, satisfied = 0;
2957  VALUE v, val;
2958 
2959  RETURN_ENUMERATOR(ary, 0, 0);
2960  while (low < high) {
2961  mid = low + ((high - low) / 2);
2962  val = rb_ary_entry(ary, mid);
2963  v = rb_yield(val);
2964  if (FIXNUM_P(v)) {
2965  if (v == INT2FIX(0)) return INT2FIX(mid);
2966  smaller = (SIGNED_VALUE)v < 0; /* Fixnum preserves its sign-bit */
2967  }
2968  else if (v == Qtrue) {
2969  satisfied = 1;
2970  smaller = 1;
2971  }
2972  else if (v == Qfalse || v == Qnil) {
2973  smaller = 0;
2974  }
2975  else if (rb_obj_is_kind_of(v, rb_cNumeric)) {
2976  const VALUE zero = INT2FIX(0);
2977  switch (rb_cmpint(rb_funcallv(v, id_cmp, 1, &zero), v, zero)) {
2978  case 0: return INT2FIX(mid);
2979  case 1: smaller = 1; break;
2980  case -1: smaller = 0;
2981  }
2982  }
2983  else {
2984  rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE
2985  " (must be numeric, true, false or nil)",
2986  rb_obj_class(v));
2987  }
2988  if (smaller) {
2989  high = mid;
2990  }
2991  else {
2992  low = mid + 1;
2993  }
2994  }
2995  if (!satisfied) return Qnil;
2996  return INT2FIX(low);
2997 }
2998 
2999 
3000 static VALUE
3001 sort_by_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, dummy))
3002 {
3003  return rb_yield(i);
3004 }
3005 
3006 /*
3007  * call-seq:
3008  * ary.sort_by! {|obj| block} -> ary
3009  * ary.sort_by! -> Enumerator
3010  *
3011  * Sorts +self+ in place using a set of keys generated by mapping the
3012  * values in +self+ through the given block.
3013  *
3014  * The result is not guaranteed to be stable. When two keys are equal,
3015  * the order of the corresponding elements is unpredictable.
3016  *
3017  * If no block is given, an Enumerator is returned instead.
3018  *
3019  * See also Enumerable#sort_by.
3020  */
3021 
3022 static VALUE
3023 rb_ary_sort_by_bang(VALUE ary)
3024 {
3025  VALUE sorted;
3026 
3027  RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
3028  rb_ary_modify(ary);
3029  sorted = rb_block_call(ary, rb_intern("sort_by"), 0, 0, sort_by_i, 0);
3030  rb_ary_replace(ary, sorted);
3031  return ary;
3032 }
3033 
3034 
3035 /*
3036  * call-seq:
3037  * ary.collect {|item| block} -> new_ary
3038  * ary.map {|item| block} -> new_ary
3039  * ary.collect -> Enumerator
3040  * ary.map -> Enumerator
3041  *
3042  * Invokes the given block once for each element of +self+.
3043  *
3044  * Creates a new array containing the values returned by the block.
3045  *
3046  * See also Enumerable#collect.
3047  *
3048  * If no block is given, an Enumerator is returned instead.
3049  *
3050  * a = [ "a", "b", "c", "d" ]
3051  * a.collect {|x| x + "!"} #=> ["a!", "b!", "c!", "d!"]
3052  * a.map.with_index {|x, i| x * i} #=> ["", "b", "cc", "ddd"]
3053  * a #=> ["a", "b", "c", "d"]
3054  */
3055 
3056 static VALUE
3057 rb_ary_collect(VALUE ary)
3058 {
3059  long i;
3060  VALUE collect;
3061 
3062  RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
3063  collect = rb_ary_new2(RARRAY_LEN(ary));
3064  for (i = 0; i < RARRAY_LEN(ary); i++) {
3065  rb_ary_push(collect, rb_yield(RARRAY_AREF(ary, i)));
3066  }
3067  return collect;
3068 }
3069 
3070 
3071 /*
3072  * call-seq:
3073  * ary.collect! {|item| block } -> ary
3074  * ary.map! {|item| block } -> ary
3075  * ary.collect! -> Enumerator
3076  * ary.map! -> Enumerator
3077  *
3078  * Invokes the given block once for each element of +self+, replacing the
3079  * element with the value returned by the block.
3080  *
3081  * See also Enumerable#collect.
3082  *
3083  * If no block is given, an Enumerator is returned instead.
3084  *
3085  * a = [ "a", "b", "c", "d" ]
3086  * a.map! {|x| x + "!" }
3087  * a #=> [ "a!", "b!", "c!", "d!" ]
3088  * a.collect!.with_index {|x, i| x[0...i] }
3089  * a #=> ["", "b", "c!", "d!"]
3090  */
3091 
3092 static VALUE
3093 rb_ary_collect_bang(VALUE ary)
3094 {
3095  long i;
3096 
3097  RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
3098  rb_ary_modify(ary);
3099  for (i = 0; i < RARRAY_LEN(ary); i++) {
3101  }
3102  return ary;
3103 }
3104 
3105 VALUE
3106 rb_get_values_at(VALUE obj, long olen, int argc, const VALUE *argv, VALUE (*func) (VALUE, long))
3107 {
3108  VALUE result = rb_ary_new2(argc);
3109  long beg, len, i, j;
3110 
3111  for (i=0; i<argc; i++) {
3112  if (FIXNUM_P(argv[i])) {
3113  rb_ary_push(result, (*func)(obj, FIX2LONG(argv[i])));
3114  continue;
3115  }
3116  /* check if idx is Range */
3117  if (rb_range_beg_len(argv[i], &beg, &len, olen, 1)) {
3118  long end = olen < beg+len ? olen : beg+len;
3119  for (j = beg; j < end; j++) {
3120  rb_ary_push(result, (*func)(obj, j));
3121  }
3122  if (beg + len > j)
3123  rb_ary_resize(result, RARRAY_LEN(result) + (beg + len) - j);
3124  continue;
3125  }
3126  rb_ary_push(result, (*func)(obj, NUM2LONG(argv[i])));
3127  }
3128  return result;
3129 }
3130 
3131 static VALUE
3132 append_values_at_single(VALUE result, VALUE ary, long olen, VALUE idx)
3133 {
3134  long beg, len;
3135  if (FIXNUM_P(idx)) {
3136  beg = FIX2LONG(idx);
3137  }
3138  /* check if idx is Range */
3139  else if (rb_range_beg_len(idx, &beg, &len, olen, 1)) {
3140  if (len > 0) {
3141  const VALUE *const src = RARRAY_CONST_PTR_TRANSIENT(ary);
3142  const long end = beg + len;
3143  const long prevlen = RARRAY_LEN(result);
3144  if (beg < olen) {
3145  rb_ary_cat(result, src + beg, end > olen ? olen-beg : len);
3146  }
3147  if (end > olen) {
3148  rb_ary_store(result, prevlen + len - 1, Qnil);
3149  }
3150  }
3151  return result;
3152  }
3153  else {
3154  beg = NUM2LONG(idx);
3155  }
3156  return rb_ary_push(result, rb_ary_entry(ary, beg));
3157 }
3158 
3159 /*
3160  * call-seq:
3161  * ary.values_at(selector, ...) -> new_ary
3162  *
3163  * Returns an array containing the elements in +self+ corresponding to the
3164  * given +selector+(s).
3165  *
3166  * The selectors may be either integer indices or ranges.
3167  *
3168  * See also Array#select.
3169  *
3170  * a = %w{ a b c d e f }
3171  * a.values_at(1, 3, 5) # => ["b", "d", "f"]
3172  * a.values_at(1, 3, 5, 7) # => ["b", "d", "f", nil]
3173  * a.values_at(-1, -2, -2, -7) # => ["f", "e", "e", nil]
3174  * a.values_at(4..6, 3...6) # => ["e", "f", nil, "d", "e", "f"]
3175  */
3176 
3177 static VALUE
3178 rb_ary_values_at(int argc, VALUE *argv, VALUE ary)
3179 {
3180  long i, olen = RARRAY_LEN(ary);
3181  VALUE result = rb_ary_new_capa(argc);
3182  for (i = 0; i < argc; ++i) {
3183  append_values_at_single(result, ary, olen, argv[i]);
3184  }
3185  RB_GC_GUARD(ary);
3186  return result;
3187 }
3188 
3189 
3190 /*
3191  * call-seq:
3192  * ary.select {|item| block} -> new_ary
3193  * ary.select -> Enumerator
3194  * ary.filter {|item| block} -> new_ary
3195  * ary.filter -> Enumerator
3196  *
3197  * Returns a new array containing all elements of +ary+
3198  * for which the given +block+ returns a true value.
3199  *
3200  * If no block is given, an Enumerator is returned instead.
3201  *
3202  * [1,2,3,4,5].select {|num| num.even? } #=> [2, 4]
3203  *
3204  * a = %w[ a b c d e f ]
3205  * a.select {|v| v =~ /[aeiou]/ } #=> ["a", "e"]
3206  *
3207  * See also Enumerable#select.
3208  *
3209  * Array#filter is an alias for Array#select.
3210  */
3211 
3212 static VALUE
3213 rb_ary_select(VALUE ary)
3214 {
3215  VALUE result;
3216  long i;
3217 
3218  RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
3219  result = rb_ary_new2(RARRAY_LEN(ary));
3220  for (i = 0; i < RARRAY_LEN(ary); i++) {
3221  if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) {
3222  rb_ary_push(result, rb_ary_elt(ary, i));
3223  }
3224  }
3225  return result;
3226 }
3227 
3230  long len[2];
3231 };
3232 
3233 static VALUE
3234 select_bang_i(VALUE a)
3235 {
3236  volatile struct select_bang_arg *arg = (void *)a;
3237  VALUE ary = arg->ary;
3238  long i1, i2;
3239 
3240  for (i1 = i2 = 0; i1 < RARRAY_LEN(ary); arg->len[0] = ++i1) {
3241  VALUE v = RARRAY_AREF(ary, i1);
3242  if (!RTEST(rb_yield(v))) continue;
3243  if (i1 != i2) {
3244  rb_ary_store(ary, i2, v);
3245  }
3246  arg->len[1] = ++i2;
3247  }
3248  return (i1 == i2) ? Qnil : ary;
3249 }
3250 
3251 static VALUE
3252 select_bang_ensure(VALUE a)
3253 {
3254  volatile struct select_bang_arg *arg = (void *)a;
3255  VALUE ary = arg->ary;
3256  long len = RARRAY_LEN(ary);
3257  long i1 = arg->len[0], i2 = arg->len[1];
3258 
3259  if (i2 < len && i2 < i1) {
3260  long tail = 0;
3261  if (i1 < len) {
3262  tail = len - i1;
3264  MEMMOVE(ptr + i2, ptr + i1, VALUE, tail);
3265  });
3266  }
3267  ARY_SET_LEN(ary, i2 + tail);
3268  }
3269  return ary;
3270 }
3271 
3272 /*
3273  * call-seq:
3274  * ary.select! {|item| block } -> ary or nil
3275  * ary.select! -> Enumerator
3276  * ary.filter! {|item| block } -> ary or nil
3277  * ary.filter! -> Enumerator
3278  *
3279  * Invokes the given block passing in successive elements from +self+,
3280  * deleting elements for which the block returns a +false+ value.
3281  *
3282  * The array may not be changed instantly every time the block is called.
3283  *
3284  * If changes were made, it will return +self+, otherwise it returns +nil+.
3285  *
3286  * If no block is given, an Enumerator is returned instead.
3287  *
3288  * See also Array#keep_if.
3289  *
3290  * Array#filter! is an alias for Array#select!.
3291  */
3292 
3293 static VALUE
3294 rb_ary_select_bang(VALUE ary)
3295 {
3296  struct select_bang_arg args;
3297 
3298  RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
3299  rb_ary_modify(ary);
3300 
3301  args.ary = ary;
3302  args.len[0] = args.len[1] = 0;
3303  return rb_ensure(select_bang_i, (VALUE)&args, select_bang_ensure, (VALUE)&args);
3304 }
3305 
3306 /*
3307  * call-seq:
3308  * ary.keep_if {|item| block} -> ary
3309  * ary.keep_if -> Enumerator
3310  *
3311  * Deletes every element of +self+ for which the given block evaluates to
3312  * +false+, and returns +self+.
3313  *
3314  * If no block is given, an Enumerator is returned instead.
3315  *
3316  * a = %w[ a b c d e f ]
3317  * a.keep_if {|v| v =~ /[aeiou]/ } #=> ["a", "e"]
3318  * a #=> ["a", "e"]
3319  *
3320  * See also Array#select!.
3321  */
3322 
3323 static VALUE
3324 rb_ary_keep_if(VALUE ary)
3325 {
3326  RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
3327  rb_ary_select_bang(ary);
3328  return ary;
3329 }
3330 
3331 static void
3332 ary_resize_smaller(VALUE ary, long len)
3333 {
3334  rb_ary_modify(ary);
3335  if (RARRAY_LEN(ary) > len) {
3336  ARY_SET_LEN(ary, len);
3337  if (len * 2 < ARY_CAPA(ary) &&
3339  ary_resize_capa(ary, len * 2);
3340  }
3341  }
3342 }
3343 
3344 /*
3345  * call-seq:
3346  * ary.delete(obj) -> item or nil
3347  * ary.delete(obj) {block} -> item or result of block
3348  *
3349  * Deletes all items from +self+ that are equal to +obj+.
3350  *
3351  * Returns the last deleted item, or +nil+ if no matching item is found.
3352  *
3353  * If the optional code block is given, the result of the block is returned if
3354  * the item is not found. (To remove +nil+ elements and get an informative
3355  * return value, use Array#compact!)
3356  *
3357  * a = [ "a", "b", "b", "b", "c" ]
3358  * a.delete("b") #=> "b"
3359  * a #=> ["a", "c"]
3360  * a.delete("z") #=> nil
3361  * a.delete("z") {"not found"} #=> "not found"
3362  */
3363 
3364 VALUE
3366 {
3367  VALUE v = item;
3368  long i1, i2;
3369 
3370  for (i1 = i2 = 0; i1 < RARRAY_LEN(ary); i1++) {
3371  VALUE e = RARRAY_AREF(ary, i1);
3372 
3373  if (rb_equal(e, item)) {
3374  v = e;
3375  continue;
3376  }
3377  if (i1 != i2) {
3378  rb_ary_store(ary, i2, e);
3379  }
3380  i2++;
3381  }
3382  if (RARRAY_LEN(ary) == i2) {
3383  if (rb_block_given_p()) {
3384  return rb_yield(item);
3385  }
3386  return Qnil;
3387  }
3388 
3389  ary_resize_smaller(ary, i2);
3390 
3391  ary_verify(ary);
3392  return v;
3393 }
3394 
3395 void
3397 {
3398  long i1, i2;
3399 
3400  for (i1 = i2 = 0; i1 < RARRAY_LEN(ary); i1++) {
3401  VALUE e = RARRAY_AREF(ary, i1);
3402 
3403  if (e == item) {
3404  continue;
3405  }
3406  if (i1 != i2) {
3407  rb_ary_store(ary, i2, e);
3408  }
3409  i2++;
3410  }
3411  if (RARRAY_LEN(ary) == i2) {
3412  return;
3413  }
3414 
3415  ary_resize_smaller(ary, i2);
3416 }
3417 
3418 VALUE
3420 {
3421  long len = RARRAY_LEN(ary);
3422  VALUE del;
3423 
3424  if (pos >= len) return Qnil;
3425  if (pos < 0) {
3426  pos += len;
3427  if (pos < 0) return Qnil;
3428  }
3429 
3430  rb_ary_modify(ary);
3431  del = RARRAY_AREF(ary, pos);
3433  MEMMOVE(ptr+pos, ptr+pos+1, VALUE, len-pos-1);
3434  });
3435  ARY_INCREASE_LEN(ary, -1);
3436  ary_verify(ary);
3437  return del;
3438 }
3439 
3440 /*
3441  * call-seq:
3442  * ary.delete_at(index) -> obj or nil
3443  *
3444  * Deletes the element at the specified +index+, returning that element, or
3445  * +nil+ if the +index+ is out of range.
3446  *
3447  * See also Array#slice!
3448  *
3449  * a = ["ant", "bat", "cat", "dog"]
3450  * a.delete_at(2) #=> "cat"
3451  * a #=> ["ant", "bat", "dog"]
3452  * a.delete_at(99) #=> nil
3453  */
3454 
3455 static VALUE
3456 rb_ary_delete_at_m(VALUE ary, VALUE pos)
3457 {
3458  return rb_ary_delete_at(ary, NUM2LONG(pos));
3459 }
3460 
3461 /*
3462  * call-seq:
3463  * ary.slice!(index) -> obj or nil
3464  * ary.slice!(start, length) -> new_ary or nil
3465  * ary.slice!(range) -> new_ary or nil
3466  *
3467  * Deletes the element(s) given by an +index+ (optionally up to +length+
3468  * elements) or by a +range+.
3469  *
3470  * Returns the deleted object (or objects), or +nil+ if the +index+ is out of
3471  * range.
3472  *
3473  * a = [ "a", "b", "c" ]
3474  * a.slice!(1) #=> "b"
3475  * a #=> ["a", "c"]
3476  * a.slice!(-1) #=> "c"
3477  * a #=> ["a"]
3478  * a.slice!(100) #=> nil
3479  * a #=> ["a"]
3480  */
3481 
3482 static VALUE
3483 rb_ary_slice_bang(int argc, VALUE *argv, VALUE ary)
3484 {
3485  VALUE arg1, arg2;
3486  long pos, len, orig_len;
3487 
3488  rb_ary_modify_check(ary);
3489  if (argc == 2) {
3490  pos = NUM2LONG(argv[0]);
3491  len = NUM2LONG(argv[1]);
3492  delete_pos_len:
3493  if (len < 0) return Qnil;
3494  orig_len = RARRAY_LEN(ary);
3495  if (pos < 0) {
3496  pos += orig_len;
3497  if (pos < 0) return Qnil;
3498  }
3499  else if (orig_len < pos) return Qnil;
3500  if (orig_len < pos + len) {
3501  len = orig_len - pos;
3502  }
3503  if (len == 0) return rb_ary_new2(0);
3506  rb_ary_splice(ary, pos, len, 0, 0);
3507  return arg2;
3508  }
3509 
3510  rb_check_arity(argc, 1, 2);
3511  arg1 = argv[0];
3512 
3513  if (!FIXNUM_P(arg1)) {
3514  switch (rb_range_beg_len(arg1, &pos, &len, RARRAY_LEN(ary), 0)) {
3515  case Qtrue:
3516  /* valid range */
3517  goto delete_pos_len;
3518  case Qnil:
3519  /* invalid range */
3520  return Qnil;
3521  default:
3522  /* not a range */
3523  break;
3524  }
3525  }
3526 
3527  return rb_ary_delete_at(ary, NUM2LONG(arg1));
3528 }
3529 
3530 static VALUE
3531 ary_reject(VALUE orig, VALUE result)
3532 {
3533  long i;
3534 
3535  for (i = 0; i < RARRAY_LEN(orig); i++) {
3536  VALUE v = RARRAY_AREF(orig, i);
3537 
3538  if (!RTEST(rb_yield(v))) {
3539  rb_ary_push(result, v);
3540  }
3541  }
3542  return result;
3543 }
3544 
3545 static VALUE
3546 reject_bang_i(VALUE a)
3547 {
3548  volatile struct select_bang_arg *arg = (void *)a;
3549  VALUE ary = arg->ary;
3550  long i1, i2;
3551 
3552  for (i1 = i2 = 0; i1 < RARRAY_LEN(ary); arg->len[0] = ++i1) {
3553  VALUE v = RARRAY_AREF(ary, i1);
3554  if (RTEST(rb_yield(v))) continue;
3555  if (i1 != i2) {
3556  rb_ary_store(ary, i2, v);
3557  }
3558  arg->len[1] = ++i2;
3559  }
3560  return (i1 == i2) ? Qnil : ary;
3561 }
3562 
3563 static VALUE
3564 ary_reject_bang(VALUE ary)
3565 {
3566  struct select_bang_arg args;
3567  rb_ary_modify_check(ary);
3568  args.ary = ary;
3569  args.len[0] = args.len[1] = 0;
3570  return rb_ensure(reject_bang_i, (VALUE)&args, select_bang_ensure, (VALUE)&args);
3571 }
3572 
3573 /*
3574  * call-seq:
3575  * ary.reject! {|item| block} -> ary or nil
3576  * ary.reject! -> Enumerator
3577  *
3578  * Deletes every element of +self+ for which the block evaluates to +true+,
3579  * if no changes were made returns +nil+.
3580  *
3581  * The array may not be changed instantly every time the block is called.
3582  *
3583  * See also Enumerable#reject and Array#delete_if.
3584  *
3585  * If no block is given, an Enumerator is returned instead.
3586  */
3587 
3588 static VALUE
3589 rb_ary_reject_bang(VALUE ary)
3590 {
3591  RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
3592  rb_ary_modify(ary);
3593  return ary_reject_bang(ary);
3594 }
3595 
3596 /*
3597  * call-seq:
3598  * ary.reject {|item| block } -> new_ary
3599  * ary.reject -> Enumerator
3600  *
3601  * Returns a new array containing the items in +self+ for which the given
3602  * block is not +true+. The ordering of non-rejected elements is maintained.
3603  *
3604  * See also Array#delete_if
3605  *
3606  * If no block is given, an Enumerator is returned instead.
3607  */
3608 
3609 static VALUE
3610 rb_ary_reject(VALUE ary)
3611 {
3612  VALUE rejected_ary;
3613 
3614  RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
3615  rejected_ary = rb_ary_new();
3616  ary_reject(ary, rejected_ary);
3617  return rejected_ary;
3618 }
3619 
3620 /*
3621  * call-seq:
3622  * ary.delete_if {|item| block} -> ary
3623  * ary.delete_if -> Enumerator
3624  *
3625  * Deletes every element of +self+ for which block evaluates to +true+.
3626  *
3627  * The array is changed instantly every time the block is called, not after
3628  * the iteration is over.
3629  *
3630  * See also Array#reject!
3631  *
3632  * If no block is given, an Enumerator is returned instead.
3633  *
3634  * scores = [ 97, 42, 75 ]
3635  * scores.delete_if {|score| score < 80 } #=> [97]
3636  */
3637 
3638 static VALUE
3639 rb_ary_delete_if(VALUE ary)
3640 {
3641  ary_verify(ary);
3642  RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
3643  ary_reject_bang(ary);
3644  return ary;
3645 }
3646 
3647 static VALUE
3648 take_i(RB_BLOCK_CALL_FUNC_ARGLIST(val, cbarg))
3649 {
3650  VALUE *args = (VALUE *)cbarg;
3651  if (args[1] == 0) rb_iter_break();
3652  else args[1]--;
3653  if (argc > 1) val = rb_ary_new4(argc, argv);
3654  rb_ary_push(args[0], val);
3655  return Qnil;
3656 }
3657 
3658 static VALUE
3659 take_items(VALUE obj, long n)
3660 {
3661  VALUE result = rb_check_array_type(obj);
3662  VALUE args[2];
3663 
3664  if (!NIL_P(result)) return rb_ary_subseq(result, 0, n);
3665  result = rb_ary_new2(n);
3666  args[0] = result; args[1] = (VALUE)n;
3667  if (rb_check_block_call(obj, idEach, 0, 0, take_i, (VALUE)args) == Qundef)
3668  rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (must respond to :each)",
3669  rb_obj_class(obj));
3670  return result;
3671 }
3672 
3673 
3674 /*
3675  * call-seq:
3676  * ary.zip(arg, ...) -> new_ary
3677  * ary.zip(arg, ...) {|arr| block} -> nil
3678  *
3679  * Converts any arguments to arrays, then merges elements of +self+ with
3680  * corresponding elements from each argument.
3681  *
3682  * This generates a sequence of <code>ary.size</code> _n_-element arrays,
3683  * where _n_ is one more than the count of arguments.
3684  *
3685  * If the size of any argument is less than the size of the initial array,
3686  * +nil+ values are supplied.
3687  *
3688  * If a block is given, it is invoked for each output +array+, otherwise an
3689  * array of arrays is returned.
3690  *
3691  * a = [ 4, 5, 6 ]
3692  * b = [ 7, 8, 9 ]
3693  * [1, 2, 3].zip(a, b) #=> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
3694  * [1, 2].zip(a, b) #=> [[1, 4, 7], [2, 5, 8]]
3695  * a.zip([1, 2], [8]) #=> [[4, 1, 8], [5, 2, nil], [6, nil, nil]]
3696  */
3697 
3698 static VALUE
3699 rb_ary_zip(int argc, VALUE *argv, VALUE ary)
3700 {
3701  int i, j;
3702  long len = RARRAY_LEN(ary);
3703  VALUE result = Qnil;
3704 
3705  for (i=0; i<argc; i++) {
3706  argv[i] = take_items(argv[i], len);
3707  }
3708 
3709  if (rb_block_given_p()) {
3710  int arity = rb_block_arity();
3711 
3712  if (arity > 1) {
3713  VALUE work, *tmp;
3714 
3715  tmp = ALLOCV_N(VALUE, work, argc+1);
3716 
3717  for (i=0; i<RARRAY_LEN(ary); i++) {
3718  tmp[0] = RARRAY_AREF(ary, i);
3719  for (j=0; j<argc; j++) {
3720  tmp[j+1] = rb_ary_elt(argv[j], i);
3721  }
3722  rb_yield_values2(argc+1, tmp);
3723  }
3724 
3725  if (work) ALLOCV_END(work);
3726  }
3727  else {
3728  for (i=0; i<RARRAY_LEN(ary); i++) {
3729  VALUE tmp = rb_ary_new2(argc+1);
3730 
3731  rb_ary_push(tmp, RARRAY_AREF(ary, i));
3732  for (j=0; j<argc; j++) {
3733  rb_ary_push(tmp, rb_ary_elt(argv[j], i));
3734  }
3735  rb_yield(tmp);
3736  }
3737  }
3738  }
3739  else {
3740  result = rb_ary_new_capa(len);
3741 
3742  for (i=0; i<len; i++) {
3743  VALUE tmp = rb_ary_new_capa(argc+1);
3744 
3745  rb_ary_push(tmp, RARRAY_AREF(ary, i));
3746  for (j=0; j<argc; j++) {
3747  rb_ary_push(tmp, rb_ary_elt(argv[j], i));
3748  }
3749  rb_ary_push(result, tmp);
3750  }
3751  }
3752 
3753  return result;
3754 }
3755 
3756 /*
3757  * call-seq:
3758  * ary.transpose -> new_ary
3759  *
3760  * Assumes that +self+ is an array of arrays and transposes the rows and
3761  * columns.
3762  *
3763  * a = [[1,2], [3,4], [5,6]]
3764  * a.transpose #=> [[1, 3, 5], [2, 4, 6]]
3765  *
3766  * If the length of the subarrays don't match, an IndexError is raised.
3767  */
3768 
3769 static VALUE
3770 rb_ary_transpose(VALUE ary)
3771 {
3772  long elen = -1, alen, i, j;
3773  VALUE tmp, result = 0;
3774 
3775  alen = RARRAY_LEN(ary);
3776  if (alen == 0) return rb_ary_dup(ary);
3777  for (i=0; i<alen; i++) {
3778  tmp = to_ary(rb_ary_elt(ary, i));
3779  if (elen < 0) { /* first element */
3780  elen = RARRAY_LEN(tmp);
3781  result = rb_ary_new2(elen);
3782  for (j=0; j<elen; j++) {
3783  rb_ary_store(result, j, rb_ary_new2(alen));
3784  }
3785  }
3786  else if (elen != RARRAY_LEN(tmp)) {
3787  rb_raise(rb_eIndexError, "element size differs (%ld should be %ld)",
3788  RARRAY_LEN(tmp), elen);
3789  }
3790  for (j=0; j<elen; j++) {
3791  rb_ary_store(rb_ary_elt(result, j), i, rb_ary_elt(tmp, j));
3792  }
3793  }
3794  return result;
3795 }
3796 
3797 /*
3798  * call-seq:
3799  * ary.replace(other_ary) -> ary
3800  * ary.initialize_copy(other_ary) -> ary
3801  *
3802  * Replaces the contents of +self+ with the contents of +other_ary+,
3803  * truncating or expanding if necessary.
3804  *
3805  * a = [ "a", "b", "c", "d", "e" ]
3806  * a.replace([ "x", "y", "z" ]) #=> ["x", "y", "z"]
3807  * a #=> ["x", "y", "z"]
3808  */
3809 
3810 VALUE
3812 {
3813  rb_ary_modify_check(copy);
3814  orig = to_ary(orig);
3815  if (copy == orig) return copy;
3816 
3817  if (RARRAY_LEN(orig) <= RARRAY_EMBED_LEN_MAX) {
3818  VALUE shared_root = 0;
3819 
3820  if (ARY_OWNS_HEAP_P(copy)) {
3821  ary_heap_free(copy);
3822  }
3823  else if (ARY_SHARED_P(copy)) {
3824  shared_root = ARY_SHARED_ROOT(copy);
3825  FL_UNSET_SHARED(copy);
3826  }
3827  FL_SET_EMBED(copy);
3828  ary_memcpy(copy, 0, RARRAY_LEN(orig), RARRAY_CONST_PTR_TRANSIENT(orig));
3829  if (shared_root) {
3830  rb_ary_decrement_share(shared_root);
3831  }
3832  ARY_SET_LEN(copy, RARRAY_LEN(orig));
3833  }
3834  else {
3835  VALUE shared_root = ary_make_shared(orig);
3836  if (ARY_OWNS_HEAP_P(copy)) {
3837  ary_heap_free(copy);
3838  }
3839  else {
3840  rb_ary_unshare_safe(copy);
3841  }
3842  FL_UNSET_EMBED(copy);
3843  ARY_SET_PTR(copy, ARY_HEAP_PTR(orig));
3844  ARY_SET_LEN(copy, ARY_HEAP_LEN(orig));
3845  rb_ary_set_shared(copy, shared_root);
3846  }
3847  ary_verify(copy);
3848  return copy;
3849 }
3850 
3851 /*
3852  * call-seq:
3853  * ary.clear -> ary
3854  *
3855  * Removes all elements from +self+.
3856  *
3857  * a = [ "a", "b", "c", "d", "e" ]
3858  * a.clear #=> [ ]
3859  */
3860 
3861 VALUE
3863 {
3864  rb_ary_modify_check(ary);
3865  if (ARY_SHARED_P(ary)) {
3866  if (!ARY_EMBED_P(ary)) {
3867  rb_ary_unshare(ary);
3868  FL_SET_EMBED(ary);
3869  ARY_SET_EMBED_LEN(ary, 0);
3870  }
3871  }
3872  else {
3873  ARY_SET_LEN(ary, 0);
3874  if (ARY_DEFAULT_SIZE * 2 < ARY_CAPA(ary)) {
3875  ary_resize_capa(ary, ARY_DEFAULT_SIZE * 2);
3876  }
3877  }
3878  ary_verify(ary);
3879  return ary;
3880 }
3881 
3882 /*
3883  * call-seq:
3884  * ary.fill(obj) -> ary
3885  * ary.fill(obj, start [, length]) -> ary
3886  * ary.fill(obj, range) -> ary
3887  * ary.fill {|index| block} -> ary
3888  * ary.fill(start [, length]) {|index| block} -> ary
3889  * ary.fill(range) {|index| block} -> ary
3890  *
3891  * The first three forms set the selected elements of +self+ (which
3892  * may be the entire array) to +obj+.
3893  *
3894  * A +start+ of +nil+ is equivalent to zero.
3895  *
3896  * A +length+ of +nil+ is equivalent to the length of the array.
3897  *
3898  * The last three forms fill the array with the value of the given block,
3899  * which is passed the absolute index of each element to be filled.
3900  *
3901  * Negative values of +start+ count from the end of the array, where +-1+ is
3902  * the last element.
3903  *
3904  * a = [ "a", "b", "c", "d" ]
3905  * a.fill("x") #=> ["x", "x", "x", "x"]
3906  * a.fill("z", 2, 2) #=> ["x", "x", "z", "z"]
3907  * a.fill("y", 0..1) #=> ["y", "y", "z", "z"]
3908  * a.fill {|i| i*i} #=> [0, 1, 4, 9]
3909  * a.fill(-2) {|i| i*i*i} #=> [0, 1, 8, 27]
3910  */
3911 
3912 static VALUE
3913 rb_ary_fill(int argc, VALUE *argv, VALUE ary)
3914 {
3915  VALUE item = Qundef, arg1, arg2;
3916  long beg = 0, end = 0, len = 0;
3917 
3918  if (rb_block_given_p()) {
3919  rb_scan_args(argc, argv, "02", &arg1, &arg2);
3920  argc += 1; /* hackish */
3921  }
3922  else {
3923  rb_scan_args(argc, argv, "12", &item, &arg1, &arg2);
3924  }
3925  switch (argc) {
3926  case 1:
3927  beg = 0;
3928  len = RARRAY_LEN(ary);
3929  break;
3930  case 2:
3931  if (rb_range_beg_len(arg1, &beg, &len, RARRAY_LEN(ary), 1)) {
3932  break;
3933  }
3934  /* fall through */
3935  case 3:
3936  beg = NIL_P(arg1) ? 0 : NUM2LONG(arg1);
3937  if (beg < 0) {
3938  beg = RARRAY_LEN(ary) + beg;
3939  if (beg < 0) beg = 0;
3940  }
3941  len = NIL_P(arg2) ? RARRAY_LEN(ary) - beg : NUM2LONG(arg2);
3942  break;
3943  }
3944  rb_ary_modify(ary);
3945  if (len < 0) {
3946  return ary;
3947  }
3948  if (beg >= ARY_MAX_SIZE || len > ARY_MAX_SIZE - beg) {
3949  rb_raise(rb_eArgError, "argument too big");
3950  }
3951  end = beg + len;
3952  if (RARRAY_LEN(ary) < end) {
3953  if (end >= ARY_CAPA(ary)) {
3954  ary_resize_capa(ary, end);
3955  }
3956  ary_mem_clear(ary, RARRAY_LEN(ary), end - RARRAY_LEN(ary));
3957  ARY_SET_LEN(ary, end);
3958  }
3959 
3960  if (item == Qundef) {
3961  VALUE v;
3962  long i;
3963 
3964  for (i=beg; i<end; i++) {
3965  v = rb_yield(LONG2NUM(i));
3966  if (i>=RARRAY_LEN(ary)) break;
3967  ARY_SET(ary, i, v);
3968  }
3969  }
3970  else {
3971  ary_memfill(ary, beg, len, item);
3972  }
3973  return ary;
3974 }
3975 
3976 /*
3977  * call-seq:
3978  * ary + other_ary -> new_ary
3979  *
3980  * Concatenation --- Returns a new array built by concatenating the
3981  * two arrays together to produce a third array.
3982  *
3983  * [ 1, 2, 3 ] + [ 4, 5 ] #=> [ 1, 2, 3, 4, 5 ]
3984  * a = [ "a", "b", "c" ]
3985  * c = a + [ "d", "e", "f" ]
3986  * c #=> [ "a", "b", "c", "d", "e", "f" ]
3987  * a #=> [ "a", "b", "c" ]
3988  *
3989  * Note that
3990  * x += y
3991  * is the same as
3992  * x = x + y
3993  * This means that it produces a new array. As a consequence,
3994  * repeated use of <code>+=</code> on arrays can be quite inefficient.
3995  *
3996  * See also Array#concat.
3997  */
3998 
3999 VALUE
4001 {
4002  VALUE z;
4003  long len, xlen, ylen;
4004 
4005  y = to_ary(y);
4006  xlen = RARRAY_LEN(x);
4007  ylen = RARRAY_LEN(y);
4008  len = xlen + ylen;
4009  z = rb_ary_new2(len);
4010 
4011  ary_memcpy(z, 0, xlen, RARRAY_CONST_PTR_TRANSIENT(x));
4012  ary_memcpy(z, xlen, ylen, RARRAY_CONST_PTR_TRANSIENT(y));
4013  ARY_SET_LEN(z, len);
4014  return z;
4015 }
4016 
4017 static VALUE
4018 ary_append(VALUE x, VALUE y)
4019 {
4020  long n = RARRAY_LEN(y);
4021  if (n > 0) {
4022  rb_ary_splice(x, RARRAY_LEN(x), 0, RARRAY_CONST_PTR_TRANSIENT(y), n);
4023  }
4024  return x;
4025 }
4026 
4027 /*
4028  * call-seq:
4029  * ary.concat(other_ary1, other_ary2, ...) -> ary
4030  *
4031  * Appends the elements of <code>other_ary</code>s to +self+.
4032  *
4033  * [ "a", "b" ].concat( ["c", "d"]) #=> [ "a", "b", "c", "d" ]
4034  * [ "a" ].concat( ["b"], ["c", "d"]) #=> [ "a", "b", "c", "d" ]
4035  * [ "a" ].concat #=> [ "a" ]
4036  *
4037  * a = [ 1, 2, 3 ]
4038  * a.concat( [ 4, 5 ])
4039  * a #=> [ 1, 2, 3, 4, 5 ]
4040  *
4041  * a = [ 1, 2 ]
4042  * a.concat(a, a) #=> [1, 2, 1, 2, 1, 2]
4043  *
4044  * See also Array#+.
4045  */
4046 
4047 static VALUE
4048 rb_ary_concat_multi(int argc, VALUE *argv, VALUE ary)
4049 {
4050  rb_ary_modify_check(ary);
4051 
4052  if (argc == 1) {
4053  rb_ary_concat(ary, argv[0]);
4054  }
4055  else if (argc > 1) {
4056  int i;
4057  VALUE args = rb_ary_tmp_new(argc);
4058  for (i = 0; i < argc; i++) {
4059  rb_ary_concat(args, argv[i]);
4060  }
4061  ary_append(ary, args);
4062  }
4063 
4064  ary_verify(ary);
4065  return ary;
4066 }
4067 
4068 VALUE
4070 {
4071  return ary_append(x, to_ary(y));
4072 }
4073 
4074 /*
4075  * call-seq:
4076  * ary * int -> new_ary
4077  * ary * str -> new_string
4078  *
4079  * Repetition --- With a String argument, equivalent to
4080  * <code>ary.join(str)</code>.
4081  *
4082  * Otherwise, returns a new array built by concatenating the +int+ copies of
4083  * +self+.
4084  *
4085  *
4086  * [ 1, 2, 3 ] * 3 #=> [ 1, 2, 3, 1, 2, 3, 1, 2, 3 ]
4087  * [ 1, 2, 3 ] * "," #=> "1,2,3"
4088  *
4089  */
4090 
4091 static VALUE
4092 rb_ary_times(VALUE ary, VALUE times)
4093 {
4094  VALUE ary2, tmp;
4095  const VALUE *ptr;
4096  long t, len;
4097 
4098  tmp = rb_check_string_type(times);
4099  if (!NIL_P(tmp)) {
4100  return rb_ary_join(ary, tmp);
4101  }
4102 
4103  len = NUM2LONG(times);
4104  if (len == 0) {
4105  ary2 = ary_new(rb_obj_class(ary), 0);
4106  goto out;
4107  }
4108  if (len < 0) {
4109  rb_raise(rb_eArgError, "negative argument");
4110  }
4111  if (ARY_MAX_SIZE/len < RARRAY_LEN(ary)) {
4112  rb_raise(rb_eArgError, "argument too big");
4113  }
4114  len *= RARRAY_LEN(ary);
4115 
4116  ary2 = ary_new(rb_obj_class(ary), len);
4117  ARY_SET_LEN(ary2, len);
4118 
4120  t = RARRAY_LEN(ary);
4121  if (0 < t) {
4122  ary_memcpy(ary2, 0, t, ptr);
4123  while (t <= len/2) {
4124  ary_memcpy(ary2, t, t, RARRAY_CONST_PTR_TRANSIENT(ary2));
4125  t *= 2;
4126  }
4127  if (t < len) {
4128  ary_memcpy(ary2, t, len-t, RARRAY_CONST_PTR_TRANSIENT(ary2));
4129  }
4130  }
4131  out:
4132  return ary2;
4133 }
4134 
4135 /*
4136  * call-seq:
4137  * ary.assoc(obj) -> element_ary or nil
4138  *
4139  * Searches through an array whose elements are also arrays comparing +obj+
4140  * with the first element of each contained array using <code>obj.==</code>.
4141  *
4142  * Returns the first contained array that matches (that is, the first
4143  * associated array), or +nil+ if no match is found.
4144  *
4145  * See also Array#rassoc
4146  *
4147  * s1 = [ "colors", "red", "blue", "green" ]
4148  * s2 = [ "letters", "a", "b", "c" ]
4149  * s3 = "foo"
4150  * a = [ s1, s2, s3 ]
4151  * a.assoc("letters") #=> [ "letters", "a", "b", "c" ]
4152  * a.assoc("foo") #=> nil
4153  */
4154 
4155 VALUE
4157 {
4158  long i;
4159  VALUE v;
4160 
4161  for (i = 0; i < RARRAY_LEN(ary); ++i) {
4163  if (!NIL_P(v) && RARRAY_LEN(v) > 0 &&
4164  rb_equal(RARRAY_AREF(v, 0), key))
4165  return v;
4166  }
4167  return Qnil;
4168 }
4169 
4170 /*
4171  * call-seq:
4172  * ary.rassoc(obj) -> element_ary or nil
4173  *
4174  * Searches through the array whose elements are also arrays.
4175  *
4176  * Compares +obj+ with the second element of each contained array using
4177  * <code>obj.==</code>.
4178  *
4179  * Returns the first contained array that matches +obj+.
4180  *
4181  * See also Array#assoc.
4182  *
4183  * a = [ [ 1, "one"], [2, "two"], [3, "three"], ["ii", "two"] ]
4184  * a.rassoc("two") #=> [2, "two"]
4185  * a.rassoc("four") #=> nil
4186  */
4187 
4188 VALUE
4190 {
4191  long i;
4192  VALUE v;
4193 
4194  for (i = 0; i < RARRAY_LEN(ary); ++i) {
4195  v = RARRAY_AREF(ary, i);
4196  if (RB_TYPE_P(v, T_ARRAY) &&
4197  RARRAY_LEN(v) > 1 &&
4198  rb_equal(RARRAY_AREF(v, 1), value))
4199  return v;
4200  }
4201  return Qnil;
4202 }
4203 
4204 static VALUE
4205 recursive_equal(VALUE ary1, VALUE ary2, int recur)
4206 {
4207  long i, len1;
4208  const VALUE *p1, *p2;
4209 
4210  if (recur) return Qtrue; /* Subtle! */
4211 
4212  /* rb_equal() can evacuate ptrs */
4213  p1 = RARRAY_CONST_PTR(ary1);
4214  p2 = RARRAY_CONST_PTR(ary2);
4215  len1 = RARRAY_LEN(ary1);
4216 
4217  for (i = 0; i < len1; i++) {
4218  if (*p1 != *p2) {
4219  if (rb_equal(*p1, *p2)) {
4220  len1 = RARRAY_LEN(ary1);
4221  if (len1 != RARRAY_LEN(ary2))
4222  return Qfalse;
4223  if (len1 < i)
4224  return Qtrue;
4225  p1 = RARRAY_CONST_PTR(ary1) + i;
4226  p2 = RARRAY_CONST_PTR(ary2) + i;
4227  }
4228  else {
4229  return Qfalse;
4230  }
4231  }
4232  p1++;
4233  p2++;
4234  }
4235  return Qtrue;
4236 }
4237 
4238 /*
4239  * call-seq:
4240  * ary == other_ary -> bool
4241  *
4242  * Equality --- Two arrays are equal if they contain the same number of
4243  * elements and if each element is equal to (according to Object#==) the
4244  * corresponding element in +other_ary+.
4245  *
4246  * [ "a", "c" ] == [ "a", "c", 7 ] #=> false
4247  * [ "a", "c", 7 ] == [ "a", "c", 7 ] #=> true
4248  * [ "a", "c", 7 ] == [ "a", "d", "f" ] #=> false
4249  *
4250  */
4251 
4252 static VALUE
4253 rb_ary_equal(VALUE ary1, VALUE ary2)
4254 {
4255  if (ary1 == ary2) return Qtrue;
4256  if (!RB_TYPE_P(ary2, T_ARRAY)) {
4257  if (!rb_respond_to(ary2, idTo_ary)) {
4258  return Qfalse;
4259  }
4260  return rb_equal(ary2, ary1);
4261  }
4262  if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return Qfalse;
4263  if (RARRAY_CONST_PTR_TRANSIENT(ary1) == RARRAY_CONST_PTR_TRANSIENT(ary2)) return Qtrue;
4264  return rb_exec_recursive_paired(recursive_equal, ary1, ary2, ary2);
4265 }
4266 
4267 static VALUE
4268 recursive_eql(VALUE ary1, VALUE ary2, int recur)
4269 {
4270  long i;
4271 
4272  if (recur) return Qtrue; /* Subtle! */
4273  for (i=0; i<RARRAY_LEN(ary1); i++) {
4274  if (!rb_eql(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
4275  return Qfalse;
4276  }
4277  return Qtrue;
4278 }
4279 
4280 /*
4281  * call-seq:
4282  * ary.eql?(other) -> true or false
4283  *
4284  * Returns +true+ if +self+ and +other+ are the same object,
4285  * or are both arrays with the same content (according to Object#eql?).
4286  */
4287 
4288 static VALUE
4289 rb_ary_eql(VALUE ary1, VALUE ary2)
4290 {
4291  if (ary1 == ary2) return Qtrue;
4292  if (!RB_TYPE_P(ary2, T_ARRAY)) return Qfalse;
4293  if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return Qfalse;
4294  if (RARRAY_CONST_PTR_TRANSIENT(ary1) == RARRAY_CONST_PTR_TRANSIENT(ary2)) return Qtrue;
4295  return rb_exec_recursive_paired(recursive_eql, ary1, ary2, ary2);
4296 }
4297 
4298 /*
4299  * call-seq:
4300  * ary.hash -> integer
4301  *
4302  * Compute a hash-code for this array.
4303  *
4304  * Two arrays with the same content will have the same hash code (and will
4305  * compare using #eql?).
4306  *
4307  * See also Object#hash.
4308  */
4309 
4310 static VALUE
4311 rb_ary_hash(VALUE ary)
4312 {
4313  long i;
4314  st_index_t h;
4315  VALUE n;
4316 
4318  h = rb_hash_uint(h, (st_index_t)rb_ary_hash);
4319  for (i=0; i<RARRAY_LEN(ary); i++) {
4320  n = rb_hash(RARRAY_AREF(ary, i));
4321  h = rb_hash_uint(h, NUM2LONG(n));
4322  }
4323  h = rb_hash_end(h);
4324  return ST2FIX(h);
4325 }
4326 
4327 /*
4328  * call-seq:
4329  * ary.include?(object) -> true or false
4330  *
4331  * Returns +true+ if the given +object+ is present in +self+ (that is, if any
4332  * element <code>==</code> +object+), otherwise returns +false+.
4333  *
4334  * a = [ "a", "b", "c" ]
4335  * a.include?("b") #=> true
4336  * a.include?("z") #=> false
4337  */
4338 
4339 VALUE
4341 {
4342  long i;
4343  VALUE e;
4344 
4345  for (i=0; i<RARRAY_LEN(ary); i++) {
4346  e = RARRAY_AREF(ary, i);
4347  if (rb_equal(e, item)) {
4348  return Qtrue;
4349  }
4350  }
4351  return Qfalse;
4352 }
4353 
4354 static VALUE
4355 rb_ary_includes_by_eql(VALUE ary, VALUE item)
4356 {
4357  long i;
4358  VALUE e;
4359 
4360  for (i=0; i<RARRAY_LEN(ary); i++) {
4361  e = RARRAY_AREF(ary, i);
4362  if (rb_eql(item, e)) {
4363  return Qtrue;
4364  }
4365  }
4366  return Qfalse;
4367 }
4368 
4369 static VALUE
4370 recursive_cmp(VALUE ary1, VALUE ary2, int recur)
4371 {
4372  long i, len;
4373 
4374  if (recur) return Qundef; /* Subtle! */
4375  len = RARRAY_LEN(ary1);
4376  if (len > RARRAY_LEN(ary2)) {
4377  len = RARRAY_LEN(ary2);
4378  }
4379  for (i=0; i<len; i++) {
4380  VALUE e1 = rb_ary_elt(ary1, i), e2 = rb_ary_elt(ary2, i);
4381  VALUE v = rb_funcallv(e1, id_cmp, 1, &e2);
4382  if (v != INT2FIX(0)) {
4383  return v;
4384  }
4385  }
4386  return Qundef;
4387 }
4388 
4389 /*
4390  * call-seq:
4391  * ary <=> other_ary -> -1, 0, +1 or nil
4392  *
4393  * Comparison --- Returns an integer (+-1+, +0+, or <code>+1</code>) if this
4394  * array is less than, equal to, or greater than +other_ary+.
4395  *
4396  * Each object in each array is compared (using the <=> operator).
4397  *
4398  * Arrays are compared in an "element-wise" manner; the first element of +ary+
4399  * is compared with the first one of +other_ary+ using the <=> operator, then
4400  * each of the second elements, etc...
4401  * As soon as the result of any such comparison is non zero (i.e. the two
4402  * corresponding elements are not equal), that result is returned for the
4403  * whole array comparison.
4404  *
4405  * If all the elements are equal, then the result is based on a comparison of
4406  * the array lengths. Thus, two arrays are "equal" according to Array#<=> if,
4407  * and only if, they have the same length and the value of each element is
4408  * equal to the value of the corresponding element in the other array.
4409  *
4410  * +nil+ is returned if the +other_ary+ is not an array or if the comparison
4411  * of two elements returned +nil+.
4412  *
4413  * [ "a", "a", "c" ] <=> [ "a", "b", "c" ] #=> -1
4414  * [ 1, 2, 3, 4, 5, 6 ] <=> [ 1, 2 ] #=> +1
4415  * [ 1, 2 ] <=> [ 1, :two ] #=> nil
4416  *
4417  */
4418 
4419 VALUE
4421 {
4422  long len;
4423  VALUE v;
4424 
4425  ary2 = rb_check_array_type(ary2);
4426  if (NIL_P(ary2)) return Qnil;
4427  if (ary1 == ary2) return INT2FIX(0);
4428  v = rb_exec_recursive_paired(recursive_cmp, ary1, ary2, ary2);
4429  if (v != Qundef) return v;
4430  len = RARRAY_LEN(ary1) - RARRAY_LEN(ary2);
4431  if (len == 0) return INT2FIX(0);
4432  if (len > 0) return INT2FIX(1);
4433  return INT2FIX(-1);
4434 }
4435 
4436 static VALUE
4437 ary_add_hash(VALUE hash, VALUE ary)
4438 {
4439  long i;
4440 
4441  for (i=0; i<RARRAY_LEN(ary); i++) {
4442  VALUE elt = RARRAY_AREF(ary, i);
4443  rb_hash_add_new_element(hash, elt, elt);
4444  }
4445  return hash;
4446 }
4447 
4448 static inline VALUE
4449 ary_tmp_hash_new(VALUE ary)
4450 {
4451  long size = RARRAY_LEN(ary);
4453 
4454  RBASIC_CLEAR_CLASS(hash);
4455  return hash;
4456 }
4457 
4458 static VALUE
4459 ary_make_hash(VALUE ary)
4460 {
4461  VALUE hash = ary_tmp_hash_new(ary);
4462  return ary_add_hash(hash, ary);
4463 }
4464 
4465 static VALUE
4466 ary_add_hash_by(VALUE hash, VALUE ary)
4467 {
4468  long i;
4469 
4470  for (i = 0; i < RARRAY_LEN(ary); ++i) {
4471  VALUE v = rb_ary_elt(ary, i), k = rb_yield(v);
4472  rb_hash_add_new_element(hash, k, v);
4473  }
4474  return hash;
4475 }
4476 
4477 static VALUE
4478 ary_make_hash_by(VALUE ary)
4479 {
4480  VALUE hash = ary_tmp_hash_new(ary);
4481  return ary_add_hash_by(hash, ary);
4482 }
4483 
4484 static inline void
4485 ary_recycle_hash(VALUE hash)
4486 {
4487  assert(RBASIC_CLASS(hash) == 0);
4488  if (RHASH_ST_TABLE_P(hash)) {
4489  st_table *tbl = RHASH_ST_TABLE(hash);
4490  st_free_table(tbl);
4491  RHASH_ST_CLEAR(hash);
4492  }
4493 }
4494 
4495 /*
4496  * call-seq:
4497  * ary - other_ary -> new_ary
4498  *
4499  * Array Difference
4500  *
4501  * Returns a new array that is a copy of the original array, removing all
4502  * occurrences of any item that also appear in +other_ary+. The order is
4503  * preserved from the original array.
4504  *
4505  * It compares elements using their #hash and #eql? methods for efficiency.
4506  *
4507  * [ 1, 1, 2, 2, 3, 3, 4, 5 ] - [ 1, 2, 4 ] #=> [ 3, 3, 5 ]
4508  *
4509  * Note that while 1 and 2 were only present once in the array argument, and
4510  * were present twice in the receiver array, all occurrences of each Integer are
4511  * removed in the returned array.
4512  *
4513  * If you need set-like behavior, see the library class Set.
4514  *
4515  * See also Array#difference.
4516  */
4517 
4518 static VALUE
4519 rb_ary_diff(VALUE ary1, VALUE ary2)
4520 {
4521  VALUE ary3;
4522  VALUE hash;
4523  long i;
4524 
4525  ary2 = to_ary(ary2);
4526  ary3 = rb_ary_new();
4527 
4528  if (RARRAY_LEN(ary1) <= SMALL_ARRAY_LEN || RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
4529  for (i=0; i<RARRAY_LEN(ary1); i++) {
4530  VALUE elt = rb_ary_elt(ary1, i);
4531  if (rb_ary_includes_by_eql(ary2, elt)) continue;
4532  rb_ary_push(ary3, elt);
4533  }
4534  return ary3;
4535  }
4536 
4537  hash = ary_make_hash(ary2);
4538  for (i=0; i<RARRAY_LEN(ary1); i++) {
4539  if (rb_hash_stlike_lookup(hash, RARRAY_AREF(ary1, i), NULL)) continue;
4540  rb_ary_push(ary3, rb_ary_elt(ary1, i));
4541  }
4542  ary_recycle_hash(hash);
4543  return ary3;
4544 }
4545 
4546 /*
4547  * call-seq:
4548  * ary.difference(other_ary1, other_ary2, ...) -> new_ary
4549  *
4550  * Array Difference
4551  *
4552  * Returns a new array that is a copy of the original array, removing all
4553  * occurrences of any item that also appear in +other_ary+. The order is
4554  * preserved from the original array.
4555  *
4556  * It compares elements using their #hash and #eql? methods for efficiency.
4557  *
4558  * [ 1, 1, 2, 2, 3, 3, 4, 5 ].difference([ 1, 2, 4 ]) #=> [ 3, 3, 5 ]
4559  *
4560  * Note that while 1 and 2 were only present once in the array argument, and
4561  * were present twice in the receiver array, all occurrences of each Integer are
4562  * removed in the returned array.
4563  *
4564  * Multiple array arguments can be supplied and all occurrences of any element
4565  * in those supplied arrays that match the receiver will be removed from the
4566  * returned array.
4567  *
4568  * [ 1, 'c', :s, 'yep' ].difference([ 1 ], [ 'a', 'c' ]) #=> [ :s, "yep" ]
4569  *
4570  * If you need set-like behavior, see the library class Set.
4571  *
4572  * See also Array#-.
4573  */
4574 
4575 static VALUE
4576 rb_ary_difference_multi(int argc, VALUE *argv, VALUE ary)
4577 {
4578  VALUE ary_diff;
4579  long i, length;
4580  volatile VALUE t0;
4581  bool *is_hash = ALLOCV_N(bool, t0, argc);
4582  ary_diff = rb_ary_new();
4583  length = RARRAY_LEN(ary);
4584 
4585  for (i = 0; i < argc; i++) {
4586  argv[i] = to_ary(argv[i]);
4587  is_hash[i] = (length > SMALL_ARRAY_LEN && RARRAY_LEN(argv[i]) > SMALL_ARRAY_LEN);
4588  if (is_hash[i]) argv[i] = ary_make_hash(argv[i]);
4589  }
4590 
4591  for (i = 0; i < RARRAY_LEN(ary); i++) {
4592  int j;
4593  VALUE elt = rb_ary_elt(ary, i);
4594  for (j = 0; j < argc; j++) {
4595  if (is_hash[j]) {
4597  break;
4598  }
4599  else {
4600  if (rb_ary_includes_by_eql(argv[j], elt)) break;
4601  }
4602  }
4603  if (j == argc) rb_ary_push(ary_diff, elt);
4604  }
4605 
4606  ALLOCV_END(t0);
4607 
4608  return ary_diff;
4609 }
4610 
4611 
4612 /*
4613  * call-seq:
4614  * ary & other_ary -> new_ary
4615  *
4616  * Set Intersection --- Returns a new array containing unique elements common to the
4617  * two arrays. The order is preserved from the original array.
4618  *
4619  * It compares elements using their #hash and #eql? methods for efficiency.
4620  *
4621  * [ 1, 1, 3, 5 ] & [ 3, 2, 1 ] #=> [ 1, 3 ]
4622  * [ 'a', 'b', 'b', 'z' ] & [ 'a', 'b', 'c' ] #=> [ 'a', 'b' ]
4623  *
4624  * See also Array#uniq.
4625  */
4626 
4627 
4628 static VALUE
4629 rb_ary_and(VALUE ary1, VALUE ary2)
4630 {
4631  VALUE hash, ary3, v;
4632  st_data_t vv;
4633  long i;
4634 
4635  ary2 = to_ary(ary2);
4636  ary3 = rb_ary_new();
4637  if (RARRAY_LEN(ary1) == 0 || RARRAY_LEN(ary2) == 0) return ary3;
4638 
4639  if (RARRAY_LEN(ary1) <= SMALL_ARRAY_LEN && RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
4640  for (i=0; i<RARRAY_LEN(ary1); i++) {
4641  v = RARRAY_AREF(ary1, i);
4642  if (!rb_ary_includes_by_eql(ary2, v)) continue;
4643  if (rb_ary_includes_by_eql(ary3, v)) continue;
4644  rb_ary_push(ary3, v);
4645  }
4646  return ary3;
4647  }
4648 
4649  hash = ary_make_hash(ary2);
4650 
4651  for (i=0; i<RARRAY_LEN(ary1); i++) {
4652  v = RARRAY_AREF(ary1, i);
4653  vv = (st_data_t)v;
4654  if (rb_hash_stlike_delete(hash, &vv, 0)) {
4655  rb_ary_push(ary3, v);
4656  }
4657  }
4658  ary_recycle_hash(hash);
4659 
4660  return ary3;
4661 }
4662 
4663 /*
4664  * call-seq:
4665  * ary.intersection(other_ary1, other_ary2, ...) -> new_ary
4666  *
4667  * Set Intersection --- Returns a new array containing unique elements common
4668  * to +self+ and <code>other_ary</code>s. Order is preserved from the original
4669  * array.
4670  *
4671  * It compares elements using their #hash and #eql? methods for efficiency.
4672  *
4673  * [ 1, 1, 3, 5 ].intersection([ 3, 2, 1 ]) # => [ 1, 3 ]
4674  * [ "a", "b", "z" ].intersection([ "a", "b", "c" ], [ "b" ]) # => [ "b" ]
4675  * [ "a" ].intersection #=> [ "a" ]
4676  *
4677  * See also Array#&.
4678  */
4679 
4680 static VALUE
4681 rb_ary_intersection_multi(int argc, VALUE *argv, VALUE ary)
4682 {
4683  VALUE result = rb_ary_dup(ary);
4684  int i;
4685 
4686  for (i = 0; i < argc; i++) {
4687  result = rb_ary_and(result, argv[i]);
4688  }
4689 
4690  return result;
4691 }
4692 
4693 static int
4694 ary_hash_orset(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
4695 {
4696  if (existing) return ST_STOP;
4697  *key = *value = (VALUE)arg;
4698  return ST_CONTINUE;
4699 }
4700 
4701 static void
4702 rb_ary_union(VALUE ary_union, VALUE ary)
4703 {
4704  long i;
4705  for (i = 0; i < RARRAY_LEN(ary); i++) {
4706  VALUE elt = rb_ary_elt(ary, i);
4707  if (rb_ary_includes_by_eql(ary_union, elt)) continue;
4708  rb_ary_push(ary_union, elt);
4709  }
4710 }
4711 
4712 static void
4713 rb_ary_union_hash(VALUE hash, VALUE ary2)
4714 {
4715  long i;
4716  for (i = 0; i < RARRAY_LEN(ary2); i++) {
4717  VALUE elt = RARRAY_AREF(ary2, i);
4718  if (!rb_hash_stlike_update(hash, (st_data_t)elt, ary_hash_orset, (st_data_t)elt)) {
4719  RB_OBJ_WRITTEN(hash, Qundef, elt);
4720  }
4721  }
4722 }
4723 
4724 /*
4725  * call-seq:
4726  * ary | other_ary -> new_ary
4727  *
4728  * Set Union --- Returns a new array by joining +ary+ with +other_ary+,
4729  * excluding any duplicates and preserving the order from the given arrays.
4730  *
4731  * It compares elements using their #hash and #eql? methods for efficiency.
4732  *
4733  * [ "a", "b", "c" ] | [ "c", "d", "a" ] #=> [ "a", "b", "c", "d" ]
4734  * [ "c", "d", "a" ] | [ "a", "b", "c" ] #=> [ "c", "d", "a", "b" ]
4735  *
4736  * See also Array#union.
4737  */
4738 
4739 static VALUE
4740 rb_ary_or(VALUE ary1, VALUE ary2)
4741 {
4742  VALUE hash, ary3;
4743 
4744  ary2 = to_ary(ary2);
4745  if (RARRAY_LEN(ary1) + RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
4746  ary3 = rb_ary_new();
4747  rb_ary_union(ary3, ary1);
4748  rb_ary_union(ary3, ary2);
4749  return ary3;
4750  }
4751 
4752  hash = ary_make_hash(ary1);
4753  rb_ary_union_hash(hash, ary2);
4754 
4755  ary3 = rb_hash_values(hash);
4756  ary_recycle_hash(hash);
4757  return ary3;
4758 }
4759 
4760 /*
4761  * call-seq:
4762  * ary.union(other_ary1, other_ary2, ...) -> new_ary
4763  *
4764  * Set Union --- Returns a new array by joining <code>other_ary</code>s with +self+,
4765  * excluding any duplicates and preserving the order from the given arrays.
4766  *
4767  * It compares elements using their #hash and #eql? methods for efficiency.
4768  *
4769  * [ "a", "b", "c" ].union( [ "c", "d", "a" ] ) #=> [ "a", "b", "c", "d" ]
4770  * [ "a" ].union( ["e", "b"], ["a", "c", "b"] ) #=> [ "a", "e", "b", "c" ]
4771  * [ "a" ].union #=> [ "a" ]
4772  *
4773  * See also Array#|.
4774  */
4775 
4776 static VALUE
4777 rb_ary_union_multi(int argc, VALUE *argv, VALUE ary)
4778 {
4779  int i;
4780  long sum;
4781  VALUE hash, ary_union;
4782 
4783  sum = RARRAY_LEN(ary);
4784  for (i = 0; i < argc; i++) {
4785  argv[i] = to_ary(argv[i]);
4786  sum += RARRAY_LEN(argv[i]);
4787  }
4788 
4789  if (sum <= SMALL_ARRAY_LEN) {
4790  ary_union = rb_ary_new();
4791 
4792  rb_ary_union(ary_union, ary);
4793  for (i = 0; i < argc; i++) rb_ary_union(ary_union, argv[i]);
4794 
4795  return ary_union;
4796  }
4797 
4798  hash = ary_make_hash(ary);
4799  for (i = 0; i < argc; i++) rb_ary_union_hash(hash, argv[i]);
4800 
4801  ary_union = rb_hash_values(hash);
4802  ary_recycle_hash(hash);
4803  return ary_union;
4804 }
4805 
4806 /*
4807  * call-seq:
4808  * ary.max -> obj
4809  * ary.max {|a, b| block} -> obj
4810  * ary.max(n) -> array
4811  * ary.max(n) {|a, b| block} -> array
4812  *
4813  * Returns the object in _ary_ with the maximum value. The
4814  * first form assumes all objects implement Comparable;
4815  * the second uses the block to return <em>a <=> b</em>.
4816  *
4817  * ary = %w(albatross dog horse)
4818  * ary.max #=> "horse"
4819  * ary.max {|a, b| a.length <=> b.length} #=> "albatross"
4820  *
4821  * If the +n+ argument is given, maximum +n+ elements are returned
4822  * as an array.
4823  *
4824  * ary = %w[albatross dog horse]
4825  * ary.max(2) #=> ["horse", "dog"]
4826  * ary.max(2) {|a, b| a.length <=> b.length } #=> ["albatross", "horse"]
4827  */
4828 static VALUE
4829 rb_ary_max(int argc, VALUE *argv, VALUE ary)
4830 {
4831  struct cmp_opt_data cmp_opt = { 0, 0 };
4832  VALUE result = Qundef, v;
4833  VALUE num;
4834  long i;
4835 
4836  if (rb_check_arity(argc, 0, 1) && !NIL_P(num = argv[0]))
4837  return rb_nmin_run(ary, num, 0, 1, 1);
4838 
4839  if (rb_block_given_p()) {
4840  for (i = 0; i < RARRAY_LEN(ary); i++) {
4841  v = RARRAY_AREF(ary, i);
4842  if (result == Qundef || rb_cmpint(rb_yield_values(2, v, result), v, result) > 0) {
4843  result = v;
4844  }
4845  }
4846  }
4847  else {
4848  for (i = 0; i < RARRAY_LEN(ary); i++) {
4849  v = RARRAY_AREF(ary, i);
4850  if (result == Qundef || OPTIMIZED_CMP(v, result, cmp_opt) > 0) {
4851  result = v;
4852  }
4853  }
4854  }
4855  if (result == Qundef) return Qnil;
4856  return result;
4857 }
4858 
4859 /*
4860  * call-seq:
4861  * ary.min -> obj
4862  * ary.min {| a,b | block } -> obj
4863  * ary.min(n) -> array
4864  * ary.min(n) {| a,b | block } -> array
4865  *
4866  * Returns the object in _ary_ with the minimum value. The
4867  * first form assumes all objects implement Comparable;
4868  * the second uses the block to return <em>a <=> b</em>.
4869  *
4870  * ary = %w(albatross dog horse)
4871  * ary.min #=> "albatross"
4872  * ary.min {|a, b| a.length <=> b.length} #=> "dog"
4873  *
4874  * If the +n+ argument is given, minimum +n+ elements are returned
4875  * as an array.
4876  *
4877  * ary = %w[albatross dog horse]
4878  * ary.min(2) #=> ["albatross", "dog"]
4879  * ary.min(2) {|a, b| a.length <=> b.length } #=> ["dog", "horse"]
4880  */
4881 static VALUE
4882 rb_ary_min(int argc, VALUE *argv, VALUE ary)
4883 {
4884  struct cmp_opt_data cmp_opt = { 0, 0 };
4885  VALUE result = Qundef, v;
4886  VALUE num;
4887  long i;
4888 
4889  if (rb_check_arity(argc, 0, 1) && !NIL_P(num = argv[0]))
4890  return rb_nmin_run(ary, num, 0, 0, 1);
4891 
4892  if (rb_block_given_p()) {
4893  for (i = 0; i < RARRAY_LEN(ary); i++) {
4894  v = RARRAY_AREF(ary, i);
4895  if (result == Qundef || rb_cmpint(rb_yield_values(2, v, result), v, result) < 0) {
4896  result = v;
4897  }
4898  }
4899  }
4900  else {
4901  for (i = 0; i < RARRAY_LEN(ary); i++) {
4902  v = RARRAY_AREF(ary, i);
4903  if (result == Qundef || OPTIMIZED_CMP(v, result, cmp_opt) < 0) {
4904  result = v;
4905  }
4906  }
4907  }
4908  if (result == Qundef) return Qnil;
4909  return result;
4910 }
4911 
4912 /*
4913  * call-seq:
4914  * ary.minmax -> [obj, obj]
4915  * ary.minmax {| a,b | block } -> [obj, obj]
4916  *
4917  * Returns a two element array which contains the minimum and the
4918  * maximum value in the array.
4919  *
4920  * Can be given an optional block to override the default comparison
4921  * method <code>a <=> b</code>.
4922  */
4923 static VALUE
4924 rb_ary_minmax(VALUE ary)
4925 {
4926  if (rb_block_given_p()) {
4927  return rb_call_super(0, NULL);
4928  }
4929  return rb_assoc_new(rb_ary_min(0, 0, ary), rb_ary_max(0, 0, ary));
4930 }
4931 
4932 static int
4933 push_value(st_data_t key, st_data_t val, st_data_t ary)
4934 {
4935  rb_ary_push((VALUE)ary, (VALUE)val);
4936  return ST_CONTINUE;
4937 }
4938 
4939 /*
4940  * call-seq:
4941  * ary.uniq! -> ary or nil
4942  * ary.uniq! {|item| ...} -> ary or nil
4943  *
4944  * Removes duplicate elements from +self+.
4945  *
4946  * If a block is given, it will use the return value of the block for
4947  * comparison.
4948  *
4949  * It compares values using their #hash and #eql? methods for efficiency.
4950  *
4951  * +self+ is traversed in order, and the first occurrence is kept.
4952  *
4953  * Returns +nil+ if no changes are made (that is, no duplicates are found).
4954  *
4955  * a = [ "a", "a", "b", "b", "c" ]
4956  * a.uniq! # => ["a", "b", "c"]
4957  *
4958  * b = [ "a", "b", "c" ]
4959  * b.uniq! # => nil
4960  *
4961  * c = [["student","sam"], ["student","george"], ["teacher","matz"]]
4962  * c.uniq! {|s| s.first} # => [["student", "sam"], ["teacher", "matz"]]
4963  *
4964  */
4965 
4966 static VALUE
4967 rb_ary_uniq_bang(VALUE ary)
4968 {
4969  VALUE hash;
4970  long hash_size;
4971 
4972  rb_ary_modify_check(ary);
4973  if (RARRAY_LEN(ary) <= 1)
4974  return Qnil;
4975  if (rb_block_given_p())
4976  hash = ary_make_hash_by(ary);
4977  else
4978  hash = ary_make_hash(ary);
4979 
4980  hash_size = RHASH_SIZE(hash);
4981  if (RARRAY_LEN(ary) == hash_size) {
4982  return Qnil;
4983  }
4984  rb_ary_modify_check(ary);
4985  ARY_SET_LEN(ary, 0);
4986  if (ARY_SHARED_P(ary) && !ARY_EMBED_P(ary)) {
4987  rb_ary_unshare(ary);
4988  FL_SET_EMBED(ary);
4989  }
4990  ary_resize_capa(ary, hash_size);
4991  rb_hash_foreach(hash, push_value, ary);
4992  ary_recycle_hash(hash);
4993 
4994  return ary;
4995 }
4996 
4997 /*
4998  * call-seq:
4999  * ary.uniq -> new_ary
5000  * ary.uniq {|item| ...} -> new_ary
5001  *
5002  * Returns a new array by removing duplicate values in +self+.
5003  *
5004  * If a block is given, it will use the return value of the block for comparison.
5005  *
5006  * It compares values using their #hash and #eql? methods for efficiency.
5007  *
5008  * +self+ is traversed in order, and the first occurrence is kept.
5009  *
5010  * a = [ "a", "a", "b", "b", "c" ]
5011  * a.uniq # => ["a", "b", "c"]
5012  *
5013  * b = [["student","sam"], ["student","george"], ["teacher","matz"]]
5014  * b.uniq {|s| s.first} # => [["student", "sam"], ["teacher", "matz"]]
5015  *
5016  */
5017 
5018 static VALUE
5019 rb_ary_uniq(VALUE ary)
5020 {
5021  VALUE hash, uniq;
5022 
5023  if (RARRAY_LEN(ary) <= 1) {
5024  hash = 0;
5025  uniq = rb_ary_dup(ary);
5026  }
5027  else if (rb_block_given_p()) {
5028  hash = ary_make_hash_by(ary);
5029  uniq = rb_hash_values(hash);
5030  }
5031  else {
5032  hash = ary_make_hash(ary);
5033  uniq = rb_hash_values(hash);
5034  }
5035  RBASIC_SET_CLASS(uniq, rb_obj_class(ary));
5036  if (hash) {
5037  ary_recycle_hash(hash);
5038  }
5039 
5040  return uniq;
5041 }
5042 
5043 /*
5044  * call-seq:
5045  * ary.compact! -> ary or nil
5046  *
5047  * Removes +nil+ elements from the array.
5048  *
5049  * Returns +nil+ if no changes were made, otherwise returns the array.
5050  *
5051  * [ "a", nil, "b", nil, "c" ].compact! #=> [ "a", "b", "c" ]
5052  * [ "a", "b", "c" ].compact! #=> nil
5053  */
5054 
5055 static VALUE
5056 rb_ary_compact_bang(VALUE ary)
5057 {
5058  VALUE *p, *t, *end;
5059  long n;
5060 
5061  rb_ary_modify(ary);
5062  p = t = (VALUE *)RARRAY_CONST_PTR_TRANSIENT(ary); /* WB: no new reference */
5063  end = p + RARRAY_LEN(ary);
5064 
5065  while (t < end) {
5066  if (NIL_P(*t)) t++;
5067  else *p++ = *t++;
5068  }
5069  n = p - RARRAY_CONST_PTR_TRANSIENT(ary);
5070  if (RARRAY_LEN(ary) == n) {
5071  return Qnil;
5072  }
5073  ary_resize_smaller(ary, n);
5074 
5075  return ary;
5076 }
5077 
5078 /*
5079  * call-seq:
5080  * ary.compact -> new_ary
5081  *
5082  * Returns a copy of +self+ with all +nil+ elements removed.
5083  *
5084  * [ "a", nil, "b", nil, "c", nil ].compact
5085  * #=> [ "a", "b", "c" ]
5086  */
5087 
5088 static VALUE
5089 rb_ary_compact(VALUE ary)
5090 {
5091  ary = rb_ary_dup(ary);
5092  rb_ary_compact_bang(ary);
5093  return ary;
5094 }
5095 
5096 /*
5097  * call-seq:
5098  * ary.count -> int
5099  * ary.count(obj) -> int
5100  * ary.count {|item| block} -> int
5101  *
5102  * Returns the number of elements.
5103  *
5104  * If an argument is given, counts the number of elements which equal +obj+
5105  * using <code>==</code>.
5106  *
5107  * If a block is given, counts the number of elements for which the block
5108  * returns a true value.
5109  *
5110  * ary = [1, 2, 4, 2]
5111  * ary.count #=> 4
5112  * ary.count(2) #=> 2
5113  * ary.count {|x| x%2 == 0} #=> 3
5114  *
5115  */
5116 
5117 static VALUE
5118 rb_ary_count(int argc, VALUE *argv, VALUE ary)
5119 {
5120  long i, n = 0;
5121 
5122  if (rb_check_arity(argc, 0, 1) == 0) {
5123  VALUE v;
5124 
5125  if (!rb_block_given_p())
5126  return LONG2NUM(RARRAY_LEN(ary));
5127 
5128  for (i = 0; i < RARRAY_LEN(ary); i++) {
5129  v = RARRAY_AREF(ary, i);
5130  if (RTEST(rb_yield(v))) n++;
5131  }
5132  }
5133  else {
5134  VALUE obj = argv[0];
5135 
5136  if (rb_block_given_p()) {
5137  rb_warn("given block not used");
5138  }
5139  for (i = 0; i < RARRAY_LEN(ary); i++) {
5140  if (rb_equal(RARRAY_AREF(ary, i), obj)) n++;
5141  }
5142  }
5143 
5144  return LONG2NUM(n);
5145 }
5146 
5147 static VALUE
5148 flatten(VALUE ary, int level)
5149 {
5150  long i;
5151  VALUE stack, result, tmp, elt, vmemo;
5152  st_table *memo;
5153  st_data_t id;
5154 
5155  for (i = 0; i < RARRAY_LEN(ary); i++) {
5156  elt = RARRAY_AREF(ary, i);
5157  tmp = rb_check_array_type(elt);
5158  if (!NIL_P(tmp)) {
5159  break;
5160  }
5161  }
5162  if (i == RARRAY_LEN(ary)) {
5163  return ary;
5164  } else if (tmp == ary) {
5165  rb_raise(rb_eArgError, "tried to flatten recursive array");
5166  }
5167 
5168  result = ary_new(0, RARRAY_LEN(ary));
5169  ary_memcpy(result, 0, i, RARRAY_CONST_PTR_TRANSIENT(ary));
5170  ARY_SET_LEN(result, i);
5171 
5172  stack = ary_new(0, ARY_DEFAULT_SIZE);
5173  rb_ary_push(stack, ary);
5174  rb_ary_push(stack, LONG2NUM(i + 1));
5175 
5176  vmemo = rb_hash_new();
5177  RBASIC_CLEAR_CLASS(vmemo);
5178  memo = st_init_numtable();
5179  rb_hash_st_table_set(vmemo, memo);
5180  st_insert(memo, (st_data_t)ary, (st_data_t)Qtrue);
5181  st_insert(memo, (st_data_t)tmp, (st_data_t)Qtrue);
5182 
5183  ary = tmp;
5184  i = 0;
5185 
5186  while (1) {
5187  while (i < RARRAY_LEN(ary)) {
5188  elt = RARRAY_AREF(ary, i++);
5189  if (level >= 0 && RARRAY_LEN(stack) / 2 >= level) {
5190  rb_ary_push(result, elt);
5191  continue;
5192  }
5193  tmp = rb_check_array_type(elt);
5194  if (RBASIC(result)->klass) {
5195  RB_GC_GUARD(vmemo);
5196  st_clear(memo);
5197  rb_raise(rb_eRuntimeError, "flatten reentered");
5198  }
5199  if (NIL_P(tmp)) {
5200  rb_ary_push(result, elt);
5201  }
5202  else {
5203  id = (st_data_t)tmp;
5204  if (st_is_member(memo, id)) {
5205  st_clear(memo);
5206  rb_raise(rb_eArgError, "tried to flatten recursive array");
5207  }
5208  st_insert(memo, id, (st_data_t)Qtrue);
5209  rb_ary_push(stack, ary);
5210  rb_ary_push(stack, LONG2NUM(i));
5211  ary = tmp;
5212  i = 0;
5213  }
5214  }
5215  if (RARRAY_LEN(stack) == 0) {
5216  break;
5217  }
5218  id = (st_data_t)ary;
5219  st_delete(memo, &id, 0);
5220  tmp = rb_ary_pop(stack);
5221  i = NUM2LONG(tmp);
5222  ary = rb_ary_pop(stack);
5223  }
5224 
5225  st_clear(memo);
5226 
5227  RBASIC_SET_CLASS(result, rb_obj_class(ary));
5228  return result;
5229 }
5230 
5231 /*
5232  * call-seq:
5233  * ary.flatten! -> ary or nil
5234  * ary.flatten!(level) -> ary or nil
5235  *
5236  * Flattens +self+ in place.
5237  *
5238  * Returns +nil+ if no modifications were made (i.e., the array contains no
5239  * subarrays.)
5240  *
5241  * The optional +level+ argument determines the level of recursion to flatten.
5242  *
5243  * a = [ 1, 2, [3, [4, 5] ] ]
5244  * a.flatten! #=> [1, 2, 3, 4, 5]
5245  * a.flatten! #=> nil
5246  * a #=> [1, 2, 3, 4, 5]
5247  * a = [ 1, 2, [3, [4, 5] ] ]
5248  * a.flatten!(1) #=> [1, 2, 3, [4, 5]]
5249  */
5250 
5251 static VALUE
5252 rb_ary_flatten_bang(int argc, VALUE *argv, VALUE ary)
5253 {
5254  int mod = 0, level = -1;
5255  VALUE result, lv;
5256 
5257  lv = (rb_check_arity(argc, 0, 1) ? argv[0] : Qnil);
5258  rb_ary_modify_check(ary);
5259  if (!NIL_P(lv)) level = NUM2INT(lv);
5260  if (level == 0) return Qnil;
5261 
5262  result = flatten(ary, level);
5263  if (result == ary) {
5264  return Qnil;
5265  }
5266  if (!(mod = ARY_EMBED_P(result))) rb_obj_freeze(result);
5267  rb_ary_replace(ary, result);
5268  if (mod) ARY_SET_EMBED_LEN(result, 0);
5269 
5270  return ary;
5271 }
5272 
5273 /*
5274  * call-seq:
5275  * ary.flatten -> new_ary
5276  * ary.flatten(level) -> new_ary
5277  *
5278  * Returns a new array that is a one-dimensional flattening of +self+
5279  * (recursively).
5280  *
5281  * That is, for every element that is an array, extract its elements into
5282  * the new array.
5283  *
5284  * The optional +level+ argument determines the level of recursion to
5285  * flatten.
5286  *
5287  * s = [ 1, 2, 3 ] #=> [1, 2, 3]
5288  * t = [ 4, 5, 6, [7, 8] ] #=> [4, 5, 6, [7, 8]]
5289  * a = [ s, t, 9, 10 ] #=> [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10]
5290  * a.flatten #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
5291  * a = [ 1, 2, [3, [4, 5] ] ]
5292  * a.flatten(1) #=> [1, 2, 3, [4, 5]]
5293  */
5294 
5295 static VALUE
5296 rb_ary_flatten(int argc, VALUE *argv, VALUE ary)
5297 {
5298  int level = -1;
5299  VALUE result;
5300 
5301  if (rb_check_arity(argc, 0, 1) && !NIL_P(argv[0])) {
5302  level = NUM2INT(argv[0]);
5303  if (level == 0) return ary_make_shared_copy(ary);
5304  }
5305 
5306  result = flatten(ary, level);
5307  if (result == ary) {
5308  result = ary_make_shared_copy(ary);
5309  }
5310 
5311  return result;
5312 }
5313 
5314 #define OPTHASH_GIVEN_P(opts) \
5315  (argc > 0 && !NIL_P((opts) = rb_check_hash_type(argv[argc-1])) && (--argc, 1))
5316 static ID id_random;
5317 
5318 #define RAND_UPTO(max) (long)rb_random_ulong_limited((randgen), (max)-1)
5319 
5320 /*
5321  * call-seq:
5322  * ary.shuffle! -> ary
5323  * ary.shuffle!(random: rng) -> ary
5324  *
5325  * Shuffles elements in +self+ in place.
5326  *
5327  * a = [ 1, 2, 3 ] #=> [1, 2, 3]
5328  * a.shuffle! #=> [2, 3, 1]
5329  * a #=> [2, 3, 1]
5330  *
5331  * The optional +rng+ argument will be used as the random number generator.
5332  *
5333  * a.shuffle!(random: Random.new(1)) #=> [1, 3, 2]
5334  */
5335 
5336 static VALUE
5337 rb_ary_shuffle_bang(int argc, VALUE *argv, VALUE ary)
5338 {
5339  VALUE opts, randgen = rb_cRandom;
5340  long i, len;
5341 
5342  if (OPTHASH_GIVEN_P(opts)) {
5343  VALUE rnd;
5344  ID keyword_ids[1];
5345 
5346  keyword_ids[0] = id_random;
5347  rb_get_kwargs(opts, keyword_ids, 0, 1, &rnd);
5348  if (rnd != Qundef) {
5349  randgen = rnd;
5350  }
5351  }
5352  rb_check_arity(argc, 0, 0);
5353  rb_ary_modify(ary);
5354  i = len = RARRAY_LEN(ary);
5355  RARRAY_PTR_USE(ary, ptr, {
5356  while (i) {
5357  long j = RAND_UPTO(i);
5358  VALUE tmp;
5359  if (len != RARRAY_LEN(ary) || ptr != RARRAY_CONST_PTR_TRANSIENT(ary)) {
5360  rb_raise(rb_eRuntimeError, "modified during shuffle");
5361  }
5362  tmp = ptr[--i];
5363  ptr[i] = ptr[j];
5364  ptr[j] = tmp;
5365  }
5366  }); /* WB: no new reference */
5367  return ary;
5368 }
5369 
5370 
5371 /*
5372  * call-seq:
5373  * ary.shuffle -> new_ary
5374  * ary.shuffle(random: rng) -> new_ary
5375  *
5376  * Returns a new array with elements of +self+ shuffled.
5377  *
5378  * a = [ 1, 2, 3 ] #=> [1, 2, 3]
5379  * a.shuffle #=> [2, 3, 1]
5380  * a #=> [1, 2, 3]
5381  *
5382  * The optional +rng+ argument will be used as the random number generator.
5383  *
5384  * a.shuffle(random: Random.new(1)) #=> [1, 3, 2]
5385  */
5386 
5387 static VALUE
5388 rb_ary_shuffle(int argc, VALUE *argv, VALUE ary)
5389 {
5390  ary = rb_ary_dup(ary);
5391  rb_ary_shuffle_bang(argc, argv, ary);
5392  return ary;
5393 }
5394 
5395 
5396 /*
5397  * call-seq:
5398  * ary.sample -> obj
5399  * ary.sample(random: rng) -> obj
5400  * ary.sample(n) -> new_ary
5401  * ary.sample(n, random: rng) -> new_ary
5402  *
5403  * Choose a random element or +n+ random elements from the array.
5404  *
5405  * The elements are chosen by using random and unique indices into the array
5406  * in order to ensure that an element doesn't repeat itself unless the array
5407  * already contained duplicate elements.
5408  *
5409  * If the array is empty the first form returns +nil+ and the second form
5410  * returns an empty array.
5411  *
5412  * a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
5413  * a.sample #=> 7
5414  * a.sample(4) #=> [6, 4, 2, 5]
5415  *
5416  * The optional +rng+ argument will be used as the random number generator.
5417  *
5418  * a.sample(random: Random.new(1)) #=> 6
5419  * a.sample(4, random: Random.new(1)) #=> [6, 10, 9, 2]
5420  */
5421 
5422 
5423 static VALUE
5424 rb_ary_sample(int argc, VALUE *argv, VALUE ary)
5425 {
5426  VALUE nv, result;
5427  VALUE opts, randgen = rb_cRandom;
5428  long n, len, i, j, k, idx[10];
5429  long rnds[numberof(idx)];
5430  long memo_threshold;
5431 
5432  if (OPTHASH_GIVEN_P(opts)) {
5433  VALUE rnd;
5434  ID keyword_ids[1];
5435 
5436  keyword_ids[0] = id_random;
5437  rb_get_kwargs(opts, keyword_ids, 0, 1, &rnd);
5438  if (rnd != Qundef) {
5439  randgen = rnd;
5440  }
5441  }
5442  len = RARRAY_LEN(ary);
5443  if (rb_check_arity(argc, 0, 1) == 0) {
5444  if (len < 2)
5445  i = 0;
5446  else
5447  i = RAND_UPTO(len);
5448 
5449  return rb_ary_elt(ary, i);
5450  }
5451  nv = argv[0];
5452  n = NUM2LONG(nv);
5453  if (n < 0) rb_raise(rb_eArgError, "negative sample number");
5454  if (n > len) n = len;
5455  if (n <= numberof(idx)) {
5456  for (i = 0; i < n; ++i) {
5457  rnds[i] = RAND_UPTO(len - i);
5458  }
5459  }
5460  k = len;
5461  len = RARRAY_LEN(ary);
5462  if (len < k && n <= numberof(idx)) {
5463  for (i = 0; i < n; ++i) {
5464  if (rnds[i] >= len) return rb_ary_new_capa(0);
5465  }
5466  }
5467  if (n > len) n = len;
5468  switch (n) {
5469  case 0:
5470  return rb_ary_new_capa(0);
5471  case 1:
5472  i = rnds[0];
5473  return rb_ary_new_from_values(1, &RARRAY_AREF(ary, i));
5474  case 2:
5475  i = rnds[0];
5476  j = rnds[1];
5477  if (j >= i) j++;
5478  return rb_ary_new_from_args(2, RARRAY_AREF(ary, i), RARRAY_AREF(ary, j));
5479  case 3:
5480  i = rnds[0];
5481  j = rnds[1];
5482  k = rnds[2];
5483  {
5484  long l = j, g = i;
5485  if (j >= i) l = i, g = ++j;
5486  if (k >= l && (++k >= g)) ++k;
5487  }
5488  return rb_ary_new_from_args(3, RARRAY_AREF(ary, i), RARRAY_AREF(ary, j), RARRAY_AREF(ary, k));
5489  }
5490  memo_threshold =
5491  len < 2560 ? len / 128 :
5492  len < 5120 ? len / 64 :
5493  len < 10240 ? len / 32 :
5494  len / 16;
5495  if (n <= numberof(idx)) {
5496  long sorted[numberof(idx)];
5497  sorted[0] = idx[0] = rnds[0];
5498  for (i=1; i<n; i++) {
5499  k = rnds[i];
5500  for (j = 0; j < i; ++j) {
5501  if (k < sorted[j]) break;
5502  ++k;
5503  }
5504  memmove(&sorted[j+1], &sorted[j], sizeof(sorted[0])*(i-j));
5505  sorted[j] = idx[i] = k;
5506  }
5507  result = rb_ary_new_capa(n);
5508  RARRAY_PTR_USE_TRANSIENT(result, ptr_result, {
5509  for (i=0; i<n; i++) {
5510  ptr_result[i] = RARRAY_AREF(ary, idx[i]);
5511  }
5512  });
5513  }
5514  else if (n <= memo_threshold / 2) {
5515  long max_idx = 0;
5516 #undef RUBY_UNTYPED_DATA_WARNING
5517 #define RUBY_UNTYPED_DATA_WARNING 0
5518  VALUE vmemo = Data_Wrap_Struct(0, 0, st_free_table, 0);
5520  DATA_PTR(vmemo) = memo;
5521  result = rb_ary_new_capa(n);
5522  RARRAY_PTR_USE(result, ptr_result, {
5523  for (i=0; i<n; i++) {
5524  long r = RAND_UPTO(len-i) + i;
5525  ptr_result[i] = r;
5526  if (r > max_idx) max_idx = r;
5527  }
5528  len = RARRAY_LEN(ary);
5529  if (len <= max_idx) n = 0;
5530  else if (n > len) n = len;
5531  RARRAY_PTR_USE_TRANSIENT(ary, ptr_ary, {
5532  for (i=0; i<n; i++) {
5533  long j2 = j = ptr_result[i];
5534  long i2 = i;
5535  st_data_t value;
5536  if (st_lookup(memo, (st_data_t)i, &value)) i2 = (long)value;
5537  if (st_lookup(memo, (st_data_t)j, &value)) j2 = (long)value;
5538  st_insert(memo, (st_data_t)j, (st_data_t)i2);
5539  ptr_result[i] = ptr_ary[j2];
5540  }
5541  });
5542  });
5543  DATA_PTR(vmemo) = 0;
5544  st_free_table(memo);
5545  }
5546  else {
5547  result = rb_ary_dup(ary);
5548  RBASIC_CLEAR_CLASS(result);
5549  RB_GC_GUARD(ary);
5550  RARRAY_PTR_USE(result, ptr_result, {
5551  for (i=0; i<n; i++) {
5552  j = RAND_UPTO(len-i) + i;
5553  nv = ptr_result[j];
5554  ptr_result[j] = ptr_result[i];
5555  ptr_result[i] = nv;
5556  }
5557  });
5559  }
5560  ARY_SET_LEN(result, n);
5561 
5562  return result;
5563 }
5564 
5565 static VALUE
5566 rb_ary_cycle_size(VALUE self, VALUE args, VALUE eobj)
5567 {
5568  long mul;
5569  VALUE n = Qnil;
5570  if (args && (RARRAY_LEN(args) > 0)) {
5571  n = RARRAY_AREF(args, 0);
5572  }
5573  if (RARRAY_LEN(self) == 0) return INT2FIX(0);
5574  if (n == Qnil) return DBL2NUM(HUGE_VAL);
5575  mul = NUM2LONG(n);
5576  if (mul <= 0) return INT2FIX(0);
5577  n = LONG2FIX(mul);
5578  return rb_fix_mul_fix(rb_ary_length(self), n);
5579 }
5580 
5581 /*
5582  * call-seq:
5583  * ary.cycle(n=nil) {|obj| block} -> nil
5584  * ary.cycle(n=nil) -> Enumerator
5585  *
5586  * Calls the given block for each element +n+ times or forever if +nil+ is
5587  * given.
5588  *
5589  * Does nothing if a non-positive number is given or the array is empty.
5590  *
5591  * Returns +nil+ if the loop has finished without getting interrupted.
5592  *
5593  * If no block is given, an Enumerator is returned instead.
5594  *
5595  * a = ["a", "b", "c"]
5596  * a.cycle {|x| puts x} # print, a, b, c, a, b, c,.. forever.
5597  * a.cycle(2) {|x| puts x} # print, a, b, c, a, b, c.
5598  *
5599  */
5600 
5601 static VALUE
5602 rb_ary_cycle(int argc, VALUE *argv, VALUE ary)
5603 {
5604  long n, i;
5605 
5606  rb_check_arity(argc, 0, 1);
5607 
5608  RETURN_SIZED_ENUMERATOR(ary, argc, argv, rb_ary_cycle_size);
5609  if (argc == 0 || NIL_P(argv[0])) {
5610  n = -1;
5611  }
5612  else {
5613  n = NUM2LONG(argv[0]);
5614  if (n <= 0) return Qnil;
5615  }
5616 
5617  while (RARRAY_LEN(ary) > 0 && (n < 0 || 0 < n--)) {
5618  for (i=0; i<RARRAY_LEN(ary); i++) {
5619  rb_yield(RARRAY_AREF(ary, i));
5620  }
5621  }
5622  return Qnil;
5623 }
5624 
5625 #define tmpary(n) rb_ary_tmp_new(n)
5626 #define tmpary_discard(a) (ary_discard(a), RBASIC_SET_CLASS_RAW(a, rb_cArray))
5627 
5628 /*
5629  * Build a ruby array of the corresponding values and yield it to the
5630  * associated block.
5631  * Return the class of +values+ for reentry check.
5632  */
5633 static int
5634 yield_indexed_values(const VALUE values, const long r, const long *const p)
5635 {
5636  const VALUE result = rb_ary_new2(r);
5637  long i;
5638 
5639  for (i = 0; i < r; i++) ARY_SET(result, i, RARRAY_AREF(values, p[i]));
5640  ARY_SET_LEN(result, r);
5641  rb_yield(result);
5642  return !RBASIC(values)->klass;
5643 }
5644 
5645 /*
5646  * Compute permutations of +r+ elements of the set <code>[0..n-1]</code>.
5647  *
5648  * When we have a complete permutation of array indices, copy the values
5649  * at those indices into a new array and yield that array.
5650  *
5651  * n: the size of the set
5652  * r: the number of elements in each permutation
5653  * p: the array (of size r) that we're filling in
5654  * used: an array of booleans: whether a given index is already used
5655  * values: the Ruby array that holds the actual values to permute
5656  */
5657 static void
5658 permute0(const long n, const long r, long *const p, char *const used, const VALUE values)
5659 {
5660  long i = 0, index = 0;
5661 
5662  for (;;) {
5663  const char *const unused = memchr(&used[i], 0, n-i);
5664  if (!unused) {
5665  if (!index) break;
5666  i = p[--index]; /* pop index */
5667  used[i++] = 0; /* index unused */
5668  }
5669  else {
5670  i = unused - used;
5671  p[index] = i;
5672  used[i] = 1; /* mark index used */
5673  ++index;
5674  if (index < r-1) { /* if not done yet */
5675  p[index] = i = 0;
5676  continue;
5677  }
5678  for (i = 0; i < n; ++i) {
5679  if (used[i]) continue;
5680  p[index] = i;
5681  if (!yield_indexed_values(values, r, p)) {
5682  rb_raise(rb_eRuntimeError, "permute reentered");
5683  }
5684  }
5685  i = p[--index]; /* pop index */
5686  used[i] = 0; /* index unused */
5687  p[index] = ++i;
5688  }
5689  }
5690 }
5691 
5692 /*
5693  * Returns the product of from, from-1, ..., from - how_many + 1.
5694  * http://en.wikipedia.org/wiki/Pochhammer_symbol
5695  */
5696 static VALUE
5697 descending_factorial(long from, long how_many)
5698 {
5699  VALUE cnt;
5700  if (how_many > 0) {
5701  cnt = LONG2FIX(from);
5702  while (--how_many > 0) {
5703  long v = --from;
5704  cnt = rb_int_mul(cnt, LONG2FIX(v));
5705  }
5706  }
5707  else {
5708  cnt = LONG2FIX(how_many == 0);
5709  }
5710  return cnt;
5711 }
5712 
5713 static VALUE
5714 binomial_coefficient(long comb, long size)
5715 {
5716  VALUE r;
5717  long i;
5718  if (comb > size-comb) {
5719  comb = size-comb;
5720  }
5721  if (comb < 0) {
5722  return LONG2FIX(0);
5723  }
5724  else if (comb == 0) {
5725  return LONG2FIX(1);
5726  }
5727  r = LONG2FIX(size);
5728  for (i = 1; i < comb; ++i) {
5729  r = rb_int_mul(r, LONG2FIX(size - i));
5730  r = rb_int_idiv(r, LONG2FIX(i + 1));
5731  }
5732  return r;
5733 }
5734 
5735 static VALUE
5736 rb_ary_permutation_size(VALUE ary, VALUE args, VALUE eobj)
5737 {
5738  long n = RARRAY_LEN(ary);
5739  long k = (args && (RARRAY_LEN(args) > 0)) ? NUM2LONG(RARRAY_AREF(args, 0)) : n;
5740 
5741  return descending_factorial(n, k);
5742 }
5743 
5744 /*
5745  * call-seq:
5746  * ary.permutation {|p| block} -> ary
5747  * ary.permutation -> Enumerator
5748  * ary.permutation(n) {|p| block} -> ary
5749  * ary.permutation(n) -> Enumerator
5750  *
5751  * When invoked with a block, yield all permutations of length +n+ of the
5752  * elements of the array, then return the array itself.
5753  *
5754  * If +n+ is not specified, yield all permutations of all elements.
5755  *
5756  * The implementation makes no guarantees about the order in which the
5757  * permutations are yielded.
5758  *
5759  * If no block is given, an Enumerator is returned instead.
5760  *
5761  * Examples:
5762  *
5763  * a = [1, 2, 3]
5764  * a.permutation.to_a #=> [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
5765  * a.permutation(1).to_a #=> [[1],[2],[3]]
5766  * a.permutation(2).to_a #=> [[1,2],[1,3],[2,1],[2,3],[3,1],[3,2]]
5767  * a.permutation(3).to_a #=> [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
5768  * a.permutation(0).to_a #=> [[]] # one permutation of length 0
5769  * a.permutation(4).to_a #=> [] # no permutations of length 4
5770  */
5771 
5772 static VALUE
5773 rb_ary_permutation(int argc, VALUE *argv, VALUE ary)
5774 {
5775  long r, n, i;
5776 
5777  n = RARRAY_LEN(ary); /* Array length */
5778  RETURN_SIZED_ENUMERATOR(ary, argc, argv, rb_ary_permutation_size); /* Return enumerator if no block */
5779  r = n;
5780  if (rb_check_arity(argc, 0, 1) && !NIL_P(argv[0]))
5781  r = NUM2LONG(argv[0]); /* Permutation size from argument */
5782 
5783  if (r < 0 || n < r) {
5784  /* no permutations: yield nothing */
5785  }
5786  else if (r == 0) { /* exactly one permutation: the zero-length array */
5787  rb_yield(rb_ary_new2(0));
5788  }
5789  else if (r == 1) { /* this is a special, easy case */
5790  for (i = 0; i < RARRAY_LEN(ary); i++) {
5791  rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
5792  }
5793  }
5794  else { /* this is the general case */
5795  volatile VALUE t0;
5796  long *p = ALLOCV_N(long, t0, r+roomof(n, sizeof(long)));
5797  char *used = (char*)(p + r);
5798  VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
5799  RBASIC_CLEAR_CLASS(ary0);
5800 
5801  MEMZERO(used, char, n); /* initialize array */
5802 
5803  permute0(n, r, p, used, ary0); /* compute and yield permutations */
5804  ALLOCV_END(t0);
5806  }
5807  return ary;
5808 }
5809 
5810 static void
5811 combinate0(const long len, const long n, long *const stack, const VALUE values)
5812 {
5813  long lev = 0;
5814 
5815  MEMZERO(stack+1, long, n);
5816  stack[0] = -1;
5817  for (;;) {
5818  for (lev++; lev < n; lev++) {
5819  stack[lev+1] = stack[lev]+1;
5820  }
5821  if (!yield_indexed_values(values, n, stack+1)) {
5822  rb_raise(rb_eRuntimeError, "combination reentered");
5823  }
5824  do {
5825  if (lev == 0) return;
5826  stack[lev--]++;
5827  } while (stack[lev+1]+n == len+lev+1);
5828  }
5829 }
5830 
5831 static VALUE
5832 rb_ary_combination_size(VALUE ary, VALUE args, VALUE eobj)
5833 {
5834  long n = RARRAY_LEN(ary);
5835  long k = NUM2LONG(RARRAY_AREF(args, 0));
5836 
5837  return binomial_coefficient(k, n);
5838 }
5839 
5840 /*
5841  * call-seq:
5842  * ary.combination(n) {|c| block} -> ary
5843  * ary.combination(n) -> Enumerator
5844  *
5845  * When invoked with a block, yields all combinations of length +n+ of elements
5846  * from the array and then returns the array itself.
5847  *
5848  * The implementation makes no guarantees about the order in which the
5849  * combinations are yielded.
5850  *
5851  * If no block is given, an Enumerator is returned instead.
5852  *
5853  * Examples:
5854  *
5855  * a = [1, 2, 3, 4]
5856  * a.combination(1).to_a #=> [[1],[2],[3],[4]]
5857  * a.combination(2).to_a #=> [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]
5858  * a.combination(3).to_a #=> [[1,2,3],[1,2,4],[1,3,4],[2,3,4]]
5859  * a.combination(4).to_a #=> [[1,2,3,4]]
5860  * a.combination(0).to_a #=> [[]] # one combination of length 0
5861  * a.combination(5).to_a #=> [] # no combinations of length 5
5862  *
5863  */
5864 
5865 static VALUE
5866 rb_ary_combination(VALUE ary, VALUE num)
5867 {
5868  long i, n, len;
5869 
5870  n = NUM2LONG(num);
5871  RETURN_SIZED_ENUMERATOR(ary, 1, &num, rb_ary_combination_size);
5872  len = RARRAY_LEN(ary);
5873  if (n < 0 || len < n) {
5874  /* yield nothing */
5875  }
5876  else if (n == 0) {
5877  rb_yield(rb_ary_new2(0));
5878  }
5879  else if (n == 1) {
5880  for (i = 0; i < RARRAY_LEN(ary); i++) {
5881  rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
5882  }
5883  }
5884  else {
5885  VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
5886  volatile VALUE t0;
5887  long *stack = ALLOCV_N(long, t0, n+1);
5888 
5889  RBASIC_CLEAR_CLASS(ary0);
5890  combinate0(len, n, stack, ary0);
5891  ALLOCV_END(t0);
5893  }
5894  return ary;
5895 }
5896 
5897 /*
5898  * Compute repeated permutations of +r+ elements of the set
5899  * <code>[0..n-1]</code>.
5900  *
5901  * When we have a complete repeated permutation of array indices, copy the
5902  * values at those indices into a new array and yield that array.
5903  *
5904  * n: the size of the set
5905  * r: the number of elements in each permutation
5906  * p: the array (of size r) that we're filling in
5907  * values: the Ruby array that holds the actual values to permute
5908  */
5909 static void
5910 rpermute0(const long n, const long r, long *const p, const VALUE values)
5911 {
5912  long i = 0, index = 0;
5913 
5914  p[index] = i;
5915  for (;;) {
5916  if (++index < r-1) {
5917  p[index] = i = 0;
5918  continue;
5919  }
5920  for (i = 0; i < n; ++i) {
5921  p[index] = i;
5922  if (!yield_indexed_values(values, r, p)) {
5923  rb_raise(rb_eRuntimeError, "repeated permute reentered");
5924  }
5925  }
5926  do {
5927  if (index <= 0) return;
5928  } while ((i = ++p[--index]) >= n);
5929  }
5930 }
5931 
5932 static VALUE
5933 rb_ary_repeated_permutation_size(VALUE ary, VALUE args, VALUE eobj)
5934 {
5935  long n = RARRAY_LEN(ary);
5936  long k = NUM2LONG(RARRAY_AREF(args, 0));
5937 
5938  if (k < 0) {
5939  return LONG2FIX(0);
5940  }
5941  if (n <= 0) {
5942  return LONG2FIX(!k);
5943  }
5944  return rb_int_positive_pow(n, (unsigned long)k);
5945 }
5946 
5947 /*
5948  * call-seq:
5949  * ary.repeated_permutation(n) {|p| block} -> ary
5950  * ary.repeated_permutation(n) -> Enumerator
5951  *
5952  * When invoked with a block, yield all repeated permutations of length +n+ of
5953  * the elements of the array, then return the array itself.
5954  *
5955  * The implementation makes no guarantees about the order in which the repeated
5956  * permutations are yielded.
5957  *
5958  * If no block is given, an Enumerator is returned instead.
5959  *
5960  * Examples:
5961  *
5962  * a = [1, 2]
5963  * a.repeated_permutation(1).to_a #=> [[1], [2]]
5964  * a.repeated_permutation(2).to_a #=> [[1,1],[1,2],[2,1],[2,2]]
5965  * a.repeated_permutation(3).to_a #=> [[1,1,1],[1,1,2],[1,2,1],[1,2,2],
5966  * # [2,1,1],[2,1,2],[2,2,1],[2,2,2]]
5967  * a.repeated_permutation(0).to_a #=> [[]] # one permutation of length 0
5968  */
5969 
5970 static VALUE
5971 rb_ary_repeated_permutation(VALUE ary, VALUE num)
5972 {
5973  long r, n, i;
5974 
5975  n = RARRAY_LEN(ary); /* Array length */
5976  RETURN_SIZED_ENUMERATOR(ary, 1, &num, rb_ary_repeated_permutation_size); /* Return Enumerator if no block */
5977  r = NUM2LONG(num); /* Permutation size from argument */
5978 
5979  if (r < 0) {
5980  /* no permutations: yield nothing */
5981  }
5982  else if (r == 0) { /* exactly one permutation: the zero-length array */
5983  rb_yield(rb_ary_new2(0));
5984  }
5985  else if (r == 1) { /* this is a special, easy case */
5986  for (i = 0; i < RARRAY_LEN(ary); i++) {
5987  rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
5988  }
5989  }
5990  else { /* this is the general case */
5991  volatile VALUE t0;
5992  long *p = ALLOCV_N(long, t0, r);
5993  VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
5994  RBASIC_CLEAR_CLASS(ary0);
5995 
5996  rpermute0(n, r, p, ary0); /* compute and yield repeated permutations */
5997  ALLOCV_END(t0);
5999  }
6000  return ary;
6001 }
6002 
6003 static void
6004 rcombinate0(const long n, const long r, long *const p, const long rest, const VALUE values)
6005 {
6006  long i = 0, index = 0;
6007 
6008  p[index] = i;
6009  for (;;) {
6010  if (++index < r-1) {
6011  p[index] = i;
6012  continue;
6013  }
6014  for (; i < n; ++i) {
6015  p[index] = i;
6016  if (!yield_indexed_values(values, r, p)) {
6017  rb_raise(rb_eRuntimeError, "repeated combination reentered");
6018  }
6019  }
6020  do {
6021  if (index <= 0) return;
6022  } while ((i = ++p[--index]) >= n);
6023  }
6024 }
6025 
6026 static VALUE
6027 rb_ary_repeated_combination_size(VALUE ary, VALUE args, VALUE eobj)
6028 {
6029  long n = RARRAY_LEN(ary);
6030  long k = NUM2LONG(RARRAY_AREF(args, 0));
6031  if (k == 0) {
6032  return LONG2FIX(1);
6033  }
6034  return binomial_coefficient(k, n + k - 1);
6035 }
6036 
6037 /*
6038  * call-seq:
6039  * ary.repeated_combination(n) {|c| block} -> ary
6040  * ary.repeated_combination(n) -> Enumerator
6041  *
6042  * When invoked with a block, yields all repeated combinations of length +n+ of
6043  * elements from the array and then returns the array itself.
6044  *
6045  * The implementation makes no guarantees about the order in which the repeated
6046  * combinations are yielded.
6047  *
6048  * If no block is given, an Enumerator is returned instead.
6049  *
6050  * Examples:
6051  *
6052  * a = [1, 2, 3]
6053  * a.repeated_combination(1).to_a #=> [[1], [2], [3]]
6054  * a.repeated_combination(2).to_a #=> [[1,1],[1,2],[1,3],[2,2],[2,3],[3,3]]
6055  * a.repeated_combination(3).to_a #=> [[1,1,1],[1,1,2],[1,1,3],[1,2,2],[1,2,3],
6056  * # [1,3,3],[2,2,2],[2,2,3],[2,3,3],[3,3,3]]
6057  * a.repeated_combination(4).to_a #=> [[1,1,1,1],[1,1,1,2],[1,1,1,3],[1,1,2,2],[1,1,2,3],
6058  * # [1,1,3,3],[1,2,2,2],[1,2,2,3],[1,2,3,3],[1,3,3,3],
6059  * # [2,2,2,2],[2,2,2,3],[2,2,3,3],[2,3,3,3],[3,3,3,3]]
6060  * a.repeated_combination(0).to_a #=> [[]] # one combination of length 0
6061  *
6062  */
6063 
6064 static VALUE
6065 rb_ary_repeated_combination(VALUE ary, VALUE num)
6066 {
6067  long n, i, len;
6068 
6069  n = NUM2LONG(num); /* Combination size from argument */
6070  RETURN_SIZED_ENUMERATOR(ary, 1, &num, rb_ary_repeated_combination_size); /* Return enumerator if no block */
6071  len = RARRAY_LEN(ary);
6072  if (n < 0) {
6073  /* yield nothing */
6074  }
6075  else if (n == 0) {
6076  rb_yield(rb_ary_new2(0));
6077  }
6078  else if (n == 1) {
6079  for (i = 0; i < RARRAY_LEN(ary); i++) {
6080  rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
6081  }
6082  }
6083  else if (len == 0) {
6084  /* yield nothing */
6085  }
6086  else {
6087  volatile VALUE t0;
6088  long *p = ALLOCV_N(long, t0, n);
6089  VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
6090  RBASIC_CLEAR_CLASS(ary0);
6091 
6092  rcombinate0(len, n, p, n, ary0); /* compute and yield repeated combinations */
6093  ALLOCV_END(t0);
6095  }
6096  return ary;
6097 }
6098 
6099 /*
6100  * call-seq:
6101  * ary.product(other_ary, ...) -> new_ary
6102  * ary.product(other_ary, ...) {|p| block} -> ary
6103  *
6104  * Returns an array of all combinations of elements from all arrays.
6105  *
6106  * The length of the returned array is the product of the length of +self+ and
6107  * the argument arrays.
6108  *
6109  * If given a block, #product will yield all combinations and return +self+
6110  * instead.
6111  *
6112  * [1,2,3].product([4,5]) #=> [[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]]
6113  * [1,2].product([1,2]) #=> [[1,1],[1,2],[2,1],[2,2]]
6114  * [1,2].product([3,4],[5,6]) #=> [[1,3,5],[1,3,6],[1,4,5],[1,4,6],
6115  * # [2,3,5],[2,3,6],[2,4,5],[2,4,6]]
6116  * [1,2].product() #=> [[1],[2]]
6117  * [1,2].product([]) #=> []
6118  */
6119 
6120 static VALUE
6121 rb_ary_product(int argc, VALUE *argv, VALUE ary)
6122 {
6123  int n = argc+1; /* How many arrays we're operating on */
6124  volatile VALUE t0 = tmpary(n);
6125  volatile VALUE t1 = Qundef;
6126  VALUE *arrays = RARRAY_PTR(t0); /* The arrays we're computing the product of */
6127  int *counters = ALLOCV_N(int, t1, n); /* The current position in each one */
6128  VALUE result = Qnil; /* The array we'll be returning, when no block given */
6129  long i,j;
6130  long resultlen = 1;
6131 
6132  RBASIC_CLEAR_CLASS(t0);
6133 
6134  /* initialize the arrays of arrays */
6135  ARY_SET_LEN(t0, n);
6136  arrays[0] = ary;
6137  for (i = 1; i < n; i++) arrays[i] = Qnil;
6138  for (i = 1; i < n; i++) arrays[i] = to_ary(argv[i-1]);
6139 
6140  /* initialize the counters for the arrays */
6141  for (i = 0; i < n; i++) counters[i] = 0;
6142 
6143  /* Otherwise, allocate and fill in an array of results */
6144  if (rb_block_given_p()) {
6145  /* Make defensive copies of arrays; exit if any is empty */
6146  for (i = 0; i < n; i++) {
6147  if (RARRAY_LEN(arrays[i]) == 0) goto done;
6148  arrays[i] = ary_make_shared_copy(arrays[i]);
6149  }
6150  }
6151  else {
6152  /* Compute the length of the result array; return [] if any is empty */
6153  for (i = 0; i < n; i++) {
6154  long k = RARRAY_LEN(arrays[i]);
6155  if (k == 0) {
6156  result = rb_ary_new2(0);
6157  goto done;
6158  }
6159  if (MUL_OVERFLOW_LONG_P(resultlen, k))
6160  rb_raise(rb_eRangeError, "too big to product");
6161  resultlen *= k;
6162  }
6163  result = rb_ary_new2(resultlen);
6164  }
6165  for (;;) {
6166  int m;
6167  /* fill in one subarray */
6168  VALUE subarray = rb_ary_new2(n);
6169  for (j = 0; j < n; j++) {
6170  rb_ary_push(subarray, rb_ary_entry(arrays[j], counters[j]));
6171  }
6172 
6173  /* put it on the result array */
6174  if (NIL_P(result)) {
6175  FL_SET(t0, FL_USER5);
6176  rb_yield(subarray);
6177  if (! FL_TEST(t0, FL_USER5)) {
6178  rb_raise(rb_eRuntimeError, "product reentered");
6179  }
6180  else {
6181  FL_UNSET(t0, FL_USER5);
6182  }
6183  }
6184  else {
6185  rb_ary_push(result, subarray);
6186  }
6187 
6188  /*
6189  * Increment the last counter. If it overflows, reset to 0
6190  * and increment the one before it.
6191  */
6192  m = n-1;
6193  counters[m]++;
6194  while (counters[m] == RARRAY_LEN(arrays[m])) {
6195  counters[m] = 0;
6196  /* If the first counter overflows, we are done */
6197  if (--m < 0) goto done;
6198  counters[m]++;
6199  }
6200  }
6201 done:
6202  tmpary_discard(t0);
6203  ALLOCV_END(t1);
6204 
6205  return NIL_P(result) ? ary : result;
6206 }
6207 
6208 /*
6209  * call-seq:
6210  * ary.take(n) -> new_ary
6211  *
6212  * Returns first +n+ elements from the array.
6213  *
6214  * If a negative number is given, raises an ArgumentError.
6215  *
6216  * See also Array#drop
6217  *
6218  * a = [1, 2, 3, 4, 5, 0]
6219  * a.take(3) #=> [1, 2, 3]
6220  *
6221  */
6222 
6223 static VALUE
6224 rb_ary_take(VALUE obj, VALUE n)
6225 {
6226  long len = NUM2LONG(n);
6227  if (len < 0) {
6228  rb_raise(rb_eArgError, "attempt to take negative size");
6229  }
6230  return rb_ary_subseq(obj, 0, len);
6231 }
6232 
6233 /*
6234  * call-seq:
6235  * ary.take_while {|obj| block} -> new_ary
6236  * ary.take_while -> Enumerator
6237  *
6238  * Passes elements to the block until the block returns +nil+ or +false+, then
6239  * stops iterating and returns an array of all prior elements.
6240  *
6241  * If no block is given, an Enumerator is returned instead.
6242  *
6243  * See also Array#drop_while
6244  *
6245  * a = [1, 2, 3, 4, 5, 0]
6246  * a.take_while {|i| i < 3} #=> [1, 2]
6247  *
6248  */
6249 
6250 static VALUE
6251 rb_ary_take_while(VALUE ary)
6252 {
6253  long i;
6254 
6255  RETURN_ENUMERATOR(ary, 0, 0);
6256  for (i = 0; i < RARRAY_LEN(ary); i++) {
6257  if (!RTEST(rb_yield(RARRAY_AREF(ary, i)))) break;
6258  }
6259  return rb_ary_take(ary, LONG2FIX(i));
6260 }
6261 
6262 /*
6263  * call-seq:
6264  * ary.drop(n) -> new_ary
6265  *
6266  * Drops first +n+ elements from +ary+ and returns the rest of the elements in
6267  * an array.
6268  *
6269  * If a negative number is given, raises an ArgumentError.
6270  *
6271  * See also Array#take
6272  *
6273  * a = [1, 2, 3, 4, 5, 0]
6274  * a.drop(3) #=> [4, 5, 0]
6275  *
6276  */
6277 
6278 static VALUE
6279 rb_ary_drop(VALUE ary, VALUE n)
6280 {
6281  VALUE result;
6282  long pos = NUM2LONG(n);
6283  if (pos < 0) {
6284  rb_raise(rb_eArgError, "attempt to drop negative size");
6285  }
6286 
6287  result = rb_ary_subseq(ary, pos, RARRAY_LEN(ary));
6288  if (result == Qnil) result = rb_ary_new();
6289  return result;
6290 }
6291 
6292 /*
6293  * call-seq:
6294  * ary.drop_while {|obj| block} -> new_ary
6295  * ary.drop_while -> Enumerator
6296  *
6297  * Drops elements up to, but not including, the first element for which the
6298  * block returns +nil+ or +false+ and returns an array containing the
6299  * remaining elements.
6300  *
6301  * If no block is given, an Enumerator is returned instead.
6302  *
6303  * See also Array#take_while
6304  *
6305  * a = [1, 2, 3, 4, 5, 0]
6306  * a.drop_while {|i| i < 3 } #=> [3, 4, 5, 0]
6307  *
6308  */
6309 
6310 static VALUE
6311 rb_ary_drop_while(VALUE ary)
6312 {
6313  long i;
6314 
6315  RETURN_ENUMERATOR(ary, 0, 0);
6316  for (i = 0; i < RARRAY_LEN(ary); i++) {
6317  if (!RTEST(rb_yield(RARRAY_AREF(ary, i)))) break;
6318  }
6319  return rb_ary_drop(ary, LONG2FIX(i));
6320 }
6321 
6322 /*
6323  * call-seq:
6324  * ary.any? [{|obj| block} ] -> true or false
6325  * ary.any?(pattern) -> true or false
6326  *
6327  * See also Enumerable#any?
6328  */
6329 
6330 static VALUE
6331 rb_ary_any_p(int argc, VALUE *argv, VALUE ary)
6332 {
6333  long i, len = RARRAY_LEN(ary);
6334 
6335  rb_check_arity(argc, 0, 1);
6336  if (!len) return Qfalse;
6337  if (argc) {
6338  if (rb_block_given_p()) {
6339  rb_warn("given block not used");
6340  }
6341  for (i = 0; i < RARRAY_LEN(ary); ++i) {
6342  if (RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) return Qtrue;
6343  }
6344  }
6345  else if (!rb_block_given_p()) {
6346  for (i = 0; i < len; ++i) {
6347  if (RTEST(RARRAY_AREF(ary, i))) return Qtrue;
6348  }
6349  }
6350  else {
6351  for (i = 0; i < RARRAY_LEN(ary); ++i) {
6352  if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) return Qtrue;
6353  }
6354  }
6355  return Qfalse;
6356 }
6357 
6358 /*
6359  * call-seq:
6360  * ary.all? [{|obj| block} ] -> true or false
6361  * ary.all?(pattern) -> true or false
6362  *
6363  * See also Enumerable#all?
6364  */
6365 
6366 static VALUE
6367 rb_ary_all_p(int argc, VALUE *argv, VALUE ary)
6368 {
6369  long i, len = RARRAY_LEN(ary);
6370 
6371  rb_check_arity(argc, 0, 1);
6372  if (!len) return Qtrue;
6373  if (argc) {
6374  if (rb_block_given_p()) {
6375  rb_warn("given block not used");
6376  }
6377  for (i = 0; i < RARRAY_LEN(ary); ++i) {
6378  if (!RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) return Qfalse;
6379  }
6380  }
6381  else if (!rb_block_given_p()) {
6382  for (i = 0; i < len; ++i) {
6383  if (!RTEST(RARRAY_AREF(ary, i))) return Qfalse;
6384  }
6385  }
6386  else {
6387  for (i = 0; i < RARRAY_LEN(ary); ++i) {
6388  if (!RTEST(rb_yield(RARRAY_AREF(ary, i)))) return Qfalse;
6389  }
6390  }
6391  return Qtrue;
6392 }
6393 
6394 /*
6395  * call-seq:
6396  * ary.none? [{|obj| block} ] -> true or false
6397  * ary.none?(pattern) -> true or false
6398  *
6399  * See also Enumerable#none?
6400  */
6401 
6402 static VALUE
6403 rb_ary_none_p(int argc, VALUE *argv, VALUE ary)
6404 {
6405  long i, len = RARRAY_LEN(ary);
6406 
6407  rb_check_arity(argc, 0, 1);
6408  if (!len) return Qtrue;
6409  if (argc) {
6410  if (rb_block_given_p()) {
6411  rb_warn("given block not used");
6412  }
6413  for (i = 0; i < RARRAY_LEN(ary); ++i) {
6414  if (RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) return Qfalse;
6415  }
6416  }
6417  else if (!rb_block_given_p()) {
6418  for (i = 0; i < len; ++i) {
6419  if (RTEST(RARRAY_AREF(ary, i))) return Qfalse;
6420  }
6421  }
6422  else {
6423  for (i = 0; i < RARRAY_LEN(ary); ++i) {
6424  if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) return Qfalse;
6425  }
6426  }
6427  return Qtrue;
6428 }
6429 
6430 /*
6431  * call-seq:
6432  * ary.one? [{|obj| block} ] -> true or false
6433  * ary.one?(pattern) -> true or false
6434  *
6435  * See also Enumerable#one?
6436  */
6437 
6438 static VALUE
6439 rb_ary_one_p(int argc, VALUE *argv, VALUE ary)
6440 {
6441  long i, len = RARRAY_LEN(ary);
6442  VALUE result = Qfalse;
6443 
6444  rb_check_arity(argc, 0, 1);
6445  if (!len) return Qfalse;
6446  if (argc) {
6447  if (rb_block_given_p()) {
6448  rb_warn("given block not used");
6449  }
6450  for (i = 0; i < RARRAY_LEN(ary); ++i) {
6451  if (RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) {
6452  if (result) return Qfalse;
6453  result = Qtrue;
6454  }
6455  }
6456  }
6457  else if (!rb_block_given_p()) {
6458  for (i = 0; i < len; ++i) {
6459  if (RTEST(RARRAY_AREF(ary, i))) {
6460  if (result) return Qfalse;
6461  result = Qtrue;
6462  }
6463  }
6464  }
6465  else {
6466  for (i = 0; i < RARRAY_LEN(ary); ++i) {
6467  if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) {
6468  if (result) return Qfalse;
6469  result = Qtrue;
6470  }
6471  }
6472  }
6473  return result;
6474 }
6475 
6476 /*
6477  * call-seq:
6478  * ary.dig(idx, ...) -> object
6479  *
6480  * Extracts the nested value specified by the sequence of <i>idx</i>
6481  * objects by calling +dig+ at each step, returning +nil+ if any
6482  * intermediate step is +nil+.
6483  *
6484  * a = [[1, [2, 3]]]
6485  *
6486  * a.dig(0, 1, 1) #=> 3
6487  * a.dig(1, 2, 3) #=> nil
6488  * a.dig(0, 0, 0) #=> TypeError: Integer does not have #dig method
6489  * [42, {foo: :bar}].dig(1, :foo) #=> :bar
6490  */
6491 
6492 static VALUE
6493 rb_ary_dig(int argc, VALUE *argv, VALUE self)
6494 {
6496  self = rb_ary_at(self, *argv);
6497  if (!--argc) return self;
6498  ++argv;
6499  return rb_obj_dig(argc, argv, self, Qnil);
6500 }
6501 
6502 static inline VALUE
6503 finish_exact_sum(long n, VALUE r, VALUE v, int z)
6504 {
6505  if (n != 0)
6506  v = rb_fix_plus(LONG2FIX(n), v);
6507  if (r != Qundef) {
6508  /* r can be an Integer when mathn is loaded */
6509  if (FIXNUM_P(r))
6510  v = rb_fix_plus(r, v);
6511  else if (RB_TYPE_P(r, T_BIGNUM))
6512  v = rb_big_plus(r, v);
6513  else
6514  v = rb_rational_plus(r, v);
6515  }
6516  else if (!n && z) {
6517  v = rb_fix_plus(LONG2FIX(0), v);
6518  }
6519  return v;
6520 }
6521 
6522 /*
6523  * call-seq:
6524  * ary.sum(init=0) -> number
6525  * ary.sum(init=0) {|e| expr } -> number
6526  *
6527  * Returns the sum of elements.
6528  * For example, [e1, e2, e3].sum returns init + e1 + e2 + e3.
6529  *
6530  * If a block is given, the block is applied to each element
6531  * before addition.
6532  *
6533  * If <i>ary</i> is empty, it returns <i>init</i>.
6534  *
6535  * [].sum #=> 0
6536  * [].sum(0.0) #=> 0.0
6537  * [1, 2, 3].sum #=> 6
6538  * [3, 5.5].sum #=> 8.5
6539  * [2.5, 3.0].sum(0.0) {|e| e * e } #=> 15.25
6540  * [Object.new].sum #=> TypeError
6541  *
6542  * The (arithmetic) mean value of an array can be obtained as follows.
6543  *
6544  * mean = ary.sum(0.0) / ary.length
6545  *
6546  * This method can be used for non-numeric objects by
6547  * explicit <i>init</i> argument.
6548  *
6549  * ["a", "b", "c"].sum("") #=> "abc"
6550  * [[1], [[2]], [3]].sum([]) #=> [1, [2], 3]
6551  *
6552  * However, Array#join and Array#flatten is faster than Array#sum for
6553  * array of strings and array of arrays.
6554  *
6555  * ["a", "b", "c"].join #=> "abc"
6556  * [[1], [[2]], [3]].flatten(1) #=> [1, [2], 3]
6557  *
6558  *
6559  * Array#sum method may not respect method redefinition of "+" methods
6560  * such as Integer#+.
6561  *
6562  */
6563 
6564 static VALUE
6565 rb_ary_sum(int argc, VALUE *argv, VALUE ary)
6566 {
6567  VALUE e, v, r;
6568  long i, n;
6569  int block_given;
6570 
6571  v = (rb_check_arity(argc, 0, 1) ? argv[0] : LONG2FIX(0));
6572 
6573  block_given = rb_block_given_p();
6574 
6575  if (RARRAY_LEN(ary) == 0)
6576  return v;
6577 
6578  n = 0;
6579  r = Qundef;
6580  for (i = 0; i < RARRAY_LEN(ary); i++) {
6581  e = RARRAY_AREF(ary, i);
6582  if (block_given)
6583  e = rb_yield(e);
6584  if (FIXNUM_P(e)) {
6585  n += FIX2LONG(e); /* should not overflow long type */
6586  if (!FIXABLE(n)) {
6587  v = rb_big_plus(LONG2NUM(n), v);
6588  n = 0;
6589  }
6590  }
6591  else if (RB_TYPE_P(e, T_BIGNUM))
6592  v = rb_big_plus(e, v);
6593  else if (RB_TYPE_P(e, T_RATIONAL)) {
6594  if (r == Qundef)
6595  r = e;
6596  else
6597  r = rb_rational_plus(r, e);
6598  }
6599  else
6600  goto not_exact;
6601  }
6602  v = finish_exact_sum(n, r, v, argc!=0);
6603  return v;
6604 
6605  not_exact:
6606  v = finish_exact_sum(n, r, v, i!=0);
6607 
6608  if (RB_FLOAT_TYPE_P(e)) {
6609  /*
6610  * Kahan-Babuska balancing compensated summation algorithm
6611  * See http://link.springer.com/article/10.1007/s00607-005-0139-x
6612  */
6613  double f, c;
6614  double x, t;
6615 
6616  f = NUM2DBL(v);
6617  c = 0.0;
6618  goto has_float_value;
6619  for (; i < RARRAY_LEN(ary); i++) {
6620  e = RARRAY_AREF(ary, i);
6621  if (block_given)
6622  e = rb_yield(e);
6623  if (RB_FLOAT_TYPE_P(e))
6624  has_float_value:
6625  x = RFLOAT_VALUE(e);
6626  else if (FIXNUM_P(e))
6627  x = FIX2LONG(e);
6628  else if (RB_TYPE_P(e, T_BIGNUM))
6629  x = rb_big2dbl(e);
6630  else if (RB_TYPE_P(e, T_RATIONAL))
6631  x = rb_num2dbl(e);
6632  else
6633  goto not_float;
6634 
6635  if (isnan(f)) continue;
6636  if (isnan(x)) {
6637  f = x;
6638  continue;
6639  }
6640  if (isinf(x)) {
6641  if (isinf(f) && signbit(x) != signbit(f))
6642  f = NAN;
6643  else
6644  f = x;
6645  continue;
6646  }
6647  if (isinf(f)) continue;
6648 
6649  t = f + x;
6650  if (fabs(f) >= fabs(x))
6651  c += ((f - t) + x);
6652  else
6653  c += ((x - t) + f);
6654  f = t;
6655  }
6656  f += c;
6657  return DBL2NUM(f);
6658 
6659  not_float:
6660  v = DBL2NUM(f);
6661  }
6662 
6663  goto has_some_value;
6664  for (; i < RARRAY_LEN(ary); i++) {
6665  e = RARRAY_AREF(ary, i);
6666  if (block_given)
6667  e = rb_yield(e);
6668  has_some_value:
6669  v = rb_funcall(v, idPLUS, 1, e);
6670  }
6671  return v;
6672 }
6673 
6674 static VALUE
6675 rb_ary_deconstruct(VALUE ary)
6676 {
6677  return ary;
6678 }
6679 
6680 /*
6681  * Arrays are ordered, integer-indexed collections of any object.
6682  *
6683  * Array indexing starts at 0, as in C or Java. A negative index is assumed
6684  * to be relative to the end of the array---that is, an index of -1 indicates
6685  * the last element of the array, -2 is the next to last element in the
6686  * array, and so on.
6687  *
6688  * == Creating Arrays
6689  *
6690  * A new array can be created by using the literal constructor
6691  * <code>[]</code>. Arrays can contain different types of objects. For
6692  * example, the array below contains an Integer, a String and a Float:
6693  *
6694  * ary = [1, "two", 3.0] #=> [1, "two", 3.0]
6695  *
6696  * An array can also be created by explicitly calling Array.new with zero, one
6697  * (the initial size of the Array) or two arguments (the initial size and a
6698  * default object).
6699  *
6700  * ary = Array.new #=> []
6701  * Array.new(3) #=> [nil, nil, nil]
6702  * Array.new(3, true) #=> [true, true, true]
6703  *
6704  * Note that the second argument populates the array with references to the
6705  * same object. Therefore, it is only recommended in cases when you need to
6706  * instantiate arrays with natively immutable objects such as Symbols,
6707  * numbers, true or false.
6708  *
6709  * To create an array with separate objects a block can be passed instead.
6710  * This method is safe to use with mutable objects such as hashes, strings or
6711  * other arrays:
6712  *
6713  * Array.new(4) {Hash.new} #=> [{}, {}, {}, {}]
6714  * Array.new(4) {|i| i.to_s } #=> ["0", "1", "2", "3"]
6715  *
6716  * This is also a quick way to build up multi-dimensional arrays:
6717  *
6718  * empty_table = Array.new(3) {Array.new(3)}
6719  * #=> [[nil, nil, nil], [nil, nil, nil], [nil, nil, nil]]
6720  *
6721  * An array can also be created by using the Array() method, provided by
6722  * Kernel, which tries to call #to_ary, then #to_a on its argument.
6723  *
6724  * Array({:a => "a", :b => "b"}) #=> [[:a, "a"], [:b, "b"]]
6725  *
6726  * == Example Usage
6727  *
6728  * In addition to the methods it mixes in through the Enumerable module, the
6729  * Array class has proprietary methods for accessing, searching and otherwise
6730  * manipulating arrays.
6731  *
6732  * Some of the more common ones are illustrated below.
6733  *
6734  * == Accessing Elements
6735  *
6736  * Elements in an array can be retrieved using the Array#[] method. It can
6737  * take a single integer argument (a numeric index), a pair of arguments
6738  * (start and length) or a range. Negative indices start counting from the end,
6739  * with -1 being the last element.
6740  *
6741  * arr = [1, 2, 3, 4, 5, 6]
6742  * arr[2] #=> 3
6743  * arr[100] #=> nil
6744  * arr[-3] #=> 4
6745  * arr[2, 3] #=> [3, 4, 5]
6746  * arr[1..4] #=> [2, 3, 4, 5]
6747  * arr[1..-3] #=> [2, 3, 4]
6748  *
6749  * Another way to access a particular array element is by using the #at method
6750  *
6751  * arr.at(0) #=> 1
6752  *
6753  * The #slice method works in an identical manner to Array#[].
6754  *
6755  * To raise an error for indices outside of the array bounds or else to
6756  * provide a default value when that happens, you can use #fetch.
6757  *
6758  * arr = ['a', 'b', 'c', 'd', 'e', 'f']
6759  * arr.fetch(100) #=> IndexError: index 100 outside of array bounds: -6...6
6760  * arr.fetch(100, "oops") #=> "oops"
6761  *
6762  * The special methods #first and #last will return the first and last
6763  * elements of an array, respectively.
6764  *
6765  * arr.first #=> 1
6766  * arr.last #=> 6
6767  *
6768  * To return the first +n+ elements of an array, use #take
6769  *
6770  * arr.take(3) #=> [1, 2, 3]
6771  *
6772  * #drop does the opposite of #take, by returning the elements after +n+
6773  * elements have been dropped:
6774  *
6775  * arr.drop(3) #=> [4, 5, 6]
6776  *
6777  * == Obtaining Information about an Array
6778  *
6779  * Arrays keep track of their own length at all times. To query an array
6780  * about the number of elements it contains, use #length, #count or #size.
6781  *
6782  * browsers = ['Chrome', 'Firefox', 'Safari', 'Opera', 'IE']
6783  * browsers.length #=> 5
6784  * browsers.count #=> 5
6785  *
6786  * To check whether an array contains any elements at all
6787  *
6788  * browsers.empty? #=> false
6789  *
6790  * To check whether a particular item is included in the array
6791  *
6792  * browsers.include?('Konqueror') #=> false
6793  *
6794  * == Adding Items to Arrays
6795  *
6796  * Items can be added to the end of an array by using either #push or #<<
6797  *
6798  * arr = [1, 2, 3, 4]
6799  * arr.push(5) #=> [1, 2, 3, 4, 5]
6800  * arr << 6 #=> [1, 2, 3, 4, 5, 6]
6801  *
6802  * #unshift will add a new item to the beginning of an array.
6803  *
6804  * arr.unshift(0) #=> [0, 1, 2, 3, 4, 5, 6]
6805  *
6806  * With #insert you can add a new element to an array at any position.
6807  *
6808  * arr.insert(3, 'apple') #=> [0, 1, 2, 'apple', 3, 4, 5, 6]
6809  *
6810  * Using the #insert method, you can also insert multiple values at once:
6811  *
6812  * arr.insert(3, 'orange', 'pear', 'grapefruit')
6813  * #=> [0, 1, 2, "orange", "pear", "grapefruit", "apple", 3, 4, 5, 6]
6814  *
6815  * == Removing Items from an Array
6816  *
6817  * The method #pop removes the last element in an array and returns it:
6818  *
6819  * arr = [1, 2, 3, 4, 5, 6]
6820  * arr.pop #=> 6
6821  * arr #=> [1, 2, 3, 4, 5]
6822  *
6823  * To retrieve and at the same time remove the first item, use #shift:
6824  *
6825  * arr.shift #=> 1
6826  * arr #=> [2, 3, 4, 5]
6827  *
6828  * To delete an element at a particular index:
6829  *
6830  * arr.delete_at(2) #=> 4
6831  * arr #=> [2, 3, 5]
6832  *
6833  * To delete a particular element anywhere in an array, use #delete:
6834  *
6835  * arr = [1, 2, 2, 3]
6836  * arr.delete(2) #=> 2
6837  * arr #=> [1,3]
6838  *
6839  * A useful method if you need to remove +nil+ values from an array is
6840  * #compact:
6841  *
6842  * arr = ['foo', 0, nil, 'bar', 7, 'baz', nil]
6843  * arr.compact #=> ['foo', 0, 'bar', 7, 'baz']
6844  * arr #=> ['foo', 0, nil, 'bar', 7, 'baz', nil]
6845  * arr.compact! #=> ['foo', 0, 'bar', 7, 'baz']
6846  * arr #=> ['foo', 0, 'bar', 7, 'baz']
6847  *
6848  * Another common need is to remove duplicate elements from an array.
6849  *
6850  * It has the non-destructive #uniq, and destructive method #uniq!
6851  *
6852  * arr = [2, 5, 6, 556, 6, 6, 8, 9, 0, 123, 556]
6853  * arr.uniq #=> [2, 5, 6, 556, 8, 9, 0, 123]
6854  *
6855  * == Iterating over Arrays
6856  *
6857  * Like all classes that include the Enumerable module, Array has an each
6858  * method, which defines what elements should be iterated over and how. In
6859  * case of Array's #each, all elements in the Array instance are yielded to
6860  * the supplied block in sequence.
6861  *
6862  * Note that this operation leaves the array unchanged.
6863  *
6864  * arr = [1, 2, 3, 4, 5]
6865  * arr.each {|a| print a -= 10, " "}
6866  * # prints: -9 -8 -7 -6 -5
6867  * #=> [1, 2, 3, 4, 5]
6868  *
6869  * Another sometimes useful iterator is #reverse_each which will iterate over
6870  * the elements in the array in reverse order.
6871  *
6872  * words = %w[first second third fourth fifth sixth]
6873  * str = ""
6874  * words.reverse_each {|word| str += "#{word} "}
6875  * p str #=> "sixth fifth fourth third second first "
6876  *
6877  * The #map method can be used to create a new array based on the original
6878  * array, but with the values modified by the supplied block:
6879  *
6880  * arr.map {|a| 2*a} #=> [2, 4, 6, 8, 10]
6881  * arr #=> [1, 2, 3, 4, 5]
6882  * arr.map! {|a| a**2} #=> [1, 4, 9, 16, 25]
6883  * arr #=> [1, 4, 9, 16, 25]
6884  *
6885  * == Selecting Items from an Array
6886  *
6887  * Elements can be selected from an array according to criteria defined in a
6888  * block. The selection can happen in a destructive or a non-destructive
6889  * manner. While the destructive operations will modify the array they were
6890  * called on, the non-destructive methods usually return a new array with the
6891  * selected elements, but leave the original array unchanged.
6892  *
6893  * === Non-destructive Selection
6894  *
6895  * arr = [1, 2, 3, 4, 5, 6]
6896  * arr.select {|a| a > 3} #=> [4, 5, 6]
6897  * arr.reject {|a| a < 3} #=> [3, 4, 5, 6]
6898  * arr.drop_while {|a| a < 4} #=> [4, 5, 6]
6899  * arr #=> [1, 2, 3, 4, 5, 6]
6900  *
6901  * === Destructive Selection
6902  *
6903  * #select! and #reject! are the corresponding destructive methods to #select
6904  * and #reject
6905  *
6906  * Similar to #select vs. #reject, #delete_if and #keep_if have the exact
6907  * opposite result when supplied with the same block:
6908  *
6909  * arr.delete_if {|a| a < 4} #=> [4, 5, 6]
6910  * arr #=> [4, 5, 6]
6911  *
6912  * arr = [1, 2, 3, 4, 5, 6]
6913  * arr.keep_if {|a| a < 4} #=> [1, 2, 3]
6914  * arr #=> [1, 2, 3]
6915  *
6916  */
6917 
6918 void
6920 {
6921 #undef rb_intern
6922 #define rb_intern(str) rb_intern_const(str)
6923 
6924  rb_cArray = rb_define_class("Array", rb_cObject);
6926 
6927  rb_define_alloc_func(rb_cArray, empty_ary_alloc);
6928  rb_define_singleton_method(rb_cArray, "[]", rb_ary_s_create, -1);
6929  rb_define_singleton_method(rb_cArray, "try_convert", rb_ary_s_try_convert, 1);
6930  rb_define_method(rb_cArray, "initialize", rb_ary_initialize, -1);
6931  rb_define_method(rb_cArray, "initialize_copy", rb_ary_replace, 1);
6932 
6933  rb_define_method(rb_cArray, "inspect", rb_ary_inspect, 0);
6934  rb_define_alias(rb_cArray, "to_s", "inspect");
6935  rb_define_method(rb_cArray, "to_a", rb_ary_to_a, 0);
6936  rb_define_method(rb_cArray, "to_h", rb_ary_to_h, 0);
6937  rb_define_method(rb_cArray, "to_ary", rb_ary_to_ary_m, 0);
6938 
6939  rb_define_method(rb_cArray, "==", rb_ary_equal, 1);
6940  rb_define_method(rb_cArray, "eql?", rb_ary_eql, 1);
6941  rb_define_method(rb_cArray, "hash", rb_ary_hash, 0);
6942 
6944  rb_define_method(rb_cArray, "[]=", rb_ary_aset, -1);
6946  rb_define_method(rb_cArray, "fetch", rb_ary_fetch, -1);
6947  rb_define_method(rb_cArray, "first", rb_ary_first, -1);
6948  rb_define_method(rb_cArray, "last", rb_ary_last, -1);
6949  rb_define_method(rb_cArray, "concat", rb_ary_concat_multi, -1);
6950  rb_define_method(rb_cArray, "union", rb_ary_union_multi, -1);
6951  rb_define_method(rb_cArray, "difference", rb_ary_difference_multi, -1);
6952  rb_define_method(rb_cArray, "intersection", rb_ary_intersection_multi, -1);
6954  rb_define_method(rb_cArray, "push", rb_ary_push_m, -1);
6955  rb_define_alias(rb_cArray, "append", "push");
6956  rb_define_method(rb_cArray, "pop", rb_ary_pop_m, -1);
6957  rb_define_method(rb_cArray, "shift", rb_ary_shift_m, -1);
6958  rb_define_method(rb_cArray, "unshift", rb_ary_unshift_m, -1);
6959  rb_define_alias(rb_cArray, "prepend", "unshift");
6960  rb_define_method(rb_cArray, "insert", rb_ary_insert, -1);
6961  rb_define_method(rb_cArray, "each", rb_ary_each, 0);
6962  rb_define_method(rb_cArray, "each_index", rb_ary_each_index, 0);
6963  rb_define_method(rb_cArray, "reverse_each", rb_ary_reverse_each, 0);
6964  rb_define_method(rb_cArray, "length", rb_ary_length, 0);
6965  rb_define_alias(rb_cArray, "size", "length");
6966  rb_define_method(rb_cArray, "empty?", rb_ary_empty_p, 0);
6967  rb_define_method(rb_cArray, "find_index", rb_ary_index, -1);
6968  rb_define_method(rb_cArray, "index", rb_ary_index, -1);
6969  rb_define_method(rb_cArray, "rindex", rb_ary_rindex, -1);
6970  rb_define_method(rb_cArray, "join", rb_ary_join_m, -1);
6971  rb_define_method(rb_cArray, "reverse", rb_ary_reverse_m, 0);
6972  rb_define_method(rb_cArray, "reverse!", rb_ary_reverse_bang, 0);
6973  rb_define_method(rb_cArray, "rotate", rb_ary_rotate_m, -1);
6974  rb_define_method(rb_cArray, "rotate!", rb_ary_rotate_bang, -1);
6975  rb_define_method(rb_cArray, "sort", rb_ary_sort, 0);
6977  rb_define_method(rb_cArray, "sort_by!", rb_ary_sort_by_bang, 0);
6978  rb_define_method(rb_cArray, "collect", rb_ary_collect, 0);
6979  rb_define_method(rb_cArray, "collect!", rb_ary_collect_bang, 0);
6980  rb_define_method(rb_cArray, "map", rb_ary_collect, 0);
6981  rb_define_method(rb_cArray, "map!", rb_ary_collect_bang, 0);
6982  rb_define_method(rb_cArray, "select", rb_ary_select, 0);
6983  rb_define_method(rb_cArray, "select!", rb_ary_select_bang, 0);
6984  rb_define_method(rb_cArray, "filter", rb_ary_select, 0);
6985  rb_define_method(rb_cArray, "filter!", rb_ary_select_bang, 0);
6986  rb_define_method(rb_cArray, "keep_if", rb_ary_keep_if, 0);
6987  rb_define_method(rb_cArray, "values_at", rb_ary_values_at, -1);
6988  rb_define_method(rb_cArray, "delete", rb_ary_delete, 1);
6989  rb_define_method(rb_cArray, "delete_at", rb_ary_delete_at_m, 1);
6990  rb_define_method(rb_cArray, "delete_if", rb_ary_delete_if, 0);
6991  rb_define_method(rb_cArray, "reject", rb_ary_reject, 0);
6992  rb_define_method(rb_cArray, "reject!", rb_ary_reject_bang, 0);
6993  rb_define_method(rb_cArray, "zip", rb_ary_zip, -1);
6994  rb_define_method(rb_cArray, "transpose", rb_ary_transpose, 0);
6995  rb_define_method(rb_cArray, "replace", rb_ary_replace, 1);
6996  rb_define_method(rb_cArray, "clear", rb_ary_clear, 0);
6997  rb_define_method(rb_cArray, "fill", rb_ary_fill, -1);
6998  rb_define_method(rb_cArray, "include?", rb_ary_includes, 1);
7000 
7001  rb_define_method(rb_cArray, "slice", rb_ary_aref, -1);
7002  rb_define_method(rb_cArray, "slice!", rb_ary_slice_bang, -1);
7003 
7004  rb_define_method(rb_cArray, "assoc", rb_ary_assoc, 1);
7005  rb_define_method(rb_cArray, "rassoc", rb_ary_rassoc, 1);
7006 
7008  rb_define_method(rb_cArray, "*", rb_ary_times, 1);
7009 
7010  rb_define_method(rb_cArray, "-", rb_ary_diff, 1);
7011  rb_define_method(rb_cArray, "&", rb_ary_and, 1);
7012  rb_define_method(rb_cArray, "|", rb_ary_or, 1);
7013 
7014  rb_define_method(rb_cArray, "max", rb_ary_max, -1);
7015  rb_define_method(rb_cArray, "min", rb_ary_min, -1);
7016  rb_define_method(rb_cArray, "minmax", rb_ary_minmax, 0);
7017 
7018  rb_define_method(rb_cArray, "uniq", rb_ary_uniq, 0);
7019  rb_define_method(rb_cArray, "uniq!", rb_ary_uniq_bang, 0);
7020  rb_define_method(rb_cArray, "compact", rb_ary_compact, 0);
7021  rb_define_method(rb_cArray, "compact!", rb_ary_compact_bang, 0);
7022  rb_define_method(rb_cArray, "flatten", rb_ary_flatten, -1);
7023  rb_define_method(rb_cArray, "flatten!", rb_ary_flatten_bang, -1);
7024  rb_define_method(rb_cArray, "count", rb_ary_count, -1);
7025  rb_define_method(rb_cArray, "shuffle!", rb_ary_shuffle_bang, -1);
7026  rb_define_method(rb_cArray, "shuffle", rb_ary_shuffle, -1);
7027  rb_define_method(rb_cArray, "sample", rb_ary_sample, -1);
7028  rb_define_method(rb_cArray, "cycle", rb_ary_cycle, -1);
7029  rb_define_method(rb_cArray, "permutation", rb_ary_permutation, -1);
7030  rb_define_method(rb_cArray, "combination", rb_ary_combination, 1);
7031  rb_define_method(rb_cArray, "repeated_permutation", rb_ary_repeated_permutation, 1);
7032  rb_define_method(rb_cArray, "repeated_combination", rb_ary_repeated_combination, 1);
7033  rb_define_method(rb_cArray, "product", rb_ary_product, -1);
7034 
7035  rb_define_method(rb_cArray, "take", rb_ary_take, 1);
7036  rb_define_method(rb_cArray, "take_while", rb_ary_take_while, 0);
7037  rb_define_method(rb_cArray, "drop", rb_ary_drop, 1);
7038  rb_define_method(rb_cArray, "drop_while", rb_ary_drop_while, 0);
7039  rb_define_method(rb_cArray, "bsearch", rb_ary_bsearch, 0);
7040  rb_define_method(rb_cArray, "bsearch_index", rb_ary_bsearch_index, 0);
7041  rb_define_method(rb_cArray, "any?", rb_ary_any_p, -1);
7042  rb_define_method(rb_cArray, "all?", rb_ary_all_p, -1);
7043  rb_define_method(rb_cArray, "none?", rb_ary_none_p, -1);
7044  rb_define_method(rb_cArray, "one?", rb_ary_one_p, -1);
7045  rb_define_method(rb_cArray, "dig", rb_ary_dig, -1);
7046  rb_define_method(rb_cArray, "sum", rb_ary_sum, -1);
7047 
7048  rb_define_method(rb_cArray, "deconstruct", rb_ary_deconstruct, 0);
7049 
7050  id_random = rb_intern("random");
7051 }
rb_cArray
VALUE rb_cArray
Definition: array.c:27
rb_hash_st_table_set
void rb_hash_st_table_set(VALUE hash, st_table *st)
Definition: hash.c:558
ARY_SET_SHARED_ROOT_REFCNT
#define ARY_SET_SHARED_ROOT_REFCNT(ary, value)
Definition: array.c:151
ARY_HEAP_LEN
#define ARY_HEAP_LEN(a)
Definition: array.c:59
rb_ary_new_capa
VALUE rb_ary_new_capa(long capa)
Definition: array.c:717
tmpary_discard
#define tmpary_discard(a)
Definition: array.c:5626
rb_transient_heap_managed_ptr_p
int rb_transient_heap_managed_ptr_p(const void *ptr)
Definition: transient_heap.c:506
RARRAY_TRANSIENT_P
#define RARRAY_TRANSIENT_P(ary)
Definition: ruby.h:1076
rb_ary_rotate
VALUE rb_ary_rotate(VALUE ary, long cnt)
Definition: array.c:2617
rb_get_kwargs
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
Definition: class.c:1886
i
uint32_t i
Definition: rb_mjit_min_header-2.7.1.h:5464
ID
unsigned long ID
Definition: ruby.h:103
rb_define_class
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:649
Init_Array
void Init_Array(void)
Definition: array.c:6919
obj
const VALUE VALUE obj
Definition: rb_mjit_min_header-2.7.1.h:5742
ARY_HEAP_PTR
#define ARY_HEAP_PTR(a)
Definition: array.c:58
CMP_OPTIMIZABLE
#define CMP_OPTIMIZABLE(data, type)
Definition: internal.h:1330
TRUE
#define TRUE
Definition: nkf.h:175
select_bang_arg
Definition: array.c:3228
rb_check_convert_type_with_id
VALUE rb_check_convert_type_with_id(VALUE, int, const char *, ID)
Definition: object.c:2957
long
#define long
Definition: rb_mjit_min_header-2.7.1.h:2880
rb_block_arity
int rb_block_arity(void)
Definition: proc.c:1144
rb_include_module
void rb_include_module(VALUE klass, VALUE module)
Definition: class.c:869
rb_assoc_new
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Definition: array.c:896
select_bang_arg::ary
VALUE ary
Definition: array.c:3229
assert
#define assert(x)
Definition: dlmalloc.c:1176
klass
VALUE klass
Definition: rb_mjit_min_header-2.7.1.h:13259
range
#define range(low, item, hi)
Definition: date_strftime.c:21
st_data_t
unsigned long st_data_t
Definition: rb_mjit_min_header-2.7.1.h:5363
id
const int id
Definition: nkf.c:209
RUBY_ASSERT_ALWAYS
#define RUBY_ASSERT_ALWAYS(expr)
Definition: assert.h:34
rb_hash_new
VALUE rb_hash_new(void)
Definition: hash.c:1523
rb_output_fs
VALUE rb_output_fs
Definition: intern.h:584
ARY_INCREASE_LEN
#define ARY_INCREASE_LEN(ary, n)
Definition: array.c:117
RARRAY_EMBED_LEN_MAX
@ RARRAY_EMBED_LEN_MAX
Definition: ruby.h:1028
rb_ary_tmp_new_fill
VALUE rb_ary_tmp_new_fill(long capa)
Definition: array.c:776
rb_str_buf_cat2
#define rb_str_buf_cat2
Definition: intern.h:911
rb_str_buf_new
VALUE rb_str_buf_new(long)
Definition: string.c:1315
rb_warn
void rb_warn(const char *fmt,...)
Definition: error.c:313
rb_ary_to_ary
VALUE rb_ary_to_ary(VALUE obj)
Definition: array.c:1853
rb_block_given_p
int rb_block_given_p(void)
Determines if the current method is given a block.
Definition: eval.c:898
RHASH_ST_CLEAR
#define RHASH_ST_CLEAR(h)
Definition: internal.h:862
rb_ary_shared_with_p
VALUE rb_ary_shared_with_p(VALUE ary1, VALUE ary2)
Definition: array.c:661
rb_hash_values
VALUE rb_hash_values(VALUE hash)
Definition: hash.c:3450
rb_warning
void rb_warning(const char *fmt,...)
Definition: error.c:334
rb_cNumeric
RUBY_EXTERN VALUE rb_cNumeric
Definition: ruby.h:2037
rb_ary_free
void rb_ary_free(VALUE ary)
Definition: array.c:786
RBASIC_CLEAR_CLASS
#define RBASIC_CLEAR_CLASS(obj)
Definition: internal.h:1986
USE_DEBUG_COUNTER
#define USE_DEBUG_COUNTER
Definition: debug_counter.h:12
idEach
@ idEach
Definition: rb_mjit_min_header-2.7.1.h:8708
ST_STOP
@ ST_STOP
Definition: st.h:99
ARY_INCREASE_PTR
#define ARY_INCREASE_PTR(ary, n)
Definition: array.c:112
idEqq
@ idEqq
Definition: id.h:97
rb_funcall
#define rb_funcall(recv, mid, argc,...)
Definition: rb_mjit_min_header-2.7.1.h:6585
rb_gc_force_recycle
void rb_gc_force_recycle(VALUE obj)
Definition: gc.c:7013
INT2FIX
#define INT2FIX(i)
Definition: ruby.h:263
n
const char size_t n
Definition: rb_mjit_min_header-2.7.1.h:5456
st_is_member
#define st_is_member(table, key)
Definition: st.h:97
bp
#define bp()
Definition: internal.h:1445
ARY_SHARED_ROOT_OCCUPIED
#define ARY_SHARED_ROOT_OCCUPIED(ary)
Definition: array.c:150
ary_take_pos_flags
ary_take_pos_flags
Definition: array.c:1145
NUM2LONG
#define NUM2LONG(x)
Definition: ruby.h:679
rb_ary_new_from_args
VALUE() rb_ary_new_from_args(long n,...)
Definition: array.c:729
st_init_numtable
st_table * st_init_numtable(void)
Definition: st.c:653
rb_equal
VALUE rb_equal(VALUE, VALUE)
Same as Object#===, case equality.
Definition: object.c:124
rb_ary_unshift
VALUE rb_ary_unshift(VALUE ary, VALUE item)
Definition: array.c:1494
FL_FREEZE
#define FL_FREEZE
Definition: ruby.h:1287
rb_int_positive_pow
RUBY_EXTERN VALUE rb_int_positive_pow(long x, unsigned long y)
Definition: numeric.c:4033
VALUE
unsigned long VALUE
Definition: ruby.h:102
rb_nmin_run
VALUE rb_nmin_run(VALUE obj, VALUE num, int by, int rev, int ary)
Definition: enum.c:1568
rb_obj_as_string
VALUE rb_obj_as_string(VALUE)
Definition: string.c:1440
rb_ary_behead
MJIT_FUNC_EXPORTED VALUE rb_ary_behead(VALUE ary, long n)
Definition: array.c:1369
rb_eArgError
VALUE rb_eArgError
Definition: error.c:923
encoding.h
rb_ary_replace
VALUE rb_ary_replace(VALUE copy, VALUE orig)
Definition: array.c:3811
rb_intern
#define rb_intern(str)
rb_ary_store
void rb_ary_store(VALUE ary, long idx, VALUE val)
Definition: array.c:1079
MUL_OVERFLOW_LONG_P
#define MUL_OVERFLOW_LONG_P(a, b)
Definition: internal.h:282
st_delete
int st_delete(st_table *tab, st_data_t *key, st_data_t *value)
Definition: st.c:1418
RB_TYPE_P
#define RB_TYPE_P(obj, type)
Definition: ruby.h:560
rb_rational_plus
VALUE rb_rational_plus(VALUE self, VALUE other)
Definition: rational.c:737
ary_sort_data
Definition: array.c:2694
rb_ary_memsize
RUBY_FUNC_EXPORTED size_t rb_ary_memsize(VALUE ary)
Definition: array.c:816
RARRAY_TRANSIENT_FLAG
@ RARRAY_TRANSIENT_FLAG
Definition: ruby.h:1035
rb_ary_each
VALUE rb_ary_each(VALUE ary)
Definition: array.c:2129
rb_ary_ptr_use_start
VALUE * rb_ary_ptr_use_start(VALUE ary)
Definition: array.c:226
RARRAY_PTR
#define RARRAY_PTR(a)
Definition: ruby.h:1110
RUBY_DTRACE_CREATE_HOOK
#define RUBY_DTRACE_CREATE_HOOK(name, arg)
Definition: internal.h:2589
rb_ary_transient_heap_evacuate
void rb_ary_transient_heap_evacuate(VALUE ary, int promote)
Definition: array.c:402
id.h
SIGNED_VALUE
#define SIGNED_VALUE
Definition: ruby.h:104
rb_to_array_type
VALUE rb_to_array_type(VALUE ary)
Definition: array.c:902
isinf
#define isinf(__x)
Definition: rb_mjit_min_header-2.7.1.h:3673
rb_call_super
VALUE rb_call_super(int, const VALUE *)
Definition: vm_eval.c:306
rb_inspect
VALUE rb_inspect(VALUE)
Convenient wrapper of Object::inspect.
Definition: object.c:551
rb_ary_resurrect
VALUE rb_ary_resurrect(VALUE ary)
Definition: array.c:2251
rb_check_to_array
MJIT_FUNC_EXPORTED VALUE rb_check_to_array(VALUE ary)
Definition: array.c:915
rb_usascii_str_new_cstr
#define rb_usascii_str_new_cstr(str)
Definition: rb_mjit_min_header-2.7.1.h:6121
arg
VALUE arg
Definition: rb_mjit_min_header-2.7.1.h:5601
rb_eIndexError
VALUE rb_eIndexError
Definition: error.c:924
rb_get_values_at
VALUE rb_get_values_at(VALUE obj, long olen, int argc, const VALUE *argv, VALUE(*func)(VALUE, long))
Definition: array.c:3106
rb_check_string_type
VALUE rb_check_string_type(VALUE)
Definition: string.c:2314
Qundef
#define Qundef
Definition: ruby.h:470
RARRAY_PTR_IN_USE_FLAG
#define RARRAY_PTR_IN_USE_FLAG
Definition: internal.h:1367
rb_define_singleton_method
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1755
T_RATIONAL
#define T_RATIONAL
Definition: ruby.h:541
rb_define_method
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1551
Data_Wrap_Struct
#define Data_Wrap_Struct(klass, mark, free, sval)
Definition: ruby.h:1211
RARRAY_PTR_USE
#define RARRAY_PTR_USE(ary, ptr_name, expr)
Definition: ruby.h:1094
rb_ary_shift
VALUE rb_ary_shift(VALUE ary)
Definition: array.c:1294
ptr
struct RIMemo * ptr
Definition: debug.c:74
rb_str_new
#define rb_str_new(str, len)
Definition: rb_mjit_min_header-2.7.1.h:6116
cmp_opt_data::opt_inited
unsigned int opt_inited
Definition: internal.h:1324
NAN
#define NAN
Definition: missing.h:156
Qfalse
#define Qfalse
Definition: ruby.h:467
ARY_EMBED_P
#define ARY_EMBED_P(ary)
Definition: array.c:53
RAND_UPTO
#define RAND_UPTO(max)
Definition: array.c:5318
RETURN_SIZED_ENUMERATOR
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn)
Definition: intern.h:271
DBL2NUM
#define DBL2NUM(dbl)
Definition: ruby.h:967
RARRAY_ASET
#define RARRAY_ASET(a, i, v)
Definition: ruby.h:1102
SMALL_ARRAY_LEN
#define SMALL_ARRAY_LEN
Definition: array.c:34
rb_ary_subseq
VALUE rb_ary_subseq(VALUE ary, long beg, long len)
Definition: array.c:1518
rb_hash_stlike_lookup
MJIT_FUNC_EXPORTED int rb_hash_stlike_lookup(VALUE hash, st_data_t key, st_data_t *pval)
Definition: hash.c:2012
rb_ary_rassoc
VALUE rb_ary_rassoc(VALUE ary, VALUE value)
Definition: array.c:4189
rb_ary_delete
VALUE rb_ary_delete(VALUE ary, VALUE item)
Definition: array.c:3365
rb_ary_new3
#define rb_ary_new3
Definition: intern.h:104
st.h
NULL
#define NULL
Definition: _sdbm.c:101
rb_cmpint
#define rb_cmpint(cmp, a, b)
FL_TEST
#define FL_TEST(x, f)
Definition: ruby.h:1353
FL_WB_PROTECTED
#define FL_WB_PROTECTED
Definition: ruby.h:1279
PRIsVALUE
#define PRIsVALUE
Definition: ruby.h:166
RBASIC_SET_CLASS
#define RBASIC_SET_CLASS(obj, cls)
Definition: internal.h:1988
FL_SET_SHARED
#define FL_SET_SHARED(ary)
Definition: array.c:81
last
unsigned int last
Definition: nkf.c:4324
ARY_TAKE_LAST
@ ARY_TAKE_LAST
Definition: array.c:1148
FL_SET
#define FL_SET(x, f)
Definition: ruby.h:1359
ARY_SET_CAPA
#define ARY_SET_CAPA(ary, n)
Definition: array.c:129
st_insert
int st_insert(st_table *tab, st_data_t key, st_data_t value)
Definition: st.c:1171
FIX2LONG
#define FIX2LONG(x)
Definition: ruby.h:394
rb_int_idiv
VALUE rb_int_idiv(VALUE x, VALUE y)
Definition: numeric.c:3843
ARY_OWNS_HEAP_P
#define ARY_OWNS_HEAP_P(a)
Definition: array.c:70
OBJ_FREEZE
#define OBJ_FREEZE(x)
Definition: ruby.h:1377
rb_ary_pop
VALUE rb_ary_pop(VALUE ary)
Definition: array.c:1241
RARY_TRANSIENT_SET
#define RARY_TRANSIENT_SET(ary)
Definition: internal.h:1381
ARY_HEAP_CAPA
#define ARY_HEAP_CAPA(a)
Definition: array.c:60
rb_define_alias
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition: class.c:1800
ARY_SET_EMBED_LEN
#define ARY_SET_EMBED_LEN(ary, n)
Definition: array.c:92
rb_respond_to
int rb_respond_to(VALUE, ID)
Definition: vm_method.c:2190
RB_BLOCK_CALL_FUNC_ARGLIST
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)
Definition: ruby.h:1964
ARY_SHARED_ROOT_P
#define ARY_SHARED_ROOT_P(ary)
Definition: array.c:146
rb_check_arity
#define rb_check_arity
Definition: intern.h:347
rb_eql
int rb_eql(VALUE, VALUE)
Determines if obj1 and obj2 are equal in terms of Object::eql?.
Definition: object.c:147
RUBY_FUNC_EXPORTED
#define RUBY_FUNC_EXPORTED
Definition: defines.h:391
rb_hash_new_with_size
MJIT_FUNC_EXPORTED VALUE rb_hash_new_with_size(st_index_t size)
Definition: hash.c:1529
ary_sort_data::ary
VALUE ary
Definition: array.c:2695
ALLOC_N
#define ALLOC_N(type, n)
Definition: ruby.h:1663
idTo_a
@ idTo_a
Definition: rb_mjit_min_header-2.7.1.h:8725
UNLIMITED_ARGUMENTS
#define UNLIMITED_ARGUMENTS
Definition: intern.h:57
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2669
rb_ary_entry
VALUE rb_ary_entry(VALUE ary, long offset)
Definition: array.c:1512
rb_usascii_str_new
#define rb_usascii_str_new(str, len)
Definition: rb_mjit_min_header-2.7.1.h:6118
FL_USER5
#define FL_USER5
Definition: ruby.h:1296
rb_eRangeError
VALUE rb_eRangeError
Definition: error.c:926
ARY_SHARED_ROOT
#define ARY_SHARED_ROOT(ary)
Definition: array.c:136
ARY_EMBED_LEN
#define ARY_EMBED_LEN(a)
Definition: array.c:64
ARY_SHARED_ROOT_REFCNT
#define ARY_SHARED_ROOT_REFCNT(ary)
Definition: array.c:148
LONG2NUM
#define LONG2NUM(x)
Definition: ruby.h:1644
rb_hash_stlike_update
int rb_hash_stlike_update(VALUE hash, st_data_t key, st_update_callback_func func, st_data_t arg)
Definition: hash.c:1646
rb_obj_class
VALUE rb_obj_class(VALUE)
Equivalent to Object#class in Ruby.
Definition: object.c:217
rb_ary_assoc
VALUE rb_ary_assoc(VALUE ary, VALUE key)
Definition: array.c:4156
ELTS_SHARED
#define ELTS_SHARED
Definition: ruby.h:970
probes.h
rb_hash_add_new_element
int rb_hash_add_new_element(VALUE hash, VALUE key, VALUE val)
Definition: hash.c:4541
rb_fix_plus
VALUE rb_fix_plus(VALUE x, VALUE y)
Definition: numeric.c:3604
HUGE_VAL
#define HUGE_VAL
Definition: missing.h:161
ARY_MAX_SIZE
#define ARY_MAX_SIZE
Definition: array.c:33
va_start
#define va_start(v, l)
Definition: rb_mjit_min_header-2.7.1.h:3978
DATA_PTR
#define DATA_PTR(dta)
Definition: ruby.h:1175
rb_int_mul
VALUE rb_int_mul(VALUE x, VALUE y)
Definition: numeric.c:3699
st_clear
void st_clear(st_table *tab)
Definition: st.c:698
ALLOCV_END
#define ALLOCV_END(v)
Definition: ruby.h:1750
rb_check_frozen
#define rb_check_frozen(obj)
Definition: intern.h:319
rb_ary_sort
VALUE rb_ary_sort(VALUE ary)
Definition: array.c:2866
RHASH_SIZE
#define RHASH_SIZE(hsh)
Definition: fbuffer.h:8
rb_ary_includes
VALUE rb_ary_includes(VALUE ary, VALUE item)
Definition: array.c:4340
st_init_numtable_with_size
st_table * st_init_numtable_with_size(st_index_t size)
Definition: st.c:660
rb_obj_dig
VALUE rb_obj_dig(int argc, VALUE *argv, VALUE self, VALUE notfound)
Definition: object.c:3791
rb_convert_type_with_id
VALUE rb_convert_type_with_id(VALUE, int, const char *, ID)
Definition: object.c:2914
ALLOCV_N
#define ALLOCV_N(type, v, n)
Definition: ruby.h:1749
rb_hash_stlike_delete
int rb_hash_stlike_delete(VALUE hash, st_data_t *pkey, st_data_t *pval)
Definition: hash.c:2305
rb_ary_cat
VALUE rb_ary_cat(VALUE ary, const VALUE *argv, long len)
Definition: array.c:1208
rb_ary_tmp_new
VALUE rb_ary_tmp_new(long capa)
Definition: array.c:768
h
size_t st_index_t h
Definition: rb_mjit_min_header-2.7.1.h:5462
RB_OBJ_WRITTEN
#define RB_OBJ_WRITTEN(a, oldv, b)
Definition: ruby.h:1509
rb_ary_sort_bang
VALUE rb_ary_sort_bang(VALUE ary)
Definition: array.c:2777
to_ary
#define to_ary
Definition: array.c:906
STRING_P
#define STRING_P(s)
Definition: internal.h:1308
st_data_t
RUBY_SYMBOL_EXPORT_BEGIN typedef unsigned long st_data_t
Definition: st.h:22
rb_ary_last
VALUE rb_ary_last(int argc, const VALUE *argv, VALUE ary)
Definition: array.c:1677
FL_UNSET
#define FL_UNSET(x, f)
Definition: ruby.h:1361
rb_ary_push
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:1195
st_index_t
st_data_t st_index_t
Definition: st.h:50
ARY_SET_PTR
#define ARY_SET_PTR(ary, p)
Definition: array.c:87
cnt
rb_atomic_t cnt[RUBY_NSIG]
Definition: signal.c:503
ary_verify
#define ary_verify(ary)
Definition: array.c:222
rb_hash_start
st_index_t rb_hash_start(st_index_t)
Definition: random.c:1434
transient_heap.h
rb_obj_freeze
VALUE rb_obj_freeze(VALUE)
Make the object unmodifiable.
Definition: object.c:1080
va_list
__gnuc_va_list va_list
Definition: rb_mjit_min_header-2.7.1.h:836
dup
int dup(int __fildes)
RARRAY_SHARED_ROOT_FLAG
#define RARRAY_SHARED_ROOT_FLAG
Definition: array.c:145
va_arg
#define va_arg(v, l)
Definition: rb_mjit_min_header-2.7.1.h:3980
isnan
#define isnan(x)
Definition: win32.h:369
rb_eTypeError
VALUE rb_eTypeError
Definition: error.c:922
rb_ary_concat
VALUE rb_ary_concat(VALUE x, VALUE y)
Definition: array.c:4069
RBASIC_CLASS
#define RBASIC_CLASS(obj)
Definition: ruby.h:906
SIZED_REALLOC_N
#define SIZED_REALLOC_N(var, type, n, old_n)
Definition: internal.h:1662
idPLUS
@ idPLUS
Definition: id.h:85
rb_ary_set_len
void rb_ary_set_len(VALUE ary, long len)
Definition: array.c:1932
RARRAY_EMBED_FLAG
@ RARRAY_EMBED_FLAG
Definition: ruby.h:1029
rb_eRuntimeError
VALUE rb_eRuntimeError
Definition: error.c:920
tmpary
#define tmpary(n)
Definition: array.c:5625
RETURN_ENUMERATOR
#define RETURN_ENUMERATOR(obj, argc, argv)
Definition: intern.h:279
mod
#define mod(x, y)
Definition: date_strftime.c:28
ARY_SET_SHARED
#define ARY_SET_SHARED(ary, value)
Definition: array.c:137
RARRAY_AREF
#define RARRAY_AREF(a, i)
Definition: ruby.h:1101
rb_transient_heap_alloc
void * rb_transient_heap_alloc(VALUE obj, size_t req_size)
Definition: transient_heap.c:359
rb_mem_clear
void rb_mem_clear(VALUE *mem, long size)
Definition: array.c:243
rb_enc_copy
void rb_enc_copy(VALUE obj1, VALUE obj2)
Definition: encoding.c:990
size
int size
Definition: encoding.c:58
rb_str_set_len
void rb_str_set_len(VALUE, long)
Definition: string.c:2692
FALSE
#define FALSE
Definition: nkf.h:174
rb_ary_resize
VALUE rb_ary_resize(VALUE ary, long len)
expands or shrinks ary to len elements.
Definition: array.c:1955
FIXNUM_P
#define FIXNUM_P(f)
Definition: ruby.h:396
mul
#define mul(x, y)
Definition: date_strftime.c:25
cmp_opt_data
Definition: internal.h:1322
rb_ary_to_s
VALUE rb_ary_to_s(VALUE ary)
Definition: array.c:2453
rb_gc_writebarrier_remember
MJIT_FUNC_EXPORTED void rb_gc_writebarrier_remember(VALUE obj)
Definition: gc.c:6877
ARY_HEAP_SIZE
#define ARY_HEAP_SIZE(a)
Definition: array.c:68
rb_hash_foreach
void rb_hash_foreach(VALUE hash, rb_foreach_func *func, VALUE farg)
Definition: hash.c:1483
MEMZERO
#define MEMZERO(p, type, n)
Definition: ruby.h:1752
FL_SET_RAW
#define FL_SET_RAW(x, f)
Definition: ruby.h:1358
rb_iter_break
void rb_iter_break(void)
Definition: vm.c:1546
RARRAY_EMBED_LEN_MASK
@ RARRAY_EMBED_LEN_MASK
Definition: ruby.h:1031
RArray
Definition: ruby.h:1048
RB_OBJ_WRITE
#define RB_OBJ_WRITE(a, slot, b)
Definition: ruby.h:1508
ARY_SET_LEN
#define ARY_SET_LEN(ary, n)
Definition: array.c:103
FL_SET_SHARED_ROOT
#define FL_SET_SHARED_ROOT(ary)
Definition: array.c:155
index
int index
Definition: rb_mjit_min_header-2.7.1.h:11251
rb_check_array_type
VALUE rb_check_array_type(VALUE ary)
Definition: array.c:909
key
key
Definition: openssl_missing.h:181
rb_yield_values2
VALUE rb_yield_values2(int n, const VALUE *argv)
Definition: vm_eval.c:1271
ARY_TAKE_FIRST
@ ARY_TAKE_FIRST
Definition: array.c:1147
RHASH_ST_TABLE_P
#define RHASH_ST_TABLE_P(h)
Definition: internal.h:861
memchr
void * memchr(const void *, int, size_t)
RARRAY_CONST_PTR
#define RARRAY_CONST_PTR(a)
Definition: ruby.h:1072
rb_ary_clear
VALUE rb_ary_clear(VALUE ary)
Definition: array.c:3862
rb_str_buf_append
VALUE rb_str_buf_append(VALUE, VALUE)
Definition: string.c:2950
rb_ary_ptr_use_end
void rb_ary_ptr_use_end(VALUE ary)
Definition: array.c:235
rb_yield_values
#define rb_yield_values(argc,...)
Definition: rb_mjit_min_header-2.7.1.h:6584
fabs
double fabs(double)
RARRAY_LEN
#define RARRAY_LEN(a)
Definition: ruby.h:1070
rb_check_block_call
VALUE rb_check_block_call(VALUE, ID, int, const VALUE *, rb_block_call_func_t, VALUE)
Definition: vm_eval.c:1528
rb_scan_args
#define rb_scan_args(argc, argvp, fmt,...)
Definition: rb_mjit_min_header-2.7.1.h:6372
rb_ary_new4
#define rb_ary_new4
Definition: intern.h:105
rb_cObject
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:2010
rb_ary_new2
#define rb_ary_new2
Definition: intern.h:103
ARY_CAPA
#define ARY_CAPA(ary)
Definition: array.c:127
rb_ary_aref1
MJIT_FUNC_EXPORTED VALUE rb_ary_aref1(VALUE ary, VALUE arg)
Definition: array.c:1595
FL_UNSET_RAW
#define FL_UNSET_RAW(x, f)
Definition: ruby.h:1360
T_BIGNUM
#define T_BIGNUM
Definition: ruby.h:533
rb_ary_new_from_values
VALUE rb_ary_new_from_values(long n, const VALUE *elts)
Definition: array.c:762
RARY_TRANSIENT_UNSET
#define RARY_TRANSIENT_UNSET(ary)
Definition: internal.h:1382
rb_bug
void rb_bug(const char *fmt,...)
Definition: error.c:634
StringValue
use StringValue() instead")))
OPTHASH_GIVEN_P
#define OPTHASH_GIVEN_P(opts)
Definition: array.c:5314
internal.h
T_ARRAY
#define T_ARRAY
Definition: ruby.h:530
OPTIMIZED_CMP
#define OPTIMIZED_CMP(a, b, data)
Definition: internal.h:1337
argv
char ** argv
Definition: ruby.c:223
f
#define f
RHASH_ST_TABLE
#define RHASH_ST_TABLE(hash)
Definition: internal.h:856
ST_CONTINUE
@ ST_CONTINUE
Definition: st.h:99
rb_hash_uint
#define rb_hash_uint(h, i)
Definition: intern.h:815
rb_range_beg_len
VALUE rb_range_beg_len(VALUE, long *, long *, long, int)
Definition: range.c:1273
RARRAY
#define RARRAY(obj)
Definition: ruby.h:1273
rb_ary_join
VALUE rb_ary_join(VALUE ary, VALUE sep)
Definition: array.c:2347
rb_hash
VALUE rb_hash(VALUE obj)
Definition: hash.c:129
str
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
rb_ary_delete_at
VALUE rb_ary_delete_at(VALUE ary, long pos)
Definition: array.c:3419
rb_ary_detransient
void rb_ary_detransient(VALUE ary)
Definition: array.c:408
rb_hash_end
#define rb_hash_end(h)
Definition: intern.h:816
RGENGC_WB_PROTECTED_ARRAY
#define RGENGC_WB_PROTECTED_ARRAY
Definition: ruby.h:802
debug_counter.h
MEMCPY
#define MEMCPY(p1, p2, type, n)
Definition: ruby.h:1753
FL_UNSET_SHARED
#define FL_UNSET_SHARED(ary)
Definition: array.c:85
rb_ary_tmp_new_from_values
MJIT_FUNC_EXPORTED VALUE rb_ary_tmp_new_from_values(VALUE klass, long n, const VALUE *elts)
Definition: array.c:748
rb_hash_aset
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
Definition: hash.c:2847
ruby::backward::cxxanyargs::rb_block_call
VALUE rb_block_call(VALUE q, ID w, int e, const VALUE *r, type *t, VALUE y)
Call a method with a block.
Definition: cxxanyargs.hpp:178
NIL_P
#define NIL_P(v)
Definition: ruby.h:482
RB_OBJ_WB_UNPROTECT_FOR
#define RB_OBJ_WB_UNPROTECT_FOR(type, obj)
Definition: ruby.h:901
argc
int argc
Definition: ruby.c:222
rb_num2dbl
double rb_num2dbl(VALUE)
Converts a Numeric object to double.
Definition: object.c:3616
rb_exec_recursive
VALUE rb_exec_recursive(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE)
Definition: thread.c:5075
rb_big_plus
VALUE rb_big_plus(VALUE x, VALUE y)
Definition: bignum.c:5824
roomof
#define roomof(x, y)
Definition: internal.h:1298
recur
#define recur(fmt)
Definition: date_strptime.c:152
id_cmp
#define id_cmp
Definition: array.c:30
memmove
#define memmove(dst, src, len)
Definition: rb_mjit_min_header-2.7.1.h:2848
RFLOAT_VALUE
#define RFLOAT_VALUE(v)
Definition: ruby.h:966
rb_ary_freeze
VALUE rb_ary_freeze(VALUE ary)
Definition: array.c:648
v
int VALUE v
Definition: rb_mjit_min_header-2.7.1.h:12337
RBASIC
#define RBASIC(obj)
Definition: ruby.h:1267
ARY_SHARED_P
#define ARY_SHARED_P(ary)
Definition: array.c:48
ARY_SET_HEAP_LEN
#define ARY_SET_HEAP_LEN(ary, n)
Definition: array.c:99
ruby_sized_xfree
#define ruby_sized_xfree(ptr, size)
Definition: rb_mjit_min_header-2.7.1.h:7372
MJIT_FUNC_EXPORTED
#define MJIT_FUNC_EXPORTED
Definition: defines.h:396
Qtrue
#define Qtrue
Definition: ruby.h:468
OBJ_FROZEN
#define OBJ_FROZEN(x)
Definition: ruby.h:1375
FL_SET_EMBED
#define FL_SET_EMBED(a)
Definition: array.c:73
len
uint8_t len
Definition: escape.c:17
RB_DEBUG_COUNTER_INC
#define RB_DEBUG_COUNTER_INC(type)
Definition: debug_counter.h:375
rb_usascii_str_new2
#define rb_usascii_str_new2
Definition: intern.h:909
MEMMOVE
#define MEMMOVE(p1, p2, type, n)
Definition: ruby.h:1754
rb_ary_dup
VALUE rb_ary_dup(VALUE ary)
Definition: array.c:2238
rb_exec_recursive_paired
VALUE rb_exec_recursive_paired(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE, VALUE)
Definition: thread.c:5086
LONG2FIX
#define LONG2FIX(i)
Definition: ruby.h:265
RBASIC_SET_CLASS_RAW
#define RBASIC_SET_CLASS_RAW(obj, cls)
Definition: internal.h:1987
ARY_EMBED_PTR
#define ARY_EMBED_PTR(a)
Definition: array.c:63
T_STRING
#define T_STRING
Definition: ruby.h:528
top
unsigned int top
Definition: nkf.c:4323
ARY_DEFAULT_SIZE
#define ARY_DEFAULT_SIZE
Definition: array.c:32
select_bang_arg::len
long len[2]
Definition: array.c:3230
rb_ary_at
VALUE rb_ary_at(VALUE ary, VALUE pos)
Definition: array.c:1629
rb_yield
VALUE rb_yield(VALUE)
Definition: vm_eval.c:1237
rb_yield_force_blockarg
VALUE rb_yield_force_blockarg(VALUE values)
Definition: vm_eval.c:1309
rb_ary_plus
VALUE rb_ary_plus(VALUE x, VALUE y)
Definition: array.c:4000
FIXABLE
#define FIXABLE(f)
Definition: ruby.h:399
rb_ensure
VALUE rb_ensure(VALUE(*b_proc)(VALUE), VALUE data1, VALUE(*e_proc)(VALUE), VALUE data2)
An equivalent to ensure clause.
Definition: eval.c:1115
RARRAY_CONST_PTR_TRANSIENT
#define RARRAY_CONST_PTR_TRANSIENT(a)
Definition: ruby.h:1073
ST2FIX
#define ST2FIX(h)
Definition: ruby_missing.h:21
rb_ary_reverse
VALUE rb_ary_reverse(VALUE ary)
Definition: array.c:2544
rb_ary_new
VALUE rb_ary_new(void)
Definition: array.c:723
NEWOBJ_OF
#define NEWOBJ_OF(obj, type, klass, flags)
Definition: ruby.h:785
rb_big2dbl
double rb_big2dbl(VALUE x)
Definition: bignum.c:5310
NUM2INT
#define NUM2INT(x)
Definition: ruby.h:715
Qnil
#define Qnil
Definition: ruby.h:469
FL_UNSET_EMBED
#define FL_UNSET_EMBED(ary)
Definition: array.c:80
ARY_PTR_USING_P
#define ARY_PTR_USING_P(ary)
Definition: internal.h:1368
idTo_ary
@ idTo_ary
Definition: rb_mjit_min_header-2.7.1.h:8719
NUM2DBL
#define NUM2DBL(x)
Definition: ruby.h:774
rb_mEnumerable
VALUE rb_mEnumerable
Definition: enum.c:20
ruby_qsort
void ruby_qsort(void *, const size_t, const size_t, int(*)(const void *, const void *, void *), void *)
st_lookup
int st_lookup(st_table *tab, st_data_t key, st_data_t *value)
Definition: st.c:1101
util.h
cmp_opt_data::opt_methods
unsigned int opt_methods
Definition: internal.h:1323
RB_GC_GUARD
#define RB_GC_GUARD(v)
Definition: ruby.h:585
numberof
#define numberof(array)
Definition: etc.c:618
RARRAY_PTR_USE_TRANSIENT
#define RARRAY_PTR_USE_TRANSIENT(ary, ptr_name, expr)
Definition: ruby.h:1084
rb_ary_delete_same
void rb_ary_delete_same(VALUE ary, VALUE item)
Definition: array.c:3396
RSTRING_LEN
#define RSTRING_LEN(str)
Definition: ruby.h:1005
st_free_table
void st_free_table(st_table *tab)
Definition: st.c:709
st_table
Definition: st.h:79
rb_transient_heap_verify
void rb_transient_heap_verify(void)
Definition: transient_heap.c:219
ruby_assert.h
rb_enc_associate
VALUE rb_enc_associate(VALUE obj, rb_encoding *enc)
Definition: encoding.c:866
rb_obj_is_kind_of
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Determines if obj is a kind of c.
Definition: object.c:692
rb_define_alloc_func
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
RTEST
#define RTEST(v)
Definition: ruby.h:481
rb_str_buf_new2
#define rb_str_buf_new2
Definition: intern.h:908
rb_cRandom
RUBY_EXTERN VALUE rb_cRandom
Definition: ruby.h:2039
va_end
#define va_end(v)
Definition: rb_mjit_min_header-2.7.1.h:3979
RB_FLOAT_TYPE_P
#define RB_FLOAT_TYPE_P(obj)
Definition: ruby.h:556
rb_float_cmp
int rb_float_cmp(VALUE x, VALUE y)
Definition: numeric.c:1487
rb_usascii_encoding
rb_encoding * rb_usascii_encoding(void)
Definition: encoding.c:1340
rb_str_cmp
int rb_str_cmp(VALUE, VALUE)
Definition: string.c:3228
src
__inline__ const void *__restrict src
Definition: rb_mjit_min_header-2.7.1.h:2836
ary_sort_data::cmp_opt
struct cmp_opt_data cmp_opt
Definition: array.c:2696
rb_ary_modify
void rb_ary_modify(VALUE ary)
Definition: array.c:548
signbit
#define signbit(__x)
Definition: rb_mjit_min_header-2.7.1.h:3676
rb_ary_aref
VALUE rb_ary_aref(int argc, const VALUE *argv, VALUE ary)
Definition: array.c:1574
rb_funcallv
#define rb_funcallv(recv, mid, argc, argv)
Definition: rb_mjit_min_header-2.7.1.h:7904
rb_ary_cmp
VALUE rb_ary_cmp(VALUE ary1, VALUE ary2)
Definition: array.c:4420