list 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 264292b03be68afb56aa90769cddbe53f77973a9
4
+ data.tar.gz: 64157b4b9936f988264f238c7e77db0cc47bbdae
5
+ SHA512:
6
+ metadata.gz: aae8d581f0359c840d9370d75cacdd31d0a10481353b303371790c94254958acb0ee136cbace00903037df94240cd69fab1c5b2d5f5ac65d93e0c73e0ac9b187
7
+ data.tar.gz: 5752f7964479242e99c30d9b474100b70e344e81552eaa3df72820047ba9bc45cc115931aead439e654b0cb2805f982af0834707797da5cee4348676109eb32f
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ *.bundle
4
+ *.so
5
+ *.o
6
+ .config
7
+ .yardoc
8
+ Gemfile.lock
9
+ InstalledFiles
10
+ _yardoc
11
+ coverage
12
+ doc/
13
+ lib/bundler/man
14
+ pkg
15
+ rdoc
16
+ spec/reports
17
+ test/tmp
18
+ test/version_tmp
19
+ tmp
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.0
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 ksss
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,60 @@
1
+ # List
2
+
3
+ List in Ruby.
4
+
5
+ [![Build Status](https://travis-ci.org/ksss/list.png?branch=master)](https://travis-ci.org/ksss/list)
6
+
7
+ ## Usage
8
+
9
+ All interface is same with Array class.
10
+
11
+ ```ruby
12
+ list = List.new
13
+ list.push 1,2,3
14
+ list.pop
15
+ list[0,1]
16
+ list.each do |i|
17
+ end
18
+ ```
19
+
20
+ +---------+ +->+---------+ +->+---------+
21
+ | value | | | value | | | value |
22
+ | next |--+ | next |--+ | next |
23
+ +---------+ +---------+ +---------+
24
+
25
+ But, List is not Array.
26
+
27
+ ```ruby
28
+ list = List[1,2,3]
29
+ list.ring.each do |i|
30
+ puts i # print infinitely 1,2,3,1,2,3,1,2...
31
+ end
32
+ ```
33
+
34
+ +->+---------+ +->+---------+ +->+---------+
35
+ | | value | | | value | | | value |
36
+ | | next |--+ | next |--+ | next |--+
37
+ | +---------+ +---------+ +---------+ |
38
+ +-----------------------------------------------+
39
+
40
+ ## Installation
41
+
42
+ Add this line to your application's Gemfile:
43
+
44
+ gem 'list'
45
+
46
+ And then execute:
47
+
48
+ $ bundle
49
+
50
+ Or install it yourself as:
51
+
52
+ $ gem install list
53
+
54
+ ## Contributing
55
+
56
+ 1. Fork it ( http://github.com/ksss/list/fork )
57
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
58
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
59
+ 4. Push to the branch (`git push origin my-new-feature`)
60
+ 5. Create new Pull Request
@@ -0,0 +1,30 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rspec/core'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec) do |t|
7
+ t.rspec_opts = ["-c", "-f progress", "-Ilib"]
8
+ t.pattern = "spec/**/*_spec.rb"
9
+ t.verbose = true
10
+ end
11
+ task :spec => :compile
12
+
13
+ require 'rake/extensiontask'
14
+ spec = Bundler::GemHelper.gemspec
15
+ Rake::ExtensionTask.new('list', spec) do |ext|
16
+ ext.ext_dir = 'ext/list'
17
+ ext.lib_dir = 'lib'
18
+ end
19
+
20
+ desc "gem reinstall"
21
+ task :reinstall do |t|
22
+ system "gem uninstall list"
23
+ system "rake clean"
24
+ system "bundle exec rake"
25
+ system "rake install"
26
+ system "irb -rlist"
27
+ end
28
+
29
+
30
+ task :default => [:spec,:build]
@@ -0,0 +1,5 @@
1
+ require 'mkmf'
2
+
3
+ $CFLAGS << " -Wall"
4
+
5
+ create_makefile('list')
@@ -0,0 +1,2084 @@
1
+ #include "ruby.h"
2
+ #include "ruby/encoding.h"
3
+
4
+ #define LIST_VERSION "0.0.1"
5
+
6
+ VALUE cList;
7
+
8
+ ID id_cmp, id_each;
9
+
10
+ typedef struct item_t {
11
+ VALUE value;
12
+ struct item_t *next;
13
+ } item_t;
14
+
15
+ typedef struct {
16
+ item_t *first;
17
+ item_t *last;
18
+ long len;
19
+ } list_t;
20
+
21
+ #define DEBUG 0
22
+
23
+ #define LIST_MAX_SIZE ULONG_MAX
24
+
25
+ #ifndef FALSE
26
+ # define FALSE 0
27
+ #endif
28
+
29
+ #ifndef TRUE
30
+ # define TRUE 1
31
+ #endif
32
+
33
+ /* compatible for ruby-v1.9.3 */
34
+ #ifndef UNLIMITED_ARGUMENTS
35
+ # define UNLIMITED_ARGUMENTS (-1)
36
+ #endif
37
+
38
+ /* compatible for ruby-v1.9.3 */
39
+ #ifndef rb_check_arity
40
+ # define rb_check_arity(argc,min,max) do { \
41
+ if (((argc) < (min) || ((max) != UNLIMITED_ARGUMENTS && (max) < (argc)))) { \
42
+ rb_raise(rb_eArgError, "wrong number of argument (%d for %d..%d)", argc, min, max); \
43
+ } \
44
+ } while (0)
45
+ #endif
46
+
47
+ /* compatible for ruby-v1.9.3 */
48
+ #ifndef RETURN_SIZED_ENUMERATOR
49
+ # define RETURN_SIZED_ENUMERATOR(a,b,c,d) RETURN_ENUMERATOR(a,b,c)
50
+ #else
51
+ static VALUE
52
+ list_enum_length(VALUE self, VALUE args, VALUE eobj)
53
+ {
54
+ list_t *ptr;
55
+ Data_Get_Struct(self, list_t, ptr);
56
+ return LONG2NUM(ptr->len);
57
+ }
58
+ #endif
59
+
60
+ #define LIST_FOR(ptr, c) for (c = ptr->first; c; c = c->next)
61
+
62
+ #define LIST_FOR_DOUBLE(ptr1, c1, ptr2, c2, code) do { \
63
+ c1 = (ptr1)->first; \
64
+ c2 = (ptr2)->first; \
65
+ while ((c1) && (c2)) { \
66
+ (code); \
67
+ c1 = (c1)->next; \
68
+ c2 = (c2)->next; \
69
+ } \
70
+ } while (0)
71
+
72
+ enum list_take_pos_flags {
73
+ LIST_TAKE_FIRST,
74
+ LIST_TAKE_LAST
75
+ };
76
+
77
+ static VALUE list_push_ary(VALUE, VALUE);
78
+ static VALUE list_push(VALUE, VALUE);
79
+ static VALUE list_unshift(VALUE, VALUE);
80
+ static VALUE list_replace(VALUE, VALUE);
81
+
82
+ #if DEBUG
83
+ static void
84
+ p(const char *str)
85
+ {
86
+ rb_p(rb_str_new2(str));
87
+ }
88
+
89
+ static void
90
+ check_print(list_t *ptr, const char *msg, long lineno)
91
+ {
92
+ printf("===ERROR(%s)", msg);
93
+ printf("lineno:%ld===\n", lineno);
94
+ printf("ptr:%p\n",ptr);
95
+ printf("ptr->len:%ld\n",ptr->len);
96
+ printf("ptr->first:%p\n",ptr->first);
97
+ printf("ptr->last:%p\n",ptr->last);
98
+ rb_raise(rb_eRuntimeError, "check is NG!");
99
+ }
100
+
101
+ static void
102
+ check(list_t *ptr, const char *msg)
103
+ {
104
+ item_t *end;
105
+ item_t *c, *b;
106
+ long len, i;
107
+
108
+ if (ptr->len == 0 && ptr->first != NULL) check_print(ptr, msg, __LINE__);
109
+ if (ptr->len != 0 && ptr->first == NULL) check_print(ptr, msg, __LINE__);
110
+ if (ptr->len == 0 && ptr->last != NULL) check_print(ptr, msg, __LINE__);
111
+ if (ptr->len != 0 && ptr->last == NULL) check_print(ptr, msg, __LINE__);
112
+ if (ptr->first == NULL && ptr->last != NULL) check_print(ptr, msg, __LINE__);
113
+ if (ptr->first != NULL && ptr->last == NULL) check_print(ptr, msg, __LINE__);
114
+ len = ptr->len;
115
+ if (len == 0) return;
116
+ i = 0;
117
+ end = ptr->last->next;
118
+ i++;
119
+ for (c = ptr->first->next; c != end; c = c->next) {
120
+ i++;
121
+ b = c;
122
+ }
123
+ if (b != ptr->last) check_print(ptr, msg, __LINE__);
124
+ if (len != i) check_print(ptr, msg, __LINE__);
125
+ }
126
+ #endif
127
+
128
+ static inline VALUE
129
+ list_new(void)
130
+ {
131
+ return rb_obj_alloc(cList);
132
+ }
133
+
134
+ static VALUE
135
+ collect_all(VALUE i, VALUE list, int argc, VALUE *argv)
136
+ {
137
+ VALUE pack;
138
+ rb_thread_check_ints();
139
+ if (argc == 0) pack = Qnil;
140
+ else if (argc == 1) pack = argv[0];
141
+ else pack = rb_ary_new4(argc, argv);
142
+
143
+ list_push(list, pack);
144
+ return Qnil;
145
+ }
146
+
147
+ static VALUE
148
+ ary_to_list(int argc, VALUE *argv, VALUE obj)
149
+ {
150
+ VALUE list = list_new();
151
+ rb_block_call(obj, id_each, argc, argv, collect_all, list);
152
+ OBJ_INFECT(list, obj);
153
+ return list;
154
+ }
155
+
156
+ static VALUE
157
+ to_list(VALUE obj)
158
+ {
159
+ switch (rb_type(obj)) {
160
+ case T_DATA:
161
+ return obj;
162
+ case T_ARRAY:
163
+ return ary_to_list(0, NULL, obj);
164
+ default:
165
+ return Qnil;
166
+ }
167
+ }
168
+
169
+ static inline void
170
+ list_modify_check(VALUE self)
171
+ {
172
+ rb_check_frozen(self);
173
+ }
174
+
175
+ static void
176
+ list_mark(list_t *ptr)
177
+ {
178
+ item_t *c;
179
+ item_t *end;
180
+
181
+ if (ptr->first == NULL) return;
182
+ end = ptr->last->next;
183
+ rb_gc_mark(ptr->first->value);
184
+ for (c = ptr->first->next; c != end; c = c->next) {
185
+ rb_gc_mark(c->value);
186
+ }
187
+ }
188
+
189
+ static void
190
+ list_free(list_t *ptr)
191
+ {
192
+ item_t *c;
193
+ item_t *first_next;
194
+ item_t *next;
195
+ item_t *end;
196
+
197
+ if (ptr->first == NULL) return;
198
+ first_next = ptr->first->next;
199
+ end = ptr->last->next;
200
+ xfree(ptr->first);
201
+ for (c = first_next; c != end;) {
202
+ next = c->next;
203
+ xfree(c);
204
+ c = next;
205
+ }
206
+ }
207
+
208
+ static void
209
+ list_mem_clear(list_t *ptr, long beg, long len)
210
+ {
211
+ long i;
212
+ item_t *c;
213
+ item_t *next;
214
+ item_t *mid, *last;
215
+
216
+ if (beg == 0 && len == ptr->len) {
217
+ list_free(ptr);
218
+ ptr->first = NULL;
219
+ ptr->last = NULL;
220
+ ptr->len = 0;
221
+ return;
222
+ }
223
+
224
+ i = -1;
225
+ if (beg == 0) {
226
+ for (c = ptr->first; c;) {
227
+ i++;
228
+ if (i < len) { // mid
229
+ next = c->next;
230
+ xfree(c);
231
+ c = next;
232
+ }
233
+ if (len == i) { // end
234
+ ptr->first = c;
235
+ break;
236
+ }
237
+ }
238
+ } else if (beg + len == ptr->len) {
239
+ for (c = ptr->first; c;) {
240
+ i++;
241
+ next = c->next;
242
+ if (beg - 1 == i) { // begin
243
+ last = c;
244
+ } else if (beg <= i) { // mid
245
+ xfree(c);
246
+ }
247
+ c = next;
248
+ }
249
+ ptr->last = last;
250
+ ptr->last->next = NULL;
251
+ } else {
252
+ for (c = ptr->first; c;) {
253
+ i++;
254
+ if (beg == i) { // begin
255
+ mid = next;
256
+ }
257
+ if (beg + len == i) { // end
258
+ mid->next = c;
259
+ break;
260
+ }
261
+ if (beg <= i) { // mid
262
+ next = c->next;
263
+ xfree(c);
264
+ c = next;
265
+ }
266
+ }
267
+ }
268
+
269
+ ptr->len -= len;
270
+ }
271
+
272
+ static inline list_t *
273
+ list_new_ptr(void)
274
+ {
275
+ list_t *ptr = ALLOC(list_t);
276
+ ptr->first = NULL;
277
+ ptr->last = ptr->first;
278
+ ptr->len = 0;
279
+ return ptr;
280
+ }
281
+
282
+ static VALUE
283
+ list_alloc(VALUE self)
284
+ {
285
+ list_t *ptr = list_new_ptr();
286
+ return Data_Wrap_Struct(self, list_mark, list_free, ptr);
287
+ }
288
+
289
+ static item_t *
290
+ item_alloc(VALUE obj, item_t *next)
291
+ {
292
+ item_t *item;
293
+ item = xmalloc(sizeof(item_t));
294
+ item->value = obj;
295
+ item->next = next;
296
+ return item;
297
+ }
298
+
299
+ static VALUE
300
+ list_push(VALUE self, VALUE obj)
301
+ {
302
+ list_t *ptr;
303
+ item_t *next;
304
+
305
+ list_modify_check(self);
306
+ if (self == obj) {
307
+ rb_raise(rb_eArgError, "`List' cannot set recursive");
308
+ }
309
+
310
+ next = item_alloc(obj, NULL);
311
+
312
+ Data_Get_Struct(self, list_t, ptr);
313
+ if (ptr->first == NULL) {
314
+ ptr->first = next;
315
+ ptr->last = next;
316
+ ptr->last->next = NULL;
317
+ } else {
318
+ ptr->last->next = next;
319
+ ptr->last = next;
320
+ }
321
+ ptr->len++;
322
+ return self;
323
+ }
324
+
325
+ static VALUE
326
+ list_push_ary(VALUE self, VALUE ary)
327
+ {
328
+ long i;
329
+
330
+ list_modify_check(self);
331
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
332
+ list_push(self, rb_ary_entry(ary, i));
333
+ }
334
+ return self;
335
+ }
336
+
337
+ static VALUE
338
+ list_push_m(int argc, VALUE *argv, VALUE self)
339
+ {
340
+ long i;
341
+
342
+ list_modify_check(self);
343
+ if (argc == 0) return self;
344
+ for (i = 0; i < argc; i++) {
345
+ list_push(self, argv[i]);
346
+ }
347
+ return self;
348
+ }
349
+
350
+ static VALUE
351
+ list_s_create(int argc, VALUE *argv, VALUE klass)
352
+ {
353
+ VALUE list;
354
+
355
+ list = rb_obj_alloc(klass);
356
+ return list_push_m(argc, argv, list);
357
+ }
358
+
359
+ static VALUE
360
+ check_list_type(VALUE obj)
361
+ {
362
+ return to_list(obj);
363
+ }
364
+
365
+ static VALUE
366
+ list_s_try_convert(VALUE dummy, VALUE obj)
367
+ {
368
+ return check_list_type(obj);
369
+ }
370
+
371
+ static VALUE
372
+ list_initialize(int argc, VALUE *argv, VALUE self)
373
+ {
374
+ VALUE size, val;
375
+ long len;
376
+ long i;
377
+
378
+ list_modify_check(self);
379
+ if (argc == 0) {
380
+ return self;
381
+ }
382
+ if (argc == 1 && !FIXNUM_P(argv[0])) {
383
+ switch (rb_type(argv[0])) {
384
+ case T_ARRAY:
385
+ return list_push_ary(self, argv[0]);
386
+ case T_DATA:
387
+ return list_replace(self, argv[0]);
388
+ default:
389
+ break;
390
+ }
391
+ }
392
+
393
+ rb_scan_args(argc, argv, "02", &size, &val);
394
+
395
+ len = NUM2LONG(size);
396
+ if (len < 0) {
397
+ rb_raise(rb_eArgError, "negative size");
398
+ }
399
+ if (LIST_MAX_SIZE < len) {
400
+ rb_raise(rb_eArgError, "size too big");
401
+ }
402
+
403
+ if (rb_block_given_p()) {
404
+ if (argc == 2) {
405
+ rb_warn("block supersedes default value argument");
406
+ }
407
+ for (i = 0; i < len; i++) {
408
+ list_push(self, rb_yield(LONG2NUM(i)));
409
+ }
410
+ } else {
411
+ for (i = 0; i < len; i++) {
412
+ list_push(self, val);
413
+ }
414
+ }
415
+ return self;
416
+ }
417
+
418
+ static VALUE
419
+ list_each(VALUE self)
420
+ {
421
+ item_t *c;
422
+ list_t *ptr;
423
+
424
+ RETURN_SIZED_ENUMERATOR(self, 0, 0, list_enum_length);
425
+ Data_Get_Struct(self, list_t, ptr);
426
+ if (ptr->first == NULL) return self;
427
+
428
+ LIST_FOR(ptr, c) {
429
+ rb_yield(c->value);
430
+ }
431
+ return self;
432
+ }
433
+
434
+ static VALUE
435
+ list_each_index(VALUE self)
436
+ {
437
+ item_t *c;
438
+ list_t *ptr;
439
+ long index;
440
+
441
+ RETURN_SIZED_ENUMERATOR(self, 0, 0, list_enum_length);
442
+ Data_Get_Struct(self, list_t, ptr);
443
+ if (ptr->first == NULL) return self;
444
+
445
+ index = 0;
446
+ LIST_FOR(ptr, c) {
447
+ rb_yield(LONG2NUM(index++));
448
+ }
449
+ return self;
450
+ }
451
+
452
+ static VALUE
453
+ list_clear(VALUE self)
454
+ {
455
+ list_modify_check(self);
456
+ list_t *ptr;
457
+ Data_Get_Struct(self, list_t, ptr);
458
+ list_free(ptr);
459
+ ptr->first = NULL;
460
+ ptr->last = NULL;
461
+ ptr->len = 0;
462
+ return self;
463
+ }
464
+
465
+ static VALUE
466
+ list_replace_ary(VALUE copy, VALUE orig)
467
+ {
468
+ list_t *ptr_copy;
469
+ item_t *c_copy;
470
+ long i, olen;
471
+
472
+ list_modify_check(copy);
473
+ if (copy == orig) return copy;
474
+
475
+ Data_Get_Struct(copy, list_t, ptr_copy);
476
+ olen = RARRAY_LEN(orig);
477
+ if (olen == 0) {
478
+ return list_clear(copy);
479
+ }
480
+ if (olen == ptr_copy->len) {
481
+ i = 0;
482
+ LIST_FOR(ptr_copy, c_copy) {
483
+ c_copy->value = rb_ary_entry(orig, i);
484
+ i++;
485
+ }
486
+ } else {
487
+ list_clear(copy);
488
+ for (i = 0; i < olen; i++) {
489
+ list_push(copy, rb_ary_entry(orig, i));
490
+ }
491
+ }
492
+ return copy;
493
+ }
494
+
495
+ static VALUE
496
+ list_replace(VALUE copy, VALUE orig)
497
+ {
498
+ list_t *ptr_copy;
499
+ list_t *ptr_orig;
500
+ item_t *c_orig;
501
+ item_t *c_copy;
502
+ long olen;
503
+
504
+ list_modify_check(copy);
505
+ if (copy == orig) return copy;
506
+
507
+ switch (rb_type(orig)) {
508
+ case T_ARRAY:
509
+ return list_replace_ary(copy, orig);
510
+ case T_DATA:
511
+ break;
512
+ default:
513
+ rb_raise(rb_eTypeError, "cannot convert to list");
514
+ }
515
+ orig = to_list(orig);
516
+ Data_Get_Struct(copy, list_t, ptr_copy);
517
+ Data_Get_Struct(orig, list_t, ptr_orig);
518
+ olen = ptr_orig->len;
519
+ if (olen == 0) {
520
+ return list_clear(copy);
521
+ }
522
+ if (olen == ptr_copy->len) {
523
+ LIST_FOR_DOUBLE(ptr_orig, c_orig, ptr_copy, c_copy, {
524
+ c_copy->value = c_orig->value;
525
+ });
526
+ } else {
527
+ list_clear(copy);
528
+ LIST_FOR(ptr_orig, c_orig) {
529
+ list_push(copy, c_orig->value);
530
+ }
531
+ }
532
+
533
+ return copy;
534
+ }
535
+
536
+ static VALUE
537
+ inspect_list(VALUE self, VALUE dummy, int recur)
538
+ {
539
+ VALUE str, s;
540
+ list_t *ptr;
541
+ item_t *c;
542
+
543
+ Data_Get_Struct(self, list_t, ptr);
544
+ if (recur) return rb_usascii_str_new_cstr("[...]");
545
+
546
+ str = rb_str_buf_new2("#<");
547
+ rb_str_buf_cat2(str, rb_obj_classname(self));
548
+ rb_str_buf_cat2(str, ": [");
549
+ LIST_FOR(ptr, c) {
550
+ s = rb_inspect(c->value);
551
+ if (ptr->first == c) rb_enc_copy(str, s);
552
+ else rb_str_buf_cat2(str, ", ");
553
+ rb_str_buf_append(str, s);
554
+ }
555
+ rb_str_buf_cat2(str, "]>");
556
+ return str;
557
+ }
558
+
559
+ static VALUE
560
+ list_inspect(VALUE self)
561
+ {
562
+ list_t *ptr;
563
+ Data_Get_Struct(self, list_t, ptr);
564
+ if (ptr->len == 0)
565
+ return rb_sprintf("#<%s: []>", rb_obj_classname(self));
566
+ return rb_exec_recursive(inspect_list, self, 0);
567
+ }
568
+
569
+ static VALUE
570
+ list_to_a(VALUE self)
571
+ {
572
+ list_t *ptr;
573
+ item_t *c;
574
+ VALUE ary;
575
+ long i = 0;
576
+
577
+ Data_Get_Struct(self, list_t, ptr);
578
+ ary = rb_ary_new2(ptr->len);
579
+ LIST_FOR(ptr, c) {
580
+ rb_ary_store(ary, i++, c->value);
581
+ }
582
+ return ary;
583
+ }
584
+
585
+ static VALUE
586
+ list_frozen_p(VALUE self)
587
+ {
588
+ if (OBJ_FROZEN(self)) return Qtrue;
589
+ return Qfalse;
590
+ }
591
+
592
+ static VALUE
593
+ recursive_equal(VALUE list1, VALUE list2, int recur)
594
+ {
595
+ list_t *p1, *p2;
596
+ item_t *c1, *c2;
597
+
598
+ if (recur) return Qtrue;
599
+
600
+ Data_Get_Struct(list1, list_t, p1);
601
+ Data_Get_Struct(list2, list_t, p2);
602
+ if (p1->len != p2->len) return Qfalse;
603
+
604
+ LIST_FOR_DOUBLE(p1, c1, p2, c2, {
605
+ if (c1->value != c2->value) {
606
+ if (!rb_equal(c1->value, c2->value)) {
607
+ return Qfalse;
608
+ }
609
+ }
610
+ });
611
+ return Qtrue;
612
+ }
613
+
614
+ static VALUE
615
+ list_equal(VALUE self, VALUE obj)
616
+ {
617
+ if (self == obj)
618
+ return Qtrue;
619
+
620
+ if (!rb_obj_is_kind_of(obj, cList)) {
621
+ if (rb_type(obj) == T_ARRAY) {
622
+ return Qfalse;
623
+ }
624
+ if (!rb_respond_to(obj, rb_intern("to_list"))) {
625
+ return Qfalse;
626
+ }
627
+ return rb_equal(obj, self);
628
+ }
629
+ return rb_exec_recursive_paired(recursive_equal, self, obj, obj);
630
+
631
+ }
632
+
633
+ static VALUE
634
+ list_hash(VALUE self)
635
+ {
636
+ item_t *c;
637
+ st_index_t h;
638
+ list_t *ptr;
639
+ VALUE n;
640
+
641
+ Data_Get_Struct(self, list_t, ptr);
642
+ h = rb_hash_start(ptr->len);
643
+ h = rb_hash_uint(h, (st_index_t)list_hash);
644
+ LIST_FOR(ptr, c) {
645
+ n = rb_hash(c->value);
646
+ h = rb_hash_uint(h, NUM2LONG(n));
647
+ }
648
+ h = rb_hash_end(h);
649
+ return LONG2FIX(h);
650
+ }
651
+
652
+ static VALUE
653
+ list_elt_ptr(list_t* ptr, long offset)
654
+ {
655
+ long i;
656
+ item_t *c;
657
+ long len;
658
+
659
+ len = ptr->len;
660
+ if (len == 0) return Qnil;
661
+ if (offset < 0 || len <= offset) {
662
+ return Qnil;
663
+ }
664
+
665
+ i = 0;
666
+ LIST_FOR(ptr, c) {
667
+ if (i++ == offset) {
668
+ return c->value;
669
+ }
670
+ }
671
+ return Qnil;
672
+ }
673
+
674
+ static VALUE
675
+ list_elt(VALUE self, long offset)
676
+ {
677
+ list_t *ptr;
678
+ Data_Get_Struct(self, list_t, ptr);
679
+ return list_elt_ptr(ptr, offset);
680
+ }
681
+
682
+ static VALUE
683
+ list_entry(VALUE self, long offset)
684
+ {
685
+ list_t *ptr;
686
+
687
+ Data_Get_Struct(self, list_t, ptr);
688
+ if (offset < 0) {
689
+ offset += ptr->len;
690
+ }
691
+ return list_elt(self, offset);
692
+ }
693
+
694
+ static VALUE
695
+ list_make_partial(VALUE self, VALUE klass, long offset, long len)
696
+ {
697
+ VALUE instance;
698
+ item_t *c;
699
+ list_t *ptr;
700
+ long i;
701
+
702
+ Data_Get_Struct(self, list_t, ptr);
703
+ instance = rb_obj_alloc(klass);
704
+ i = -1;
705
+ LIST_FOR(ptr, c) {
706
+ i++;
707
+ if (i < offset) continue;
708
+
709
+ if (i < offset + len) {
710
+ list_push(instance, c->value);
711
+ } else {
712
+ break;
713
+ }
714
+ }
715
+ return instance;
716
+ }
717
+
718
+ static VALUE
719
+ list_subseq(VALUE self, long beg, long len)
720
+ {
721
+ long alen;
722
+ list_t *ptr;
723
+
724
+ Data_Get_Struct(self, list_t, ptr);
725
+ alen = ptr->len;
726
+
727
+ if (alen < beg) return Qnil;
728
+ if (beg < 0 || len < 0) return Qnil;
729
+
730
+ if (alen < len || alen < beg + len) {
731
+ len = alen - beg;
732
+ }
733
+ if (len == 0) {
734
+ return list_new();
735
+ }
736
+
737
+ return list_make_partial(self, cList, beg, len);
738
+ }
739
+
740
+ static VALUE
741
+ list_aref(int argc, VALUE *argv, VALUE self)
742
+ {
743
+ VALUE arg;
744
+ long beg, len;
745
+ list_t *ptr;
746
+
747
+ Data_Get_Struct(self, list_t, ptr);
748
+ if (argc == 2) {
749
+ beg = NUM2LONG(argv[0]);
750
+ len = NUM2LONG(argv[1]);
751
+ if (beg < 0) {
752
+ beg += ptr->len;
753
+ }
754
+ return list_subseq(self, beg, len);
755
+ }
756
+ if (argc != 1) {
757
+ rb_scan_args(argc, argv, "11", NULL, NULL);
758
+ }
759
+ arg = argv[0];
760
+
761
+ /* special case - speeding up */
762
+ if (FIXNUM_P(arg)) {
763
+ return list_entry(self, FIX2LONG(arg));
764
+ }
765
+ /* check if idx is Range */
766
+ switch (rb_range_beg_len(arg, &beg, &len, ptr->len, 0)) {
767
+ case Qfalse:
768
+ break;
769
+ case Qnil:
770
+ return Qnil;
771
+ default:
772
+ return list_subseq(self, beg, len);
773
+ }
774
+ return list_entry(self, NUM2LONG(arg));
775
+ }
776
+
777
+ static void
778
+ list_splice(VALUE self, long beg, long len, VALUE rpl)
779
+ {
780
+ long i;
781
+ long rlen, olen, alen;
782
+ list_t *ptr;
783
+ item_t *c = NULL;
784
+ item_t *item_first = NULL, *item_last = NULL, *first = NULL, *last = NULL;
785
+
786
+ if (len < 0)
787
+ rb_raise(rb_eIndexError, "negative length (%ld)", len);
788
+
789
+ Data_Get_Struct(self, list_t, ptr);
790
+ olen = ptr->len;
791
+ if (beg < 0) {
792
+ beg += olen;
793
+ if (beg < 0) {
794
+ rb_raise(rb_eIndexError, "index %ld too small for array; minimum: %ld",
795
+ beg - olen, -olen);
796
+ }
797
+ }
798
+ if (olen < len || olen < beg + len) {
799
+ len = olen - beg;
800
+ }
801
+
802
+ if (rpl == Qundef) {
803
+ rlen = 0;
804
+ } else {
805
+ rpl = rb_ary_to_ary(rpl);
806
+ rlen = RARRAY_LEN(rpl);
807
+ olen = ptr->len;
808
+ }
809
+ if (olen <= beg) {
810
+ if (LIST_MAX_SIZE - rlen < beg) {
811
+ rb_raise(rb_eIndexError, "index %ld too big", beg);
812
+ }
813
+ for (i = ptr->len; i < beg; i++) {
814
+ list_push(self, Qnil);
815
+ }
816
+ list_push_ary(self, rpl);
817
+ } else {
818
+ alen = olen + rlen - len;
819
+ if (len != rlen) {
820
+ for (i = rlen; 0 < i; i--) {
821
+ c = item_alloc(rb_ary_entry(rpl, i - 1), c);
822
+ if (i == rlen) {
823
+ item_last = c;
824
+ }
825
+ }
826
+ item_first = c;
827
+
828
+ i = -1;
829
+ LIST_FOR(ptr, c) {
830
+ i++;
831
+ if (i == beg - 1) {
832
+ first = c;
833
+ }
834
+ if (i == beg + len) {
835
+ last = c;
836
+ break;
837
+ }
838
+ }
839
+ if (beg == 0) {
840
+ ptr->first = item_first;
841
+ } else {
842
+ first->next = item_first;
843
+ }
844
+ if (rlen == 0) {
845
+ ptr->last = first;
846
+ ptr->last->next = NULL;
847
+ } else {
848
+ item_last->next = last;
849
+ }
850
+ ptr->len += rlen - len;
851
+ } else {
852
+ i = -1;
853
+ LIST_FOR(ptr, c) {
854
+ i++;
855
+ if (beg <= i && i < beg + rlen) {
856
+ c->value = rb_ary_entry(rpl, i - beg);
857
+ }
858
+ }
859
+ }
860
+
861
+ }
862
+ }
863
+
864
+ static void
865
+ list_store(VALUE self, long idx, VALUE val)
866
+ {
867
+ item_t *c;
868
+ list_t *ptr;
869
+ long len, i;
870
+
871
+ Data_Get_Struct(self, list_t, ptr);
872
+ len = ptr->len;
873
+
874
+ if (idx < 0) {
875
+ idx += len;
876
+ if (idx < 0) {
877
+ rb_raise(rb_eIndexError, "index %ld too small for list; minimum: %ld",
878
+ idx - len, -len);
879
+ }
880
+ } else if (LIST_MAX_SIZE <= idx) {
881
+ rb_raise(rb_eIndexError, "index %ld too big", idx);
882
+ }
883
+
884
+ if (ptr->len <= idx) {
885
+ for (i = ptr->len; i <= idx; i++) {
886
+ list_push(self, Qnil);
887
+ }
888
+ }
889
+
890
+ i = -1;
891
+ LIST_FOR(ptr, c) {
892
+ i++;
893
+ if (i == idx) {
894
+ c->value = val;
895
+ break;
896
+ }
897
+ }
898
+ }
899
+
900
+ static VALUE
901
+ list_aset(int argc, VALUE *argv, VALUE self)
902
+ {
903
+ long offset, beg, len;
904
+ list_t *ptr;
905
+
906
+ list_modify_check(self);
907
+ Data_Get_Struct(self, list_t, ptr);
908
+ if (argc == 3) {
909
+ beg = NUM2LONG(argv[0]);
910
+ len = NUM2LONG(argv[1]);
911
+ list_splice(self, beg, len, argv[2]);
912
+ return argv[2];
913
+ }
914
+ rb_check_arity(argc, 2, 2);
915
+ if (FIXNUM_P(argv[0])) {
916
+ offset = FIX2LONG(argv[0]);
917
+ goto fixnum;
918
+ }
919
+ if (rb_range_beg_len(argv[0], &beg, &len, ptr->len, 1)) {
920
+ /* check if idx is Range */
921
+ list_splice(self, beg, len, argv[1]);
922
+ return argv[1];
923
+ }
924
+
925
+ offset = NUM2LONG(argv[0]);
926
+ fixnum:
927
+ list_store(self, offset, argv[1]);
928
+ return argv[1];
929
+ }
930
+
931
+ static VALUE
932
+ list_at(VALUE self, VALUE pos)
933
+ {
934
+ return list_entry(self, NUM2LONG(pos));
935
+ }
936
+
937
+ static VALUE
938
+ list_fetch(int argc, VALUE *argv, VALUE self)
939
+ {
940
+ VALUE pos, ifnone;
941
+ long block_given;
942
+ long idx;
943
+ list_t *ptr;
944
+
945
+ Data_Get_Struct(self, list_t, ptr);
946
+ rb_scan_args(argc, argv, "11", &pos, &ifnone);
947
+ block_given = rb_block_given_p();
948
+ if (block_given && argc == 2) {
949
+ rb_warn("block supersedes default value argument");
950
+ }
951
+ idx = NUM2LONG(pos);
952
+
953
+ if (idx < 0) {
954
+ idx += ptr->len;
955
+ }
956
+ if (idx < 0 || ptr->len <= idx) {
957
+ if (block_given) return rb_yield(pos);
958
+ if (argc == 1) {
959
+ rb_raise(rb_eIndexError, "index %ld outside of array bounds: %ld...%ld",
960
+ idx - (idx < 0 ? ptr->len : 0), -ptr->len, ptr->len);
961
+ }
962
+ return ifnone;
963
+ }
964
+ return list_entry(self, idx);
965
+ }
966
+
967
+ static VALUE
968
+ list_take_first_or_last(int argc, VALUE *argv, VALUE self, enum list_take_pos_flags flag)
969
+ {
970
+ VALUE nv;
971
+ long n;
972
+ long len;
973
+ long offset = 0;
974
+ list_t *ptr;
975
+
976
+ Data_Get_Struct(self, list_t, ptr);
977
+ rb_scan_args(argc, argv, "1", &nv);
978
+ n = NUM2LONG(nv);
979
+ len = ptr->len;
980
+ if (n > len) {
981
+ n = len;
982
+ } else if (n < 0) {
983
+ rb_raise(rb_eArgError, "negative array size");
984
+ }
985
+ if (flag == LIST_TAKE_LAST) {
986
+ offset = len - n;
987
+ }
988
+ return list_make_partial(self, cList, offset, n);
989
+ }
990
+
991
+ static VALUE
992
+ list_first(int argc, VALUE *argv, VALUE self)
993
+ {
994
+ list_t *ptr;
995
+ Data_Get_Struct(self, list_t, ptr);
996
+ if (argc == 0) {
997
+ if (ptr->first == NULL) return Qnil;
998
+ return ptr->first->value;
999
+ } else {
1000
+ return list_take_first_or_last(argc, argv, self, LIST_TAKE_FIRST);
1001
+ }
1002
+ }
1003
+
1004
+ static VALUE
1005
+ list_last(int argc, VALUE *argv, VALUE self)
1006
+ {
1007
+ list_t *ptr;
1008
+ long len;
1009
+
1010
+ Data_Get_Struct(self, list_t, ptr);
1011
+ if (argc == 0) {
1012
+ len = ptr->len;
1013
+ if (len == 0) return Qnil;
1014
+ return list_elt(self, len - 1);
1015
+ } else {
1016
+ return list_take_first_or_last(argc, argv, self, LIST_TAKE_LAST);
1017
+ }
1018
+ }
1019
+
1020
+ static VALUE
1021
+ list_concat(VALUE self, VALUE obj)
1022
+ {
1023
+ long len;
1024
+ list_t *ptr_self;
1025
+ list_t *ptr_obj;
1026
+ enum ruby_value_type type;
1027
+
1028
+ list_modify_check(self);
1029
+ type = rb_type(obj);
1030
+ if (type == T_DATA) {
1031
+ Data_Get_Struct(obj, list_t, ptr_obj);
1032
+ len = ptr_obj->len;
1033
+ } else if (type == T_ARRAY) {
1034
+ len = RARRAY_LEN(obj);
1035
+ } else {
1036
+ obj = to_list(obj);
1037
+ Data_Get_Struct(obj, list_t, ptr_obj);
1038
+ len = ptr_obj->len;
1039
+ }
1040
+
1041
+ Data_Get_Struct(self, list_t, ptr_self);
1042
+ if (0 < len) {
1043
+ list_splice(self, ptr_self->len, 0, obj);
1044
+ }
1045
+ return self;
1046
+ }
1047
+
1048
+ static VALUE
1049
+ list_pop(VALUE self)
1050
+ {
1051
+ VALUE result;
1052
+ list_t *ptr;
1053
+
1054
+ list_modify_check(self);
1055
+ Data_Get_Struct(self, list_t, ptr);
1056
+ if (ptr->len == 0) return Qnil;
1057
+ result = ptr->last->value;
1058
+ list_mem_clear(ptr, ptr->len - 1, 1);
1059
+ return result;
1060
+ }
1061
+
1062
+ static VALUE
1063
+ list_pop_m(int argc, VALUE *argv, VALUE self)
1064
+ {
1065
+ list_t *ptr;
1066
+ VALUE result;
1067
+ long n;
1068
+
1069
+ if (argc == 0) {
1070
+ return list_pop(self);
1071
+ }
1072
+
1073
+ list_modify_check(self);
1074
+ result = list_take_first_or_last(argc, argv, self, LIST_TAKE_LAST);
1075
+ Data_Get_Struct(self, list_t, ptr);
1076
+ n = NUM2LONG(argv[0]);
1077
+ list_mem_clear(ptr, ptr->len - n, n);
1078
+ return result;
1079
+ }
1080
+
1081
+ static VALUE
1082
+ list_shift(VALUE self)
1083
+ {
1084
+ VALUE result;
1085
+ list_t *ptr;
1086
+
1087
+ Data_Get_Struct(self, list_t, ptr);
1088
+ if (ptr->len == 0) return Qnil;
1089
+ result = list_first(0, NULL, self);
1090
+ list_mem_clear(ptr, 0, 1);
1091
+ return result;
1092
+ }
1093
+
1094
+ static VALUE
1095
+ list_shift_m(int argc, VALUE *argv, VALUE self)
1096
+ {
1097
+ VALUE result;
1098
+ long i;
1099
+ list_t *ptr_res;
1100
+
1101
+ if (argc == 0) {
1102
+ return list_shift(self);
1103
+ }
1104
+
1105
+ list_modify_check(self);
1106
+ result = list_take_first_or_last(argc, argv, self, LIST_TAKE_FIRST);
1107
+ Data_Get_Struct(result, list_t, ptr_res);
1108
+ for (i = 0; i < ptr_res->len; i++) {
1109
+ list_shift(self);
1110
+ }
1111
+ return result;
1112
+ }
1113
+
1114
+ static VALUE
1115
+ list_unshift(VALUE self, VALUE obj)
1116
+ {
1117
+ list_t *ptr;
1118
+ item_t *first;
1119
+ Data_Get_Struct(self, list_t, ptr);
1120
+
1121
+ first = item_alloc(obj, ptr->first);
1122
+ if (ptr->first == NULL) {
1123
+ ptr->first = first;
1124
+ ptr->last = first;
1125
+ ptr->last->next = NULL;
1126
+ } else {
1127
+ ptr->first = first;
1128
+ }
1129
+ ptr->len++;
1130
+ return self;
1131
+ }
1132
+
1133
+ static VALUE
1134
+ list_unshift_m(int argc, VALUE *argv, VALUE self)
1135
+ {
1136
+ long i;
1137
+
1138
+ list_modify_check(self);
1139
+ if (argc == 0) return self;
1140
+ for (i = 0; i < argc; i++) {
1141
+ list_unshift(self, argv[i]);
1142
+ }
1143
+ return self;
1144
+ }
1145
+
1146
+ static VALUE
1147
+ list_insert(int argc, VALUE *argv, VALUE self)
1148
+ {
1149
+ list_t *ptr;
1150
+ long pos;
1151
+
1152
+ Data_Get_Struct(self, list_t, ptr);
1153
+ rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
1154
+ list_modify_check(self);
1155
+ if (argc == 1) return self;
1156
+ pos = NUM2LONG(argv[0]);
1157
+ if (pos == -1) {
1158
+ pos = ptr->len;
1159
+ }
1160
+ if (pos < 0) {
1161
+ pos++;
1162
+ }
1163
+ list_splice(self, pos, 0, rb_ary_new4(argc - 1, argv + 1));
1164
+ return self;
1165
+ }
1166
+
1167
+ static VALUE
1168
+ list_length(VALUE self)
1169
+ {
1170
+ list_t *ptr;
1171
+ Data_Get_Struct(self, list_t, ptr);
1172
+ return LONG2NUM(ptr->len);
1173
+ }
1174
+
1175
+ static VALUE
1176
+ list_empty_p(VALUE self)
1177
+ {
1178
+ list_t *ptr;
1179
+ Data_Get_Struct(self, list_t, ptr);
1180
+ if (ptr->len == 0)
1181
+ return Qtrue;
1182
+ return Qfalse;
1183
+ }
1184
+
1185
+ static VALUE
1186
+ list_rindex(int argc, VALUE *argv, VALUE self)
1187
+ {
1188
+ list_t *ptr;
1189
+ long i;
1190
+ long len;
1191
+ VALUE val;
1192
+
1193
+ Data_Get_Struct(self, list_t, ptr);
1194
+ i = ptr->len;
1195
+ if (argc == 0) {
1196
+ RETURN_ENUMERATOR(self, 0, 0);
1197
+ while (i--) {
1198
+ Data_Get_Struct(self, list_t, ptr);
1199
+ if (RTEST(rb_yield(list_elt_ptr(ptr, i))))
1200
+ return LONG2NUM(i);
1201
+ if (ptr->len < i) {
1202
+ i = ptr->len;
1203
+ }
1204
+ }
1205
+ return Qnil;
1206
+ }
1207
+ rb_check_arity(argc, 0, 1);
1208
+ val = argv[0];
1209
+ if (rb_block_given_p())
1210
+ rb_warn("given block not used");
1211
+ Data_Get_Struct(self, list_t, ptr);
1212
+ while (i--) {
1213
+ if (rb_equal(list_elt_ptr(ptr, i), val)) {
1214
+ return LONG2NUM(i);
1215
+ }
1216
+ len = ptr->len;
1217
+ if (len < i) {
1218
+ i = len;
1219
+ }
1220
+ Data_Get_Struct(self, list_t, ptr);
1221
+ }
1222
+ return Qnil;
1223
+ }
1224
+
1225
+ extern VALUE rb_output_fs;
1226
+
1227
+ static void list_join_1(VALUE obj, VALUE ary, VALUE sep, long i, VALUE result, int *first);
1228
+
1229
+ static VALUE
1230
+ recursive_join(VALUE obj, VALUE argp, int recur)
1231
+ {
1232
+ VALUE *arg = (VALUE *)argp;
1233
+ VALUE ary = arg[0];
1234
+ VALUE sep = arg[1];
1235
+ VALUE result = arg[2];
1236
+ int *first = (int *)arg[3];
1237
+
1238
+ if (recur) {
1239
+ rb_raise(rb_eArgError, "recursive list join");
1240
+ } else {
1241
+ list_join_1(obj, ary, sep, 0, result, first);
1242
+ }
1243
+ return Qnil;
1244
+ }
1245
+
1246
+ /* only string join */
1247
+ static void
1248
+ list_join_0(VALUE self, VALUE sep, long max, VALUE result)
1249
+ {
1250
+ list_t *ptr;
1251
+ item_t *c;
1252
+ long i = 1;
1253
+
1254
+ Data_Get_Struct(self, list_t, ptr);
1255
+ if (0 < max) rb_enc_copy(result, list_elt_ptr(ptr, 0));
1256
+ if (max <= i) return;
1257
+ c = ptr->first;
1258
+ rb_str_buf_append(result, c->value);
1259
+ for (c = c->next; i < max; c = c->next) {
1260
+ if (!NIL_P(sep))
1261
+ rb_str_buf_append(result, sep);
1262
+ rb_str_buf_append(result, c->value);
1263
+ i++;
1264
+ }
1265
+ }
1266
+
1267
+ /* another object join */
1268
+ static void
1269
+ list_join_1(VALUE obj, VALUE list, VALUE sep, long i, VALUE result, int *first)
1270
+ {
1271
+ list_t *ptr;
1272
+ item_t *c;
1273
+ VALUE val, tmp;
1274
+
1275
+ Data_Get_Struct(list, list_t, ptr);
1276
+ if (ptr->len == 0) return;
1277
+
1278
+ LIST_FOR(ptr, c) {
1279
+ val = c->value;
1280
+ if (0 < i++ && !NIL_P(sep))
1281
+ rb_str_buf_append(result, sep);
1282
+
1283
+ switch (rb_type(val)) {
1284
+ case T_STRING:
1285
+ str_join:
1286
+ rb_str_buf_append(result, val);
1287
+ *first = FALSE;
1288
+ break;
1289
+ case T_ARRAY:
1290
+ case T_DATA:
1291
+ obj = val;
1292
+ ary_join:
1293
+ if (val == list) {
1294
+ rb_raise(rb_eArgError, "recursive list join");
1295
+ }
1296
+ VALUE args[4];
1297
+ args[0] = val;
1298
+ args[1] = sep;
1299
+ args[2] = result;
1300
+ args[3] = (VALUE)first;
1301
+ rb_exec_recursive(recursive_join, obj, (VALUE)args);
1302
+ break;
1303
+ default:
1304
+ tmp = rb_check_string_type(val);
1305
+ if (!NIL_P(tmp)) {
1306
+ val = tmp;
1307
+ goto str_join;
1308
+ }
1309
+ tmp = rb_check_convert_type(val, T_ARRAY, "Array", "to_ary");
1310
+ if (!NIL_P(tmp)) {
1311
+ obj = val;
1312
+ val = tmp;
1313
+ goto ary_join;
1314
+ }
1315
+ val = rb_obj_as_string(val);
1316
+ if (*first) {
1317
+ rb_enc_copy(result, val);
1318
+ *first = FALSE;
1319
+ }
1320
+ goto str_join;
1321
+ }
1322
+ }
1323
+ }
1324
+
1325
+ static VALUE
1326
+ list_join(VALUE self, VALUE sep)
1327
+ {
1328
+ list_t *ptr;
1329
+ long len = 1;
1330
+ long i = 0;
1331
+ VALUE val, tmp;
1332
+ VALUE result;
1333
+ item_t *c;
1334
+ int first;
1335
+
1336
+ Data_Get_Struct(self, list_t, ptr);
1337
+ if (ptr->len == 0) return rb_usascii_str_new(0, 0);
1338
+
1339
+ if (!NIL_P(sep)) {
1340
+ StringValue(sep);
1341
+ len += RSTRING_LEN(sep) * (ptr->len - 1);
1342
+ }
1343
+ LIST_FOR(ptr, c) {
1344
+ val = c->value;
1345
+ tmp = rb_check_string_type(val);
1346
+ if (NIL_P(val) || c->value != tmp) {
1347
+ result = rb_str_buf_new(len + ptr->len);
1348
+ rb_enc_associate(result, rb_usascii_encoding());
1349
+ list_join_0(self, sep, i, result);
1350
+ first = i == 0;
1351
+ list_join_1(self, self, sep, i, result, &first);
1352
+ return result;
1353
+ }
1354
+ len += RSTRING_LEN(val);
1355
+ }
1356
+ result = rb_str_buf_new(len);
1357
+ list_join_0(self, sep, ptr->len, result);
1358
+
1359
+ return result;
1360
+ }
1361
+
1362
+ static VALUE
1363
+ list_join_m(int argc, VALUE *argv, VALUE self)
1364
+ {
1365
+ VALUE sep;
1366
+
1367
+ rb_scan_args(argc, argv, "01", &sep);
1368
+ if (NIL_P(sep)) sep = rb_output_fs;
1369
+
1370
+ return list_join(self, sep);
1371
+ }
1372
+
1373
+ static VALUE
1374
+ list_reverse_bang(VALUE self)
1375
+ {
1376
+ VALUE tmp;
1377
+ item_t *c;
1378
+ list_t *ptr;
1379
+ long len;
1380
+
1381
+ Data_Get_Struct(self, list_t, ptr);
1382
+ if (ptr->len == 0) return self;
1383
+ tmp = list_to_a(self);
1384
+ len = ptr->len;
1385
+ LIST_FOR(ptr, c) {
1386
+ c->value = rb_ary_entry(tmp, --len);
1387
+ }
1388
+ return self;
1389
+ }
1390
+
1391
+ static VALUE
1392
+ list_reverse_m(VALUE self)
1393
+ {
1394
+ VALUE result;
1395
+ item_t *c;
1396
+ list_t *ptr;
1397
+
1398
+ Data_Get_Struct(self, list_t, ptr);
1399
+ result = list_new();
1400
+ if (ptr->len == 0) return result;
1401
+ LIST_FOR(ptr, c) {
1402
+ list_unshift(result, c->value);
1403
+ }
1404
+ return result;
1405
+ }
1406
+
1407
+ static VALUE
1408
+ list_rotate_bang(int argc, VALUE *argv, VALUE self)
1409
+ {
1410
+ list_t *ptr;
1411
+ item_t *c;
1412
+ long cnt = 1;
1413
+ long i = 0;
1414
+
1415
+ switch (argc) {
1416
+ case 1: cnt = NUM2LONG(argv[0]);
1417
+ case 0: break;
1418
+ default: rb_scan_args(argc, argv, "01", NULL);
1419
+ }
1420
+
1421
+ Data_Get_Struct(self, list_t, ptr);
1422
+ if (ptr->len == 0) return self;
1423
+ cnt = (cnt < 0) ? (ptr->len - (~cnt % ptr->len) - 1) : (cnt & ptr->len);
1424
+ LIST_FOR(ptr, c) {
1425
+ if (cnt == ++i) break;
1426
+ }
1427
+ ptr->last->next = ptr->first;
1428
+ ptr->first = c->next;
1429
+ ptr->last = c;
1430
+ ptr->last->next = NULL;
1431
+ return self;
1432
+ }
1433
+
1434
+ static VALUE
1435
+ list_rotate_m(int argc, VALUE *argv, VALUE self)
1436
+ {
1437
+ VALUE clone = rb_obj_clone(self);
1438
+ return list_rotate_bang(argc, argv, clone);
1439
+ }
1440
+
1441
+ static VALUE
1442
+ list_sort_bang(VALUE self)
1443
+ {
1444
+ list_t *ptr;
1445
+ item_t *c;
1446
+ long i = 0;
1447
+
1448
+ VALUE ary = list_to_a(self);
1449
+ rb_ary_sort_bang(ary);
1450
+ Data_Get_Struct(self, list_t, ptr);
1451
+ LIST_FOR(ptr, c) {
1452
+ c->value = rb_ary_entry(ary, i++);
1453
+ }
1454
+ return self;
1455
+ }
1456
+
1457
+ static VALUE
1458
+ list_sort(VALUE self)
1459
+ {
1460
+ VALUE clone = rb_obj_clone(self);
1461
+ return list_sort_bang(clone);
1462
+ }
1463
+
1464
+ static VALUE
1465
+ sort_by_i(VALUE i, VALUE _data, int argc, VALUE *argv)
1466
+ {
1467
+ return rb_yield(i);
1468
+ }
1469
+
1470
+ static VALUE
1471
+ list_sort_by(VALUE self)
1472
+ {
1473
+ VALUE ary;
1474
+
1475
+ RETURN_SIZED_ENUMERATOR(self, 0, 0, list_enum_length);
1476
+ ary = rb_block_call(list_to_a(self), rb_intern("sort_by"), 0, 0, sort_by_i, 0);
1477
+ return to_list(ary);
1478
+ }
1479
+
1480
+ static VALUE
1481
+ list_sort_by_bang(VALUE self)
1482
+ {
1483
+ VALUE sorted;
1484
+
1485
+ sorted = list_sort_by(self);
1486
+ return list_replace(self, sorted);
1487
+ }
1488
+
1489
+ static VALUE
1490
+ list_collect_bang(VALUE self)
1491
+ {
1492
+ list_t *ptr;
1493
+ item_t *c;
1494
+
1495
+ RETURN_SIZED_ENUMERATOR(self, 0, 0, list_enum_length);
1496
+ Data_Get_Struct(self, list_t, ptr);
1497
+ LIST_FOR(ptr, c) {
1498
+ c->value = rb_yield(c->value);
1499
+ }
1500
+ return self;
1501
+ }
1502
+
1503
+ static VALUE
1504
+ list_collect(VALUE self)
1505
+ {
1506
+ return list_collect_bang(rb_obj_clone(self));
1507
+ }
1508
+
1509
+ static VALUE
1510
+ list_select(VALUE self)
1511
+ {
1512
+ VALUE result;
1513
+ list_t *ptr;
1514
+ item_t *c;
1515
+
1516
+ RETURN_SIZED_ENUMERATOR(self, 0, 0, list_enum_length);
1517
+ Data_Get_Struct(self, list_t, ptr);
1518
+ result = list_new();
1519
+ LIST_FOR(ptr, c) {
1520
+ if (RTEST(rb_yield(c->value))) {
1521
+ list_push(result, c->value);
1522
+ }
1523
+ }
1524
+ return result;
1525
+ }
1526
+
1527
+ static VALUE
1528
+ list_select_bang(VALUE self)
1529
+ {
1530
+ VALUE result;
1531
+ list_t *ptr;
1532
+ item_t *c;
1533
+ long i = 0;
1534
+
1535
+ RETURN_SIZED_ENUMERATOR(self, 0, 0, list_enum_length);
1536
+ Data_Get_Struct(self, list_t, ptr);
1537
+ result = list_new();
1538
+ LIST_FOR(ptr, c) {
1539
+ if (RTEST(rb_yield(c->value))) {
1540
+ i++;
1541
+ list_push(result, c->value);
1542
+ }
1543
+ }
1544
+
1545
+ if (i == ptr->len) return Qnil;
1546
+ return list_replace(self, result);
1547
+ }
1548
+
1549
+ static VALUE
1550
+ list_keep_if(VALUE self)
1551
+ {
1552
+ RETURN_SIZED_ENUMERATOR(self, 0, 0, list_enum_length);
1553
+ list_select_bang(self);
1554
+ return self;
1555
+ }
1556
+
1557
+ static VALUE
1558
+ list_values_at(int argc, VALUE *argv, VALUE self)
1559
+ {
1560
+ VALUE result = list_new();
1561
+ long beg, len;
1562
+ long i, j;
1563
+ list_t *ptr;
1564
+
1565
+ Data_Get_Struct(self, list_t, ptr);
1566
+ for (i = 0; i < argc; i++) {
1567
+ if (FIXNUM_P(argv[i])) {
1568
+ list_push(result, list_entry(self, FIX2LONG(argv[i])));
1569
+ } else if (rb_range_beg_len(argv[i], &beg, &len, ptr->len, 1)) {
1570
+ for (j = beg; j < beg + len; j++) {
1571
+ if (ptr->len < j) {
1572
+ list_push(result, Qnil);
1573
+ } else {
1574
+ list_push(result, list_elt_ptr(ptr, j));
1575
+ }
1576
+ }
1577
+ } else {
1578
+ list_push(result, list_entry(self, NUM2LONG(argv[i])));
1579
+ }
1580
+ }
1581
+ return result;
1582
+ }
1583
+
1584
+ static VALUE
1585
+ list_delete(VALUE self, VALUE item)
1586
+ {
1587
+ list_t *ptr;
1588
+ item_t *c, *before = NULL, *next;
1589
+ long len;
1590
+
1591
+ list_modify_check(self);
1592
+ Data_Get_Struct(self, list_t, ptr);
1593
+ if (ptr->len == 0) return Qnil;
1594
+
1595
+ len = ptr->len;
1596
+ for (c = ptr->first; c; c = next) {
1597
+ next = c->next;
1598
+ if (rb_equal(c->value, item)) {
1599
+ if (ptr->first == ptr->last) {
1600
+ ptr->first = NULL;
1601
+ ptr->last = NULL;
1602
+ } else if (c == ptr->first) {
1603
+ ptr->first = c->next;
1604
+ } else if (c == ptr->last) {
1605
+ ptr->last = before;
1606
+ ptr->last->next = NULL;
1607
+ } else {
1608
+ before->next = c->next;
1609
+ }
1610
+ xfree(c);
1611
+ ptr->len--;
1612
+ } else {
1613
+ before = c;
1614
+ }
1615
+ }
1616
+
1617
+ if (ptr->len == len) {
1618
+ if (rb_block_given_p()) {
1619
+ return rb_yield(item);
1620
+ }
1621
+ return Qnil;
1622
+ } else {
1623
+ return item;
1624
+ }
1625
+ }
1626
+
1627
+ static VALUE
1628
+ list_delete_at(VALUE self, long pos)
1629
+ {
1630
+ VALUE del;
1631
+ list_t *ptr;
1632
+ item_t *c, *before = NULL, *next;
1633
+ long len, i = 0;
1634
+
1635
+ Data_Get_Struct(self, list_t, ptr);
1636
+ len = ptr->len;
1637
+ if (ptr->len == 0) return Qnil;
1638
+ if (pos < 0) {
1639
+ pos += len;
1640
+ if (pos < 0) return Qnil;
1641
+ }
1642
+ list_modify_check(self);
1643
+
1644
+ for (c = ptr->first; c; c = next) {
1645
+ next = c->next;
1646
+ if (pos == i++) {
1647
+ del = c->value;
1648
+ if (ptr->first == ptr->last) {
1649
+ ptr->first = NULL;
1650
+ ptr->last = NULL;
1651
+ } else if (c == ptr->first) {
1652
+ ptr->first = c->next;
1653
+ } else if (c == ptr->last) {
1654
+ ptr->last = before;
1655
+ ptr->last->next = NULL;
1656
+ } else {
1657
+ before->next = c->next;
1658
+ }
1659
+ xfree(c);
1660
+ ptr->len--;
1661
+ break;
1662
+ } else {
1663
+ before = c;
1664
+ }
1665
+ }
1666
+
1667
+ if (ptr->len == len) {
1668
+ return Qnil;
1669
+ } else {
1670
+ return del;
1671
+ }
1672
+ }
1673
+
1674
+ static VALUE
1675
+ list_delete_at_m(VALUE self, VALUE pos)
1676
+ {
1677
+ return list_delete_at(self, NUM2LONG(pos));
1678
+ }
1679
+
1680
+ static VALUE
1681
+ reject(VALUE self, VALUE result)
1682
+ {
1683
+ list_t *ptr;
1684
+ item_t *c;
1685
+
1686
+ Data_Get_Struct(self, list_t, ptr);
1687
+ LIST_FOR(ptr, c) {
1688
+ if (!RTEST(rb_yield(c->value))) {
1689
+ list_push(result, c->value);
1690
+ }
1691
+ }
1692
+ return result;
1693
+ }
1694
+
1695
+ static VALUE
1696
+ reject_bang(VALUE self)
1697
+ {
1698
+ list_t *ptr;
1699
+ item_t *c, *before = NULL, *next;
1700
+ long len;
1701
+
1702
+ Data_Get_Struct(self, list_t, ptr);
1703
+ len = ptr->len;
1704
+ for (c = ptr->first; c; c = next) {
1705
+ next = c->next;
1706
+ if (RTEST(rb_yield(c->value))) {
1707
+ if (ptr->first == ptr->last) {
1708
+ ptr->first = NULL;
1709
+ ptr->last = NULL;
1710
+ } else if (c == ptr->first) {
1711
+ ptr->first = c->next;
1712
+ } else if (c == ptr->last) {
1713
+ ptr->last = before;
1714
+ ptr->last->next = NULL;
1715
+ } else {
1716
+ before->next = c->next;
1717
+ }
1718
+ xfree(c);
1719
+ ptr->len--;
1720
+ } else {
1721
+ before = c;
1722
+ }
1723
+ }
1724
+
1725
+ if (ptr->len == len) {
1726
+ return Qnil;
1727
+ } else {
1728
+ return self;
1729
+ }
1730
+ }
1731
+
1732
+ static VALUE
1733
+ list_reject_bang(VALUE self)
1734
+ {
1735
+ RETURN_SIZED_ENUMERATOR(self, 0, 0, list_enum_length);
1736
+ return reject_bang(self);
1737
+ }
1738
+
1739
+ static VALUE
1740
+ list_reject(VALUE self)
1741
+ {
1742
+ VALUE rejected_list;
1743
+
1744
+ RETURN_SIZED_ENUMERATOR(self, 0, 0, list_enum_length);
1745
+ rejected_list = list_new();
1746
+ reject(self, rejected_list);
1747
+ return rejected_list;
1748
+ }
1749
+
1750
+ static VALUE
1751
+ list_delete_if(VALUE self)
1752
+ {
1753
+ RETURN_SIZED_ENUMERATOR(self, 0, 0, list_enum_length);
1754
+ list_reject_bang(self);
1755
+ return self;
1756
+ }
1757
+
1758
+ static VALUE
1759
+ list_zip(int argc, VALUE *argv, VALUE self)
1760
+ {
1761
+ VALUE ary;
1762
+ long i;
1763
+
1764
+ ary = rb_funcall2(list_to_a(self), rb_intern("zip"), argc, argv);
1765
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
1766
+ rb_ary_store(ary, i, to_list(rb_ary_entry(ary, i)));
1767
+ }
1768
+ if (rb_block_given_p()) {
1769
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
1770
+ rb_yield(rb_ary_entry(ary, i));
1771
+ }
1772
+ return Qnil;
1773
+ } else {
1774
+ return to_list(ary);
1775
+ }
1776
+ }
1777
+
1778
+ static VALUE
1779
+ list_transpose(VALUE self)
1780
+ {
1781
+ VALUE ary;
1782
+ long i;
1783
+
1784
+ ary = rb_funcall(list_to_a(self), rb_intern("transpose"), 0);
1785
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
1786
+ rb_ary_store(ary, i, to_list(rb_ary_entry(ary, i)));
1787
+ }
1788
+ return to_list(ary);
1789
+ }
1790
+
1791
+ static VALUE
1792
+ list_fill(int argc, VALUE *argv, VALUE self)
1793
+ {
1794
+ VALUE item, arg1, arg2;
1795
+ long beg = 0, len = 0, end = 0;
1796
+ long i;
1797
+ int block_p = FALSE;
1798
+ list_t *ptr;
1799
+ item_t *c;
1800
+
1801
+ Data_Get_Struct(self, list_t, ptr);
1802
+
1803
+ list_modify_check(self);
1804
+ if (rb_block_given_p()) {
1805
+ block_p = TRUE;
1806
+ rb_scan_args(argc, argv, "02", &arg1, &arg2);
1807
+ argc += 1; /* hackish */
1808
+ } else {
1809
+ rb_scan_args(argc, argv, "12", &item, &arg1, &arg2);
1810
+ }
1811
+ switch (argc) {
1812
+ case 1:
1813
+ beg = 0;
1814
+ len = ptr->len;
1815
+ break;
1816
+ case 2:
1817
+ if (rb_range_beg_len(arg1, &beg, &len, ptr->len, 1)) {
1818
+ break;
1819
+ }
1820
+ /* fall through */
1821
+ case 3:
1822
+ beg = NIL_P(arg1) ? 0 : NUM2LONG(arg1);
1823
+ if (beg < 0) {
1824
+ beg = ptr->len + beg;
1825
+ if (beg < 0) beg = 0;
1826
+ }
1827
+ len = NIL_P(arg2) ? ptr->len - beg : NUM2LONG(arg2);
1828
+ break;
1829
+ }
1830
+ if (len < 0) {
1831
+ return self;
1832
+ }
1833
+ if (LIST_MAX_SIZE <= beg || LIST_MAX_SIZE - beg < len) {
1834
+ rb_raise(rb_eArgError, "argument too big");
1835
+ }
1836
+ end = beg + len;
1837
+ if (ptr->len < end) {
1838
+ for (i = 0; i < end - ptr->len; i++) {
1839
+ list_push(self, Qnil);
1840
+ }
1841
+ }
1842
+
1843
+ i = -1;
1844
+ LIST_FOR(ptr, c) {
1845
+ i++;
1846
+ if (i < beg) continue;
1847
+ if ((end - 1) < i) break;
1848
+ if (block_p) {
1849
+ c->value = rb_yield(LONG2NUM(i));
1850
+ } else {
1851
+ c->value = item;
1852
+ }
1853
+ }
1854
+ return self;
1855
+ }
1856
+
1857
+ static VALUE
1858
+ list_include_p(VALUE self, VALUE item)
1859
+ {
1860
+ list_t *ptr;
1861
+ item_t *c;
1862
+
1863
+ Data_Get_Struct(self, list_t, ptr);
1864
+ LIST_FOR (ptr, c) {
1865
+ if (rb_equal(c->value, item)) {
1866
+ return Qtrue;
1867
+ }
1868
+ }
1869
+ return Qfalse;
1870
+ }
1871
+
1872
+ static VALUE
1873
+ recursive_cmp(VALUE list1, VALUE list2, int recur)
1874
+ {
1875
+ list_t *p1, *p2;
1876
+ item_t *c1, *c2;
1877
+ long len;
1878
+
1879
+ if (recur) return Qundef;
1880
+ Data_Get_Struct(list1, list_t, p1);
1881
+ Data_Get_Struct(list2, list_t, p2);
1882
+ len = p1->len;
1883
+ if (p2->len < len) {
1884
+ len = p2->len;
1885
+ }
1886
+ LIST_FOR_DOUBLE(p1,c1,p2,c2,{
1887
+ VALUE v = rb_funcall2(c1->value, id_cmp, 1, &(c2->value));
1888
+ if (v != INT2FIX(0)) {
1889
+ return v;
1890
+ }
1891
+ });
1892
+ return Qundef;
1893
+ }
1894
+
1895
+ static VALUE
1896
+ list_cmp(VALUE list1, VALUE list2)
1897
+ {
1898
+ VALUE v;
1899
+ list_t *p1, *p2;
1900
+ long len;
1901
+
1902
+ if (rb_type(list2) != T_DATA) return Qnil;
1903
+ if (list1 == list2) return INT2FIX(0);
1904
+ v = rb_exec_recursive_paired(recursive_cmp, list1, list2, list2);
1905
+ if (v != Qundef) return v;
1906
+ Data_Get_Struct(list1, list_t, p1);
1907
+ Data_Get_Struct(list2, list_t, p2);
1908
+ len = p1->len - p2->len;
1909
+ if (len == 0) return INT2FIX(0);
1910
+ if (0 < len) return INT2FIX(1);
1911
+ return INT2FIX(-1);
1912
+ }
1913
+
1914
+ static VALUE
1915
+ list_slice_bang(int argc, VALUE *argv, VALUE self)
1916
+ {
1917
+ long pos = 0, len = 0;
1918
+ list_t *ptr;
1919
+
1920
+ Data_Get_Struct(self, list_t, ptr);
1921
+
1922
+ list_modify_check(self);
1923
+ if (argc == 1) {
1924
+ if (FIXNUM_P(argv[0])) {
1925
+ return list_delete_at(self, NUM2LONG(argv[0]));
1926
+ } else {
1927
+ switch (rb_range_beg_len(argv[0], &pos, &len, ptr->len, 0)) {
1928
+ case Qtrue: /* valid range */
1929
+ break;
1930
+ case Qnil: /* invalid range */
1931
+ return Qnil;
1932
+ default: /* not a range */
1933
+ return list_delete_at(self, NUM2LONG(argv[0]));
1934
+ }
1935
+ }
1936
+ } else if (argc == 2) {
1937
+ pos = NUM2LONG(argv[0]);
1938
+ len = NUM2LONG(argv[1]);
1939
+ } else {
1940
+ rb_scan_args(argc, argv, "11", NULL, NULL);
1941
+ }
1942
+ if (len < 0) return Qnil;
1943
+ if (pos < 0) {
1944
+ pos += ptr->len;
1945
+ if (pos < 0) return Qnil;
1946
+ } else if (ptr->len < pos) {
1947
+ return Qnil;
1948
+ }
1949
+ if (ptr->len < pos + len) {
1950
+ len = ptr->len - pos;
1951
+ }
1952
+ if (len == 0) return list_new();
1953
+ VALUE list2 = list_subseq(self, pos, len);
1954
+ list_mem_clear(ptr, pos, len);
1955
+ return list2;
1956
+ }
1957
+
1958
+ static VALUE
1959
+ list_ring_bang(VALUE self)
1960
+ {
1961
+ list_t *ptr;
1962
+
1963
+ Data_Get_Struct(self, list_t, ptr);
1964
+ if (ptr->first == NULL)
1965
+ rb_raise(rb_eRuntimeError, "length is zero list cannot to change ring");
1966
+ rb_obj_freeze(self);
1967
+ ptr->last->next = ptr->first;
1968
+ return self;
1969
+ }
1970
+
1971
+ static VALUE
1972
+ list_ring(VALUE self)
1973
+ {
1974
+ VALUE clone = rb_obj_clone(self);
1975
+ return list_ring_bang(clone);
1976
+ }
1977
+
1978
+ static VALUE
1979
+ list_ring_p(VALUE self)
1980
+ {
1981
+ list_t *ptr;
1982
+
1983
+ Data_Get_Struct(self, list_t, ptr);
1984
+ if (ptr->first == NULL)
1985
+ return Qfalse;
1986
+ if (ptr->first == ptr->last->next)
1987
+ return Qtrue;
1988
+ return Qfalse;
1989
+ }
1990
+
1991
+ static VALUE
1992
+ list_to_list(VALUE self)
1993
+ {
1994
+ return self;
1995
+ }
1996
+
1997
+ void
1998
+ Init_list(void)
1999
+ {
2000
+ cList = rb_define_class("List", rb_cObject);
2001
+ rb_include_module(cList, rb_mEnumerable);
2002
+
2003
+ rb_define_alloc_func(cList, list_alloc);
2004
+
2005
+ rb_define_singleton_method(cList, "[]", list_s_create, -1);
2006
+ rb_define_singleton_method(cList, "try_convert", list_s_try_convert, 1);
2007
+
2008
+ rb_define_method(cList, "initialize", list_initialize, -1);
2009
+ rb_define_method(cList, "initialize_copy", list_replace, 1);
2010
+
2011
+ rb_define_method(cList, "inspect", list_inspect, 0);
2012
+ rb_define_alias(cList, "to_s", "inspect");
2013
+ rb_define_method(cList, "to_a", list_to_a, 0);
2014
+ rb_define_method(cList, "to_ary", list_to_a, 0);
2015
+ rb_define_method(cList, "frozen?", list_frozen_p, 0);
2016
+
2017
+ rb_define_method(cList, "==", list_equal, 1);
2018
+ rb_define_method(cList, "hash", list_hash, 0);
2019
+
2020
+ rb_define_method(cList, "[]", list_aref, -1);
2021
+ rb_define_method(cList, "[]=", list_aset, -1);
2022
+ rb_define_method(cList, "at", list_at, 1);
2023
+ rb_define_method(cList, "fetch", list_fetch, -1);
2024
+ rb_define_method(cList, "first", list_first, -1);
2025
+ rb_define_method(cList, "last", list_last, -1);
2026
+ rb_define_method(cList, "concat", list_concat, 1);
2027
+ rb_define_method(cList, "<<", list_push, 1);
2028
+ rb_define_method(cList, "push", list_push_m, -1);
2029
+ rb_define_method(cList, "pop", list_pop_m, -1);
2030
+ rb_define_method(cList, "shift", list_shift_m, -1);
2031
+ rb_define_method(cList, "unshift", list_unshift_m, -1);
2032
+ rb_define_method(cList, "insert", list_insert, -1);
2033
+ rb_define_method(cList, "each", list_each, 0);
2034
+ rb_define_method(cList, "each_index", list_each_index, 0);
2035
+ rb_define_method(cList, "length", list_length, 0);
2036
+ rb_define_alias(cList, "size", "length");
2037
+ rb_define_method(cList, "empty?", list_empty_p, 0);
2038
+ rb_define_alias(cList, "index", "find_index");
2039
+ rb_define_method(cList, "rindex", list_rindex, -1);
2040
+ rb_define_method(cList, "join", list_join_m, -1);
2041
+ rb_define_method(cList, "reverse", list_reverse_m, 0);
2042
+ rb_define_method(cList, "reverse!", list_reverse_bang, 0);
2043
+ rb_define_method(cList, "rotate", list_rotate_m, -1);
2044
+ rb_define_method(cList, "rotate!", list_rotate_bang, -1);
2045
+ rb_define_method(cList, "sort", list_sort, 0);
2046
+ rb_define_method(cList, "sort!", list_sort_bang, 0);
2047
+ rb_define_method(cList, "sort_by", list_sort_by, 0);
2048
+ rb_define_method(cList, "sort_by!", list_sort_by_bang, 0);
2049
+ rb_define_method(cList, "collect", list_collect, 0);
2050
+ rb_define_method(cList, "collect!", list_collect_bang, 0);
2051
+ rb_define_method(cList, "map", list_collect, 0);
2052
+ rb_define_method(cList, "map!", list_collect_bang, 0);
2053
+ rb_define_method(cList, "select", list_select, 0);
2054
+ rb_define_method(cList, "select!", list_select_bang, 0);
2055
+ rb_define_method(cList, "keep_if", list_keep_if, 0);
2056
+ rb_define_method(cList, "values_at", list_values_at, -1);
2057
+ rb_define_method(cList, "delete", list_delete, 1);
2058
+ rb_define_method(cList, "delete_at", list_delete_at_m, 1);
2059
+ rb_define_method(cList, "delete_if", list_delete_if, 0);
2060
+ rb_define_method(cList, "reject", list_reject, 0);
2061
+ rb_define_method(cList, "reject!", list_reject_bang, 0);
2062
+ rb_define_method(cList, "zip", list_zip, -1);
2063
+ rb_define_method(cList, "transpose", list_transpose, 0);
2064
+ rb_define_method(cList, "replace", list_replace, 1);
2065
+ rb_define_method(cList, "clear", list_clear, 0);
2066
+ rb_define_method(cList, "fill", list_fill, -1);
2067
+ rb_define_method(cList, "include?", list_include_p, 1);
2068
+ rb_define_method(cList, "<=>", list_cmp, 1);
2069
+
2070
+ rb_define_method(cList, "slice", list_aref, -1);
2071
+ rb_define_method(cList, "slice!", list_slice_bang, -1);
2072
+
2073
+ rb_define_method(cList, "ring", list_ring, 0);
2074
+ rb_define_method(cList, "ring!", list_ring_bang, 0);
2075
+ rb_define_method(cList, "ring?", list_ring_p, 0);
2076
+
2077
+ rb_define_method(cList, "to_list", list_to_list, 0);
2078
+ rb_define_method(rb_mEnumerable, "to_list", ary_to_list, -1);
2079
+
2080
+ rb_define_const(cList, "VERSION", rb_str_new2(LIST_VERSION));
2081
+
2082
+ id_cmp = rb_intern("<=>");
2083
+ id_each = rb_intern("each");
2084
+ }