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