Ruby  2.1.3p242(2014-09-19revision47630)
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 }
1589 
1590 void
1591 rb_ary_set_len(VALUE ary, long len)
1592 {
1593  long capa;
1594 
1595  rb_ary_modify_check(ary);
1596  if (ARY_SHARED_P(ary)) {
1597  rb_raise(rb_eRuntimeError, "can't set length of shared ");
1598  }
1599  if (len > (capa = (long)ARY_CAPA(ary))) {
1600  rb_bug("probable buffer overflow: %ld for %ld", len, capa);
1601  }
1602  ARY_SET_LEN(ary, len);
1603 }
1604 
1613 VALUE
1614 rb_ary_resize(VALUE ary, long len)
1615 {
1616  long olen;
1617 
1618  rb_ary_modify(ary);
1619  olen = RARRAY_LEN(ary);
1620  if (len == olen) return ary;
1621  if (len > ARY_MAX_SIZE) {
1622  rb_raise(rb_eIndexError, "index %ld too big", len);
1623  }
1624  if (len > olen) {
1625  if (len >= ARY_CAPA(ary)) {
1626  ary_double_capa(ary, len);
1627  }
1628  ary_mem_clear(ary, olen, len - olen);
1629  ARY_SET_LEN(ary, len);
1630  }
1631  else if (ARY_EMBED_P(ary)) {
1632  ARY_SET_EMBED_LEN(ary, len);
1633  }
1634  else if (len <= RARRAY_EMBED_LEN_MAX) {
1636  MEMCPY(tmp, ARY_HEAP_PTR(ary), VALUE, len);
1637  ary_discard(ary);
1638  MEMCPY((VALUE *)ARY_EMBED_PTR(ary), tmp, VALUE, len); /* WB: no new reference */
1639  ARY_SET_EMBED_LEN(ary, len);
1640  }
1641  else {
1642  if (olen > len + ARY_DEFAULT_SIZE) {
1643  SIZED_REALLOC_N(RARRAY(ary)->as.heap.ptr, VALUE, len, RARRAY(ary)->as.heap.aux.capa);
1644  ARY_SET_CAPA(ary, len);
1645  }
1646  ARY_SET_HEAP_LEN(ary, len);
1647  }
1648  return ary;
1649 }
1650 
1651 /*
1652  * call-seq:
1653  * ary[index] = obj -> obj
1654  * ary[start, length] = obj or other_ary or nil -> obj or other_ary or nil
1655  * ary[range] = obj or other_ary or nil -> obj or other_ary or nil
1656  *
1657  * Element Assignment --- Sets the element at +index+, or replaces a subarray
1658  * from the +start+ index for +length+ elements, or replaces a subarray
1659  * specified by the +range+ of indices.
1660  *
1661  * If indices are greater than the current capacity of the array, the array
1662  * grows automatically. Elements are inserted into the array at +start+ if
1663  * +length+ is zero.
1664  *
1665  * Negative indices will count backward from the end of the array. For
1666  * +start+ and +range+ cases the starting index is just before an element.
1667  *
1668  * An IndexError is raised if a negative index points past the beginning of
1669  * the array.
1670  *
1671  * See also Array#push, and Array#unshift.
1672  *
1673  * a = Array.new
1674  * a[4] = "4"; #=> [nil, nil, nil, nil, "4"]
1675  * a[0, 3] = [ 'a', 'b', 'c' ] #=> ["a", "b", "c", nil, "4"]
1676  * a[1..2] = [ 1, 2 ] #=> ["a", 1, 2, nil, "4"]
1677  * a[0, 2] = "?" #=> ["?", 2, nil, "4"]
1678  * a[0..2] = "A" #=> ["A", "4"]
1679  * a[-1] = "Z" #=> ["A", "Z"]
1680  * a[1..-1] = nil #=> ["A", nil]
1681  * a[1..-1] = [] #=> ["A"]
1682  * a[0, 0] = [ 1, 2 ] #=> [1, 2, "A"]
1683  * a[3, 0] = "B" #=> [1, 2, "A", "B"]
1684  */
1685 
1686 static VALUE
1688 {
1689  long offset, beg, len;
1690 
1691  if (argc == 3) {
1692  rb_ary_modify_check(ary);
1693  beg = NUM2LONG(argv[0]);
1694  len = NUM2LONG(argv[1]);
1695  rb_ary_splice(ary, beg, len, argv[2]);
1696  return argv[2];
1697  }
1698  rb_check_arity(argc, 2, 2);
1699  rb_ary_modify_check(ary);
1700  if (FIXNUM_P(argv[0])) {
1701  offset = FIX2LONG(argv[0]);
1702  goto fixnum;
1703  }
1704  if (rb_range_beg_len(argv[0], &beg, &len, RARRAY_LEN(ary), 1)) {
1705  /* check if idx is Range */
1706  rb_ary_splice(ary, beg, len, argv[1]);
1707  return argv[1];
1708  }
1709 
1710  offset = NUM2LONG(argv[0]);
1711 fixnum:
1712  rb_ary_store(ary, offset, argv[1]);
1713  return argv[1];
1714 }
1715 
1716 /*
1717  * call-seq:
1718  * ary.insert(index, obj...) -> ary
1719  *
1720  * Inserts the given values before the element with the given +index+.
1721  *
1722  * Negative indices count backwards from the end of the array, where +-1+ is
1723  * the last element.
1724  *
1725  * a = %w{ a b c d }
1726  * a.insert(2, 99) #=> ["a", "b", 99, "c", "d"]
1727  * a.insert(-2, 1, 2, 3) #=> ["a", "b", 99, "c", 1, 2, 3, "d"]
1728  */
1729 
1730 static VALUE
1732 {
1733  long pos;
1734 
1736  rb_ary_modify_check(ary);
1737  if (argc == 1) return ary;
1738  pos = NUM2LONG(argv[0]);
1739  if (pos == -1) {
1740  pos = RARRAY_LEN(ary);
1741  }
1742  if (pos < 0) {
1743  pos++;
1744  }
1745  rb_ary_splice(ary, pos, 0, rb_ary_new4(argc - 1, argv + 1));
1746  return ary;
1747 }
1748 
1749 static VALUE
1750 rb_ary_length(VALUE ary);
1751 
1752 static VALUE
1754 {
1755  return rb_ary_length(ary);
1756 }
1757 
1758 /*
1759  * call-seq:
1760  * ary.each { |item| block } -> ary
1761  * ary.each -> Enumerator
1762  *
1763  * Calls the given block once for each element in +self+, passing that element
1764  * as a parameter.
1765  *
1766  * An Enumerator is returned if no block is given.
1767  *
1768  * a = [ "a", "b", "c" ]
1769  * a.each {|x| print x, " -- " }
1770  *
1771  * produces:
1772  *
1773  * a -- b -- c --
1774  */
1775 
1776 VALUE
1778 {
1779  long i;
1780  volatile VALUE ary = array;
1781 
1783  for (i=0; i<RARRAY_LEN(ary); i++) {
1784  rb_yield(RARRAY_AREF(ary, i));
1785  }
1786  return ary;
1787 }
1788 
1789 /*
1790  * call-seq:
1791  * ary.each_index { |index| block } -> ary
1792  * ary.each_index -> Enumerator
1793  *
1794  * Same as Array#each, but passes the +index+ of the element instead of the
1795  * element itself.
1796  *
1797  * An Enumerator is returned if no block is given.
1798  *
1799  * a = [ "a", "b", "c" ]
1800  * a.each_index {|x| print x, " -- " }
1801  *
1802  * produces:
1803  *
1804  * 0 -- 1 -- 2 --
1805  */
1806 
1807 static VALUE
1809 {
1810  long i;
1812 
1813  for (i=0; i<RARRAY_LEN(ary); i++) {
1814  rb_yield(LONG2NUM(i));
1815  }
1816  return ary;
1817 }
1818 
1819 /*
1820  * call-seq:
1821  * ary.reverse_each { |item| block } -> ary
1822  * ary.reverse_each -> Enumerator
1823  *
1824  * Same as Array#each, but traverses +self+ in reverse order.
1825  *
1826  * a = [ "a", "b", "c" ]
1827  * a.reverse_each {|x| print x, " " }
1828  *
1829  * produces:
1830  *
1831  * c b a
1832  */
1833 
1834 static VALUE
1836 {
1837  long len;
1838 
1840  len = RARRAY_LEN(ary);
1841  while (len--) {
1842  long nlen;
1843  rb_yield(RARRAY_AREF(ary, len));
1844  nlen = RARRAY_LEN(ary);
1845  if (nlen < len) {
1846  len = nlen;
1847  }
1848  }
1849  return ary;
1850 }
1851 
1852 /*
1853  * call-seq:
1854  * ary.length -> int
1855  *
1856  * Returns the number of elements in +self+. May be zero.
1857  *
1858  * [ 1, 2, 3, 4, 5 ].length #=> 5
1859  * [].length #=> 0
1860  */
1861 
1862 static VALUE
1864 {
1865  long len = RARRAY_LEN(ary);
1866  return LONG2NUM(len);
1867 }
1868 
1869 /*
1870  * call-seq:
1871  * ary.empty? -> true or false
1872  *
1873  * Returns +true+ if +self+ contains no elements.
1874  *
1875  * [].empty? #=> true
1876  */
1877 
1878 static VALUE
1880 {
1881  if (RARRAY_LEN(ary) == 0)
1882  return Qtrue;
1883  return Qfalse;
1884 }
1885 
1886 VALUE
1888 {
1889  long len = RARRAY_LEN(ary);
1890  VALUE dup = rb_ary_new2(len);
1891  ary_memcpy(dup, 0, len, RARRAY_CONST_PTR(ary));
1892  ARY_SET_LEN(dup, len);
1893  return dup;
1894 }
1895 
1896 VALUE
1898 {
1899  return rb_ary_new4(RARRAY_LEN(ary), RARRAY_CONST_PTR(ary));
1900 }
1901 
1902 extern VALUE rb_output_fs;
1903 
1904 static void ary_join_1(VALUE obj, VALUE ary, VALUE sep, long i, VALUE result, int *first);
1905 
1906 static VALUE
1908 {
1909  VALUE *arg = (VALUE *)argp;
1910  VALUE ary = arg[0];
1911  VALUE sep = arg[1];
1912  VALUE result = arg[2];
1913  int *first = (int *)arg[3];
1914 
1915  if (recur) {
1916  rb_raise(rb_eArgError, "recursive array join");
1917  }
1918  else {
1919  ary_join_1(obj, ary, sep, 0, result, first);
1920  }
1921  return Qnil;
1922 }
1923 
1924 static void
1926 {
1927  long i;
1928  VALUE val;
1929 
1930  if (max > 0) rb_enc_copy(result, RARRAY_AREF(ary, 0));
1931  for (i=0; i<max; i++) {
1932  val = RARRAY_AREF(ary, i);
1933  if (i > 0 && !NIL_P(sep))
1934  rb_str_buf_append(result, sep);
1935  rb_str_buf_append(result, val);
1936  if (OBJ_TAINTED(val)) OBJ_TAINT(result);
1937  }
1938 }
1939 
1940 static void
1941 ary_join_1(VALUE obj, VALUE ary, VALUE sep, long i, VALUE result, int *first)
1942 {
1943  VALUE val, tmp;
1944 
1945  for (; i<RARRAY_LEN(ary); i++) {
1946  if (i > 0 && !NIL_P(sep))
1947  rb_str_buf_append(result, sep);
1948 
1949  val = RARRAY_AREF(ary, i);
1950  if (RB_TYPE_P(val, T_STRING)) {
1951  str_join:
1952  rb_str_buf_append(result, val);
1953  *first = FALSE;
1954  }
1955  else if (RB_TYPE_P(val, T_ARRAY)) {
1956  obj = val;
1957  ary_join:
1958  if (val == ary) {
1959  rb_raise(rb_eArgError, "recursive array join");
1960  }
1961  else {
1962  VALUE args[4];
1963 
1964  args[0] = val;
1965  args[1] = sep;
1966  args[2] = result;
1967  args[3] = (VALUE)first;
1968  rb_exec_recursive(recursive_join, obj, (VALUE)args);
1969  }
1970  }
1971  else {
1972  tmp = rb_check_string_type(val);
1973  if (!NIL_P(tmp)) {
1974  val = tmp;
1975  goto str_join;
1976  }
1977  tmp = rb_check_convert_type(val, T_ARRAY, "Array", "to_ary");
1978  if (!NIL_P(tmp)) {
1979  obj = val;
1980  val = tmp;
1981  goto ary_join;
1982  }
1983  val = rb_obj_as_string(val);
1984  if (*first) {
1985  rb_enc_copy(result, val);
1986  *first = FALSE;
1987  }
1988  goto str_join;
1989  }
1990  }
1991 }
1992 
1993 VALUE
1995 {
1996  long len = 1, i;
1997  int taint = FALSE;
1998  VALUE val, tmp, result;
1999 
2000  if (RARRAY_LEN(ary) == 0) return rb_usascii_str_new(0, 0);
2001  if (OBJ_TAINTED(ary)) taint = TRUE;
2002 
2003  if (!NIL_P(sep)) {
2004  StringValue(sep);
2005  len += RSTRING_LEN(sep) * (RARRAY_LEN(ary) - 1);
2006  }
2007  for (i=0; i<RARRAY_LEN(ary); i++) {
2008  val = RARRAY_AREF(ary, i);
2009  tmp = rb_check_string_type(val);
2010 
2011  if (NIL_P(tmp) || tmp != val) {
2012  int first;
2013  result = rb_str_buf_new(len + (RARRAY_LEN(ary)-i)*10);
2015  if (taint) OBJ_TAINT(result);
2016  ary_join_0(ary, sep, i, result);
2017  first = i == 0;
2018  ary_join_1(ary, ary, sep, i, result, &first);
2019  return result;
2020  }
2021 
2022  len += RSTRING_LEN(tmp);
2023  }
2024 
2025  result = rb_str_buf_new(len);
2026  if (taint) OBJ_TAINT(result);
2027  ary_join_0(ary, sep, RARRAY_LEN(ary), result);
2028 
2029  return result;
2030 }
2031 
2032 /*
2033  * call-seq:
2034  * ary.join(separator=$,) -> str
2035  *
2036  * Returns a string created by converting each element of the array to
2037  * a string, separated by the given +separator+.
2038  * If the +separator+ is +nil+, it uses current $,.
2039  * If both the +separator+ and $, are nil, it uses empty string.
2040  *
2041  * [ "a", "b", "c" ].join #=> "abc"
2042  * [ "a", "b", "c" ].join("-") #=> "a-b-c"
2043  */
2044 
2045 static VALUE
2047 {
2048  VALUE sep;
2049 
2050  rb_scan_args(argc, argv, "01", &sep);
2051  if (NIL_P(sep)) sep = rb_output_fs;
2052 
2053  return rb_ary_join(ary, sep);
2054 }
2055 
2056 static VALUE
2057 inspect_ary(VALUE ary, VALUE dummy, int recur)
2058 {
2059  int tainted = OBJ_TAINTED(ary);
2060  long i;
2061  VALUE s, str;
2062 
2063  if (recur) return rb_usascii_str_new_cstr("[...]");
2064  str = rb_str_buf_new2("[");
2065  for (i=0; i<RARRAY_LEN(ary); i++) {
2066  s = rb_inspect(RARRAY_AREF(ary, i));
2067  if (OBJ_TAINTED(s)) tainted = TRUE;
2068  if (i > 0) rb_str_buf_cat2(str, ", ");
2069  else rb_enc_copy(str, s);
2070  rb_str_buf_append(str, s);
2071  }
2072  rb_str_buf_cat2(str, "]");
2073  if (tainted) OBJ_TAINT(str);
2074  return str;
2075 }
2076 
2077 /*
2078  * call-seq:
2079  * ary.inspect -> string
2080  * ary.to_s -> string
2081  *
2082  * Creates a string representation of +self+.
2083  *
2084  * [ "a", "b", "c" ].to_s #=> "[\"a\", \"b\", \"c\"]"
2085  */
2086 
2087 static VALUE
2089 {
2090  if (RARRAY_LEN(ary) == 0) return rb_usascii_str_new2("[]");
2091  return rb_exec_recursive(inspect_ary, ary, 0);
2092 }
2093 
2094 VALUE
2096 {
2097  return rb_ary_inspect(ary);
2098 }
2099 
2100 /*
2101  * call-seq:
2102  * ary.to_a -> ary
2103  *
2104  * Returns +self+.
2105  *
2106  * If called on a subclass of Array, converts the receiver to an Array object.
2107  */
2108 
2109 static VALUE
2111 {
2112  if (rb_obj_class(ary) != rb_cArray) {
2113  VALUE dup = rb_ary_new2(RARRAY_LEN(ary));
2114  rb_ary_replace(dup, ary);
2115  return dup;
2116  }
2117  return ary;
2118 }
2119 
2120 /*
2121  * call-seq:
2122  * ary.to_h -> hash
2123  *
2124  * Returns the result of interpreting <i>ary</i> as an array of
2125  * <tt>[key, value]</tt> pairs.
2126  *
2127  * [[:foo, :bar], [1, 2]].to_h
2128  * # => {:foo => :bar, 1 => 2}
2129  */
2130 
2131 static VALUE
2133 {
2134  long i;
2135  VALUE hash = rb_hash_new();
2136  for (i=0; i<RARRAY_LEN(ary); i++) {
2137  VALUE key_value_pair = rb_check_array_type(rb_ary_elt(ary, i));
2138  if (NIL_P(key_value_pair)) {
2139  rb_raise(rb_eTypeError, "wrong element type %s at %ld (expected array)",
2140  rb_builtin_class_name(rb_ary_elt(ary, i)), i);
2141  }
2142  if (RARRAY_LEN(key_value_pair) != 2) {
2143  rb_raise(rb_eArgError, "wrong array length at %ld (expected 2, was %ld)",
2144  i, RARRAY_LEN(key_value_pair));
2145  }
2146  rb_hash_aset(hash, RARRAY_AREF(key_value_pair, 0), RARRAY_AREF(key_value_pair, 1));
2147  }
2148  return hash;
2149 }
2150 
2151 /*
2152  * call-seq:
2153  * ary.to_ary -> ary
2154  *
2155  * Returns +self+.
2156  */
2157 
2158 static VALUE
2160 {
2161  return ary;
2162 }
2163 
2164 static void
2166 {
2167  while (p1 < p2) {
2168  VALUE tmp = *p1;
2169  *p1++ = *p2;
2170  *p2-- = tmp;
2171  }
2172 }
2173 
2174 VALUE
2176 {
2177  VALUE *p2;
2178  long len = RARRAY_LEN(ary);
2179 
2180  rb_ary_modify(ary);
2181  if (len > 1) {
2182  RARRAY_PTR_USE(ary, p1, {
2183  p2 = p1 + len - 1; /* points last item */
2184  ary_reverse(p1, p2);
2185  }); /* WB: no new reference */
2186  }
2187  return ary;
2188 }
2189 
2190 /*
2191  * call-seq:
2192  * ary.reverse! -> ary
2193  *
2194  * Reverses +self+ in place.
2195  *
2196  * a = [ "a", "b", "c" ]
2197  * a.reverse! #=> ["c", "b", "a"]
2198  * a #=> ["c", "b", "a"]
2199  */
2200 
2201 static VALUE
2203 {
2204  return rb_ary_reverse(ary);
2205 }
2206 
2207 /*
2208  * call-seq:
2209  * ary.reverse -> new_ary
2210  *
2211  * Returns a new array containing +self+'s elements in reverse order.
2212  *
2213  * [ "a", "b", "c" ].reverse #=> ["c", "b", "a"]
2214  * [ 1 ].reverse #=> [1]
2215  */
2216 
2217 static VALUE
2219 {
2220  long len = RARRAY_LEN(ary);
2221  VALUE dup = rb_ary_new2(len);
2222 
2223  if (len > 0) {
2224  const VALUE *p1 = RARRAY_CONST_PTR(ary);
2225  VALUE *p2 = (VALUE *)RARRAY_CONST_PTR(dup) + len - 1;
2226  do *p2-- = *p1++; while (--len > 0);
2227  }
2228  ARY_SET_LEN(dup, RARRAY_LEN(ary));
2229  return dup;
2230 }
2231 
2232 static inline long
2233 rotate_count(long cnt, long len)
2234 {
2235  return (cnt < 0) ? (len - (~cnt % len) - 1) : (cnt % len);
2236 }
2237 
2238 VALUE
2240 {
2241  rb_ary_modify(ary);
2242 
2243  if (cnt != 0) {
2244  VALUE *ptr = RARRAY_PTR(ary);
2245  long len = RARRAY_LEN(ary);
2246 
2247  if (len > 0 && (cnt = rotate_count(cnt, len)) > 0) {
2248  --len;
2249  if (cnt < len) ary_reverse(ptr + cnt, ptr + len);
2250  if (--cnt > 0) ary_reverse(ptr, ptr + cnt);
2251  if (len > 0) ary_reverse(ptr, ptr + len);
2252  return ary;
2253  }
2254  }
2255 
2256  return Qnil;
2257 }
2258 
2259 /*
2260  * call-seq:
2261  * ary.rotate!(count=1) -> ary
2262  *
2263  * Rotates +self+ in place so that the element at +count+ comes first, and
2264  * returns +self+.
2265  *
2266  * If +count+ is negative then it rotates in the opposite direction, starting
2267  * from the end of the array where +-1+ is the last element.
2268  *
2269  * a = [ "a", "b", "c", "d" ]
2270  * a.rotate! #=> ["b", "c", "d", "a"]
2271  * a #=> ["b", "c", "d", "a"]
2272  * a.rotate!(2) #=> ["d", "a", "b", "c"]
2273  * a.rotate!(-3) #=> ["a", "b", "c", "d"]
2274  */
2275 
2276 static VALUE
2278 {
2279  long n = 1;
2280 
2281  switch (argc) {
2282  case 1: n = NUM2LONG(argv[0]);
2283  case 0: break;
2284  default: rb_scan_args(argc, argv, "01", NULL);
2285  }
2286  rb_ary_rotate(ary, n);
2287  return ary;
2288 }
2289 
2290 /*
2291  * call-seq:
2292  * ary.rotate(count=1) -> new_ary
2293  *
2294  * Returns a new array by rotating +self+ so that the element at +count+ is
2295  * the first element of the new array.
2296  *
2297  * If +count+ is negative then it rotates in the opposite direction, starting
2298  * from the end of +self+ where +-1+ is the last element.
2299  *
2300  * a = [ "a", "b", "c", "d" ]
2301  * a.rotate #=> ["b", "c", "d", "a"]
2302  * a #=> ["a", "b", "c", "d"]
2303  * a.rotate(2) #=> ["c", "d", "a", "b"]
2304  * a.rotate(-3) #=> ["b", "c", "d", "a"]
2305  */
2306 
2307 static VALUE
2309 {
2310  VALUE rotated;
2311  const VALUE *ptr;
2312  long len, cnt = 1;
2313 
2314  switch (argc) {
2315  case 1: cnt = NUM2LONG(argv[0]);
2316  case 0: break;
2317  default: rb_scan_args(argc, argv, "01", NULL);
2318  }
2319 
2320  len = RARRAY_LEN(ary);
2321  rotated = rb_ary_new2(len);
2322  if (len > 0) {
2323  cnt = rotate_count(cnt, len);
2324  ptr = RARRAY_CONST_PTR(ary);
2325  len -= cnt;
2326  ary_memcpy(rotated, 0, len, ptr + cnt);
2327  ary_memcpy(rotated, len, cnt, ptr);
2328  }
2329  ARY_SET_LEN(rotated, RARRAY_LEN(ary));
2330  return rotated;
2331 }
2332 
2337 };
2338 
2339 enum {
2343 };
2344 
2345 #define STRING_P(s) (RB_TYPE_P((s), T_STRING) && CLASS_OF(s) == rb_cString)
2346 
2347 #define SORT_OPTIMIZABLE_BIT(type) (1U << TOKEN_PASTE(sort_opt_,type))
2348 #define SORT_OPTIMIZABLE(data, type) \
2349  (((data)->opt_inited & SORT_OPTIMIZABLE_BIT(type)) ? \
2350  ((data)->opt_methods & SORT_OPTIMIZABLE_BIT(type)) : \
2351  (((data)->opt_inited |= SORT_OPTIMIZABLE_BIT(type)), \
2352  rb_method_basic_definition_p(TOKEN_PASTE(rb_c,type), id_cmp) && \
2353  ((data)->opt_methods |= SORT_OPTIMIZABLE_BIT(type))))
2354 
2355 static VALUE
2357 {
2358  if (RBASIC(ary)->klass) {
2359  rb_raise(rb_eRuntimeError, "sort reentered");
2360  }
2361  return Qnil;
2362 }
2363 
2364 static int
2365 sort_1(const void *ap, const void *bp, void *dummy)
2366 {
2367  struct ary_sort_data *data = dummy;
2368  VALUE retval = sort_reentered(data->ary);
2369  VALUE a = *(const VALUE *)ap, b = *(const VALUE *)bp;
2370  int n;
2371 
2372  retval = rb_yield_values(2, a, b);
2373  n = rb_cmpint(retval, a, b);
2374  sort_reentered(data->ary);
2375  return n;
2376 }
2377 
2378 static int
2379 sort_2(const void *ap, const void *bp, void *dummy)
2380 {
2381  struct ary_sort_data *data = dummy;
2382  VALUE retval = sort_reentered(data->ary);
2383  VALUE a = *(const VALUE *)ap, b = *(const VALUE *)bp;
2384  int n;
2385 
2386  if (FIXNUM_P(a) && FIXNUM_P(b) && SORT_OPTIMIZABLE(data, Fixnum)) {
2387  if ((long)a > (long)b) return 1;
2388  if ((long)a < (long)b) return -1;
2389  return 0;
2390  }
2391  if (STRING_P(a) && STRING_P(b) && SORT_OPTIMIZABLE(data, String)) {
2392  return rb_str_cmp(a, b);
2393  }
2394 
2395  retval = rb_funcallv(a, id_cmp, 1, &b);
2396  n = rb_cmpint(retval, a, b);
2397  sort_reentered(data->ary);
2398 
2399  return n;
2400 }
2401 
2402 /*
2403  * call-seq:
2404  * ary.sort! -> ary
2405  * ary.sort! { |a, b| block } -> ary
2406  *
2407  * Sorts +self+ in place.
2408  *
2409  * Comparisons for the sort will be done using the <code><=></code> operator
2410  * or using an optional code block.
2411  *
2412  * The block must implement a comparison between +a+ and +b+, and return
2413  * +-1+, when +a+ follows +b+, +0+ when +a+ and +b+ are equivalent, or ++1+
2414  * if +b+ follows +a+.
2415  *
2416  * See also Enumerable#sort_by.
2417  *
2418  * a = [ "d", "a", "e", "c", "b" ]
2419  * a.sort! #=> ["a", "b", "c", "d", "e"]
2420  * a.sort! { |x,y| y <=> x } #=> ["e", "d", "c", "b", "a"]
2421  */
2422 
2423 VALUE
2425 {
2426  rb_ary_modify(ary);
2427  assert(!ARY_SHARED_P(ary));
2428  if (RARRAY_LEN(ary) > 1) {
2429  VALUE tmp = ary_make_substitution(ary); /* only ary refers tmp */
2430  struct ary_sort_data data;
2431  long len = RARRAY_LEN(ary);
2432 
2433  RBASIC_CLEAR_CLASS(tmp);
2434  data.ary = tmp;
2435  data.opt_methods = 0;
2436  data.opt_inited = 0;
2437  RARRAY_PTR_USE(tmp, ptr, {
2438  ruby_qsort(ptr, len, sizeof(VALUE),
2439  rb_block_given_p()?sort_1:sort_2, &data);
2440  }); /* WB: no new reference */
2441  rb_ary_modify(ary);
2442  if (ARY_EMBED_P(tmp)) {
2443  if (ARY_SHARED_P(ary)) { /* ary might be destructively operated in the given block */
2444  rb_ary_unshare(ary);
2445  }
2446  FL_SET_EMBED(ary);
2447  ary_memcpy(ary, 0, ARY_EMBED_LEN(tmp), ARY_EMBED_PTR(tmp));
2448  ARY_SET_LEN(ary, ARY_EMBED_LEN(tmp));
2449  }
2450  else {
2451  if (!ARY_EMBED_P(ary) && ARY_HEAP_PTR(ary) == ARY_HEAP_PTR(tmp)) {
2452  FL_UNSET_SHARED(ary);
2453  ARY_SET_CAPA(ary, RARRAY_LEN(tmp));
2454  }
2455  else {
2456  assert(!ARY_SHARED_P(tmp));
2457  if (ARY_EMBED_P(ary)) {
2458  FL_UNSET_EMBED(ary);
2459  }
2460  else if (ARY_SHARED_P(ary)) {
2461  /* ary might be destructively operated in the given block */
2462  rb_ary_unshare(ary);
2463  }
2464  else {
2465  ruby_sized_xfree((void *)ARY_HEAP_PTR(ary), ARY_HEAP_SIZE(ary));
2466  }
2467  ARY_SET_PTR(ary, RARRAY_CONST_PTR(tmp));
2468  ARY_SET_HEAP_LEN(ary, len);
2469  ARY_SET_CAPA(ary, RARRAY_LEN(tmp));
2470  }
2471  /* tmp was lost ownership for the ptr */
2472  FL_UNSET(tmp, FL_FREEZE);
2473  FL_SET_EMBED(tmp);
2474  ARY_SET_EMBED_LEN(tmp, 0);
2475  FL_SET(tmp, FL_FREEZE);
2476  }
2477  /* tmp will be GC'ed. */
2478  RBASIC_SET_CLASS_RAW(tmp, rb_cArray); /* rb_cArray must be marked */
2479  }
2480  return ary;
2481 }
2482 
2483 /*
2484  * call-seq:
2485  * ary.sort -> new_ary
2486  * ary.sort { |a, b| block } -> new_ary
2487  *
2488  * Returns a new array created by sorting +self+.
2489  *
2490  * Comparisons for the sort will be done using the <code><=></code> operator
2491  * or using an optional code block.
2492  *
2493  * The block must implement a comparison between +a+ and +b+, and return
2494  * +-1+, when +a+ follows +b+, +0+ when +a+ and +b+ are equivalent, or ++1+
2495  * if +b+ follows +a+.
2496  *
2497  *
2498  * See also Enumerable#sort_by.
2499  *
2500  * a = [ "d", "a", "e", "c", "b" ]
2501  * a.sort #=> ["a", "b", "c", "d", "e"]
2502  * a.sort { |x,y| y <=> x } #=> ["e", "d", "c", "b", "a"]
2503  */
2504 
2505 VALUE
2507 {
2508  ary = rb_ary_dup(ary);
2509  rb_ary_sort_bang(ary);
2510  return ary;
2511 }
2512 
2513 /*
2514  * call-seq:
2515  * ary.bsearch {|x| block } -> elem
2516  *
2517  * By using binary search, finds a value from this array which meets
2518  * the given condition in O(log n) where n is the size of the array.
2519  *
2520  * You can use this method in two use cases: a find-minimum mode and
2521  * a find-any mode. In either case, the elements of the array must be
2522  * monotone (or sorted) with respect to the block.
2523  *
2524  * In find-minimum mode (this is a good choice for typical use case),
2525  * the block must return true or false, and there must be an index i
2526  * (0 <= i <= ary.size) so that:
2527  *
2528  * - the block returns false for any element whose index is less than
2529  * i, and
2530  * - the block returns true for any element whose index is greater
2531  * than or equal to i.
2532  *
2533  * This method returns the i-th element. If i is equal to ary.size,
2534  * it returns nil.
2535  *
2536  * ary = [0, 4, 7, 10, 12]
2537  * ary.bsearch {|x| x >= 4 } #=> 4
2538  * ary.bsearch {|x| x >= 6 } #=> 7
2539  * ary.bsearch {|x| x >= -1 } #=> 0
2540  * ary.bsearch {|x| x >= 100 } #=> nil
2541  *
2542  * In find-any mode (this behaves like libc's bsearch(3)), the block
2543  * must return a number, and there must be two indices i and j
2544  * (0 <= i <= j <= ary.size) so that:
2545  *
2546  * - the block returns a positive number for ary[k] if 0 <= k < i,
2547  * - the block returns zero for ary[k] if i <= k < j, and
2548  * - the block returns a negative number for ary[k] if
2549  * j <= k < ary.size.
2550  *
2551  * Under this condition, this method returns any element whose index
2552  * is within i...j. If i is equal to j (i.e., there is no element
2553  * that satisfies the block), this method returns nil.
2554  *
2555  * ary = [0, 4, 7, 10, 12]
2556  * # try to find v such that 4 <= v < 8
2557  * ary.bsearch {|x| 1 - x / 4 } #=> 4 or 7
2558  * # try to find v such that 8 <= v < 10
2559  * ary.bsearch {|x| 4 - x / 2 } #=> nil
2560  *
2561  * You must not mix the two modes at a time; the block must always
2562  * return either true/false, or always return a number. It is
2563  * undefined which value is actually picked up at each iteration.
2564  */
2565 
2566 static VALUE
2568 {
2569  long low = 0, high = RARRAY_LEN(ary), mid;
2570  int smaller = 0, satisfied = 0;
2571  VALUE v, val;
2572 
2573  RETURN_ENUMERATOR(ary, 0, 0);
2574  while (low < high) {
2575  mid = low + ((high - low) / 2);
2576  val = rb_ary_entry(ary, mid);
2577  v = rb_yield(val);
2578  if (FIXNUM_P(v)) {
2579  if (FIX2INT(v) == 0) return val;
2580  smaller = FIX2INT(v) < 0;
2581  }
2582  else if (v == Qtrue) {
2583  satisfied = 1;
2584  smaller = 1;
2585  }
2586  else if (v == Qfalse || v == Qnil) {
2587  smaller = 0;
2588  }
2589  else if (rb_obj_is_kind_of(v, rb_cNumeric)) {
2590  const VALUE zero = INT2FIX(0);
2591  switch (rb_cmpint(rb_funcallv(v, id_cmp, 1, &zero), v, INT2FIX(0))) {
2592  case 0: return val;
2593  case 1: smaller = 1; break;
2594  case -1: smaller = 0;
2595  }
2596  }
2597  else {
2598  rb_raise(rb_eTypeError, "wrong argument type %s"
2599  " (must be numeric, true, false or nil)",
2600  rb_obj_classname(v));
2601  }
2602  if (smaller) {
2603  high = mid;
2604  }
2605  else {
2606  low = mid + 1;
2607  }
2608  }
2609  if (low == RARRAY_LEN(ary)) return Qnil;
2610  if (!satisfied) return Qnil;
2611  return rb_ary_entry(ary, low);
2612 }
2613 
2614 
2615 static VALUE
2617 {
2618  return rb_yield(i);
2619 }
2620 
2621 /*
2622  * call-seq:
2623  * ary.sort_by! { |obj| block } -> ary
2624  * ary.sort_by! -> Enumerator
2625  *
2626  * Sorts +self+ in place using a set of keys generated by mapping the
2627  * values in +self+ through the given block.
2628  *
2629  * If no block is given, an Enumerator is returned instead.
2630  *
2631  */
2632 
2633 static VALUE
2635 {
2636  VALUE sorted;
2637 
2639  rb_ary_modify(ary);
2640  sorted = rb_block_call(ary, rb_intern("sort_by"), 0, 0, sort_by_i, 0);
2641  rb_ary_replace(ary, sorted);
2642  return ary;
2643 }
2644 
2645 
2646 /*
2647  * call-seq:
2648  * ary.collect { |item| block } -> new_ary
2649  * ary.map { |item| block } -> new_ary
2650  * ary.collect -> Enumerator
2651  * ary.map -> Enumerator
2652  *
2653  * Invokes the given block once for each element of +self+.
2654  *
2655  * Creates a new array containing the values returned by the block.
2656  *
2657  * See also Enumerable#collect.
2658  *
2659  * If no block is given, an Enumerator is returned instead.
2660  *
2661  * a = [ "a", "b", "c", "d" ]
2662  * a.collect { |x| x + "!" } #=> ["a!", "b!", "c!", "d!"]
2663  * a.map.with_index{ |x, i| x * i } #=> ["", "b", "cc", "ddd"]
2664  * a #=> ["a", "b", "c", "d"]
2665  */
2666 
2667 static VALUE
2669 {
2670  long i;
2671  VALUE collect;
2672 
2674  collect = rb_ary_new2(RARRAY_LEN(ary));
2675  for (i = 0; i < RARRAY_LEN(ary); i++) {
2676  rb_ary_push(collect, rb_yield(RARRAY_AREF(ary, i)));
2677  }
2678  return collect;
2679 }
2680 
2681 
2682 /*
2683  * call-seq:
2684  * ary.collect! {|item| block } -> ary
2685  * ary.map! {|item| block } -> ary
2686  * ary.collect! -> Enumerator
2687  * ary.map! -> Enumerator
2688  *
2689  * Invokes the given block once for each element of +self+, replacing the
2690  * element with the value returned by the block.
2691  *
2692  * See also Enumerable#collect.
2693  *
2694  * If no block is given, an Enumerator is returned instead.
2695  *
2696  * a = [ "a", "b", "c", "d" ]
2697  * a.map! {|x| x + "!" }
2698  * a #=> [ "a!", "b!", "c!", "d!" ]
2699  * a.collect!.with_index {|x, i| x[0...i] }
2700  * a #=> ["", "b", "c!", "d!"]
2701  */
2702 
2703 static VALUE
2705 {
2706  long i;
2707 
2709  rb_ary_modify(ary);
2710  for (i = 0; i < RARRAY_LEN(ary); i++) {
2711  rb_ary_store(ary, i, rb_yield(RARRAY_AREF(ary, i)));
2712  }
2713  return ary;
2714 }
2715 
2716 VALUE
2717 rb_get_values_at(VALUE obj, long olen, int argc, VALUE *argv, VALUE (*func) (VALUE, long))
2718 {
2719  VALUE result = rb_ary_new2(argc);
2720  long beg, len, i, j;
2721 
2722  for (i=0; i<argc; i++) {
2723  if (FIXNUM_P(argv[i])) {
2724  rb_ary_push(result, (*func)(obj, FIX2LONG(argv[i])));
2725  continue;
2726  }
2727  /* check if idx is Range */
2728  if (rb_range_beg_len(argv[i], &beg, &len, olen, 1)) {
2729  long end = olen < beg+len ? olen : beg+len;
2730  for (j = beg; j < end; j++) {
2731  rb_ary_push(result, (*func)(obj, j));
2732  }
2733  if (beg + len > j)
2734  rb_ary_resize(result, RARRAY_LEN(result) + (beg + len) - j);
2735  continue;
2736  }
2737  rb_ary_push(result, (*func)(obj, NUM2LONG(argv[i])));
2738  }
2739  return result;
2740 }
2741 
2742 /*
2743  * call-seq:
2744  * ary.values_at(selector, ...) -> new_ary
2745  *
2746  * Returns an array containing the elements in +self+ corresponding to the
2747  * given +selector+(s).
2748  *
2749  * The selectors may be either integer indices or ranges.
2750  *
2751  * See also Array#select.
2752  *
2753  * a = %w{ a b c d e f }
2754  * a.values_at(1, 3, 5) # => ["b", "d", "f"]
2755  * a.values_at(1, 3, 5, 7) # => ["b", "d", "f", nil]
2756  * a.values_at(-1, -2, -2, -7) # => ["f", "e", "e", nil]
2757  * a.values_at(4..6, 3...6) # => ["e", "f", nil, "d", "e", "f"]
2758  */
2759 
2760 static VALUE
2761 rb_ary_values_at(int argc, VALUE *argv, VALUE ary)
2762 {
2763  return rb_get_values_at(ary, RARRAY_LEN(ary), argc, argv, rb_ary_entry);
2764 }
2765 
2766 
2767 /*
2768  * call-seq:
2769  * ary.select { |item| block } -> new_ary
2770  * ary.select -> Enumerator
2771  *
2772  * Returns a new array containing all elements of +ary+
2773  * for which the given +block+ returns a true value.
2774  *
2775  * If no block is given, an Enumerator is returned instead.
2776  *
2777  * [1,2,3,4,5].select { |num| num.even? } #=> [2, 4]
2778  *
2779  * a = %w{ a b c d e f }
2780  * a.select { |v| v =~ /[aeiou]/ } #=> ["a", "e"]
2781  *
2782  * See also Enumerable#select.
2783  */
2784 
2785 static VALUE
2787 {
2788  VALUE result;
2789  long i;
2790 
2792  result = rb_ary_new2(RARRAY_LEN(ary));
2793  for (i = 0; i < RARRAY_LEN(ary); i++) {
2794  if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) {
2795  rb_ary_push(result, rb_ary_elt(ary, i));
2796  }
2797  }
2798  return result;
2799 }
2800 
2801 /*
2802  * call-seq:
2803  * ary.select! {|item| block } -> ary or nil
2804  * ary.select! -> Enumerator
2805  *
2806  * Invokes the given block passing in successive elements from +self+,
2807  * deleting elements for which the block returns a +false+ value.
2808  *
2809  * If changes were made, it will return +self+, otherwise it returns +nil+.
2810  *
2811  * See also Array#keep_if
2812  *
2813  * If no block is given, an Enumerator is returned instead.
2814  *
2815  */
2816 
2817 static VALUE
2819 {
2820  long i1, i2;
2821 
2823  rb_ary_modify(ary);
2824  for (i1 = i2 = 0; i1 < RARRAY_LEN(ary); i1++) {
2825  VALUE v = RARRAY_AREF(ary, i1);
2826  if (!RTEST(rb_yield(v))) continue;
2827  if (i1 != i2) {
2828  rb_ary_store(ary, i2, v);
2829  }
2830  i2++;
2831  }
2832 
2833  if (i1 == i2) return Qnil;
2834  if (i2 < i1)
2835  ARY_SET_LEN(ary, i2);
2836  return ary;
2837 }
2838 
2839 /*
2840  * call-seq:
2841  * ary.keep_if { |item| block } -> ary
2842  * ary.keep_if -> Enumerator
2843  *
2844  * Deletes every element of +self+ for which the given block evaluates to
2845  * +false+.
2846  *
2847  * See also Array#select!
2848  *
2849  * If no block is given, an Enumerator is returned instead.
2850  *
2851  * a = %w{ a b c d e f }
2852  * a.keep_if { |v| v =~ /[aeiou]/ } #=> ["a", "e"]
2853  */
2854 
2855 static VALUE
2857 {
2859  rb_ary_select_bang(ary);
2860  return ary;
2861 }
2862 
2863 static void
2865 {
2866  rb_ary_modify(ary);
2867  if (RARRAY_LEN(ary) > len) {
2868  ARY_SET_LEN(ary, len);
2869  if (len * 2 < ARY_CAPA(ary) &&
2870  ARY_CAPA(ary) > ARY_DEFAULT_SIZE) {
2871  ary_resize_capa(ary, len * 2);
2872  }
2873  }
2874 }
2875 
2876 /*
2877  * call-seq:
2878  * ary.delete(obj) -> item or nil
2879  * ary.delete(obj) { block } -> item or result of block
2880  *
2881  * Deletes all items from +self+ that are equal to +obj+.
2882  *
2883  * Returns the last deleted item, or +nil+ if no matching item is found.
2884  *
2885  * If the optional code block is given, the result of the block is returned if
2886  * the item is not found. (To remove +nil+ elements and get an informative
2887  * return value, use Array#compact!)
2888  *
2889  * a = [ "a", "b", "b", "b", "c" ]
2890  * a.delete("b") #=> "b"
2891  * a #=> ["a", "c"]
2892  * a.delete("z") #=> nil
2893  * a.delete("z") { "not found" } #=> "not found"
2894  */
2895 
2896 VALUE
2898 {
2899  VALUE v = item;
2900  long i1, i2;
2901 
2902  for (i1 = i2 = 0; i1 < RARRAY_LEN(ary); i1++) {
2903  VALUE e = RARRAY_AREF(ary, i1);
2904 
2905  if (rb_equal(e, item)) {
2906  v = e;
2907  continue;
2908  }
2909  if (i1 != i2) {
2910  rb_ary_store(ary, i2, e);
2911  }
2912  i2++;
2913  }
2914  if (RARRAY_LEN(ary) == i2) {
2915  if (rb_block_given_p()) {
2916  return rb_yield(item);
2917  }
2918  return Qnil;
2919  }
2920 
2921  ary_resize_smaller(ary, i2);
2922 
2923  return v;
2924 }
2925 
2926 void
2928 {
2929  long i1, i2;
2930 
2931  for (i1 = i2 = 0; i1 < RARRAY_LEN(ary); i1++) {
2932  VALUE e = RARRAY_AREF(ary, i1);
2933 
2934  if (e == item) {
2935  continue;
2936  }
2937  if (i1 != i2) {
2938  rb_ary_store(ary, i2, e);
2939  }
2940  i2++;
2941  }
2942  if (RARRAY_LEN(ary) == i2) {
2943  return;
2944  }
2945 
2946  ary_resize_smaller(ary, i2);
2947 }
2948 
2949 VALUE
2951 {
2952  long len = RARRAY_LEN(ary);
2953  VALUE del;
2954 
2955  if (pos >= len) return Qnil;
2956  if (pos < 0) {
2957  pos += len;
2958  if (pos < 0) return Qnil;
2959  }
2960 
2961  rb_ary_modify(ary);
2962  del = RARRAY_AREF(ary, pos);
2963  RARRAY_PTR_USE(ary, ptr, {
2964  MEMMOVE(ptr+pos, ptr+pos+1, VALUE, len-pos-1);
2965  });
2966  ARY_INCREASE_LEN(ary, -1);
2967 
2968  return del;
2969 }
2970 
2971 /*
2972  * call-seq:
2973  * ary.delete_at(index) -> obj or nil
2974  *
2975  * Deletes the element at the specified +index+, returning that element, or
2976  * +nil+ if the +index+ is out of range.
2977  *
2978  * See also Array#slice!
2979  *
2980  * a = ["ant", "bat", "cat", "dog"]
2981  * a.delete_at(2) #=> "cat"
2982  * a #=> ["ant", "bat", "dog"]
2983  * a.delete_at(99) #=> nil
2984  */
2985 
2986 static VALUE
2988 {
2989  return rb_ary_delete_at(ary, NUM2LONG(pos));
2990 }
2991 
2992 /*
2993  * call-seq:
2994  * ary.slice!(index) -> obj or nil
2995  * ary.slice!(start, length) -> new_ary or nil
2996  * ary.slice!(range) -> new_ary or nil
2997  *
2998  * Deletes the element(s) given by an +index+ (optionally up to +length+
2999  * elements) or by a +range+.
3000  *
3001  * Returns the deleted object (or objects), or +nil+ if the +index+ is out of
3002  * range.
3003  *
3004  * a = [ "a", "b", "c" ]
3005  * a.slice!(1) #=> "b"
3006  * a #=> ["a", "c"]
3007  * a.slice!(-1) #=> "c"
3008  * a #=> ["a"]
3009  * a.slice!(100) #=> nil
3010  * a #=> ["a"]
3011  */
3012 
3013 static VALUE
3015 {
3016  VALUE arg1, arg2;
3017  long pos, len, orig_len;
3018 
3019  rb_ary_modify_check(ary);
3020  if (argc == 2) {
3021  pos = NUM2LONG(argv[0]);
3022  len = NUM2LONG(argv[1]);
3023  delete_pos_len:
3024  if (len < 0) return Qnil;
3025  orig_len = RARRAY_LEN(ary);
3026  if (pos < 0) {
3027  pos += orig_len;
3028  if (pos < 0) return Qnil;
3029  }
3030  else if (orig_len < pos) return Qnil;
3031  if (orig_len < pos + len) {
3032  len = orig_len - pos;
3033  }
3034  if (len == 0) return rb_ary_new2(0);
3035  arg2 = rb_ary_new4(len, RARRAY_CONST_PTR(ary)+pos);
3036  RBASIC_SET_CLASS(arg2, rb_obj_class(ary));
3037  rb_ary_splice(ary, pos, len, Qundef);
3038  return arg2;
3039  }
3040 
3041  if (argc != 1) {
3042  /* error report */
3043  rb_scan_args(argc, argv, "11", NULL, NULL);
3044  }
3045  arg1 = argv[0];
3046 
3047  if (!FIXNUM_P(arg1)) {
3048  switch (rb_range_beg_len(arg1, &pos, &len, RARRAY_LEN(ary), 0)) {
3049  case Qtrue:
3050  /* valid range */
3051  goto delete_pos_len;
3052  case Qnil:
3053  /* invalid range */
3054  return Qnil;
3055  default:
3056  /* not a range */
3057  break;
3058  }
3059  }
3060 
3061  return rb_ary_delete_at(ary, NUM2LONG(arg1));
3062 }
3063 
3064 static VALUE
3066 {
3067  long i;
3068 
3069  for (i = 0; i < RARRAY_LEN(orig); i++) {
3070  VALUE v = RARRAY_AREF(orig, i);
3071  if (!RTEST(rb_yield(v))) {
3072  rb_ary_push(result, v);
3073  }
3074  }
3075  return result;
3076 }
3077 
3078 static VALUE
3080 {
3081  long i;
3082  VALUE result = Qnil;
3083 
3084  rb_ary_modify_check(ary);
3085  for (i = 0; i < RARRAY_LEN(ary); ) {
3086  VALUE v = RARRAY_AREF(ary, i);
3087  if (RTEST(rb_yield(v))) {
3088  rb_ary_delete_at(ary, i);
3089  result = ary;
3090  }
3091  else {
3092  i++;
3093  }
3094  }
3095  return result;
3096 }
3097 
3098 /*
3099  * call-seq:
3100  * ary.reject! { |item| block } -> ary or nil
3101  * ary.reject! -> Enumerator
3102  *
3103  * Equivalent to Array#delete_if, deleting elements from +self+ for which the
3104  * block evaluates to +true+, but returns +nil+ if no changes were made.
3105  *
3106  * The array is changed instantly every time the block is called, not after
3107  * the iteration is over.
3108  *
3109  * See also Enumerable#reject and Array#delete_if.
3110  *
3111  * If no block is given, an Enumerator is returned instead.
3112  */
3113 
3114 static VALUE
3116 {
3118  return ary_reject_bang(ary);
3119 }
3120 
3121 /*
3122  * call-seq:
3123  * ary.reject {|item| block } -> new_ary
3124  * ary.reject -> Enumerator
3125  *
3126  * Returns a new array containing the items in +self+ for which the given
3127  * block is not +true+.
3128  *
3129  * See also Array#delete_if
3130  *
3131  * If no block is given, an Enumerator is returned instead.
3132  */
3133 
3134 static VALUE
3136 {
3137  VALUE rejected_ary;
3138 
3140  rejected_ary = rb_ary_new();
3141  ary_reject(ary, rejected_ary);
3142  return rejected_ary;
3143 }
3144 
3145 /*
3146  * call-seq:
3147  * ary.delete_if { |item| block } -> ary
3148  * ary.delete_if -> Enumerator
3149  *
3150  * Deletes every element of +self+ for which block evaluates to +true+.
3151  *
3152  * The array is changed instantly every time the block is called, not after
3153  * the iteration is over.
3154  *
3155  * See also Array#reject!
3156  *
3157  * If no block is given, an Enumerator is returned instead.
3158  *
3159  * scores = [ 97, 42, 75 ]
3160  * scores.delete_if {|score| score < 80 } #=> [97]
3161  */
3162 
3163 static VALUE
3165 {
3167  ary_reject_bang(ary);
3168  return ary;
3169 }
3170 
3171 static VALUE
3173 {
3174  VALUE *args = (VALUE *)cbarg;
3175  if (args[1]-- == 0) rb_iter_break();
3176  if (argc > 1) val = rb_ary_new4(argc, argv);
3177  rb_ary_push(args[0], val);
3178  return Qnil;
3179 }
3180 
3181 static VALUE
3182 take_items(VALUE obj, long n)
3183 {
3185  VALUE args[2];
3186 
3187  if (!NIL_P(result)) return rb_ary_subseq(result, 0, n);
3188  result = rb_ary_new2(n);
3189  args[0] = result; args[1] = (VALUE)n;
3190  if (rb_check_block_call(obj, idEach, 0, 0, take_i, (VALUE)args) == Qundef)
3191  rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (must respond to :each)",
3192  rb_obj_class(obj));
3193  return result;
3194 }
3195 
3196 
3197 /*
3198  * call-seq:
3199  * ary.zip(arg, ...) -> new_ary
3200  * ary.zip(arg, ...) { |arr| block } -> nil
3201  *
3202  * Converts any arguments to arrays, then merges elements of +self+ with
3203  * corresponding elements from each argument.
3204  *
3205  * This generates a sequence of <code>ary.size</code> _n_-element arrays,
3206  * where _n_ is one more than the count of arguments.
3207  *
3208  * If the size of any argument is less than the size of the initial array,
3209  * +nil+ values are supplied.
3210  *
3211  * If a block is given, it is invoked for each output +array+, otherwise an
3212  * array of arrays is returned.
3213  *
3214  * a = [ 4, 5, 6 ]
3215  * b = [ 7, 8, 9 ]
3216  * [1, 2, 3].zip(a, b) #=> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
3217  * [1, 2].zip(a, b) #=> [[1, 4, 7], [2, 5, 8]]
3218  * a.zip([1, 2], [8]) #=> [[4, 1, 8], [5, 2, nil], [6, nil, nil]]
3219  */
3220 
3221 static VALUE
3222 rb_ary_zip(int argc, VALUE *argv, VALUE ary)
3223 {
3224  int i, j;
3225  long len = RARRAY_LEN(ary);
3226  VALUE result = Qnil;
3227 
3228  for (i=0; i<argc; i++) {
3229  argv[i] = take_items(argv[i], len);
3230  }
3231 
3232  if (rb_block_given_p()) {
3233  int arity = rb_block_arity();
3234 
3235  if (arity > 1 && argc+1 < 0x100) {
3236  VALUE *tmp = ALLOCA_N(VALUE, argc+1);
3237 
3238  for (i=0; i<RARRAY_LEN(ary); i++) {
3239  tmp[0] = RARRAY_AREF(ary, i);
3240  for (j=0; j<argc; j++) {
3241  tmp[j+1] = rb_ary_elt(argv[j], i);
3242  }
3243  rb_yield_values2(argc+1, tmp);
3244  }
3245  }
3246  else {
3247  for (i=0; i<RARRAY_LEN(ary); i++) {
3248  VALUE tmp = rb_ary_new2(argc+1);
3249 
3250  rb_ary_push(tmp, RARRAY_AREF(ary, i));
3251  for (j=0; j<argc; j++) {
3252  rb_ary_push(tmp, rb_ary_elt(argv[j], i));
3253  }
3254  rb_yield(tmp);
3255  }
3256  }
3257  }
3258  else {
3259  result = rb_ary_new_capa(len);
3260 
3261  for (i=0; i<len; i++) {
3262  VALUE tmp = rb_ary_new_capa(argc+1);
3263 
3264  rb_ary_push(tmp, RARRAY_AREF(ary, i));
3265  for (j=0; j<argc; j++) {
3266  rb_ary_push(tmp, rb_ary_elt(argv[j], i));
3267  }
3268  rb_ary_push(result, tmp);
3269  }
3270  }
3271 
3272  return result;
3273 }
3274 
3275 /*
3276  * call-seq:
3277  * ary.transpose -> new_ary
3278  *
3279  * Assumes that +self+ is an array of arrays and transposes the rows and
3280  * columns.
3281  *
3282  * a = [[1,2], [3,4], [5,6]]
3283  * a.transpose #=> [[1, 3, 5], [2, 4, 6]]
3284  *
3285  * If the length of the subarrays don't match, an IndexError is raised.
3286  */
3287 
3288 static VALUE
3290 {
3291  long elen = -1, alen, i, j;
3292  VALUE tmp, result = 0;
3293 
3294  alen = RARRAY_LEN(ary);
3295  if (alen == 0) return rb_ary_dup(ary);
3296  for (i=0; i<alen; i++) {
3297  tmp = to_ary(rb_ary_elt(ary, i));
3298  if (elen < 0) { /* first element */
3299  elen = RARRAY_LEN(tmp);
3300  result = rb_ary_new2(elen);
3301  for (j=0; j<elen; j++) {
3302  rb_ary_store(result, j, rb_ary_new2(alen));
3303  }
3304  }
3305  else if (elen != RARRAY_LEN(tmp)) {
3306  rb_raise(rb_eIndexError, "element size differs (%ld should be %ld)",
3307  RARRAY_LEN(tmp), elen);
3308  }
3309  for (j=0; j<elen; j++) {
3310  rb_ary_store(rb_ary_elt(result, j), i, rb_ary_elt(tmp, j));
3311  }
3312  }
3313  return result;
3314 }
3315 
3316 /*
3317  * call-seq:
3318  * ary.replace(other_ary) -> ary
3319  * ary.initialize_copy(other_ary) -> ary
3320  *
3321  * Replaces the contents of +self+ with the contents of +other_ary+,
3322  * truncating or expanding if necessary.
3323  *
3324  * a = [ "a", "b", "c", "d", "e" ]
3325  * a.replace([ "x", "y", "z" ]) #=> ["x", "y", "z"]
3326  * a #=> ["x", "y", "z"]
3327  */
3328 
3329 VALUE
3331 {
3332  rb_ary_modify_check(copy);
3333  orig = to_ary(orig);
3334  if (copy == orig) return copy;
3335 
3336  if (RARRAY_LEN(orig) <= RARRAY_EMBED_LEN_MAX) {
3337  VALUE shared = 0;
3338 
3339  if (ARY_OWNS_HEAP_P(copy)) {
3340  RARRAY_PTR_USE(copy, ptr, ruby_sized_xfree(ptr, ARY_HEAP_SIZE(copy)));
3341  }
3342  else if (ARY_SHARED_P(copy)) {
3343  shared = ARY_SHARED(copy);
3344  FL_UNSET_SHARED(copy);
3345  }
3346  FL_SET_EMBED(copy);
3347  ary_memcpy(copy, 0, RARRAY_LEN(orig), RARRAY_CONST_PTR(orig));
3348  if (shared) {
3349  rb_ary_decrement_share(shared);
3350  }
3351  ARY_SET_LEN(copy, RARRAY_LEN(orig));
3352  }
3353  else {
3354  VALUE shared = ary_make_shared(orig);
3355  if (ARY_OWNS_HEAP_P(copy)) {
3356  RARRAY_PTR_USE(copy, ptr, ruby_sized_xfree(ptr, ARY_HEAP_SIZE(copy)));
3357  }
3358  else {
3359  rb_ary_unshare_safe(copy);
3360  }
3361  FL_UNSET_EMBED(copy);
3362  ARY_SET_PTR(copy, RARRAY_CONST_PTR(orig));
3363  ARY_SET_LEN(copy, RARRAY_LEN(orig));
3364  rb_ary_set_shared(copy, shared);
3365  }
3366  return copy;
3367 }
3368 
3369 /*
3370  * call-seq:
3371  * ary.clear -> ary
3372  *
3373  * Removes all elements from +self+.
3374  *
3375  * a = [ "a", "b", "c", "d", "e" ]
3376  * a.clear #=> [ ]
3377  */
3378 
3379 VALUE
3381 {
3382  rb_ary_modify_check(ary);
3383  ARY_SET_LEN(ary, 0);
3384  if (ARY_SHARED_P(ary)) {
3385  if (!ARY_EMBED_P(ary)) {
3386  rb_ary_unshare(ary);
3387  FL_SET_EMBED(ary);
3388  }
3389  }
3390  else if (ARY_DEFAULT_SIZE * 2 < ARY_CAPA(ary)) {
3392  }
3393  return ary;
3394 }
3395 
3396 /*
3397  * call-seq:
3398  * ary.fill(obj) -> ary
3399  * ary.fill(obj, start [, length]) -> ary
3400  * ary.fill(obj, range ) -> ary
3401  * ary.fill { |index| block } -> ary
3402  * ary.fill(start [, length] ) { |index| block } -> ary
3403  * ary.fill(range) { |index| block } -> ary
3404  *
3405  * The first three forms set the selected elements of +self+ (which
3406  * may be the entire array) to +obj+.
3407  *
3408  * A +start+ of +nil+ is equivalent to zero.
3409  *
3410  * A +length+ of +nil+ is equivalent to the length of the array.
3411  *
3412  * The last three forms fill the array with the value of the given block,
3413  * which is passed the absolute index of each element to be filled.
3414  *
3415  * Negative values of +start+ count from the end of the array, where +-1+ is
3416  * the last element.
3417  *
3418  * a = [ "a", "b", "c", "d" ]
3419  * a.fill("x") #=> ["x", "x", "x", "x"]
3420  * a.fill("z", 2, 2) #=> ["x", "x", "z", "z"]
3421  * a.fill("y", 0..1) #=> ["y", "y", "z", "z"]
3422  * a.fill { |i| i*i } #=> [0, 1, 4, 9]
3423  * a.fill(-2) { |i| i*i*i } #=> [0, 1, 8, 27]
3424  */
3425 
3426 static VALUE
3427 rb_ary_fill(int argc, VALUE *argv, VALUE ary)
3428 {
3429  VALUE item, arg1, arg2;
3430  long beg = 0, end = 0, len = 0;
3431  int block_p = FALSE;
3432 
3433  if (rb_block_given_p()) {
3434  block_p = TRUE;
3435  rb_scan_args(argc, argv, "02", &arg1, &arg2);
3436  argc += 1; /* hackish */
3437  }
3438  else {
3439  rb_scan_args(argc, argv, "12", &item, &arg1, &arg2);
3440  }
3441  switch (argc) {
3442  case 1:
3443  beg = 0;
3444  len = RARRAY_LEN(ary);
3445  break;
3446  case 2:
3447  if (rb_range_beg_len(arg1, &beg, &len, RARRAY_LEN(ary), 1)) {
3448  break;
3449  }
3450  /* fall through */
3451  case 3:
3452  beg = NIL_P(arg1) ? 0 : NUM2LONG(arg1);
3453  if (beg < 0) {
3454  beg = RARRAY_LEN(ary) + beg;
3455  if (beg < 0) beg = 0;
3456  }
3457  len = NIL_P(arg2) ? RARRAY_LEN(ary) - beg : NUM2LONG(arg2);
3458  break;
3459  }
3460  rb_ary_modify(ary);
3461  if (len < 0) {
3462  return ary;
3463  }
3464  if (beg >= ARY_MAX_SIZE || len > ARY_MAX_SIZE - beg) {
3465  rb_raise(rb_eArgError, "argument too big");
3466  }
3467  end = beg + len;
3468  if (RARRAY_LEN(ary) < end) {
3469  if (end >= ARY_CAPA(ary)) {
3470  ary_resize_capa(ary, end);
3471  }
3472  ary_mem_clear(ary, RARRAY_LEN(ary), end - RARRAY_LEN(ary));
3473  ARY_SET_LEN(ary, end);
3474  }
3475 
3476  if (block_p) {
3477  VALUE v;
3478  long i;
3479 
3480  for (i=beg; i<end; i++) {
3481  v = rb_yield(LONG2NUM(i));
3482  if (i>=RARRAY_LEN(ary)) break;
3483  RARRAY_ASET(ary, i, v);
3484  }
3485  }
3486  else {
3487  ary_memfill(ary, beg, len, item);
3488  }
3489  return ary;
3490 }
3491 
3492 /*
3493  * call-seq:
3494  * ary + other_ary -> new_ary
3495  *
3496  * Concatenation --- Returns a new array built by concatenating the
3497  * two arrays together to produce a third array.
3498  *
3499  * [ 1, 2, 3 ] + [ 4, 5 ] #=> [ 1, 2, 3, 4, 5 ]
3500  * a = [ "a", "b", "c" ]
3501  * c = a + [ "d", "e", "f" ]
3502  * c #=> [ "a", "b", "c", "d", "e", "f" ]
3503  * a #=> [ "a", "b", "c" ]
3504  *
3505  * See also Array#concat.
3506  */
3507 
3508 VALUE
3510 {
3511  VALUE z;
3512  long len, xlen, ylen;
3513 
3514  y = to_ary(y);
3515  xlen = RARRAY_LEN(x);
3516  ylen = RARRAY_LEN(y);
3517  len = xlen + ylen;
3518  z = rb_ary_new2(len);
3519 
3520  ary_memcpy(z, 0, xlen, RARRAY_CONST_PTR(x));
3521  ary_memcpy(z, xlen, ylen, RARRAY_CONST_PTR(y));
3522  ARY_SET_LEN(z, len);
3523  return z;
3524 }
3525 
3526 /*
3527  * call-seq:
3528  * ary.concat(other_ary) -> ary
3529  *
3530  * Appends the elements of +other_ary+ to +self+.
3531  *
3532  * [ "a", "b" ].concat( ["c", "d"] ) #=> [ "a", "b", "c", "d" ]
3533  * a = [ 1, 2, 3 ]
3534  * a.concat( [ 4, 5 ] )
3535  * a #=> [ 1, 2, 3, 4, 5 ]
3536  *
3537  * See also Array#+.
3538  */
3539 
3540 VALUE
3542 {
3544  y = to_ary(y);
3545  if (RARRAY_LEN(y) > 0) {
3546  rb_ary_splice(x, RARRAY_LEN(x), 0, y);
3547  }
3548  return x;
3549 }
3550 
3551 
3552 /*
3553  * call-seq:
3554  * ary * int -> new_ary
3555  * ary * str -> new_string
3556  *
3557  * Repetition --- With a String argument, equivalent to
3558  * <code>ary.join(str)</code>.
3559  *
3560  * Otherwise, returns a new array built by concatenating the +int+ copies of
3561  * +self+.
3562  *
3563  *
3564  * [ 1, 2, 3 ] * 3 #=> [ 1, 2, 3, 1, 2, 3, 1, 2, 3 ]
3565  * [ 1, 2, 3 ] * "," #=> "1,2,3"
3566  *
3567  */
3568 
3569 static VALUE
3571 {
3572  VALUE ary2, tmp;
3573  const VALUE *ptr;
3574  long t, len;
3575 
3576  tmp = rb_check_string_type(times);
3577  if (!NIL_P(tmp)) {
3578  return rb_ary_join(ary, tmp);
3579  }
3580 
3581  len = NUM2LONG(times);
3582  if (len == 0) {
3583  ary2 = ary_new(rb_obj_class(ary), 0);
3584  goto out;
3585  }
3586  if (len < 0) {
3587  rb_raise(rb_eArgError, "negative argument");
3588  }
3589  if (ARY_MAX_SIZE/len < RARRAY_LEN(ary)) {
3590  rb_raise(rb_eArgError, "argument too big");
3591  }
3592  len *= RARRAY_LEN(ary);
3593 
3594  ary2 = ary_new(rb_obj_class(ary), len);
3595  ARY_SET_LEN(ary2, len);
3596 
3597  ptr = RARRAY_CONST_PTR(ary);
3598  t = RARRAY_LEN(ary);
3599  if (0 < t) {
3600  ary_memcpy(ary2, 0, t, ptr);
3601  while (t <= len/2) {
3602  ary_memcpy(ary2, t, t, RARRAY_CONST_PTR(ary2));
3603  t *= 2;
3604  }
3605  if (t < len) {
3606  ary_memcpy(ary2, t, len-t, RARRAY_CONST_PTR(ary2));
3607  }
3608  }
3609  out:
3610  OBJ_INFECT(ary2, ary);
3611 
3612  return ary2;
3613 }
3614 
3615 /*
3616  * call-seq:
3617  * ary.assoc(obj) -> new_ary or nil
3618  *
3619  * Searches through an array whose elements are also arrays comparing +obj+
3620  * with the first element of each contained array using <code>obj.==</code>.
3621  *
3622  * Returns the first contained array that matches (that is, the first
3623  * associated array), or +nil+ if no match is found.
3624  *
3625  * See also Array#rassoc
3626  *
3627  * s1 = [ "colors", "red", "blue", "green" ]
3628  * s2 = [ "letters", "a", "b", "c" ]
3629  * s3 = "foo"
3630  * a = [ s1, s2, s3 ]
3631  * a.assoc("letters") #=> [ "letters", "a", "b", "c" ]
3632  * a.assoc("foo") #=> nil
3633  */
3634 
3635 VALUE
3637 {
3638  long i;
3639  VALUE v;
3640 
3641  for (i = 0; i < RARRAY_LEN(ary); ++i) {
3642  v = rb_check_array_type(RARRAY_AREF(ary, i));
3643  if (!NIL_P(v) && RARRAY_LEN(v) > 0 &&
3644  rb_equal(RARRAY_AREF(v, 0), key))
3645  return v;
3646  }
3647  return Qnil;
3648 }
3649 
3650 /*
3651  * call-seq:
3652  * ary.rassoc(obj) -> new_ary or nil
3653  *
3654  * Searches through the array whose elements are also arrays.
3655  *
3656  * Compares +obj+ with the second element of each contained array using
3657  * <code>obj.==</code>.
3658  *
3659  * Returns the first contained array that matches +obj+.
3660  *
3661  * See also Array#assoc.
3662  *
3663  * a = [ [ 1, "one"], [2, "two"], [3, "three"], ["ii", "two"] ]
3664  * a.rassoc("two") #=> [2, "two"]
3665  * a.rassoc("four") #=> nil
3666  */
3667 
3668 VALUE
3670 {
3671  long i;
3672  VALUE v;
3673 
3674  for (i = 0; i < RARRAY_LEN(ary); ++i) {
3675  v = RARRAY_AREF(ary, i);
3676  if (RB_TYPE_P(v, T_ARRAY) &&
3677  RARRAY_LEN(v) > 1 &&
3678  rb_equal(RARRAY_AREF(v, 1), value))
3679  return v;
3680  }
3681  return Qnil;
3682 }
3683 
3684 static VALUE
3686 {
3687  long i, len1;
3688  const VALUE *p1, *p2;
3689 
3690  if (recur) return Qtrue; /* Subtle! */
3691 
3692  p1 = RARRAY_CONST_PTR(ary1);
3693  p2 = RARRAY_CONST_PTR(ary2);
3694  len1 = RARRAY_LEN(ary1);
3695 
3696  for (i = 0; i < len1; i++) {
3697  if (*p1 != *p2) {
3698  if (rb_equal(*p1, *p2)) {
3699  len1 = RARRAY_LEN(ary1);
3700  if (len1 != RARRAY_LEN(ary2))
3701  return Qfalse;
3702  if (len1 < i)
3703  return Qtrue;
3704  p1 = RARRAY_CONST_PTR(ary1) + i;
3705  p2 = RARRAY_CONST_PTR(ary2) + i;
3706  }
3707  else {
3708  return Qfalse;
3709  }
3710  }
3711  p1++;
3712  p2++;
3713  }
3714  return Qtrue;
3715 }
3716 
3717 /*
3718  * call-seq:
3719  * ary == other_ary -> bool
3720  *
3721  * Equality --- Two arrays are equal if they contain the same number of
3722  * elements and if each element is equal to (according to Object#==) the
3723  * corresponding element in +other_ary+.
3724  *
3725  * [ "a", "c" ] == [ "a", "c", 7 ] #=> false
3726  * [ "a", "c", 7 ] == [ "a", "c", 7 ] #=> true
3727  * [ "a", "c", 7 ] == [ "a", "d", "f" ] #=> false
3728  *
3729  */
3730 
3731 static VALUE
3733 {
3734  if (ary1 == ary2) return Qtrue;
3735  if (!RB_TYPE_P(ary2, T_ARRAY)) {
3736  if (!rb_respond_to(ary2, rb_intern("to_ary"))) {
3737  return Qfalse;
3738  }
3739  return rb_equal(ary2, ary1);
3740  }
3741  if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return Qfalse;
3742  if (RARRAY_CONST_PTR(ary1) == RARRAY_CONST_PTR(ary2)) return Qtrue;
3743  return rb_exec_recursive_paired(recursive_equal, ary1, ary2, ary2);
3744 }
3745 
3746 static VALUE
3747 recursive_eql(VALUE ary1, VALUE ary2, int recur)
3748 {
3749  long i;
3750 
3751  if (recur) return Qtrue; /* Subtle! */
3752  for (i=0; i<RARRAY_LEN(ary1); i++) {
3753  if (!rb_eql(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
3754  return Qfalse;
3755  }
3756  return Qtrue;
3757 }
3758 
3759 /*
3760  * call-seq:
3761  * ary.eql?(other) -> true or false
3762  *
3763  * Returns +true+ if +self+ and +other+ are the same object,
3764  * or are both arrays with the same content (according to Object#eql?).
3765  */
3766 
3767 static VALUE
3769 {
3770  if (ary1 == ary2) return Qtrue;
3771  if (!RB_TYPE_P(ary2, T_ARRAY)) return Qfalse;
3772  if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return Qfalse;
3773  if (RARRAY_CONST_PTR(ary1) == RARRAY_CONST_PTR(ary2)) return Qtrue;
3774  return rb_exec_recursive_paired(recursive_eql, ary1, ary2, ary2);
3775 }
3776 
3777 /*
3778  * call-seq:
3779  * ary.hash -> fixnum
3780  *
3781  * Compute a hash-code for this array.
3782  *
3783  * Two arrays with the same content will have the same hash code (and will
3784  * compare using #eql?).
3785  */
3786 
3787 static VALUE
3789 {
3790  long i;
3791  st_index_t h;
3792  VALUE n;
3793 
3794  h = rb_hash_start(RARRAY_LEN(ary));
3796  for (i=0; i<RARRAY_LEN(ary); i++) {
3797  n = rb_hash(RARRAY_AREF(ary, i));
3798  h = rb_hash_uint(h, NUM2LONG(n));
3799  }
3800  h = rb_hash_end(h);
3801  return LONG2FIX(h);
3802 }
3803 
3804 /*
3805  * call-seq:
3806  * ary.include?(object) -> true or false
3807  *
3808  * Returns +true+ if the given +object+ is present in +self+ (that is, if any
3809  * element <code>==</code> +object+), otherwise returns +false+.
3810  *
3811  * a = [ "a", "b", "c" ]
3812  * a.include?("b") #=> true
3813  * a.include?("z") #=> false
3814  */
3815 
3816 VALUE
3818 {
3819  long i;
3820 
3821  for (i=0; i<RARRAY_LEN(ary); i++) {
3822  if (rb_equal(RARRAY_AREF(ary, i), item)) {
3823  return Qtrue;
3824  }
3825  }
3826  return Qfalse;
3827 }
3828 
3829 
3830 static VALUE
3831 recursive_cmp(VALUE ary1, VALUE ary2, int recur)
3832 {
3833  long i, len;
3834 
3835  if (recur) return Qundef; /* Subtle! */
3836  len = RARRAY_LEN(ary1);
3837  if (len > RARRAY_LEN(ary2)) {
3838  len = RARRAY_LEN(ary2);
3839  }
3840  for (i=0; i<len; i++) {
3841  VALUE e1 = rb_ary_elt(ary1, i), e2 = rb_ary_elt(ary2, i);
3842  VALUE v = rb_funcallv(e1, id_cmp, 1, &e2);
3843  if (v != INT2FIX(0)) {
3844  return v;
3845  }
3846  }
3847  return Qundef;
3848 }
3849 
3850 /*
3851  * call-seq:
3852  * ary <=> other_ary -> -1, 0, +1 or nil
3853  *
3854  * Comparison --- Returns an integer (+-1+, +0+, or <code>+1</code>) if this
3855  * array is less than, equal to, or greater than +other_ary+.
3856  *
3857  * +nil+ is returned if the two values are incomparable.
3858  *
3859  * Each object in each array is compared (using the <=> operator).
3860  *
3861  * Arrays are compared in an "element-wise" manner; the first two elements
3862  * that are not equal will determine the return value for the whole
3863  * comparison.
3864  *
3865  * If all the values are equal, then the return is based on a comparison of
3866  * the array lengths. Thus, two arrays are "equal" according to Array#<=> if,
3867  * and only if, they have the same length and the value of each element is
3868  * equal to the value of the corresponding element in the other array.
3869  *
3870  * [ "a", "a", "c" ] <=> [ "a", "b", "c" ] #=> -1
3871  * [ 1, 2, 3, 4, 5, 6 ] <=> [ 1, 2 ] #=> +1
3872  *
3873  */
3874 
3875 VALUE
3877 {
3878  long len;
3879  VALUE v;
3880 
3881  ary2 = rb_check_array_type(ary2);
3882  if (NIL_P(ary2)) return Qnil;
3883  if (ary1 == ary2) return INT2FIX(0);
3884  v = rb_exec_recursive_paired(recursive_cmp, ary1, ary2, ary2);
3885  if (v != Qundef) return v;
3886  len = RARRAY_LEN(ary1) - RARRAY_LEN(ary2);
3887  if (len == 0) return INT2FIX(0);
3888  if (len > 0) return INT2FIX(1);
3889  return INT2FIX(-1);
3890 }
3891 
3892 static VALUE
3894 {
3895  long i;
3896 
3897  for (i=0; i<RARRAY_LEN(ary); i++) {
3898  VALUE elt = RARRAY_AREF(ary, i);
3899  if (rb_hash_lookup2(hash, elt, Qundef) == Qundef) {
3900  rb_hash_aset(hash, elt, elt);
3901  }
3902  }
3903  return hash;
3904 }
3905 
3906 static inline VALUE
3908 {
3909  VALUE hash = rb_hash_new();
3910 
3911  RBASIC_CLEAR_CLASS(hash);
3912  return hash;
3913 }
3914 
3915 static VALUE
3917 {
3919  return ary_add_hash(hash, ary);
3920 }
3921 
3922 static VALUE
3924 {
3925  long i;
3926 
3927  for (i = 0; i < RARRAY_LEN(ary); ++i) {
3928  VALUE v = rb_ary_elt(ary, i), k = rb_yield(v);
3929  if (rb_hash_lookup2(hash, k, Qundef) == Qundef) {
3930  rb_hash_aset(hash, k, v);
3931  }
3932  }
3933  return hash;
3934 }
3935 
3936 static VALUE
3938 {
3940  return ary_add_hash_by(hash, ary);
3941 }
3942 
3943 static inline void
3945 {
3946  if (RHASH(hash)->ntbl) {
3947  st_table *tbl = RHASH(hash)->ntbl;
3948  RHASH(hash)->ntbl = 0;
3949  st_free_table(tbl);
3950  }
3951 }
3952 
3953 /*
3954  * call-seq:
3955  * ary - other_ary -> new_ary
3956  *
3957  * Array Difference
3958  *
3959  * Returns a new array that is a copy of the original array, removing any
3960  * items that also appear in +other_ary+. The order is preserved from the
3961  * original array.
3962  *
3963  * It compares elements using their #hash and #eql? methods for efficiency.
3964  *
3965  * [ 1, 1, 2, 2, 3, 3, 4, 5 ] - [ 1, 2, 4 ] #=> [ 3, 3, 5 ]
3966  *
3967  * If you need set-like behavior, see the library class Set.
3968  */
3969 
3970 static VALUE
3972 {
3973  VALUE ary3;
3974  volatile VALUE hash;
3975  long i;
3976 
3977  hash = ary_make_hash(to_ary(ary2));
3978  ary3 = rb_ary_new();
3979 
3980  for (i=0; i<RARRAY_LEN(ary1); i++) {
3981  if (st_lookup(rb_hash_tbl_raw(hash), RARRAY_AREF(ary1, i), 0)) continue;
3982  rb_ary_push(ary3, rb_ary_elt(ary1, i));
3983  }
3984  ary_recycle_hash(hash);
3985  return ary3;
3986 }
3987 
3988 /*
3989  * call-seq:
3990  * ary & other_ary -> new_ary
3991  *
3992  * Set Intersection --- Returns a new array containing elements common to the
3993  * two arrays, excluding any duplicates. The order is preserved from the
3994  * original array.
3995  *
3996  * It compares elements using their #hash and #eql? methods for efficiency.
3997  *
3998  * [ 1, 1, 3, 5 ] & [ 1, 2, 3 ] #=> [ 1, 3 ]
3999  * [ 'a', 'b', 'b', 'z' ] & [ 'a', 'b', 'c' ] #=> [ 'a', 'b' ]
4000  *
4001  * See also Array#uniq.
4002  */
4003 
4004 
4005 static VALUE
4007 {
4008  VALUE hash, ary3, v;
4009  st_table *table;
4010  st_data_t vv;
4011  long i;
4012 
4013  ary2 = to_ary(ary2);
4014  ary3 = rb_ary_new();
4015  if (RARRAY_LEN(ary2) == 0) return ary3;
4016  hash = ary_make_hash(ary2);
4017  table = rb_hash_tbl_raw(hash);
4018 
4019  for (i=0; i<RARRAY_LEN(ary1); i++) {
4020  v = RARRAY_AREF(ary1, i);
4021  vv = (st_data_t)v;
4022  if (st_delete(table, &vv, 0)) {
4023  rb_ary_push(ary3, v);
4024  }
4025  }
4026  ary_recycle_hash(hash);
4027 
4028  return ary3;
4029 }
4030 
4031 static int
4032 ary_hash_orset(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
4033 {
4034  if (existing) return ST_STOP;
4035  *key = *value = (VALUE)arg;
4036  return ST_CONTINUE;
4037 }
4038 
4039 /*
4040  * call-seq:
4041  * ary | other_ary -> new_ary
4042  *
4043  * Set Union --- Returns a new array by joining +ary+ with +other_ary+,
4044  * excluding any duplicates and preserving the order from the original array.
4045  *
4046  * It compares elements using their #hash and #eql? methods for efficiency.
4047  *
4048  * [ "a", "b", "c" ] | [ "c", "d", "a" ] #=> [ "a", "b", "c", "d" ]
4049  *
4050  * See also Array#uniq.
4051  */
4052 
4053 static VALUE
4054 rb_ary_or(VALUE ary1, VALUE ary2)
4055 {
4056  VALUE hash, ary3;
4057  long i;
4058 
4059  ary2 = to_ary(ary2);
4060  hash = ary_make_hash(ary1);
4061 
4062  for (i=0; i<RARRAY_LEN(ary2); i++) {
4063  VALUE elt = RARRAY_AREF(ary2, i);
4064  if (!st_update(RHASH_TBL_RAW(hash), (st_data_t)elt, ary_hash_orset, (st_data_t)elt)) {
4065  RB_OBJ_WRITTEN(hash, Qundef, elt);
4066  }
4067  }
4068  ary3 = rb_hash_values(hash);
4069  ary_recycle_hash(hash);
4070  return ary3;
4071 }
4072 
4073 static int
4075 {
4076  rb_ary_push((VALUE)ary, (VALUE)val);
4077  return ST_CONTINUE;
4078 }
4079 
4080 /*
4081  * call-seq:
4082  * ary.uniq! -> ary or nil
4083  * ary.uniq! { |item| ... } -> ary or nil
4084  *
4085  * Removes duplicate elements from +self+.
4086  *
4087  * If a block is given, it will use the return value of the block for
4088  * comparison.
4089  *
4090  * It compares values using their #hash and #eql? methods for efficiency.
4091  *
4092  * Returns +nil+ if no changes are made (that is, no duplicates are found).
4093  *
4094  * a = [ "a", "a", "b", "b", "c" ]
4095  * a.uniq! # => ["a", "b", "c"]
4096  *
4097  * b = [ "a", "b", "c" ]
4098  * b.uniq! # => nil
4099  *
4100  * c = [["student","sam"], ["student","george"], ["teacher","matz"]]
4101  * c.uniq! { |s| s.first } # => [["student", "sam"], ["teacher", "matz"]]
4102  *
4103  */
4104 
4105 static VALUE
4107 {
4108  VALUE hash;
4109  long hash_size;
4110 
4111  rb_ary_modify_check(ary);
4112  if (RARRAY_LEN(ary) <= 1)
4113  return Qnil;
4114  if (rb_block_given_p())
4115  hash = ary_make_hash_by(ary);
4116  else
4117  hash = ary_make_hash(ary);
4118 
4119  hash_size = RHASH_SIZE(hash);
4120  if (RARRAY_LEN(ary) == hash_size) {
4121  return Qnil;
4122  }
4123  rb_ary_modify_check(ary);
4124  ARY_SET_LEN(ary, 0);
4125  if (ARY_SHARED_P(ary) && !ARY_EMBED_P(ary)) {
4126  rb_ary_unshare(ary);
4127  FL_SET_EMBED(ary);
4128  }
4129  ary_resize_capa(ary, hash_size);
4130  st_foreach(rb_hash_tbl_raw(hash), push_value, ary);
4131  ary_recycle_hash(hash);
4132 
4133  return ary;
4134 }
4135 
4136 /*
4137  * call-seq:
4138  * ary.uniq -> new_ary
4139  * ary.uniq { |item| ... } -> new_ary
4140  *
4141  * Returns a new array by removing duplicate values in +self+.
4142  *
4143  * If a block is given, it will use the return value of the block for comparison.
4144  *
4145  * It compares values using their #hash and #eql? methods for efficiency.
4146  *
4147  * a = [ "a", "a", "b", "b", "c" ]
4148  * a.uniq # => ["a", "b", "c"]
4149  *
4150  * b = [["student","sam"], ["student","george"], ["teacher","matz"]]
4151  * b.uniq { |s| s.first } # => [["student", "sam"], ["teacher", "matz"]]
4152  *
4153  */
4154 
4155 static VALUE
4157 {
4158  VALUE hash, uniq;
4159 
4160  if (RARRAY_LEN(ary) <= 1)
4161  return rb_ary_dup(ary);
4162  if (rb_block_given_p()) {
4163  hash = ary_make_hash_by(ary);
4164  uniq = rb_hash_values(hash);
4165  }
4166  else {
4167  hash = ary_make_hash(ary);
4168  uniq = rb_hash_values(hash);
4169  }
4170  RBASIC_SET_CLASS(uniq, rb_obj_class(ary));
4171  ary_recycle_hash(hash);
4172 
4173  return uniq;
4174 }
4175 
4176 /*
4177  * call-seq:
4178  * ary.compact! -> ary or nil
4179  *
4180  * Removes +nil+ elements from the array.
4181  *
4182  * Returns +nil+ if no changes were made, otherwise returns the array.
4183  *
4184  * [ "a", nil, "b", nil, "c" ].compact! #=> [ "a", "b", "c" ]
4185  * [ "a", "b", "c" ].compact! #=> nil
4186  */
4187 
4188 static VALUE
4190 {
4191  VALUE *p, *t, *end;
4192  long n;
4193 
4194  rb_ary_modify(ary);
4195  p = t = (VALUE *)RARRAY_CONST_PTR(ary); /* WB: no new reference */
4196  end = p + RARRAY_LEN(ary);
4197 
4198  while (t < end) {
4199  if (NIL_P(*t)) t++;
4200  else *p++ = *t++;
4201  }
4202  n = p - RARRAY_CONST_PTR(ary);
4203  if (RARRAY_LEN(ary) == n) {
4204  return Qnil;
4205  }
4206  ary_resize_smaller(ary, n);
4207 
4208  return ary;
4209 }
4210 
4211 /*
4212  * call-seq:
4213  * ary.compact -> new_ary
4214  *
4215  * Returns a copy of +self+ with all +nil+ elements removed.
4216  *
4217  * [ "a", nil, "b", nil, "c", nil ].compact
4218  * #=> [ "a", "b", "c" ]
4219  */
4220 
4221 static VALUE
4223 {
4224  ary = rb_ary_dup(ary);
4225  rb_ary_compact_bang(ary);
4226  return ary;
4227 }
4228 
4229 /*
4230  * call-seq:
4231  * ary.count -> int
4232  * ary.count(obj) -> int
4233  * ary.count { |item| block } -> int
4234  *
4235  * Returns the number of elements.
4236  *
4237  * If an argument is given, counts the number of elements which equal +obj+
4238  * using <code>==</code>.
4239  *
4240  * If a block is given, counts the number of elements for which the block
4241  * returns a true value.
4242  *
4243  * ary = [1, 2, 4, 2]
4244  * ary.count #=> 4
4245  * ary.count(2) #=> 2
4246  * ary.count { |x| x%2 == 0 } #=> 3
4247  *
4248  */
4249 
4250 static VALUE
4251 rb_ary_count(int argc, VALUE *argv, VALUE ary)
4252 {
4253  long i, n = 0;
4254 
4255  if (argc == 0) {
4256  VALUE v;
4257 
4258  if (!rb_block_given_p())
4259  return LONG2NUM(RARRAY_LEN(ary));
4260 
4261  for (i = 0; i < RARRAY_LEN(ary); i++) {
4262  v = RARRAY_AREF(ary, i);
4263  if (RTEST(rb_yield(v))) n++;
4264  }
4265  }
4266  else {
4267  VALUE obj;
4268 
4269  rb_scan_args(argc, argv, "1", &obj);
4270  if (rb_block_given_p()) {
4271  rb_warn("given block not used");
4272  }
4273  for (i = 0; i < RARRAY_LEN(ary); i++) {
4274  if (rb_equal(RARRAY_AREF(ary, i), obj)) n++;
4275  }
4276  }
4277 
4278  return LONG2NUM(n);
4279 }
4280 
4281 static VALUE
4282 flatten(VALUE ary, int level, int *modified)
4283 {
4284  long i = 0;
4285  VALUE stack, result, tmp, elt;
4286  st_table *memo;
4287  st_data_t id;
4288 
4289  stack = ary_new(0, ARY_DEFAULT_SIZE);
4290  result = ary_new(0, RARRAY_LEN(ary));
4291  memo = st_init_numtable();
4292  st_insert(memo, (st_data_t)ary, (st_data_t)Qtrue);
4293  *modified = 0;
4294 
4295  while (1) {
4296  while (i < RARRAY_LEN(ary)) {
4297  elt = RARRAY_AREF(ary, i++);
4298  tmp = rb_check_array_type(elt);
4299  if (RBASIC(result)->klass) {
4300  rb_raise(rb_eRuntimeError, "flatten reentered");
4301  }
4302  if (NIL_P(tmp) || (level >= 0 && RARRAY_LEN(stack) / 2 >= level)) {
4303  rb_ary_push(result, elt);
4304  }
4305  else {
4306  *modified = 1;
4307  id = (st_data_t)tmp;
4308  if (st_lookup(memo, id, 0)) {
4309  st_free_table(memo);
4310  rb_raise(rb_eArgError, "tried to flatten recursive array");
4311  }
4312  st_insert(memo, id, (st_data_t)Qtrue);
4313  rb_ary_push(stack, ary);
4314  rb_ary_push(stack, LONG2NUM(i));
4315  ary = tmp;
4316  i = 0;
4317  }
4318  }
4319  if (RARRAY_LEN(stack) == 0) {
4320  break;
4321  }
4322  id = (st_data_t)ary;
4323  st_delete(memo, &id, 0);
4324  tmp = rb_ary_pop(stack);
4325  i = NUM2LONG(tmp);
4326  ary = rb_ary_pop(stack);
4327  }
4328 
4329  st_free_table(memo);
4330 
4331  RBASIC_SET_CLASS(result, rb_class_of(ary));
4332  return result;
4333 }
4334 
4335 /*
4336  * call-seq:
4337  * ary.flatten! -> ary or nil
4338  * ary.flatten!(level) -> ary or nil
4339  *
4340  * Flattens +self+ in place.
4341  *
4342  * Returns +nil+ if no modifications were made (i.e., the array contains no
4343  * subarrays.)
4344  *
4345  * The optional +level+ argument determines the level of recursion to flatten.
4346  *
4347  * a = [ 1, 2, [3, [4, 5] ] ]
4348  * a.flatten! #=> [1, 2, 3, 4, 5]
4349  * a.flatten! #=> nil
4350  * a #=> [1, 2, 3, 4, 5]
4351  * a = [ 1, 2, [3, [4, 5] ] ]
4352  * a.flatten!(1) #=> [1, 2, 3, [4, 5]]
4353  */
4354 
4355 static VALUE
4357 {
4358  int mod = 0, level = -1;
4359  VALUE result, lv;
4360 
4361  rb_scan_args(argc, argv, "01", &lv);
4362  rb_ary_modify_check(ary);
4363  if (!NIL_P(lv)) level = NUM2INT(lv);
4364  if (level == 0) return Qnil;
4365 
4366  result = flatten(ary, level, &mod);
4367  if (mod == 0) {
4368  ary_discard(result);
4369  return Qnil;
4370  }
4371  if (!(mod = ARY_EMBED_P(result))) rb_obj_freeze(result);
4372  rb_ary_replace(ary, result);
4373  if (mod) ARY_SET_EMBED_LEN(result, 0);
4374 
4375  return ary;
4376 }
4377 
4378 /*
4379  * call-seq:
4380  * ary.flatten -> new_ary
4381  * ary.flatten(level) -> new_ary
4382  *
4383  * Returns a new array that is a one-dimensional flattening of +self+
4384  * (recursively).
4385  *
4386  * That is, for every element that is an array, extract its elements into
4387  * the new array.
4388  *
4389  * The optional +level+ argument determines the level of recursion to
4390  * flatten.
4391  *
4392  * s = [ 1, 2, 3 ] #=> [1, 2, 3]
4393  * t = [ 4, 5, 6, [7, 8] ] #=> [4, 5, 6, [7, 8]]
4394  * a = [ s, t, 9, 10 ] #=> [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10]
4395  * a.flatten #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
4396  * a = [ 1, 2, [3, [4, 5] ] ]
4397  * a.flatten(1) #=> [1, 2, 3, [4, 5]]
4398  */
4399 
4400 static VALUE
4401 rb_ary_flatten(int argc, VALUE *argv, VALUE ary)
4402 {
4403  int mod = 0, level = -1;
4404  VALUE result, lv;
4405 
4406  rb_scan_args(argc, argv, "01", &lv);
4407  if (!NIL_P(lv)) level = NUM2INT(lv);
4408  if (level == 0) return ary_make_shared_copy(ary);
4409 
4410  result = flatten(ary, level, &mod);
4411  OBJ_INFECT(result, ary);
4412 
4413  return result;
4414 }
4415 
4416 #define OPTHASH_GIVEN_P(opts) \
4417  (argc > 0 && !NIL_P((opts) = rb_check_hash_type(argv[argc-1])) && (--argc, 1))
4418 static ID id_random;
4419 
4420 #define RAND_UPTO(max) (long)rb_random_ulong_limited((randgen), (max)-1)
4421 
4422 /*
4423  * call-seq:
4424  * ary.shuffle! -> ary
4425  * ary.shuffle!(random: rng) -> ary
4426  *
4427  * Shuffles elements in +self+ in place.
4428  *
4429  * The optional +rng+ argument will be used as the random number generator.
4430  */
4431 
4432 static VALUE
4434 {
4435  VALUE opts, randgen = rb_cRandom;
4436  long i, len;
4437 
4438  if (OPTHASH_GIVEN_P(opts)) {
4439  VALUE rnd;
4440  ID keyword_ids[1];
4441 
4442  keyword_ids[0] = id_random;
4443  rb_get_kwargs(opts, keyword_ids, 0, 1, &rnd);
4444  if (rnd != Qundef) {
4445  randgen = rnd;
4446  }
4447  }
4448  rb_check_arity(argc, 0, 0);
4449  rb_ary_modify(ary);
4450  i = len = RARRAY_LEN(ary);
4451  RARRAY_PTR_USE(ary, ptr, {
4452  while (i) {
4453  long j = RAND_UPTO(i);
4454  VALUE tmp;
4455  if (len != RARRAY_LEN(ary) || ptr != RARRAY_CONST_PTR(ary)) {
4456  rb_raise(rb_eRuntimeError, "modified during shuffle");
4457  }
4458  tmp = ptr[--i];
4459  ptr[i] = ptr[j];
4460  ptr[j] = tmp;
4461  }
4462  }); /* WB: no new reference */
4463  return ary;
4464 }
4465 
4466 
4467 /*
4468  * call-seq:
4469  * ary.shuffle -> new_ary
4470  * ary.shuffle(random: rng) -> new_ary
4471  *
4472  * Returns a new array with elements of +self+ shuffled.
4473  *
4474  * a = [ 1, 2, 3 ] #=> [1, 2, 3]
4475  * a.shuffle #=> [2, 3, 1]
4476  *
4477  * The optional +rng+ argument will be used as the random number generator.
4478  *
4479  * a.shuffle(random: Random.new(1)) #=> [1, 3, 2]
4480  */
4481 
4482 static VALUE
4483 rb_ary_shuffle(int argc, VALUE *argv, VALUE ary)
4484 {
4485  ary = rb_ary_dup(ary);
4486  rb_ary_shuffle_bang(argc, argv, ary);
4487  return ary;
4488 }
4489 
4490 
4491 /*
4492  * call-seq:
4493  * ary.sample -> obj
4494  * ary.sample(random: rng) -> obj
4495  * ary.sample(n) -> new_ary
4496  * ary.sample(n, random: rng) -> new_ary
4497  *
4498  * Choose a random element or +n+ random elements from the array.
4499  *
4500  * The elements are chosen by using random and unique indices into the array
4501  * in order to ensure that an element doesn't repeat itself unless the array
4502  * already contained duplicate elements.
4503  *
4504  * If the array is empty the first form returns +nil+ and the second form
4505  * returns an empty array.
4506  *
4507  * The optional +rng+ argument will be used as the random number generator.
4508  *
4509  * a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
4510  * a.sample #=> 7
4511  * a.sample(4) #=> [6, 4, 2, 5]
4512  */
4513 
4514 
4515 static VALUE
4516 rb_ary_sample(int argc, VALUE *argv, VALUE ary)
4517 {
4518  VALUE nv, result;
4519  VALUE opts, randgen = rb_cRandom;
4520  long n, len, i, j, k, idx[10];
4521  long rnds[numberof(idx)];
4522 
4523  if (OPTHASH_GIVEN_P(opts)) {
4524  VALUE rnd;
4525  ID keyword_ids[1];
4526 
4527  keyword_ids[0] = id_random;
4528  rb_get_kwargs(opts, keyword_ids, 0, 1, &rnd);
4529  if (rnd != Qundef) {
4530  randgen = rnd;
4531  }
4532  }
4533  len = RARRAY_LEN(ary);
4534  if (argc == 0) {
4535  if (len < 2)
4536  i = 0;
4537  else
4538  i = RAND_UPTO(len);
4539 
4540  return rb_ary_elt(ary, i);
4541  }
4542  rb_scan_args(argc, argv, "1", &nv);
4543  n = NUM2LONG(nv);
4544  if (n < 0) rb_raise(rb_eArgError, "negative sample number");
4545  if (n > len) n = len;
4546  if (n <= numberof(idx)) {
4547  for (i = 0; i < n; ++i) {
4548  rnds[i] = RAND_UPTO(len - i);
4549  }
4550  }
4551  k = len;
4552  len = RARRAY_LEN(ary);
4553  if (len < k && n <= numberof(idx)) {
4554  for (i = 0; i < n; ++i) {
4555  if (rnds[i] >= len) return rb_ary_new_capa(0);
4556  }
4557  }
4558  if (n > len) n = len;
4559  switch (n) {
4560  case 0:
4561  return rb_ary_new_capa(0);
4562  case 1:
4563  i = rnds[0];
4564  return rb_ary_new_from_values(1, &RARRAY_AREF(ary, i));
4565  case 2:
4566  i = rnds[0];
4567  j = rnds[1];
4568  if (j >= i) j++;
4569  return rb_ary_new_from_args(2, RARRAY_AREF(ary, i), RARRAY_AREF(ary, j));
4570  case 3:
4571  i = rnds[0];
4572  j = rnds[1];
4573  k = rnds[2];
4574  {
4575  long l = j, g = i;
4576  if (j >= i) l = i, g = ++j;
4577  if (k >= l && (++k >= g)) ++k;
4578  }
4579  return rb_ary_new_from_args(3, RARRAY_AREF(ary, i), RARRAY_AREF(ary, j), RARRAY_AREF(ary, k));
4580  }
4581  if (n <= numberof(idx)) {
4582  long sorted[numberof(idx)];
4583  sorted[0] = idx[0] = rnds[0];
4584  for (i=1; i<n; i++) {
4585  k = rnds[i];
4586  for (j = 0; j < i; ++j) {
4587  if (k < sorted[j]) break;
4588  ++k;
4589  }
4590  memmove(&sorted[j+1], &sorted[j], sizeof(sorted[0])*(i-j));
4591  sorted[j] = idx[i] = k;
4592  }
4593  result = rb_ary_new_capa(n);
4594  RARRAY_PTR_USE(result, ptr_result, {
4595  for (i=0; i<n; i++) {
4596  ptr_result[i] = RARRAY_AREF(ary, idx[i]);
4597  }
4598  });
4599  }
4600  else {
4601  result = rb_ary_dup(ary);
4602  RBASIC_CLEAR_CLASS(result);
4603  RB_GC_GUARD(ary);
4604  RARRAY_PTR_USE(result, ptr_result, {
4605  for (i=0; i<n; i++) {
4606  j = RAND_UPTO(len-i) + i;
4607  nv = ptr_result[j];
4608  ptr_result[j] = ptr_result[i];
4609  ptr_result[i] = nv;
4610  }
4611  });
4613  }
4614  ARY_SET_LEN(result, n);
4615 
4616  return result;
4617 }
4618 
4619 static VALUE
4621 {
4622  long mul;
4623  VALUE n = Qnil;
4624  if (args && (RARRAY_LEN(args) > 0)) {
4625  n = RARRAY_AREF(args, 0);
4626  }
4627  if (RARRAY_LEN(self) == 0) return INT2FIX(0);
4628  if (n == Qnil) return DBL2NUM(INFINITY);
4629  mul = NUM2LONG(n);
4630  if (mul <= 0) return INT2FIX(0);
4631  n = LONG2FIX(mul);
4632  return rb_funcallv(rb_ary_length(self), '*', 1, &n);
4633 }
4634 
4635 /*
4636  * call-seq:
4637  * ary.cycle(n=nil) { |obj| block } -> nil
4638  * ary.cycle(n=nil) -> Enumerator
4639  *
4640  * Calls the given block for each element +n+ times or forever if +nil+ is
4641  * given.
4642  *
4643  * Does nothing if a non-positive number is given or the array is empty.
4644  *
4645  * Returns +nil+ if the loop has finished without getting interrupted.
4646  *
4647  * If no block is given, an Enumerator is returned instead.
4648  *
4649  * a = ["a", "b", "c"]
4650  * a.cycle { |x| puts x } # print, a, b, c, a, b, c,.. forever.
4651  * a.cycle(2) { |x| puts x } # print, a, b, c, a, b, c.
4652  *
4653  */
4654 
4655 static VALUE
4656 rb_ary_cycle(int argc, VALUE *argv, VALUE ary)
4657 {
4658  long n, i;
4659  VALUE nv = Qnil;
4660 
4661  rb_scan_args(argc, argv, "01", &nv);
4662 
4663  RETURN_SIZED_ENUMERATOR(ary, argc, argv, rb_ary_cycle_size);
4664  if (NIL_P(nv)) {
4665  n = -1;
4666  }
4667  else {
4668  n = NUM2LONG(nv);
4669  if (n <= 0) return Qnil;
4670  }
4671 
4672  while (RARRAY_LEN(ary) > 0 && (n < 0 || 0 < n--)) {
4673  for (i=0; i<RARRAY_LEN(ary); i++) {
4674  rb_yield(RARRAY_AREF(ary, i));
4675  }
4676  }
4677  return Qnil;
4678 }
4679 
4680 #define tmpbuf(n, size) rb_str_tmp_new((n)*(size))
4681 #define tmpbuf_discard(s) (rb_str_resize((s), 0L), RBASIC_SET_CLASS_RAW(s, rb_cString))
4682 #define tmpary(n) rb_ary_tmp_new(n)
4683 #define tmpary_discard(a) (ary_discard(a), RBASIC_SET_CLASS_RAW(a, rb_cArray))
4684 
4685 /*
4686  * Build a ruby array of the corresponding values and yield it to the
4687  * associated block.
4688  * Return the class of +values+ for reentry check.
4689  */
4690 static int
4691 yield_indexed_values(const VALUE values, const long r, const long *const p)
4692 {
4693  const VALUE result = rb_ary_new2(r);
4694  VALUE *const result_array = RARRAY_PTR(result);
4695  const VALUE *const values_array = RARRAY_CONST_PTR(values);
4696  long i;
4697 
4698  for (i = 0; i < r; i++) result_array[i] = values_array[p[i]];
4699  ARY_SET_LEN(result, r);
4700  rb_yield(result);
4701  return !RBASIC(values)->klass;
4702 }
4703 
4704 /*
4705  * Recursively compute permutations of +r+ elements of the set
4706  * <code>[0..n-1]</code>.
4707  *
4708  * When we have a complete permutation of array indexes, copy the values
4709  * at those indexes into a new array and yield that array.
4710  *
4711  * n: the size of the set
4712  * r: the number of elements in each permutation
4713  * p: the array (of size r) that we're filling in
4714  * index: what index we're filling in now
4715  * used: an array of booleans: whether a given index is already used
4716  * values: the Ruby array that holds the actual values to permute
4717  */
4718 static void
4719 permute0(long n, long r, long *p, long index, char *used, VALUE values)
4720 {
4721  long i;
4722  for (i = 0; i < n; i++) {
4723  if (used[i] == 0) {
4724  p[index] = i;
4725  if (index < r-1) { /* if not done yet */
4726  used[i] = 1; /* mark index used */
4727  permute0(n, r, p, index+1, /* recurse */
4728  used, values);
4729  used[i] = 0; /* index unused */
4730  }
4731  else {
4732  if (!yield_indexed_values(values, r, p)) {
4733  rb_raise(rb_eRuntimeError, "permute reentered");
4734  }
4735  }
4736  }
4737  }
4738 }
4739 
4740 /*
4741  * Returns the product of from, from-1, ..., from - how_many + 1.
4742  * http://en.wikipedia.org/wiki/Pochhammer_symbol
4743  */
4744 static VALUE
4745 descending_factorial(long from, long how_many)
4746 {
4747  VALUE cnt = LONG2FIX(how_many >= 0);
4748  while (how_many-- > 0) {
4749  VALUE v = LONG2FIX(from--);
4750  cnt = rb_funcallv(cnt, '*', 1, &v);
4751  }
4752  return cnt;
4753 }
4754 
4755 static VALUE
4756 binomial_coefficient(long comb, long size)
4757 {
4758  VALUE r, v;
4759  if (comb > size-comb) {
4760  comb = size-comb;
4761  }
4762  if (comb < 0) {
4763  return LONG2FIX(0);
4764  }
4765  r = descending_factorial(size, comb);
4766  v = descending_factorial(comb, comb);
4767  return rb_funcallv(r, id_div, 1, &v);
4768 }
4769 
4770 static VALUE
4772 {
4773  long n = RARRAY_LEN(ary);
4774  long k = (args && (RARRAY_LEN(args) > 0)) ? NUM2LONG(RARRAY_AREF(args, 0)) : n;
4775 
4776  return descending_factorial(n, k);
4777 }
4778 
4779 /*
4780  * call-seq:
4781  * ary.permutation { |p| block } -> ary
4782  * ary.permutation -> Enumerator
4783  * ary.permutation(n) { |p| block } -> ary
4784  * ary.permutation(n) -> Enumerator
4785  *
4786  * When invoked with a block, yield all permutations of length +n+ of the
4787  * elements of the array, then return the array itself.
4788  *
4789  * If +n+ is not specified, yield all permutations of all elements.
4790  *
4791  * The implementation makes no guarantees about the order in which the
4792  * permutations are yielded.
4793  *
4794  * If no block is given, an Enumerator is returned instead.
4795  *
4796  * Examples:
4797  *
4798  * a = [1, 2, 3]
4799  * a.permutation.to_a #=> [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
4800  * a.permutation(1).to_a #=> [[1],[2],[3]]
4801  * a.permutation(2).to_a #=> [[1,2],[1,3],[2,1],[2,3],[3,1],[3,2]]
4802  * a.permutation(3).to_a #=> [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
4803  * a.permutation(0).to_a #=> [[]] # one permutation of length 0
4804  * a.permutation(4).to_a #=> [] # no permutations of length 4
4805  */
4806 
4807 static VALUE
4809 {
4810  VALUE num;
4811  long r, n, i;
4812 
4813  n = RARRAY_LEN(ary); /* Array length */
4814  RETURN_SIZED_ENUMERATOR(ary, argc, argv, rb_ary_permutation_size); /* Return enumerator if no block */
4815  rb_scan_args(argc, argv, "01", &num);
4816  r = NIL_P(num) ? n : NUM2LONG(num); /* Permutation size from argument */
4817 
4818  if (r < 0 || n < r) {
4819  /* no permutations: yield nothing */
4820  }
4821  else if (r == 0) { /* exactly one permutation: the zero-length array */
4822  rb_yield(rb_ary_new2(0));
4823  }
4824  else if (r == 1) { /* this is a special, easy case */
4825  for (i = 0; i < RARRAY_LEN(ary); i++) {
4826  rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
4827  }
4828  }
4829  else { /* this is the general case */
4830  volatile VALUE t0 = tmpbuf(r,sizeof(long));
4831  long *p = (long*)RSTRING_PTR(t0);
4832  volatile VALUE t1 = tmpbuf(n,sizeof(char));
4833  char *used = (char*)RSTRING_PTR(t1);
4834  VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
4835  RBASIC_CLEAR_CLASS(ary0);
4836 
4837  MEMZERO(used, char, n); /* initialize array */
4838 
4839  permute0(n, r, p, 0, used, ary0); /* compute and yield permutations */
4840  tmpbuf_discard(t0);
4841  tmpbuf_discard(t1);
4843  }
4844  return ary;
4845 }
4846 
4847 static VALUE
4849 {
4850  long n = RARRAY_LEN(ary);
4851  long k = NUM2LONG(RARRAY_AREF(args, 0));
4852 
4853  return binomial_coefficient(k, n);
4854 }
4855 
4856 /*
4857  * call-seq:
4858  * ary.combination(n) { |c| block } -> ary
4859  * ary.combination(n) -> Enumerator
4860  *
4861  * When invoked with a block, yields all combinations of length +n+ of elements
4862  * from the array and then returns the array itself.
4863  *
4864  * The implementation makes no guarantees about the order in which the
4865  * combinations are yielded.
4866  *
4867  * If no block is given, an Enumerator is returned instead.
4868  *
4869  * Examples:
4870  *
4871  * a = [1, 2, 3, 4]
4872  * a.combination(1).to_a #=> [[1],[2],[3],[4]]
4873  * a.combination(2).to_a #=> [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]
4874  * a.combination(3).to_a #=> [[1,2,3],[1,2,4],[1,3,4],[2,3,4]]
4875  * a.combination(4).to_a #=> [[1,2,3,4]]
4876  * a.combination(0).to_a #=> [[]] # one combination of length 0
4877  * a.combination(5).to_a #=> [] # no combinations of length 5
4878  *
4879  */
4880 
4881 static VALUE
4883 {
4884  long n, i, len;
4885 
4886  n = NUM2LONG(num);
4888  len = RARRAY_LEN(ary);
4889  if (n < 0 || len < n) {
4890  /* yield nothing */
4891  }
4892  else if (n == 0) {
4893  rb_yield(rb_ary_new2(0));
4894  }
4895  else if (n == 1) {
4896  for (i = 0; i < len; i++) {
4897  rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
4898  }
4899  }
4900  else {
4901  VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
4902  volatile VALUE t0;
4903  long *stack = ALLOCV_N(long, t0, n+1);
4904  long lev = 0;
4905 
4906  RBASIC_CLEAR_CLASS(ary0);
4907  MEMZERO(stack+1, long, n);
4908  stack[0] = -1;
4909  for (;;) {
4910  for (lev++; lev < n; lev++) {
4911  stack[lev+1] = stack[lev]+1;
4912  }
4913  if (!yield_indexed_values(ary0, n, stack+1)) {
4914  rb_raise(rb_eRuntimeError, "combination reentered");
4915  }
4916  do {
4917  if (lev == 0) goto done;
4918  stack[lev--]++;
4919  } while (stack[lev+1]+n == len+lev+1);
4920  }
4921  done:
4922  ALLOCV_END(t0);
4924  }
4925  return ary;
4926 }
4927 
4928 /*
4929  * Recursively compute repeated permutations of +r+ elements of the set
4930  * <code>[0..n-1]</code>.
4931  *
4932  * When we have a complete repeated permutation of array indexes, copy the
4933  * values at those indexes into a new array and yield that array.
4934  *
4935  * n: the size of the set
4936  * r: the number of elements in each permutation
4937  * p: the array (of size r) that we're filling in
4938  * index: what index we're filling in now
4939  * values: the Ruby array that holds the actual values to permute
4940  */
4941 static void
4942 rpermute0(long n, long r, long *p, long index, VALUE values)
4943 {
4944  long i;
4945  for (i = 0; i < n; i++) {
4946  p[index] = i;
4947  if (index < r-1) { /* if not done yet */
4948  rpermute0(n, r, p, index+1, values); /* recurse */
4949  }
4950  else {
4951  if (!yield_indexed_values(values, r, p)) {
4952  rb_raise(rb_eRuntimeError, "repeated permute reentered");
4953  }
4954  }
4955  }
4956 }
4957 
4958 static VALUE
4960 {
4961  long n = RARRAY_LEN(ary);
4962  long k = NUM2LONG(RARRAY_AREF(args, 0));
4963  VALUE v;
4964 
4965  if (k < 0) {
4966  return LONG2FIX(0);
4967  }
4968 
4969  v = LONG2NUM(k);
4970  return rb_funcallv(LONG2NUM(n), id_power, 1, &v);
4971 }
4972 
4973 /*
4974  * call-seq:
4975  * ary.repeated_permutation(n) { |p| block } -> ary
4976  * ary.repeated_permutation(n) -> Enumerator
4977  *
4978  * When invoked with a block, yield all repeated permutations of length +n+ of
4979  * the elements of the array, then return the array itself.
4980  *
4981  * The implementation makes no guarantees about the order in which the repeated
4982  * permutations are yielded.
4983  *
4984  * If no block is given, an Enumerator is returned instead.
4985  *
4986  * Examples:
4987  *
4988  * a = [1, 2]
4989  * a.repeated_permutation(1).to_a #=> [[1], [2]]
4990  * a.repeated_permutation(2).to_a #=> [[1,1],[1,2],[2,1],[2,2]]
4991  * a.repeated_permutation(3).to_a #=> [[1,1,1],[1,1,2],[1,2,1],[1,2,2],
4992  * # [2,1,1],[2,1,2],[2,2,1],[2,2,2]]
4993  * a.repeated_permutation(0).to_a #=> [[]] # one permutation of length 0
4994  */
4995 
4996 static VALUE
4998 {
4999  long r, n, i;
5000 
5001  n = RARRAY_LEN(ary); /* Array length */
5002  RETURN_SIZED_ENUMERATOR(ary, 1, &num, rb_ary_repeated_permutation_size); /* Return Enumerator if no block */
5003  r = NUM2LONG(num); /* Permutation size from argument */
5004 
5005  if (r < 0) {
5006  /* no permutations: yield nothing */
5007  }
5008  else if (r == 0) { /* exactly one permutation: the zero-length array */
5009  rb_yield(rb_ary_new2(0));
5010  }
5011  else if (r == 1) { /* this is a special, easy case */
5012  for (i = 0; i < RARRAY_LEN(ary); i++) {
5013  rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
5014  }
5015  }
5016  else { /* this is the general case */
5017  volatile VALUE t0 = tmpbuf(r, sizeof(long));
5018  long *p = (long*)RSTRING_PTR(t0);
5019  VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
5020  RBASIC_CLEAR_CLASS(ary0);
5021 
5022  rpermute0(n, r, p, 0, ary0); /* compute and yield repeated permutations */
5023  tmpbuf_discard(t0);
5025  }
5026  return ary;
5027 }
5028 
5029 static void
5030 rcombinate0(long n, long r, long *p, long index, long rest, VALUE values)
5031 {
5032  if (rest > 0) {
5033  for (; index < n; ++index) {
5034  p[r-rest] = index;
5035  rcombinate0(n, r, p, index, rest-1, values);
5036  }
5037  }
5038  else {
5039  if (!yield_indexed_values(values, r, p)) {
5040  rb_raise(rb_eRuntimeError, "repeated combination reentered");
5041  }
5042  }
5043 }
5044 
5045 static VALUE
5047 {
5048  long n = RARRAY_LEN(ary);
5049  long k = NUM2LONG(RARRAY_AREF(args, 0));
5050  if (k == 0) {
5051  return LONG2FIX(1);
5052  }
5053  return binomial_coefficient(k, n + k - 1);
5054 }
5055 
5056 /*
5057  * call-seq:
5058  * ary.repeated_combination(n) { |c| block } -> ary
5059  * ary.repeated_combination(n) -> Enumerator
5060  *
5061  * When invoked with a block, yields all repeated combinations of length +n+ of
5062  * elements from the array and then returns the array itself.
5063  *
5064  * The implementation makes no guarantees about the order in which the repeated
5065  * combinations are yielded.
5066  *
5067  * If no block is given, an Enumerator is returned instead.
5068  *
5069  * Examples:
5070  *
5071  * a = [1, 2, 3]
5072  * a.repeated_combination(1).to_a #=> [[1], [2], [3]]
5073  * a.repeated_combination(2).to_a #=> [[1,1],[1,2],[1,3],[2,2],[2,3],[3,3]]
5074  * a.repeated_combination(3).to_a #=> [[1,1,1],[1,1,2],[1,1,3],[1,2,2],[1,2,3],
5075  * # [1,3,3],[2,2,2],[2,2,3],[2,3,3],[3,3,3]]
5076  * 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],
5077  * # [1,1,3,3],[1,2,2,2],[1,2,2,3],[1,2,3,3],[1,3,3,3],
5078  * # [2,2,2,2],[2,2,2,3],[2,2,3,3],[2,3,3,3],[3,3,3,3]]
5079  * a.repeated_combination(0).to_a #=> [[]] # one combination of length 0
5080  *
5081  */
5082 
5083 static VALUE
5085 {
5086  long n, i, len;
5087 
5088  n = NUM2LONG(num); /* Combination size from argument */
5089  RETURN_SIZED_ENUMERATOR(ary, 1, &num, rb_ary_repeated_combination_size); /* Return enumerator if no block */
5090  len = RARRAY_LEN(ary);
5091  if (n < 0) {
5092  /* yield nothing */
5093  }
5094  else if (n == 0) {
5095  rb_yield(rb_ary_new2(0));
5096  }
5097  else if (n == 1) {
5098  for (i = 0; i < len; i++) {
5099  rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
5100  }
5101  }
5102  else if (len == 0) {
5103  /* yield nothing */
5104  }
5105  else {
5106  volatile VALUE t0 = tmpbuf(n, sizeof(long));
5107  long *p = (long*)RSTRING_PTR(t0);
5108  VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
5109  RBASIC_CLEAR_CLASS(ary0);
5110 
5111  rcombinate0(len, n, p, 0, n, ary0); /* compute and yield repeated combinations */
5112  tmpbuf_discard(t0);
5114  }
5115  return ary;
5116 }
5117 
5118 /*
5119  * call-seq:
5120  * ary.product(other_ary, ...) -> new_ary
5121  * ary.product(other_ary, ...) { |p| block } -> ary
5122  *
5123  * Returns an array of all combinations of elements from all arrays.
5124  *
5125  * The length of the returned array is the product of the length of +self+ and
5126  * the argument arrays.
5127  *
5128  * If given a block, #product will yield all combinations and return +self+
5129  * instead.
5130  *
5131  * [1,2,3].product([4,5]) #=> [[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]]
5132  * [1,2].product([1,2]) #=> [[1,1],[1,2],[2,1],[2,2]]
5133  * [1,2].product([3,4],[5,6]) #=> [[1,3,5],[1,3,6],[1,4,5],[1,4,6],
5134  * # [2,3,5],[2,3,6],[2,4,5],[2,4,6]]
5135  * [1,2].product() #=> [[1],[2]]
5136  * [1,2].product([]) #=> []
5137  */
5138 
5139 static VALUE
5140 rb_ary_product(int argc, VALUE *argv, VALUE ary)
5141 {
5142  int n = argc+1; /* How many arrays we're operating on */
5143  volatile VALUE t0 = tmpary(n);
5144  volatile VALUE t1 = tmpbuf(n, sizeof(int));
5145  VALUE *arrays = RARRAY_PTR(t0); /* The arrays we're computing the product of */
5146  int *counters = (int*)RSTRING_PTR(t1); /* The current position in each one */
5147  VALUE result = Qnil; /* The array we'll be returning, when no block given */
5148  long i,j;
5149  long resultlen = 1;
5150 
5151  RBASIC_CLEAR_CLASS(t0);
5152  RBASIC_CLEAR_CLASS(t1);
5153 
5154  /* initialize the arrays of arrays */
5155  ARY_SET_LEN(t0, n);
5156  arrays[0] = ary;
5157  for (i = 1; i < n; i++) arrays[i] = Qnil;
5158  for (i = 1; i < n; i++) arrays[i] = to_ary(argv[i-1]);
5159 
5160  /* initialize the counters for the arrays */
5161  for (i = 0; i < n; i++) counters[i] = 0;
5162 
5163  /* Otherwise, allocate and fill in an array of results */
5164  if (rb_block_given_p()) {
5165  /* Make defensive copies of arrays; exit if any is empty */
5166  for (i = 0; i < n; i++) {
5167  if (RARRAY_LEN(arrays[i]) == 0) goto done;
5168  arrays[i] = ary_make_shared_copy(arrays[i]);
5169  }
5170  }
5171  else {
5172  /* Compute the length of the result array; return [] if any is empty */
5173  for (i = 0; i < n; i++) {
5174  long k = RARRAY_LEN(arrays[i]);
5175  if (k == 0) {
5176  result = rb_ary_new2(0);
5177  goto done;
5178  }
5179  if (MUL_OVERFLOW_LONG_P(resultlen, k))
5180  rb_raise(rb_eRangeError, "too big to product");
5181  resultlen *= k;
5182  }
5183  result = rb_ary_new2(resultlen);
5184  }
5185  for (;;) {
5186  int m;
5187  /* fill in one subarray */
5188  VALUE subarray = rb_ary_new2(n);
5189  for (j = 0; j < n; j++) {
5190  rb_ary_push(subarray, rb_ary_entry(arrays[j], counters[j]));
5191  }
5192 
5193  /* put it on the result array */
5194  if (NIL_P(result)) {
5195  FL_SET(t0, FL_USER5);
5196  rb_yield(subarray);
5197  if (! FL_TEST(t0, FL_USER5)) {
5198  rb_raise(rb_eRuntimeError, "product reentered");
5199  }
5200  else {
5201  FL_UNSET(t0, FL_USER5);
5202  }
5203  }
5204  else {
5205  rb_ary_push(result, subarray);
5206  }
5207 
5208  /*
5209  * Increment the last counter. If it overflows, reset to 0
5210  * and increment the one before it.
5211  */
5212  m = n-1;
5213  counters[m]++;
5214  while (counters[m] == RARRAY_LEN(arrays[m])) {
5215  counters[m] = 0;
5216  /* If the first counter overflows, we are done */
5217  if (--m < 0) goto done;
5218  counters[m]++;
5219  }
5220  }
5221 done:
5222  tmpary_discard(t0);
5223  tmpbuf_discard(t1);
5224 
5225  return NIL_P(result) ? ary : result;
5226 }
5227 
5228 /*
5229  * call-seq:
5230  * ary.take(n) -> new_ary
5231  *
5232  * Returns first +n+ elements from the array.
5233  *
5234  * If a negative number is given, raises an ArgumentError.
5235  *
5236  * See also Array#drop
5237  *
5238  * a = [1, 2, 3, 4, 5, 0]
5239  * a.take(3) #=> [1, 2, 3]
5240  *
5241  */
5242 
5243 static VALUE
5245 {
5246  long len = NUM2LONG(n);
5247  if (len < 0) {
5248  rb_raise(rb_eArgError, "attempt to take negative size");
5249  }
5250  return rb_ary_subseq(obj, 0, len);
5251 }
5252 
5253 /*
5254  * call-seq:
5255  * ary.take_while { |arr| block } -> new_ary
5256  * ary.take_while -> Enumerator
5257  *
5258  * Passes elements to the block until the block returns +nil+ or +false+, then
5259  * stops iterating and returns an array of all prior elements.
5260  *
5261  * If no block is given, an Enumerator is returned instead.
5262  *
5263  * See also Array#drop_while
5264  *
5265  * a = [1, 2, 3, 4, 5, 0]
5266  * a.take_while { |i| i < 3 } #=> [1, 2]
5267  *
5268  */
5269 
5270 static VALUE
5272 {
5273  long i;
5274 
5275  RETURN_ENUMERATOR(ary, 0, 0);
5276  for (i = 0; i < RARRAY_LEN(ary); i++) {
5277  if (!RTEST(rb_yield(RARRAY_AREF(ary, i)))) break;
5278  }
5279  return rb_ary_take(ary, LONG2FIX(i));
5280 }
5281 
5282 /*
5283  * call-seq:
5284  * ary.drop(n) -> new_ary
5285  *
5286  * Drops first +n+ elements from +ary+ and returns the rest of the elements in
5287  * an array.
5288  *
5289  * If a negative number is given, raises an ArgumentError.
5290  *
5291  * See also Array#take
5292  *
5293  * a = [1, 2, 3, 4, 5, 0]
5294  * a.drop(3) #=> [4, 5, 0]
5295  *
5296  */
5297 
5298 static VALUE
5300 {
5301  VALUE result;
5302  long pos = NUM2LONG(n);
5303  if (pos < 0) {
5304  rb_raise(rb_eArgError, "attempt to drop negative size");
5305  }
5306 
5307  result = rb_ary_subseq(ary, pos, RARRAY_LEN(ary));
5308  if (result == Qnil) result = rb_ary_new();
5309  return result;
5310 }
5311 
5312 /*
5313  * call-seq:
5314  * ary.drop_while { |arr| block } -> new_ary
5315  * ary.drop_while -> Enumerator
5316  *
5317  * Drops elements up to, but not including, the first element for which the
5318  * block returns +nil+ or +false+ and returns an array containing the
5319  * remaining elements.
5320  *
5321  * If no block is given, an Enumerator is returned instead.
5322  *
5323  * See also Array#take_while
5324  *
5325  * a = [1, 2, 3, 4, 5, 0]
5326  * a.drop_while {|i| i < 3 } #=> [3, 4, 5, 0]
5327  *
5328  */
5329 
5330 static VALUE
5332 {
5333  long i;
5334 
5335  RETURN_ENUMERATOR(ary, 0, 0);
5336  for (i = 0; i < RARRAY_LEN(ary); i++) {
5337  if (!RTEST(rb_yield(RARRAY_AREF(ary, i)))) break;
5338  }
5339  return rb_ary_drop(ary, LONG2FIX(i));
5340 }
5341 
5342 /*
5343  * Arrays are ordered, integer-indexed collections of any object.
5344  *
5345  * Array indexing starts at 0, as in C or Java. A negative index is assumed
5346  * to be relative to the end of the array---that is, an index of -1 indicates
5347  * the last element of the array, -2 is the next to last element in the
5348  * array, and so on.
5349  *
5350  * == Creating Arrays
5351  *
5352  * A new array can be created by using the literal constructor
5353  * <code>[]</code>. Arrays can contain different types of objects. For
5354  * example, the array below contains an Integer, a String and a Float:
5355  *
5356  * ary = [1, "two", 3.0] #=> [1, "two", 3.0]
5357  *
5358  * An array can also be created by explicitly calling Array.new with zero, one
5359  * (the initial size of the Array) or two arguments (the initial size and a
5360  * default object).
5361  *
5362  * ary = Array.new #=> []
5363  * Array.new(3) #=> [nil, nil, nil]
5364  * Array.new(3, true) #=> [true, true, true]
5365  *
5366  * Note that the second argument populates the array with references to the
5367  * same object. Therefore, it is only recommended in cases when you need to
5368  * instantiate arrays with natively immutable objects such as Symbols,
5369  * numbers, true or false.
5370  *
5371  * To create an array with separate objects a block can be passed instead.
5372  * This method is safe to use with mutable objects such as hashes, strings or
5373  * other arrays:
5374  *
5375  * Array.new(4) { Hash.new } #=> [{}, {}, {}, {}]
5376  *
5377  * This is also a quick way to build up multi-dimensional arrays:
5378  *
5379  * empty_table = Array.new(3) { Array.new(3) }
5380  * #=> [[nil, nil, nil], [nil, nil, nil], [nil, nil, nil]]
5381  *
5382  * An array can also be created by using the Array() method, provided by
5383  * Kernel, which tries to call #to_ary, then #to_a on its argument.
5384  *
5385  * Array({:a => "a", :b => "b"}) #=> [[:a, "a"], [:b, "b"]]
5386  *
5387  * == Example Usage
5388  *
5389  * In addition to the methods it mixes in through the Enumerable module, the
5390  * Array class has proprietary methods for accessing, searching and otherwise
5391  * manipulating arrays.
5392  *
5393  * Some of the more common ones are illustrated below.
5394  *
5395  * == Accessing Elements
5396  *
5397  * Elements in an array can be retrieved using the Array#[] method. It can
5398  * take a single integer argument (a numeric index), a pair of arguments
5399  * (start and length) or a range. Negative indices start counting from the end,
5400  * with -1 being the last element.
5401  *
5402  * arr = [1, 2, 3, 4, 5, 6]
5403  * arr[2] #=> 3
5404  * arr[100] #=> nil
5405  * arr[-3] #=> 4
5406  * arr[2, 3] #=> [3, 4, 5]
5407  * arr[1..4] #=> [2, 3, 4, 5]
5408  * arr[1..-3] #=> [2, 3, 4]
5409  *
5410  * Another way to access a particular array element is by using the #at method
5411  *
5412  * arr.at(0) #=> 1
5413  *
5414  * The #slice method works in an identical manner to Array#[].
5415  *
5416  * To raise an error for indices outside of the array bounds or else to
5417  * provide a default value when that happens, you can use #fetch.
5418  *
5419  * arr = ['a', 'b', 'c', 'd', 'e', 'f']
5420  * arr.fetch(100) #=> IndexError: index 100 outside of array bounds: -6...6
5421  * arr.fetch(100, "oops") #=> "oops"
5422  *
5423  * The special methods #first and #last will return the first and last
5424  * elements of an array, respectively.
5425  *
5426  * arr.first #=> 1
5427  * arr.last #=> 6
5428  *
5429  * To return the first +n+ elements of an array, use #take
5430  *
5431  * arr.take(3) #=> [1, 2, 3]
5432  *
5433  * #drop does the opposite of #take, by returning the elements after +n+
5434  * elements have been dropped:
5435  *
5436  * arr.drop(3) #=> [4, 5, 6]
5437  *
5438  * == Obtaining Information about an Array
5439  *
5440  * Arrays keep track of their own length at all times. To query an array
5441  * about the number of elements it contains, use #length, #count or #size.
5442  *
5443  * browsers = ['Chrome', 'Firefox', 'Safari', 'Opera', 'IE']
5444  * browsers.length #=> 5
5445  * browsers.count #=> 5
5446  *
5447  * To check whether an array contains any elements at all
5448  *
5449  * browsers.empty? #=> false
5450  *
5451  * To check whether a particular item is included in the array
5452  *
5453  * browsers.include?('Konqueror') #=> false
5454  *
5455  * == Adding Items to Arrays
5456  *
5457  * Items can be added to the end of an array by using either #push or #<<
5458  *
5459  * arr = [1, 2, 3, 4]
5460  * arr.push(5) #=> [1, 2, 3, 4, 5]
5461  * arr << 6 #=> [1, 2, 3, 4, 5, 6]
5462  *
5463  * #unshift will add a new item to the beginning of an array.
5464  *
5465  * arr.unshift(0) #=> [0, 1, 2, 3, 4, 5, 6]
5466  *
5467  * With #insert you can add a new element to an array at any position.
5468  *
5469  * arr.insert(3, 'apple') #=> [0, 1, 2, 'apple', 3, 4, 5, 6]
5470  *
5471  * Using the #insert method, you can also insert multiple values at once:
5472  *
5473  * arr.insert(3, 'orange', 'pear', 'grapefruit')
5474  * #=> [0, 1, 2, "orange", "pear", "grapefruit", "apple", 3, 4, 5, 6]
5475  *
5476  * == Removing Items from an Array
5477  *
5478  * The method #pop removes the last element in an array and returns it:
5479  *
5480  * arr = [1, 2, 3, 4, 5, 6]
5481  * arr.pop #=> 6
5482  * arr #=> [1, 2, 3, 4, 5]
5483  *
5484  * To retrieve and at the same time remove the first item, use #shift:
5485  *
5486  * arr.shift #=> 1
5487  * arr #=> [2, 3, 4, 5]
5488  *
5489  * To delete an element at a particular index:
5490  *
5491  * arr.delete_at(2) #=> 4
5492  * arr #=> [2, 3, 5]
5493  *
5494  * To delete a particular element anywhere in an array, use #delete:
5495  *
5496  * arr = [1, 2, 2, 3]
5497  * arr.delete(2) #=> 2
5498  * arr #=> [1,3]
5499  *
5500  * A useful method if you need to remove +nil+ values from an array is
5501  * #compact:
5502  *
5503  * arr = ['foo', 0, nil, 'bar', 7, 'baz', nil]
5504  * arr.compact #=> ['foo', 0, 'bar', 7, 'baz']
5505  * arr #=> ['foo', 0, nil, 'bar', 7, 'baz', nil]
5506  * arr.compact! #=> ['foo', 0, 'bar', 7, 'baz']
5507  * arr #=> ['foo', 0, 'bar', 7, 'baz']
5508  *
5509  * Another common need is to remove duplicate elements from an array.
5510  *
5511  * It has the non-destructive #uniq, and destructive method #uniq!
5512  *
5513  * arr = [2, 5, 6, 556, 6, 6, 8, 9, 0, 123, 556]
5514  * arr.uniq #=> [2, 5, 6, 556, 8, 9, 0, 123]
5515  *
5516  * == Iterating over Arrays
5517  *
5518  * Like all classes that include the Enumerable module, Array has an each
5519  * method, which defines what elements should be iterated over and how. In
5520  * case of Array's #each, all elements in the Array instance are yielded to
5521  * the supplied block in sequence.
5522  *
5523  * Note that this operation leaves the array unchanged.
5524  *
5525  * arr = [1, 2, 3, 4, 5]
5526  * arr.each { |a| print a -= 10, " " }
5527  * # prints: -9 -8 -7 -6 -5
5528  * #=> [1, 2, 3, 4, 5]
5529  *
5530  * Another sometimes useful iterator is #reverse_each which will iterate over
5531  * the elements in the array in reverse order.
5532  *
5533  * words = %w[first second third fourth fifth sixth]
5534  * str = ""
5535  * words.reverse_each { |word| str += "#{word} " }
5536  * p str #=> "sixth fifth fourth third second first "
5537  *
5538  * The #map method can be used to create a new array based on the original
5539  * array, but with the values modified by the supplied block:
5540  *
5541  * arr.map { |a| 2*a } #=> [2, 4, 6, 8, 10]
5542  * arr #=> [1, 2, 3, 4, 5]
5543  * arr.map! { |a| a**2 } #=> [1, 4, 9, 16, 25]
5544  * arr #=> [1, 4, 9, 16, 25]
5545  *
5546  * == Selecting Items from an Array
5547  *
5548  * Elements can be selected from an array according to criteria defined in a
5549  * block. The selection can happen in a destructive or a non-destructive
5550  * manner. While the destructive operations will modify the array they were
5551  * called on, the non-destructive methods usually return a new array with the
5552  * selected elements, but leave the original array unchanged.
5553  *
5554  * === Non-destructive Selection
5555  *
5556  * arr = [1, 2, 3, 4, 5, 6]
5557  * arr.select { |a| a > 3 } #=> [4, 5, 6]
5558  * arr.reject { |a| a < 3 } #=> [3, 4, 5, 6]
5559  * arr.drop_while { |a| a < 4 } #=> [4, 5, 6]
5560  * arr #=> [1, 2, 3, 4, 5, 6]
5561  *
5562  * === Destructive Selection
5563  *
5564  * #select! and #reject! are the corresponding destructive methods to #select
5565  * and #reject
5566  *
5567  * Similar to #select vs. #reject, #delete_if and #keep_if have the exact
5568  * opposite result when supplied with the same block:
5569  *
5570  * arr.delete_if { |a| a < 4 } #=> [4, 5, 6]
5571  * arr #=> [4, 5, 6]
5572  *
5573  * arr = [1, 2, 3, 4, 5, 6]
5574  * arr.keep_if { |a| a < 4 } #=> [1, 2, 3]
5575  * arr #=> [1, 2, 3]
5576  *
5577  */
5578 
5579 void
5581 {
5582 #undef rb_intern
5583 #define rb_intern(str) rb_intern_const(str)
5584 
5585  rb_cArray = rb_define_class("Array", rb_cObject);
5587 
5591  rb_define_method(rb_cArray, "initialize", rb_ary_initialize, -1);
5592  rb_define_method(rb_cArray, "initialize_copy", rb_ary_replace, 1);
5593 
5594  rb_define_method(rb_cArray, "inspect", rb_ary_inspect, 0);
5595  rb_define_alias(rb_cArray, "to_s", "inspect");
5596  rb_define_method(rb_cArray, "to_a", rb_ary_to_a, 0);
5597  rb_define_method(rb_cArray, "to_h", rb_ary_to_h, 0);
5599  rb_define_method(rb_cArray, "frozen?", rb_ary_frozen_p, 0);
5600 
5602  rb_define_method(rb_cArray, "eql?", rb_ary_eql, 1);
5603  rb_define_method(rb_cArray, "hash", rb_ary_hash, 0);
5604 
5606  rb_define_method(rb_cArray, "[]=", rb_ary_aset, -1);
5608  rb_define_method(rb_cArray, "fetch", rb_ary_fetch, -1);
5609  rb_define_method(rb_cArray, "first", rb_ary_first, -1);
5610  rb_define_method(rb_cArray, "last", rb_ary_last, -1);
5611  rb_define_method(rb_cArray, "concat", rb_ary_concat, 1);
5615  rb_define_method(rb_cArray, "shift", rb_ary_shift_m, -1);
5616  rb_define_method(rb_cArray, "unshift", rb_ary_unshift_m, -1);
5617  rb_define_method(rb_cArray, "insert", rb_ary_insert, -1);
5618  rb_define_method(rb_cArray, "each", rb_ary_each, 0);
5619  rb_define_method(rb_cArray, "each_index", rb_ary_each_index, 0);
5620  rb_define_method(rb_cArray, "reverse_each", rb_ary_reverse_each, 0);
5621  rb_define_method(rb_cArray, "length", rb_ary_length, 0);
5622  rb_define_alias(rb_cArray, "size", "length");
5623  rb_define_method(rb_cArray, "empty?", rb_ary_empty_p, 0);
5624  rb_define_method(rb_cArray, "find_index", rb_ary_index, -1);
5625  rb_define_method(rb_cArray, "index", rb_ary_index, -1);
5626  rb_define_method(rb_cArray, "rindex", rb_ary_rindex, -1);
5630  rb_define_method(rb_cArray, "rotate", rb_ary_rotate_m, -1);
5632  rb_define_method(rb_cArray, "sort", rb_ary_sort, 0);
5635  rb_define_method(rb_cArray, "collect", rb_ary_collect, 0);
5639  rb_define_method(rb_cArray, "select", rb_ary_select, 0);
5641  rb_define_method(rb_cArray, "keep_if", rb_ary_keep_if, 0);
5642  rb_define_method(rb_cArray, "values_at", rb_ary_values_at, -1);
5643  rb_define_method(rb_cArray, "delete", rb_ary_delete, 1);
5644  rb_define_method(rb_cArray, "delete_at", rb_ary_delete_at_m, 1);
5645  rb_define_method(rb_cArray, "delete_if", rb_ary_delete_if, 0);
5646  rb_define_method(rb_cArray, "reject", rb_ary_reject, 0);
5648  rb_define_method(rb_cArray, "zip", rb_ary_zip, -1);
5649  rb_define_method(rb_cArray, "transpose", rb_ary_transpose, 0);
5650  rb_define_method(rb_cArray, "replace", rb_ary_replace, 1);
5651  rb_define_method(rb_cArray, "clear", rb_ary_clear, 0);
5652  rb_define_method(rb_cArray, "fill", rb_ary_fill, -1);
5653  rb_define_method(rb_cArray, "include?", rb_ary_includes, 1);
5655 
5656  rb_define_method(rb_cArray, "slice", rb_ary_aref, -1);
5658 
5659  rb_define_method(rb_cArray, "assoc", rb_ary_assoc, 1);
5660  rb_define_method(rb_cArray, "rassoc", rb_ary_rassoc, 1);
5661 
5664 
5668 
5669  rb_define_method(rb_cArray, "uniq", rb_ary_uniq, 0);
5671  rb_define_method(rb_cArray, "compact", rb_ary_compact, 0);
5673  rb_define_method(rb_cArray, "flatten", rb_ary_flatten, -1);
5675  rb_define_method(rb_cArray, "count", rb_ary_count, -1);
5677  rb_define_method(rb_cArray, "shuffle", rb_ary_shuffle, -1);
5678  rb_define_method(rb_cArray, "sample", rb_ary_sample, -1);
5679  rb_define_method(rb_cArray, "cycle", rb_ary_cycle, -1);
5680  rb_define_method(rb_cArray, "permutation", rb_ary_permutation, -1);
5681  rb_define_method(rb_cArray, "combination", rb_ary_combination, 1);
5682  rb_define_method(rb_cArray, "repeated_permutation", rb_ary_repeated_permutation, 1);
5683  rb_define_method(rb_cArray, "repeated_combination", rb_ary_repeated_combination, 1);
5684  rb_define_method(rb_cArray, "product", rb_ary_product, -1);
5685 
5686  rb_define_method(rb_cArray, "take", rb_ary_take, 1);
5687  rb_define_method(rb_cArray, "take_while", rb_ary_take_while, 0);
5688  rb_define_method(rb_cArray, "drop", rb_ary_drop, 1);
5689  rb_define_method(rb_cArray, "drop_while", rb_ary_drop_while, 0);
5690  rb_define_method(rb_cArray, "bsearch", rb_ary_bsearch, 0);
5691 
5692  id_cmp = rb_intern("<=>");
5693  id_random = rb_intern("random");
5694  id_div = rb_intern("div");
5695  id_power = rb_intern("**");
5696 }
static VALUE rb_ary_transpose(VALUE ary)
Definition: array.c:3289
#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:3172
static void ary_reverse(VALUE *p1, VALUE *p2)
Definition: array.c:2165
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:3831
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:1941
static double zero(void)
Definition: isinf.c:51
static VALUE ary_reject(VALUE orig, VALUE result)
Definition: array.c:3065
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:2856
#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:3570
Definition: st.h:69
Definition: st.h:100
static VALUE rb_ary_drop_while(VALUE ary)
Definition: array.c:5331
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:4882
VALUE rb_ary_sort(VALUE ary)
Definition: array.c:2506
#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:4516
#define FL_SET_EMBED(a)
Definition: array.c:115
static VALUE rb_ary_compact(VALUE ary)
Definition: array.c:4222
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:2950
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
Definition: class.c:1916
#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:3182
VALUE rb_ary_shift(VALUE ary)
Definition: array.c:991
static VALUE rb_ary_reverse_each(VALUE ary)
Definition: array.c:1835
#define FL_UNSET_SHARED(ary)
Definition: array.c:124
VALUE rb_ary_each(VALUE array)
Definition: array.c:1777
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:4420
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:2218
#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:4719
#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:3669
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:5271
#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:1925
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1854
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:3115
VALUE rb_enc_associate(VALUE obj, rb_encoding *enc)
Definition: encoding.c:826
VALUE rb_ary_clear(VALUE ary)
Definition: array.c:3380
#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:2617
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:653
static int sort_2(const void *ap, const void *bp, void *dummy)
Definition: array.c:2379
int opt_inited
Definition: array.c:2336
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:3014
static VALUE rb_ary_reject(VALUE ary)
Definition: array.c:3135
VALUE rb_ary_rotate(VALUE ary, long cnt)
Definition: array.c:2239
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:1808
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:2202
static int ary_hash_orset(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
Definition: array.c:4032
#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:2987
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:2046
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:4251
#define ARY_DEFAULT_SIZE
Definition: array.c:31
static VALUE rb_ary_sort_by_bang(VALUE ary)
Definition: array.c:2634
#define ARY_HEAP_PTR(a)
Definition: array.c:105
#define OPTHASH_GIVEN_P(opts)
Definition: array.c:4416
#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:1687
VALUE rb_ary_assoc(VALUE ary, VALUE key)
Definition: array.c:3636
#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:1119
#define FL_TEST(x, f)
Definition: ruby.h:1169
static VALUE ary_enum_length(VALUE ary, VALUE args, VALUE eobj)
Definition: array.c:1753
static VALUE rb_ary_inspect(VALUE ary)
Definition: array.c:2088
static VALUE rb_ary_compact_bang(VALUE ary)
Definition: array.c:4189
static VALUE rb_ary_select(VALUE ary)
Definition: array.c:2786
static void ary_memcpy(VALUE ary, long beg, long argc, const VALUE *argv)
Definition: array.c:68
#define tmpbuf_discard(s)
Definition: array.c:4681
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:4682
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:4054
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:4683
VALUE rb_ary_replace(VALUE copy, VALUE orig)
Definition: array.c:3330
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:3222
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:2095
static VALUE binomial_coefficient(long comb, long size)
Definition: array.c:4756
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:5140
static VALUE rb_ary_insert(int argc, VALUE *argv, VALUE ary)
Definition: array.c:1731
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:4808
static void ary_resize_smaller(VALUE ary, long len)
Definition: array.c:2864
rb_atomic_t cnt[RUBY_NSIG]
Definition: signal.c:489
#define OBJ_FROZEN(x)
Definition: ruby.h:1185
static VALUE rb_ary_shuffle_bang(int argc, VALUE *argv, VALUE ary)
Definition: array.c:4433
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:5030
#define Qfalse
Definition: ruby.h:425
static VALUE rb_ary_uniq_bang(VALUE ary)
Definition: array.c:4106
#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:1907
static VALUE rb_ary_combination_size(VALUE ary, VALUE args, VALUE eobj)
Definition: array.c:4848
static VALUE rb_ary_take(VALUE obj, VALUE n)
Definition: array.c:5244
static VALUE rb_ary_select_bang(VALUE ary)
Definition: array.c:2818
#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:2057
#define OBJ_FREEZE(x)
Definition: ruby.h:1186
VALUE ary
Definition: array.c:2334
#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:4745
static VALUE rb_ary_collect(VALUE ary)
Definition: array.c:2668
static ID id_random
Definition: array.c:4418
static VALUE rb_ary_hash(VALUE ary)
Definition: array.c:3788
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:2897
#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:2365
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:2159
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:2717
unsigned long ID
Definition: ruby.h:89
int rb_block_arity(void)
Definition: proc.c:881
#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:3916
#define Qnil
Definition: ruby.h:427
static VALUE rb_ary_delete_if(VALUE ary)
Definition: array.c:3164
static VALUE rb_ary_repeated_combination_size(VALUE ary, VALUE args, VALUE eobj)
Definition: array.c:5046
#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:2132
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:2335
#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:2761
static VALUE empty_ary_alloc(VALUE klass)
Definition: array.c:448
static VALUE rb_ary_drop(VALUE ary, VALUE n)
Definition: array.c:5299
static VALUE rb_ary_collect_bang(VALUE ary)
Definition: array.c:2704
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:3893
static void rpermute0(long n, long r, long *p, long index, VALUE values)
Definition: array.c:4942
static VALUE rb_ary_diff(VALUE ary1, VALUE ary2)
Definition: array.c:3971
#define FL_UNSET(x, f)
Definition: ruby.h:1173
static VALUE ary_tmp_hash_new(void)
Definition: array.c:3907
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:1638
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:2348
static VALUE flatten(VALUE ary, int level, int *modified)
Definition: array.c:4282
static VALUE rb_ary_cycle_size(VALUE self, VALUE args, VALUE eobj)
Definition: array.c:4620
#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:1614
#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:4356
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:4691
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:3427
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:3685
static void rb_ary_modify_check(VALUE ary)
Definition: array.c:308
int rb_sourceline(void)
Definition: vm.c:966
#define RARRAY_AREF(a, i)
Definition: ruby.h:901
VALUE rb_check_convert_type(VALUE, int, const char *, const char *)
Definition: object.c:2632
#define mul(x, y)
Definition: date_strftime.c:25
VALUE rb_ary_plus(VALUE x, VALUE y)
Definition: array.c:3509
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:2308
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:2110
#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:3817
#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:3732
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:4074
#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:4959
#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:2356
static VALUE ary_make_hash_by(VALUE ary)
Definition: array.c:3937
VALUE rb_ary_sort_bang(VALUE ary)
Definition: array.c:2424
static long rotate_count(long cnt, long len)
Definition: array.c:2233
static void rb_ary_set_shared(VALUE ary, VALUE shared)
Definition: array.c:300
static VALUE rb_ary_length(VALUE ary)
Definition: array.c:1863
VALUE rb_ary_dup(VALUE ary)
Definition: array.c:1887
#define RARRAY_EMBED_LEN_MAX
Definition: ruby.h:859
static VALUE rb_ary_repeated_combination(VALUE ary, VALUE num)
Definition: array.c:5084
VALUE rb_cArray
Definition: array.c:27
VALUE rb_ary_concat(VALUE x, VALUE y)
Definition: array.c:3541
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:1994
static VALUE rb_ary_repeated_permutation(VALUE ary, VALUE num)
Definition: array.c:4997
#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:1879
static VALUE rb_ary_rotate_bang(int argc, VALUE *argv, VALUE ary)
Definition: array.c:2277
static void ary_recycle_hash(VALUE hash)
Definition: array.c:3944
static VALUE ary_make_shared(VALUE ary)
Definition: array.c:567
static VALUE recursive_eql(VALUE ary1, VALUE ary2, int recur)
Definition: array.c:3747
#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:4401
static VALUE ary_add_hash_by(VALUE hash, VALUE ary)
Definition: array.c:3923
static VALUE rb_ary_permutation_size(VALUE ary, VALUE args, VALUE eobj)
Definition: array.c:4771
VALUE rb_ary_reverse(VALUE ary)
Definition: array.c:2175
#define FL_FREEZE
Definition: ruby.h:1140
#define tmpbuf(n, size)
Definition: array.c:4680
static VALUE ary_reject_bang(VALUE ary)
Definition: array.c:3079
VALUE rb_inspect(VALUE)
Definition: object.c:471
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:4656
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:1077
VALUE rb_ary_cmp(VALUE ary1, VALUE ary2)
Definition: array.c:3876
void Init_Array(void)
Definition: array.c:5580
static VALUE rb_ary_eql(VALUE ary1, VALUE ary2)
Definition: array.c:3768
#define ARY_EMBED_PTR(a)
Definition: array.c:107
static VALUE rb_ary_uniq(VALUE ary)
Definition: array.c:4156
#define ARY_HEAP_LEN(a)
Definition: array.c:106
VALUE rb_ary_resurrect(VALUE ary)
Definition: array.c:1897
static VALUE sort_by_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, dummy))
Definition: array.c:2616
#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:2927
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:4006
VALUE rb_eArgError
Definition: error.c:549
static VALUE rb_ary_shuffle(int argc, VALUE *argv, VALUE ary)
Definition: array.c:4483
#define NUM2LONG(x)
Definition: ruby.h:600
#define STRING_P(s)
Definition: array.c:2345
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:1591
VALUE rb_obj_class(VALUE)
Definition: object.c:227
static VALUE rb_ary_bsearch(VALUE ary)
Definition: array.c:2567