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