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