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