list 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +2 -2
- data/README.md +32 -7
- data/ext/list/list.c +209 -334
- data/list.gemspec +5 -5
- data/spec/list_spec.rb +17 -6
- metadata +16 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1ec49e723056cf0dd0c9fdcb8c7cdd665cd81592
|
4
|
+
data.tar.gz: e0e5dd911328bccbfb0cfe6c5d73f35ea1f5ed56
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1542ee023efa50f6224effd1ac55aa9192a56aa4f0a78b23431885b9748d6b8f17e037f2de0ef856c14d36d4d4dc43e0d86e5adbddedb4ec94029df98457327c
|
7
|
+
data.tar.gz: 84e1ca589a2c03b81950457a245049b6534289d8e04a21e201e8ba51db1e2cb4e5660584f91c8ab3b62a0ce86a9bdd2449e577e335e7023629a438eb0ecc7f5d
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -12,17 +12,27 @@ It's can use same as **Array**. But processing speed is different.
|
|
12
12
|
|
13
13
|
All interface is same with Array class.
|
14
14
|
|
15
|
+
```
|
16
|
+
> Array.methods - List.methods
|
17
|
+
=> []
|
18
|
+
> Array.new.methods - List.new.methods
|
19
|
+
=> []
|
20
|
+
```
|
21
|
+
|
22
|
+
List can use instead of Array.
|
23
|
+
|
15
24
|
```ruby
|
16
25
|
require 'list'
|
17
26
|
|
18
|
-
list = List.new
|
27
|
+
list = List.new # or List[]
|
19
28
|
list.push 1,2,3
|
20
|
-
list.pop
|
21
|
-
list[0,
|
29
|
+
list.pop #=> 3
|
30
|
+
list[0,2] #=> List[1,2]
|
31
|
+
list[0,1] = 5
|
22
32
|
list.each do |i|
|
23
|
-
puts i #=>
|
33
|
+
puts i #=> 5,2
|
24
34
|
end
|
25
|
-
puts List[1,2,3].map
|
35
|
+
puts List[1,2,3].map{|i| i * i}.inject(:+) #=> 14
|
26
36
|
```
|
27
37
|
|
28
38
|
+---------+ +->+---------+ +->+---------+
|
@@ -47,7 +57,8 @@ end
|
|
47
57
|
|
48
58
|
## Feature
|
49
59
|
|
50
|
-
- List have all same method with Array.
|
60
|
+
- List have all same method and behavior with Array.
|
61
|
+
- include `Enumeratable`
|
51
62
|
- **insert** and **delete** is more faster than Array.
|
52
63
|
- Can use MRI at version 1.9.3, 2.0.0 and 2.1.0.
|
53
64
|
|
@@ -55,9 +66,15 @@ end
|
|
55
66
|
|
56
67
|
`List#ring`: experimental method for expressing the ring buffer.
|
57
68
|
|
69
|
+
`List#ring!`: change self to ring buffer.
|
70
|
+
|
71
|
+
`List#ring?`: check self to ring buffer.
|
72
|
+
|
58
73
|
`Enumeratable#to_list`: all class of included Enumeratable, can convert to List instance
|
59
74
|
|
60
|
-
`List#to_list`:
|
75
|
+
`List#to_list`: return self.
|
76
|
+
|
77
|
+
`List#to_a`: change from List to Array.
|
61
78
|
|
62
79
|
## Installation
|
63
80
|
|
@@ -73,6 +90,14 @@ Or install it yourself as:
|
|
73
90
|
|
74
91
|
$ gem install list
|
75
92
|
|
93
|
+
## Testing
|
94
|
+
|
95
|
+
This library is tested using [Travis](https://travis-ci.org/ksss/list).
|
96
|
+
|
97
|
+
- MRI 2.0.0
|
98
|
+
- MRI 2.1.6
|
99
|
+
- MRI 2.2.2
|
100
|
+
|
76
101
|
## Contributing
|
77
102
|
|
78
103
|
1. Fork it ( http://github.com/ksss/list/fork )
|
data/ext/list/list.c
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#include "ruby.h"
|
2
2
|
#include "ruby/encoding.h"
|
3
3
|
|
4
|
-
#define LIST_VERSION "0.
|
4
|
+
#define LIST_VERSION "0.2.0"
|
5
5
|
|
6
6
|
VALUE cList;
|
7
7
|
|
@@ -15,7 +15,10 @@ typedef struct item_t {
|
|
15
15
|
typedef struct {
|
16
16
|
item_t *first;
|
17
17
|
item_t *last;
|
18
|
-
|
18
|
+
union {
|
19
|
+
long len;
|
20
|
+
VALUE shared;
|
21
|
+
} aux;
|
19
22
|
} list_t;
|
20
23
|
|
21
24
|
static VALUE list_push_ary(VALUE, VALUE);
|
@@ -27,6 +30,21 @@ static VALUE list_length(VALUE);
|
|
27
30
|
#define DEBUG 0
|
28
31
|
|
29
32
|
#define LIST_MAX_SIZE ULONG_MAX
|
33
|
+
#define LIST_PTR(list) ((list_t*)DATA_PTR(list))
|
34
|
+
#define LIST_PTR_LEN(ptr) (ptr)->aux.len
|
35
|
+
#define LIST_LEN(list) LIST_PTR(list)->aux.len
|
36
|
+
|
37
|
+
#define LIST_FOR(self, c) for (c = LIST_PTR(self)->first; c; c = (c)->next)
|
38
|
+
|
39
|
+
#define LIST_FOR_DOUBLE(l1, c1, l2, c2, code) do { \
|
40
|
+
c1 = LIST_PTR(l1)->first; \
|
41
|
+
c2 = LIST_PTR(l2)->first; \
|
42
|
+
while ((c1) && (c2)) { \
|
43
|
+
code; \
|
44
|
+
c1 = (c1)->next; \
|
45
|
+
c2 = (c2)->next; \
|
46
|
+
} \
|
47
|
+
} while (0)
|
30
48
|
|
31
49
|
#ifndef FALSE
|
32
50
|
# define FALSE 0
|
@@ -57,22 +75,18 @@ static VALUE list_length(VALUE);
|
|
57
75
|
static VALUE
|
58
76
|
list_enum_length(VALUE self, VALUE args, VALUE eobj)
|
59
77
|
{
|
60
|
-
|
61
|
-
Data_Get_Struct(self, list_t, ptr);
|
62
|
-
return LONG2NUM(ptr->len);
|
78
|
+
return LONG2NUM(LIST_LEN(self));
|
63
79
|
}
|
64
80
|
static VALUE
|
65
81
|
list_cycle_size(VALUE self, VALUE args, VALUE eobj)
|
66
82
|
{
|
67
83
|
VALUE n = Qnil;
|
68
|
-
list_t *ptr;
|
69
84
|
long mul;
|
70
85
|
|
71
|
-
Data_Get_Struct(self, list_t, ptr);
|
72
86
|
if (args && (0 < RARRAY_LEN(args))) {
|
73
87
|
n = rb_ary_entry(args, 0);
|
74
88
|
}
|
75
|
-
if (
|
89
|
+
if (LIST_LEN(self) == 0) return INT2FIX(0);
|
76
90
|
if (n == Qnil) return DBL2NUM(INFINITY);
|
77
91
|
mul = NUM2LONG(n);
|
78
92
|
if (mul <= 0) return INT2FIX(0);
|
@@ -89,18 +103,6 @@ struct RBasicRaw {
|
|
89
103
|
};
|
90
104
|
#endif
|
91
105
|
|
92
|
-
#define LIST_FOR(p, c) for (c = (p)->first; c; c = (c)->next)
|
93
|
-
|
94
|
-
#define LIST_FOR_DOUBLE(ptr1, c1, ptr2, c2, code) do { \
|
95
|
-
c1 = (ptr1)->first; \
|
96
|
-
c2 = (ptr2)->first; \
|
97
|
-
while ((c1) && (c2)) { \
|
98
|
-
(code); \
|
99
|
-
c1 = (c1)->next; \
|
100
|
-
c2 = (c2)->next; \
|
101
|
-
} \
|
102
|
-
} while (0)
|
103
|
-
|
104
106
|
enum list_take_pos_flags {
|
105
107
|
LIST_TAKE_FIRST,
|
106
108
|
LIST_TAKE_LAST
|
@@ -119,7 +121,7 @@ check_print(list_t *ptr, const char *msg, long lineno)
|
|
119
121
|
printf("===ERROR(%s)", msg);
|
120
122
|
printf("lineno:%ld===\n", lineno);
|
121
123
|
printf("ptr:%p\n",ptr);
|
122
|
-
printf("
|
124
|
+
printf("LIST_LEN(self):%ld\n",LIST_LEN(self));
|
123
125
|
printf("ptr->first:%p\n",ptr->first);
|
124
126
|
printf("ptr->last:%p\n",ptr->last);
|
125
127
|
rb_raise(rb_eRuntimeError, "check is NG!");
|
@@ -132,13 +134,13 @@ check(list_t *ptr, const char *msg)
|
|
132
134
|
item_t *c, *b;
|
133
135
|
long len, i;
|
134
136
|
|
135
|
-
if (ptr
|
136
|
-
if (ptr
|
137
|
-
if (ptr
|
138
|
-
if (ptr
|
137
|
+
if (LIST_PTR_LEN(ptr) == 0 && ptr->first != NULL) check_print(ptr, msg, __LINE__);
|
138
|
+
if (LIST_PTR_LEN(ptr) != 0 && ptr->first == NULL) check_print(ptr, msg, __LINE__);
|
139
|
+
if (LIST_PTR_LEN(ptr) == 0 && ptr->last != NULL) check_print(ptr, msg, __LINE__);
|
140
|
+
if (LIST_PTR_LEN(ptr) != 0 && ptr->last == NULL) check_print(ptr, msg, __LINE__);
|
139
141
|
if (ptr->first == NULL && ptr->last != NULL) check_print(ptr, msg, __LINE__);
|
140
142
|
if (ptr->first != NULL && ptr->last == NULL) check_print(ptr, msg, __LINE__);
|
141
|
-
len =
|
143
|
+
len = LIST_LEN(self);
|
142
144
|
if (len == 0) return;
|
143
145
|
i = 0;
|
144
146
|
end = ptr->last->next;
|
@@ -240,18 +242,20 @@ list_free(list_t *ptr)
|
|
240
242
|
}
|
241
243
|
|
242
244
|
static void
|
243
|
-
list_mem_clear(
|
245
|
+
list_mem_clear(VALUE self, long beg, long len)
|
244
246
|
{
|
245
247
|
long i;
|
248
|
+
list_t *ptr;
|
246
249
|
item_t *c;
|
247
250
|
item_t *next;
|
248
251
|
item_t *mid, *last;
|
249
252
|
|
250
|
-
|
253
|
+
ptr = LIST_PTR(self);
|
254
|
+
if (beg == 0 && len == LIST_LEN(self)) {
|
251
255
|
list_free(ptr);
|
252
256
|
ptr->first = NULL;
|
253
257
|
ptr->last = NULL;
|
254
|
-
|
258
|
+
LIST_LEN(self) = 0;
|
255
259
|
return;
|
256
260
|
}
|
257
261
|
|
@@ -269,7 +273,7 @@ list_mem_clear(list_t *ptr, long beg, long len)
|
|
269
273
|
break;
|
270
274
|
}
|
271
275
|
}
|
272
|
-
} else if (beg + len ==
|
276
|
+
} else if (beg + len == LIST_LEN(self)) {
|
273
277
|
for (c = ptr->first; c;) {
|
274
278
|
i++;
|
275
279
|
next = c->next;
|
@@ -300,7 +304,7 @@ list_mem_clear(list_t *ptr, long beg, long len)
|
|
300
304
|
}
|
301
305
|
}
|
302
306
|
|
303
|
-
|
307
|
+
LIST_LEN(self) -= len;
|
304
308
|
}
|
305
309
|
|
306
310
|
static inline list_t *
|
@@ -309,7 +313,7 @@ list_new_ptr(void)
|
|
309
313
|
list_t *ptr = ALLOC(list_t);
|
310
314
|
ptr->first = NULL;
|
311
315
|
ptr->last = ptr->first;
|
312
|
-
ptr
|
316
|
+
LIST_PTR_LEN(ptr) = 0;
|
313
317
|
return ptr;
|
314
318
|
}
|
315
319
|
|
@@ -352,7 +356,7 @@ list_push(VALUE self, VALUE obj)
|
|
352
356
|
ptr->last->next = next;
|
353
357
|
ptr->last = next;
|
354
358
|
}
|
355
|
-
|
359
|
+
LIST_LEN(self)++;
|
356
360
|
return self;
|
357
361
|
}
|
358
362
|
|
@@ -454,13 +458,10 @@ static VALUE
|
|
454
458
|
list_each(VALUE self)
|
455
459
|
{
|
456
460
|
item_t *c;
|
457
|
-
list_t *ptr;
|
458
461
|
|
459
462
|
RETURN_SIZED_ENUMERATOR(self, 0, 0, list_enum_length);
|
460
|
-
Data_Get_Struct(self, list_t, ptr);
|
461
|
-
if (ptr->first == NULL) return self;
|
462
463
|
|
463
|
-
LIST_FOR(
|
464
|
+
LIST_FOR(self, c) {
|
464
465
|
rb_yield(c->value);
|
465
466
|
}
|
466
467
|
return self;
|
@@ -470,15 +471,12 @@ static VALUE
|
|
470
471
|
list_each_index(VALUE self)
|
471
472
|
{
|
472
473
|
item_t *c;
|
473
|
-
list_t *ptr;
|
474
474
|
long index;
|
475
475
|
|
476
476
|
RETURN_SIZED_ENUMERATOR(self, 0, 0, list_enum_length);
|
477
|
-
Data_Get_Struct(self, list_t, ptr);
|
478
|
-
if (ptr->first == NULL) return self;
|
479
477
|
|
480
478
|
index = 0;
|
481
|
-
LIST_FOR(
|
479
|
+
LIST_FOR(self, c) {
|
482
480
|
rb_yield(LONG2NUM(index++));
|
483
481
|
}
|
484
482
|
return self;
|
@@ -493,28 +491,26 @@ list_clear(VALUE self)
|
|
493
491
|
list_free(ptr);
|
494
492
|
ptr->first = NULL;
|
495
493
|
ptr->last = NULL;
|
496
|
-
|
494
|
+
LIST_LEN(self) = 0;
|
497
495
|
return self;
|
498
496
|
}
|
499
497
|
|
500
498
|
static VALUE
|
501
499
|
list_replace_ary(VALUE copy, VALUE orig)
|
502
500
|
{
|
503
|
-
list_t *ptr_copy;
|
504
501
|
item_t *c_copy;
|
505
502
|
long i, olen;
|
506
503
|
|
507
504
|
list_modify_check(copy);
|
508
505
|
if (copy == orig) return copy;
|
509
506
|
|
510
|
-
Data_Get_Struct(copy, list_t, ptr_copy);
|
511
507
|
olen = RARRAY_LEN(orig);
|
512
508
|
if (olen == 0) {
|
513
509
|
return list_clear(copy);
|
514
510
|
}
|
515
|
-
if (olen ==
|
511
|
+
if (olen == LIST_LEN(copy)) {
|
516
512
|
i = 0;
|
517
|
-
LIST_FOR(
|
513
|
+
LIST_FOR(copy, c_copy) {
|
518
514
|
c_copy->value = rb_ary_entry(orig, i);
|
519
515
|
i++;
|
520
516
|
}
|
@@ -530,8 +526,6 @@ list_replace_ary(VALUE copy, VALUE orig)
|
|
530
526
|
static VALUE
|
531
527
|
list_replace(VALUE copy, VALUE orig)
|
532
528
|
{
|
533
|
-
list_t *ptr_copy;
|
534
|
-
list_t *ptr_orig;
|
535
529
|
item_t *c_orig;
|
536
530
|
item_t *c_copy;
|
537
531
|
long olen;
|
@@ -548,19 +542,17 @@ list_replace(VALUE copy, VALUE orig)
|
|
548
542
|
rb_raise(rb_eTypeError, "cannot convert to list");
|
549
543
|
}
|
550
544
|
orig = to_list(orig);
|
551
|
-
|
552
|
-
Data_Get_Struct(orig, list_t, ptr_orig);
|
553
|
-
olen = ptr_orig->len;
|
545
|
+
olen = LIST_LEN(orig);
|
554
546
|
if (olen == 0) {
|
555
547
|
return list_clear(copy);
|
556
548
|
}
|
557
|
-
if (olen ==
|
558
|
-
LIST_FOR_DOUBLE(
|
549
|
+
if (olen == LIST_LEN(copy)) {
|
550
|
+
LIST_FOR_DOUBLE(orig, c_orig, copy, c_copy, {
|
559
551
|
c_copy->value = c_orig->value;
|
560
552
|
});
|
561
553
|
} else {
|
562
554
|
list_clear(copy);
|
563
|
-
LIST_FOR(
|
555
|
+
LIST_FOR(orig, c_orig) {
|
564
556
|
list_push(copy, c_orig->value);
|
565
557
|
}
|
566
558
|
}
|
@@ -572,18 +564,16 @@ static VALUE
|
|
572
564
|
inspect_list(VALUE self, VALUE dummy, int recur)
|
573
565
|
{
|
574
566
|
VALUE str, s;
|
575
|
-
list_t *ptr;
|
576
567
|
item_t *c;
|
577
568
|
|
578
|
-
Data_Get_Struct(self, list_t, ptr);
|
579
569
|
if (recur) return rb_usascii_str_new_cstr("[...]");
|
580
570
|
|
581
571
|
str = rb_str_buf_new2("#<");
|
582
572
|
rb_str_buf_cat2(str, rb_obj_classname(self));
|
583
573
|
rb_str_buf_cat2(str, ": [");
|
584
|
-
LIST_FOR(
|
574
|
+
LIST_FOR(self, c) {
|
585
575
|
s = rb_inspect(c->value);
|
586
|
-
if (
|
576
|
+
if (LIST_PTR(self)->first == c) rb_enc_copy(str, s);
|
587
577
|
else rb_str_buf_cat2(str, ", ");
|
588
578
|
rb_str_buf_append(str, s);
|
589
579
|
}
|
@@ -594,9 +584,7 @@ inspect_list(VALUE self, VALUE dummy, int recur)
|
|
594
584
|
static VALUE
|
595
585
|
list_inspect(VALUE self)
|
596
586
|
{
|
597
|
-
|
598
|
-
Data_Get_Struct(self, list_t, ptr);
|
599
|
-
if (ptr->len == 0)
|
587
|
+
if (LIST_LEN(self) == 0)
|
600
588
|
return rb_sprintf("#<%s: []>", rb_obj_classname(self));
|
601
589
|
return rb_exec_recursive(inspect_list, self, 0);
|
602
590
|
}
|
@@ -604,14 +592,12 @@ list_inspect(VALUE self)
|
|
604
592
|
static VALUE
|
605
593
|
list_to_a(VALUE self)
|
606
594
|
{
|
607
|
-
list_t *ptr;
|
608
595
|
item_t *c;
|
609
596
|
VALUE ary;
|
610
597
|
long i = 0;
|
611
598
|
|
612
|
-
|
613
|
-
|
614
|
-
LIST_FOR(ptr, c) {
|
599
|
+
ary = rb_ary_new2(LIST_LEN(self));
|
600
|
+
LIST_FOR(self, c) {
|
615
601
|
rb_ary_store(ary, i++, c->value);
|
616
602
|
}
|
617
603
|
return ary;
|
@@ -627,16 +613,13 @@ list_frozen_p(VALUE self)
|
|
627
613
|
static VALUE
|
628
614
|
recursive_equal(VALUE list1, VALUE list2, int recur)
|
629
615
|
{
|
630
|
-
list_t *p1, *p2;
|
631
616
|
item_t *c1, *c2;
|
632
617
|
|
633
618
|
if (recur) return Qtrue;
|
634
619
|
|
635
|
-
|
636
|
-
Data_Get_Struct(list2, list_t, p2);
|
637
|
-
if (p1->len != p2->len) return Qfalse;
|
620
|
+
if (LIST_LEN(list1) != LIST_LEN(list2)) return Qfalse;
|
638
621
|
|
639
|
-
LIST_FOR_DOUBLE(
|
622
|
+
LIST_FOR_DOUBLE(list1, c1, list2, c2, {
|
640
623
|
if (c1->value != c2->value) {
|
641
624
|
if (!rb_equal(c1->value, c2->value)) {
|
642
625
|
return Qfalse;
|
@@ -649,9 +632,15 @@ recursive_equal(VALUE list1, VALUE list2, int recur)
|
|
649
632
|
static VALUE
|
650
633
|
list_delegate_rb(int argc, VALUE *argv, VALUE list, ID id)
|
651
634
|
{
|
652
|
-
VALUE
|
653
|
-
|
654
|
-
|
635
|
+
VALUE result;
|
636
|
+
result = rb_funcall2(list_to_a(list), id, argc, argv);
|
637
|
+
switch (rb_type(result)) {
|
638
|
+
case T_DATA:
|
639
|
+
case T_ARRAY:
|
640
|
+
return to_list(result);
|
641
|
+
default:
|
642
|
+
return result;
|
643
|
+
}
|
655
644
|
}
|
656
645
|
|
657
646
|
|
@@ -679,13 +668,11 @@ list_hash(VALUE self)
|
|
679
668
|
{
|
680
669
|
item_t *c;
|
681
670
|
st_index_t h;
|
682
|
-
list_t *ptr;
|
683
671
|
VALUE n;
|
684
672
|
|
685
|
-
|
686
|
-
h = rb_hash_start(ptr->len);
|
673
|
+
h = rb_hash_start(LIST_LEN(self));
|
687
674
|
h = rb_hash_uint(h, (st_index_t)list_hash);
|
688
|
-
LIST_FOR(
|
675
|
+
LIST_FOR(self, c) {
|
689
676
|
n = rb_hash(c->value);
|
690
677
|
h = rb_hash_uint(h, NUM2LONG(n));
|
691
678
|
}
|
@@ -694,20 +681,20 @@ list_hash(VALUE self)
|
|
694
681
|
}
|
695
682
|
|
696
683
|
static VALUE
|
697
|
-
|
684
|
+
list_elt(VALUE self, long offset)
|
698
685
|
{
|
699
686
|
long i;
|
700
|
-
item_t *c;
|
701
687
|
long len;
|
688
|
+
item_t *c;
|
702
689
|
|
703
|
-
len =
|
690
|
+
len = LIST_LEN(self);
|
704
691
|
if (len == 0) return Qnil;
|
705
692
|
if (offset < 0 || len <= offset) {
|
706
693
|
return Qnil;
|
707
694
|
}
|
708
695
|
|
709
696
|
i = 0;
|
710
|
-
LIST_FOR(
|
697
|
+
LIST_FOR(self, c) {
|
711
698
|
if (i++ == offset) {
|
712
699
|
return c->value;
|
713
700
|
}
|
@@ -715,14 +702,6 @@ list_elt_ptr(list_t* ptr, long offset)
|
|
715
702
|
return Qnil;
|
716
703
|
}
|
717
704
|
|
718
|
-
static VALUE
|
719
|
-
list_elt(VALUE self, long offset)
|
720
|
-
{
|
721
|
-
list_t *ptr;
|
722
|
-
Data_Get_Struct(self, list_t, ptr);
|
723
|
-
return list_elt_ptr(ptr, offset);
|
724
|
-
}
|
725
|
-
|
726
705
|
static VALUE
|
727
706
|
list_entry(VALUE self, long offset)
|
728
707
|
{
|
@@ -730,7 +709,7 @@ list_entry(VALUE self, long offset)
|
|
730
709
|
|
731
710
|
Data_Get_Struct(self, list_t, ptr);
|
732
711
|
if (offset < 0) {
|
733
|
-
offset +=
|
712
|
+
offset += LIST_LEN(self);
|
734
713
|
}
|
735
714
|
return list_elt(self, offset);
|
736
715
|
}
|
@@ -740,13 +719,11 @@ list_make_partial(VALUE self, VALUE klass, long offset, long len)
|
|
740
719
|
{
|
741
720
|
VALUE instance;
|
742
721
|
item_t *c;
|
743
|
-
list_t *ptr;
|
744
722
|
long i;
|
745
723
|
|
746
|
-
Data_Get_Struct(self, list_t, ptr);
|
747
724
|
instance = rb_obj_alloc(klass);
|
748
725
|
i = -1;
|
749
|
-
LIST_FOR(
|
726
|
+
LIST_FOR(self, c) {
|
750
727
|
i++;
|
751
728
|
if (i < offset) continue;
|
752
729
|
|
@@ -766,7 +743,7 @@ list_subseq(VALUE self, long beg, long len)
|
|
766
743
|
list_t *ptr;
|
767
744
|
|
768
745
|
Data_Get_Struct(self, list_t, ptr);
|
769
|
-
alen =
|
746
|
+
alen = LIST_LEN(self);
|
770
747
|
|
771
748
|
if (alen < beg) return Qnil;
|
772
749
|
if (beg < 0 || len < 0) return Qnil;
|
@@ -793,7 +770,7 @@ list_aref(int argc, VALUE *argv, VALUE self)
|
|
793
770
|
beg = NUM2LONG(argv[0]);
|
794
771
|
len = NUM2LONG(argv[1]);
|
795
772
|
if (beg < 0) {
|
796
|
-
beg +=
|
773
|
+
beg += LIST_LEN(self);
|
797
774
|
}
|
798
775
|
return list_subseq(self, beg, len);
|
799
776
|
}
|
@@ -807,7 +784,7 @@ list_aref(int argc, VALUE *argv, VALUE self)
|
|
807
784
|
return list_entry(self, FIX2LONG(arg));
|
808
785
|
}
|
809
786
|
/* check if idx is Range */
|
810
|
-
switch (rb_range_beg_len(arg, &beg, &len,
|
787
|
+
switch (rb_range_beg_len(arg, &beg, &len, LIST_LEN(self), 0)) {
|
811
788
|
case Qfalse:
|
812
789
|
break;
|
813
790
|
case Qnil:
|
@@ -823,15 +800,13 @@ list_splice(VALUE self, long beg, long len, VALUE rpl)
|
|
823
800
|
{
|
824
801
|
long i;
|
825
802
|
long rlen, olen, alen;
|
826
|
-
list_t *ptr;
|
827
803
|
item_t *c = NULL;
|
828
804
|
item_t *item_first = NULL, *item_last = NULL, *first = NULL, *last = NULL;
|
829
805
|
|
830
806
|
if (len < 0)
|
831
807
|
rb_raise(rb_eIndexError, "negative length (%ld)", len);
|
832
808
|
|
833
|
-
|
834
|
-
olen = ptr->len;
|
809
|
+
olen = LIST_LEN(self);
|
835
810
|
if (beg < 0) {
|
836
811
|
beg += olen;
|
837
812
|
if (beg < 0) {
|
@@ -848,13 +823,13 @@ list_splice(VALUE self, long beg, long len, VALUE rpl)
|
|
848
823
|
} else {
|
849
824
|
rpl = rb_ary_to_ary(rpl);
|
850
825
|
rlen = RARRAY_LEN(rpl);
|
851
|
-
olen =
|
826
|
+
olen = LIST_LEN(self);
|
852
827
|
}
|
853
828
|
if (olen <= beg) {
|
854
829
|
if (LIST_MAX_SIZE - rlen < beg) {
|
855
830
|
rb_raise(rb_eIndexError, "index %ld too big", beg);
|
856
831
|
}
|
857
|
-
for (i =
|
832
|
+
for (i = LIST_LEN(self); i < beg; i++) {
|
858
833
|
list_push(self, Qnil);
|
859
834
|
}
|
860
835
|
list_push_ary(self, rpl);
|
@@ -870,7 +845,7 @@ list_splice(VALUE self, long beg, long len, VALUE rpl)
|
|
870
845
|
item_first = c;
|
871
846
|
|
872
847
|
i = -1;
|
873
|
-
LIST_FOR(
|
848
|
+
LIST_FOR(self, c) {
|
874
849
|
i++;
|
875
850
|
if (i == beg - 1) {
|
876
851
|
first = c;
|
@@ -881,20 +856,20 @@ list_splice(VALUE self, long beg, long len, VALUE rpl)
|
|
881
856
|
}
|
882
857
|
}
|
883
858
|
if (beg == 0) {
|
884
|
-
|
859
|
+
LIST_PTR(self)->first = item_first;
|
885
860
|
} else {
|
886
861
|
first->next = item_first;
|
887
862
|
}
|
888
863
|
if (rlen == 0) {
|
889
|
-
|
890
|
-
|
864
|
+
LIST_PTR(self)->last = first;
|
865
|
+
LIST_PTR(self)->last->next = NULL;
|
891
866
|
} else {
|
892
867
|
item_last->next = last;
|
893
868
|
}
|
894
|
-
|
869
|
+
LIST_LEN(self) += rlen - len;
|
895
870
|
} else {
|
896
871
|
i = -1;
|
897
|
-
LIST_FOR(
|
872
|
+
LIST_FOR(self, c) {
|
898
873
|
i++;
|
899
874
|
if (beg <= i && i < beg + rlen) {
|
900
875
|
c->value = rb_ary_entry(rpl, i - beg);
|
@@ -909,11 +884,9 @@ static void
|
|
909
884
|
list_store(VALUE self, long idx, VALUE val)
|
910
885
|
{
|
911
886
|
item_t *c;
|
912
|
-
list_t *ptr;
|
913
887
|
long len, i;
|
914
888
|
|
915
|
-
|
916
|
-
len = ptr->len;
|
889
|
+
len = LIST_LEN(self);
|
917
890
|
|
918
891
|
if (idx < 0) {
|
919
892
|
idx += len;
|
@@ -925,14 +898,14 @@ list_store(VALUE self, long idx, VALUE val)
|
|
925
898
|
rb_raise(rb_eIndexError, "index %ld too big", idx);
|
926
899
|
}
|
927
900
|
|
928
|
-
if (
|
929
|
-
for (i =
|
901
|
+
if (LIST_LEN(self) <= idx) {
|
902
|
+
for (i = LIST_LEN(self); i <= idx; i++) {
|
930
903
|
list_push(self, Qnil);
|
931
904
|
}
|
932
905
|
}
|
933
906
|
|
934
907
|
i = -1;
|
935
|
-
LIST_FOR(
|
908
|
+
LIST_FOR(self, c) {
|
936
909
|
i++;
|
937
910
|
if (i == idx) {
|
938
911
|
c->value = val;
|
@@ -961,7 +934,7 @@ list_aset(int argc, VALUE *argv, VALUE self)
|
|
961
934
|
offset = FIX2LONG(argv[0]);
|
962
935
|
goto fixnum;
|
963
936
|
}
|
964
|
-
if (rb_range_beg_len(argv[0], &beg, &len,
|
937
|
+
if (rb_range_beg_len(argv[0], &beg, &len, LIST_LEN(self), 1)) {
|
965
938
|
/* check if idx is Range */
|
966
939
|
list_splice(self, beg, len, argv[1]);
|
967
940
|
return argv[1];
|
@@ -996,13 +969,13 @@ list_fetch(int argc, VALUE *argv, VALUE self)
|
|
996
969
|
idx = NUM2LONG(pos);
|
997
970
|
|
998
971
|
if (idx < 0) {
|
999
|
-
idx +=
|
972
|
+
idx += LIST_LEN(self);
|
1000
973
|
}
|
1001
|
-
if (idx < 0 ||
|
974
|
+
if (idx < 0 || LIST_LEN(self) <= idx) {
|
1002
975
|
if (block_given) return rb_yield(pos);
|
1003
976
|
if (argc == 1) {
|
1004
977
|
rb_raise(rb_eIndexError, "index %ld outside of array bounds: %ld...%ld",
|
1005
|
-
idx - (idx < 0 ?
|
978
|
+
idx - (idx < 0 ? LIST_LEN(self) : 0), -LIST_LEN(self), LIST_LEN(self));
|
1006
979
|
}
|
1007
980
|
return ifnone;
|
1008
981
|
}
|
@@ -1021,7 +994,7 @@ list_take_first_or_last(int argc, VALUE *argv, VALUE self, enum list_take_pos_fl
|
|
1021
994
|
Data_Get_Struct(self, list_t, ptr);
|
1022
995
|
rb_scan_args(argc, argv, "1", &nv);
|
1023
996
|
n = NUM2LONG(nv);
|
1024
|
-
len =
|
997
|
+
len = LIST_LEN(self);
|
1025
998
|
if (n > len) {
|
1026
999
|
n = len;
|
1027
1000
|
} else if (n < 0) {
|
@@ -1054,7 +1027,7 @@ list_last(int argc, VALUE *argv, VALUE self)
|
|
1054
1027
|
|
1055
1028
|
Data_Get_Struct(self, list_t, ptr);
|
1056
1029
|
if (argc == 0) {
|
1057
|
-
len =
|
1030
|
+
len = LIST_LEN(self);
|
1058
1031
|
if (len == 0) return Qnil;
|
1059
1032
|
return list_elt(self, len - 1);
|
1060
1033
|
} else {
|
@@ -1066,26 +1039,21 @@ static VALUE
|
|
1066
1039
|
list_concat(VALUE self, VALUE obj)
|
1067
1040
|
{
|
1068
1041
|
long len;
|
1069
|
-
list_t *ptr_self;
|
1070
|
-
list_t *ptr_obj;
|
1071
1042
|
enum ruby_value_type type;
|
1072
1043
|
|
1073
1044
|
list_modify_check(self);
|
1074
1045
|
type = rb_type(obj);
|
1075
1046
|
if (type == T_DATA) {
|
1076
|
-
|
1077
|
-
len = ptr_obj->len;
|
1047
|
+
len = LIST_LEN(obj);
|
1078
1048
|
} else if (type == T_ARRAY) {
|
1079
1049
|
len = RARRAY_LEN(obj);
|
1080
1050
|
} else {
|
1081
1051
|
obj = to_list(obj);
|
1082
|
-
|
1083
|
-
len = ptr_obj->len;
|
1052
|
+
len = LIST_LEN(obj);
|
1084
1053
|
}
|
1085
1054
|
|
1086
|
-
Data_Get_Struct(self, list_t, ptr_self);
|
1087
1055
|
if (0 < len) {
|
1088
|
-
list_splice(self,
|
1056
|
+
list_splice(self, LIST_LEN(self), 0, obj);
|
1089
1057
|
}
|
1090
1058
|
return self;
|
1091
1059
|
}
|
@@ -1094,20 +1062,17 @@ static VALUE
|
|
1094
1062
|
list_pop(VALUE self)
|
1095
1063
|
{
|
1096
1064
|
VALUE result;
|
1097
|
-
list_t *ptr;
|
1098
1065
|
|
1099
1066
|
list_modify_check(self);
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1103
|
-
list_mem_clear(ptr, ptr->len - 1, 1);
|
1067
|
+
if (LIST_LEN(self) == 0) return Qnil;
|
1068
|
+
result = LIST_PTR(self)->last->value;
|
1069
|
+
list_mem_clear(self, LIST_LEN(self) - 1, 1);
|
1104
1070
|
return result;
|
1105
1071
|
}
|
1106
1072
|
|
1107
1073
|
static VALUE
|
1108
1074
|
list_pop_m(int argc, VALUE *argv, VALUE self)
|
1109
1075
|
{
|
1110
|
-
list_t *ptr;
|
1111
1076
|
VALUE result;
|
1112
1077
|
long n;
|
1113
1078
|
|
@@ -1117,9 +1082,8 @@ list_pop_m(int argc, VALUE *argv, VALUE self)
|
|
1117
1082
|
|
1118
1083
|
list_modify_check(self);
|
1119
1084
|
result = list_take_first_or_last(argc, argv, self, LIST_TAKE_LAST);
|
1120
|
-
Data_Get_Struct(self, list_t, ptr);
|
1121
1085
|
n = NUM2LONG(argv[0]);
|
1122
|
-
list_mem_clear(
|
1086
|
+
list_mem_clear(self, LIST_LEN(self) - n, n);
|
1123
1087
|
return result;
|
1124
1088
|
}
|
1125
1089
|
|
@@ -1127,12 +1091,10 @@ static VALUE
|
|
1127
1091
|
list_shift(VALUE self)
|
1128
1092
|
{
|
1129
1093
|
VALUE result;
|
1130
|
-
list_t *ptr;
|
1131
1094
|
|
1132
|
-
|
1133
|
-
if (ptr->len == 0) return Qnil;
|
1095
|
+
if (LIST_LEN(self) == 0) return Qnil;
|
1134
1096
|
result = list_first(0, NULL, self);
|
1135
|
-
list_mem_clear(
|
1097
|
+
list_mem_clear(self, 0, 1);
|
1136
1098
|
return result;
|
1137
1099
|
}
|
1138
1100
|
|
@@ -1141,7 +1103,7 @@ list_shift_m(int argc, VALUE *argv, VALUE self)
|
|
1141
1103
|
{
|
1142
1104
|
VALUE result;
|
1143
1105
|
long i;
|
1144
|
-
list_t *
|
1106
|
+
list_t *ptr;
|
1145
1107
|
|
1146
1108
|
if (argc == 0) {
|
1147
1109
|
return list_shift(self);
|
@@ -1149,8 +1111,8 @@ list_shift_m(int argc, VALUE *argv, VALUE self)
|
|
1149
1111
|
|
1150
1112
|
list_modify_check(self);
|
1151
1113
|
result = list_take_first_or_last(argc, argv, self, LIST_TAKE_FIRST);
|
1152
|
-
Data_Get_Struct(result, list_t,
|
1153
|
-
for (i = 0; i <
|
1114
|
+
Data_Get_Struct(result, list_t, ptr);
|
1115
|
+
for (i = 0; i < LIST_LEN(self); i++) {
|
1154
1116
|
list_shift(self);
|
1155
1117
|
}
|
1156
1118
|
return result;
|
@@ -1171,7 +1133,7 @@ list_unshift(VALUE self, VALUE obj)
|
|
1171
1133
|
} else {
|
1172
1134
|
ptr->first = first;
|
1173
1135
|
}
|
1174
|
-
|
1136
|
+
LIST_LEN(self)++;
|
1175
1137
|
return self;
|
1176
1138
|
}
|
1177
1139
|
|
@@ -1200,7 +1162,7 @@ list_insert(int argc, VALUE *argv, VALUE self)
|
|
1200
1162
|
if (argc == 1) return self;
|
1201
1163
|
pos = NUM2LONG(argv[0]);
|
1202
1164
|
if (pos == -1) {
|
1203
|
-
pos =
|
1165
|
+
pos = LIST_LEN(self);
|
1204
1166
|
}
|
1205
1167
|
if (pos < 0) {
|
1206
1168
|
pos++;
|
@@ -1214,7 +1176,7 @@ list_length(VALUE self)
|
|
1214
1176
|
{
|
1215
1177
|
list_t *ptr;
|
1216
1178
|
Data_Get_Struct(self, list_t, ptr);
|
1217
|
-
return LONG2NUM(
|
1179
|
+
return LONG2NUM(LIST_LEN(self));
|
1218
1180
|
}
|
1219
1181
|
|
1220
1182
|
static VALUE
|
@@ -1222,7 +1184,7 @@ list_empty_p(VALUE self)
|
|
1222
1184
|
{
|
1223
1185
|
list_t *ptr;
|
1224
1186
|
Data_Get_Struct(self, list_t, ptr);
|
1225
|
-
if (
|
1187
|
+
if (LIST_LEN(self) == 0)
|
1226
1188
|
return Qtrue;
|
1227
1189
|
return Qfalse;
|
1228
1190
|
}
|
@@ -1230,21 +1192,18 @@ list_empty_p(VALUE self)
|
|
1230
1192
|
static VALUE
|
1231
1193
|
list_rindex(int argc, VALUE *argv, VALUE self)
|
1232
1194
|
{
|
1233
|
-
list_t *ptr;
|
1234
1195
|
long i;
|
1235
1196
|
long len;
|
1236
1197
|
VALUE val;
|
1237
1198
|
|
1238
|
-
|
1239
|
-
i = ptr->len;
|
1199
|
+
i = LIST_LEN(self);
|
1240
1200
|
if (argc == 0) {
|
1241
1201
|
RETURN_ENUMERATOR(self, 0, 0);
|
1242
1202
|
while (i--) {
|
1243
|
-
|
1244
|
-
if (RTEST(rb_yield(list_elt_ptr(ptr, i))))
|
1203
|
+
if (RTEST(rb_yield(list_elt(self, i))))
|
1245
1204
|
return LONG2NUM(i);
|
1246
|
-
if (
|
1247
|
-
i =
|
1205
|
+
if (LIST_LEN(self) < i) {
|
1206
|
+
i = LIST_LEN(self);
|
1248
1207
|
}
|
1249
1208
|
}
|
1250
1209
|
return Qnil;
|
@@ -1253,16 +1212,14 @@ list_rindex(int argc, VALUE *argv, VALUE self)
|
|
1253
1212
|
val = argv[0];
|
1254
1213
|
if (rb_block_given_p())
|
1255
1214
|
rb_warn("given block not used");
|
1256
|
-
Data_Get_Struct(self, list_t, ptr);
|
1257
1215
|
while (i--) {
|
1258
|
-
if (rb_equal(
|
1216
|
+
if (rb_equal(list_elt(self, i), val)) {
|
1259
1217
|
return LONG2NUM(i);
|
1260
1218
|
}
|
1261
|
-
len =
|
1219
|
+
len = LIST_LEN(self);
|
1262
1220
|
if (len < i) {
|
1263
1221
|
i = len;
|
1264
1222
|
}
|
1265
|
-
Data_Get_Struct(self, list_t, ptr);
|
1266
1223
|
}
|
1267
1224
|
return Qnil;
|
1268
1225
|
}
|
@@ -1297,7 +1254,7 @@ list_join_0(VALUE self, VALUE sep, long max, VALUE result)
|
|
1297
1254
|
long i = 1;
|
1298
1255
|
|
1299
1256
|
Data_Get_Struct(self, list_t, ptr);
|
1300
|
-
if (0 < max) rb_enc_copy(result,
|
1257
|
+
if (0 < max) rb_enc_copy(result, list_elt(self, 0));
|
1301
1258
|
if (max <= i) return;
|
1302
1259
|
c = ptr->first;
|
1303
1260
|
rb_str_buf_append(result, c->value);
|
@@ -1313,14 +1270,12 @@ list_join_0(VALUE self, VALUE sep, long max, VALUE result)
|
|
1313
1270
|
static void
|
1314
1271
|
list_join_1(VALUE obj, VALUE list, VALUE sep, long i, VALUE result, int *first)
|
1315
1272
|
{
|
1316
|
-
list_t *ptr;
|
1317
1273
|
item_t *c;
|
1318
1274
|
VALUE val, tmp;
|
1319
1275
|
|
1320
|
-
|
1321
|
-
if (ptr->len == 0) return;
|
1276
|
+
if (LIST_LEN(list) == 0) return;
|
1322
1277
|
|
1323
|
-
LIST_FOR(
|
1278
|
+
LIST_FOR(list, c) {
|
1324
1279
|
val = c->value;
|
1325
1280
|
if (0 < i++ && !NIL_P(sep))
|
1326
1281
|
rb_str_buf_append(result, sep);
|
@@ -1371,7 +1326,6 @@ list_join_1(VALUE obj, VALUE list, VALUE sep, long i, VALUE result, int *first)
|
|
1371
1326
|
static VALUE
|
1372
1327
|
list_join(VALUE self, VALUE sep)
|
1373
1328
|
{
|
1374
|
-
list_t *ptr;
|
1375
1329
|
long len = 1;
|
1376
1330
|
long i = 0;
|
1377
1331
|
VALUE val, tmp;
|
@@ -1379,18 +1333,17 @@ list_join(VALUE self, VALUE sep)
|
|
1379
1333
|
item_t *c;
|
1380
1334
|
int first;
|
1381
1335
|
|
1382
|
-
|
1383
|
-
if (ptr->len == 0) return rb_usascii_str_new(0, 0);
|
1336
|
+
if (LIST_LEN(self) == 0) return rb_usascii_str_new(0, 0);
|
1384
1337
|
|
1385
1338
|
if (!NIL_P(sep)) {
|
1386
1339
|
StringValue(sep);
|
1387
|
-
len += RSTRING_LEN(sep) * (
|
1340
|
+
len += RSTRING_LEN(sep) * (LIST_LEN(self) - 1);
|
1388
1341
|
}
|
1389
|
-
LIST_FOR(
|
1342
|
+
LIST_FOR(self, c) {
|
1390
1343
|
val = c->value;
|
1391
1344
|
tmp = rb_check_string_type(val);
|
1392
1345
|
if (NIL_P(val) || c->value != tmp) {
|
1393
|
-
result = rb_str_buf_new(len +
|
1346
|
+
result = rb_str_buf_new(len + LIST_LEN(self));
|
1394
1347
|
rb_enc_associate(result, rb_usascii_encoding());
|
1395
1348
|
list_join_0(self, sep, i, result);
|
1396
1349
|
first = i == 0;
|
@@ -1400,7 +1353,7 @@ list_join(VALUE self, VALUE sep)
|
|
1400
1353
|
len += RSTRING_LEN(val);
|
1401
1354
|
}
|
1402
1355
|
result = rb_str_buf_new(len);
|
1403
|
-
list_join_0(self, sep,
|
1356
|
+
list_join_0(self, sep, LIST_LEN(self), result);
|
1404
1357
|
|
1405
1358
|
return result;
|
1406
1359
|
}
|
@@ -1421,14 +1374,12 @@ list_reverse_bang(VALUE self)
|
|
1421
1374
|
{
|
1422
1375
|
VALUE tmp;
|
1423
1376
|
item_t *c;
|
1424
|
-
list_t *ptr;
|
1425
1377
|
long len;
|
1426
1378
|
|
1427
|
-
|
1428
|
-
if (ptr->len == 0) return self;
|
1379
|
+
if (LIST_LEN(self) == 0) return self;
|
1429
1380
|
tmp = list_to_a(self);
|
1430
|
-
len =
|
1431
|
-
LIST_FOR(
|
1381
|
+
len = LIST_LEN(self);
|
1382
|
+
LIST_FOR(self, c) {
|
1432
1383
|
c->value = rb_ary_entry(tmp, --len);
|
1433
1384
|
}
|
1434
1385
|
return self;
|
@@ -1439,12 +1390,10 @@ list_reverse_m(VALUE self)
|
|
1439
1390
|
{
|
1440
1391
|
VALUE result;
|
1441
1392
|
item_t *c;
|
1442
|
-
list_t *ptr;
|
1443
1393
|
|
1444
|
-
Data_Get_Struct(self, list_t, ptr);
|
1445
1394
|
result = list_new();
|
1446
|
-
if (
|
1447
|
-
LIST_FOR(
|
1395
|
+
if (LIST_LEN(self) == 0) return result;
|
1396
|
+
LIST_FOR(self, c) {
|
1448
1397
|
list_unshift(result, c->value);
|
1449
1398
|
}
|
1450
1399
|
return result;
|
@@ -1464,12 +1413,13 @@ list_rotate_bang(int argc, VALUE *argv, VALUE self)
|
|
1464
1413
|
default: rb_scan_args(argc, argv, "01", NULL);
|
1465
1414
|
}
|
1466
1415
|
|
1416
|
+
if (LIST_LEN(self) == 0) return self;
|
1417
|
+
cnt = (cnt < 0) ? (LIST_LEN(self) - (~cnt % LIST_LEN(self)) - 1) : (cnt & LIST_LEN(self));
|
1467
1418
|
Data_Get_Struct(self, list_t, ptr);
|
1468
|
-
|
1469
|
-
cnt = (cnt < 0) ? (ptr->len - (~cnt % ptr->len) - 1) : (cnt & ptr->len);
|
1470
|
-
LIST_FOR(ptr, c) {
|
1419
|
+
LIST_FOR(self, c) {
|
1471
1420
|
if (cnt == ++i) break;
|
1472
1421
|
}
|
1422
|
+
|
1473
1423
|
ptr->last->next = ptr->first;
|
1474
1424
|
ptr->first = c->next;
|
1475
1425
|
ptr->last = c;
|
@@ -1487,14 +1437,12 @@ list_rotate_m(int argc, VALUE *argv, VALUE self)
|
|
1487
1437
|
static VALUE
|
1488
1438
|
list_sort_bang(VALUE self)
|
1489
1439
|
{
|
1490
|
-
list_t *ptr;
|
1491
1440
|
item_t *c;
|
1492
1441
|
long i = 0;
|
1493
1442
|
|
1494
1443
|
VALUE ary = list_to_a(self);
|
1495
1444
|
rb_ary_sort_bang(ary);
|
1496
|
-
|
1497
|
-
LIST_FOR(ptr, c) {
|
1445
|
+
LIST_FOR(self, c) {
|
1498
1446
|
c->value = rb_ary_entry(ary, i++);
|
1499
1447
|
}
|
1500
1448
|
return self;
|
@@ -1535,12 +1483,10 @@ list_sort_by_bang(VALUE self)
|
|
1535
1483
|
static VALUE
|
1536
1484
|
list_collect_bang(VALUE self)
|
1537
1485
|
{
|
1538
|
-
list_t *ptr;
|
1539
1486
|
item_t *c;
|
1540
1487
|
|
1541
1488
|
RETURN_SIZED_ENUMERATOR(self, 0, 0, list_enum_length);
|
1542
|
-
|
1543
|
-
LIST_FOR(ptr, c) {
|
1489
|
+
LIST_FOR(self, c) {
|
1544
1490
|
c->value = rb_yield(c->value);
|
1545
1491
|
}
|
1546
1492
|
return self;
|
@@ -1556,13 +1502,11 @@ static VALUE
|
|
1556
1502
|
list_select(VALUE self)
|
1557
1503
|
{
|
1558
1504
|
VALUE result;
|
1559
|
-
list_t *ptr;
|
1560
1505
|
item_t *c;
|
1561
1506
|
|
1562
1507
|
RETURN_SIZED_ENUMERATOR(self, 0, 0, list_enum_length);
|
1563
|
-
Data_Get_Struct(self, list_t, ptr);
|
1564
1508
|
result = list_new();
|
1565
|
-
LIST_FOR(
|
1509
|
+
LIST_FOR(self, c) {
|
1566
1510
|
if (RTEST(rb_yield(c->value))) {
|
1567
1511
|
list_push(result, c->value);
|
1568
1512
|
}
|
@@ -1574,21 +1518,19 @@ static VALUE
|
|
1574
1518
|
list_select_bang(VALUE self)
|
1575
1519
|
{
|
1576
1520
|
VALUE result;
|
1577
|
-
list_t *ptr;
|
1578
1521
|
item_t *c;
|
1579
1522
|
long i = 0;
|
1580
1523
|
|
1581
1524
|
RETURN_SIZED_ENUMERATOR(self, 0, 0, list_enum_length);
|
1582
|
-
Data_Get_Struct(self, list_t, ptr);
|
1583
1525
|
result = list_new();
|
1584
|
-
LIST_FOR(
|
1526
|
+
LIST_FOR(self, c) {
|
1585
1527
|
if (RTEST(rb_yield(c->value))) {
|
1586
1528
|
i++;
|
1587
1529
|
list_push(result, c->value);
|
1588
1530
|
}
|
1589
1531
|
}
|
1590
1532
|
|
1591
|
-
if (i ==
|
1533
|
+
if (i == LIST_LEN(self)) return Qnil;
|
1592
1534
|
return list_replace(self, result);
|
1593
1535
|
}
|
1594
1536
|
|
@@ -1612,12 +1554,12 @@ list_values_at(int argc, VALUE *argv, VALUE self)
|
|
1612
1554
|
for (i = 0; i < argc; i++) {
|
1613
1555
|
if (FIXNUM_P(argv[i])) {
|
1614
1556
|
list_push(result, list_entry(self, FIX2LONG(argv[i])));
|
1615
|
-
} else if (rb_range_beg_len(argv[i], &beg, &len,
|
1557
|
+
} else if (rb_range_beg_len(argv[i], &beg, &len, LIST_LEN(self), 1)) {
|
1616
1558
|
for (j = beg; j < beg + len; j++) {
|
1617
|
-
if (
|
1559
|
+
if (LIST_LEN(self) < j) {
|
1618
1560
|
list_push(result, Qnil);
|
1619
1561
|
} else {
|
1620
|
-
list_push(result,
|
1562
|
+
list_push(result, list_elt(self, j));
|
1621
1563
|
}
|
1622
1564
|
}
|
1623
1565
|
} else {
|
@@ -1636,9 +1578,9 @@ list_delete(VALUE self, VALUE item)
|
|
1636
1578
|
|
1637
1579
|
list_modify_check(self);
|
1638
1580
|
Data_Get_Struct(self, list_t, ptr);
|
1639
|
-
if (
|
1581
|
+
if (LIST_LEN(self) == 0) return Qnil;
|
1640
1582
|
|
1641
|
-
len =
|
1583
|
+
len = LIST_LEN(self);
|
1642
1584
|
for (c = ptr->first; c; c = next) {
|
1643
1585
|
next = c->next;
|
1644
1586
|
if (rb_equal(c->value, item)) {
|
@@ -1654,13 +1596,13 @@ list_delete(VALUE self, VALUE item)
|
|
1654
1596
|
before->next = c->next;
|
1655
1597
|
}
|
1656
1598
|
xfree(c);
|
1657
|
-
|
1599
|
+
LIST_LEN(self)--;
|
1658
1600
|
} else {
|
1659
1601
|
before = c;
|
1660
1602
|
}
|
1661
1603
|
}
|
1662
1604
|
|
1663
|
-
if (
|
1605
|
+
if (LIST_LEN(self) == len) {
|
1664
1606
|
if (rb_block_given_p()) {
|
1665
1607
|
return rb_yield(item);
|
1666
1608
|
}
|
@@ -1679,8 +1621,8 @@ list_delete_at(VALUE self, long pos)
|
|
1679
1621
|
long len, i = 0;
|
1680
1622
|
|
1681
1623
|
Data_Get_Struct(self, list_t, ptr);
|
1682
|
-
len =
|
1683
|
-
if (
|
1624
|
+
len = LIST_LEN(self);
|
1625
|
+
if (LIST_LEN(self) == 0) return Qnil;
|
1684
1626
|
if (pos < 0) {
|
1685
1627
|
pos += len;
|
1686
1628
|
if (pos < 0) return Qnil;
|
@@ -1703,14 +1645,14 @@ list_delete_at(VALUE self, long pos)
|
|
1703
1645
|
before->next = c->next;
|
1704
1646
|
}
|
1705
1647
|
xfree(c);
|
1706
|
-
|
1648
|
+
LIST_LEN(self)--;
|
1707
1649
|
break;
|
1708
1650
|
} else {
|
1709
1651
|
before = c;
|
1710
1652
|
}
|
1711
1653
|
}
|
1712
1654
|
|
1713
|
-
if (
|
1655
|
+
if (LIST_LEN(self) == len) {
|
1714
1656
|
return Qnil;
|
1715
1657
|
} else {
|
1716
1658
|
return del;
|
@@ -1726,11 +1668,9 @@ list_delete_at_m(VALUE self, VALUE pos)
|
|
1726
1668
|
static VALUE
|
1727
1669
|
reject(VALUE self, VALUE result)
|
1728
1670
|
{
|
1729
|
-
list_t *ptr;
|
1730
1671
|
item_t *c;
|
1731
1672
|
|
1732
|
-
|
1733
|
-
LIST_FOR(ptr, c) {
|
1673
|
+
LIST_FOR(self, c) {
|
1734
1674
|
if (!RTEST(rb_yield(c->value))) {
|
1735
1675
|
list_push(result, c->value);
|
1736
1676
|
}
|
@@ -1746,7 +1686,7 @@ reject_bang(VALUE self)
|
|
1746
1686
|
long len;
|
1747
1687
|
|
1748
1688
|
Data_Get_Struct(self, list_t, ptr);
|
1749
|
-
len =
|
1689
|
+
len = LIST_LEN(self);
|
1750
1690
|
for (c = ptr->first; c; c = next) {
|
1751
1691
|
next = c->next;
|
1752
1692
|
if (RTEST(rb_yield(c->value))) {
|
@@ -1762,13 +1702,13 @@ reject_bang(VALUE self)
|
|
1762
1702
|
before->next = c->next;
|
1763
1703
|
}
|
1764
1704
|
xfree(c);
|
1765
|
-
|
1705
|
+
LIST_LEN(self)--;
|
1766
1706
|
} else {
|
1767
1707
|
before = c;
|
1768
1708
|
}
|
1769
1709
|
}
|
1770
1710
|
|
1771
|
-
if (
|
1711
|
+
if (LIST_LEN(self) == len) {
|
1772
1712
|
return Qnil;
|
1773
1713
|
} else {
|
1774
1714
|
return self;
|
@@ -1831,11 +1771,8 @@ list_fill(int argc, VALUE *argv, VALUE self)
|
|
1831
1771
|
long beg = 0, len = 0, end = 0;
|
1832
1772
|
long i;
|
1833
1773
|
int block_p = FALSE;
|
1834
|
-
list_t *ptr;
|
1835
1774
|
item_t *c;
|
1836
1775
|
|
1837
|
-
Data_Get_Struct(self, list_t, ptr);
|
1838
|
-
|
1839
1776
|
list_modify_check(self);
|
1840
1777
|
if (rb_block_given_p()) {
|
1841
1778
|
block_p = TRUE;
|
@@ -1847,20 +1784,20 @@ list_fill(int argc, VALUE *argv, VALUE self)
|
|
1847
1784
|
switch (argc) {
|
1848
1785
|
case 1:
|
1849
1786
|
beg = 0;
|
1850
|
-
len =
|
1787
|
+
len = LIST_LEN(self);
|
1851
1788
|
break;
|
1852
1789
|
case 2:
|
1853
|
-
if (rb_range_beg_len(arg1, &beg, &len,
|
1790
|
+
if (rb_range_beg_len(arg1, &beg, &len, LIST_LEN(self), 1)) {
|
1854
1791
|
break;
|
1855
1792
|
}
|
1856
1793
|
/* fall through */
|
1857
1794
|
case 3:
|
1858
1795
|
beg = NIL_P(arg1) ? 0 : NUM2LONG(arg1);
|
1859
1796
|
if (beg < 0) {
|
1860
|
-
beg =
|
1797
|
+
beg = LIST_LEN(self) + beg;
|
1861
1798
|
if (beg < 0) beg = 0;
|
1862
1799
|
}
|
1863
|
-
len = NIL_P(arg2) ?
|
1800
|
+
len = NIL_P(arg2) ? LIST_LEN(self) - beg : NUM2LONG(arg2);
|
1864
1801
|
break;
|
1865
1802
|
}
|
1866
1803
|
if (len < 0) {
|
@@ -1870,14 +1807,14 @@ list_fill(int argc, VALUE *argv, VALUE self)
|
|
1870
1807
|
rb_raise(rb_eArgError, "argument too big");
|
1871
1808
|
}
|
1872
1809
|
end = beg + len;
|
1873
|
-
if (
|
1874
|
-
for (i = 0; i < end -
|
1810
|
+
if (LIST_LEN(self) < end) {
|
1811
|
+
for (i = 0; i < end - LIST_LEN(self); i++) {
|
1875
1812
|
list_push(self, Qnil);
|
1876
1813
|
}
|
1877
1814
|
}
|
1878
1815
|
|
1879
1816
|
i = -1;
|
1880
|
-
LIST_FOR(
|
1817
|
+
LIST_FOR(self, c) {
|
1881
1818
|
i++;
|
1882
1819
|
if (i < beg) continue;
|
1883
1820
|
if ((end - 1) < i) break;
|
@@ -1893,11 +1830,9 @@ list_fill(int argc, VALUE *argv, VALUE self)
|
|
1893
1830
|
static VALUE
|
1894
1831
|
list_include_p(VALUE self, VALUE item)
|
1895
1832
|
{
|
1896
|
-
list_t *ptr;
|
1897
1833
|
item_t *c;
|
1898
1834
|
|
1899
|
-
|
1900
|
-
LIST_FOR (ptr, c) {
|
1835
|
+
LIST_FOR(self, c) {
|
1901
1836
|
if (rb_equal(c->value, item)) {
|
1902
1837
|
return Qtrue;
|
1903
1838
|
}
|
@@ -1908,18 +1843,15 @@ list_include_p(VALUE self, VALUE item)
|
|
1908
1843
|
static VALUE
|
1909
1844
|
recursive_cmp(VALUE list1, VALUE list2, int recur)
|
1910
1845
|
{
|
1911
|
-
list_t *p1, *p2;
|
1912
1846
|
item_t *c1, *c2;
|
1913
1847
|
long len;
|
1914
1848
|
|
1915
1849
|
if (recur) return Qundef;
|
1916
|
-
|
1917
|
-
|
1918
|
-
|
1919
|
-
if (p2->len < len) {
|
1920
|
-
len = p2->len;
|
1850
|
+
len = LIST_LEN(list1);
|
1851
|
+
if (LIST_LEN(list2) < len) {
|
1852
|
+
len = LIST_LEN(list2);
|
1921
1853
|
}
|
1922
|
-
LIST_FOR_DOUBLE(
|
1854
|
+
LIST_FOR_DOUBLE(list1,c1,list2,c2,{
|
1923
1855
|
VALUE v = rb_funcall2(c1->value, id_cmp, 1, &(c2->value));
|
1924
1856
|
if (v != INT2FIX(0)) {
|
1925
1857
|
return v;
|
@@ -1932,16 +1864,13 @@ static VALUE
|
|
1932
1864
|
list_cmp(VALUE list1, VALUE list2)
|
1933
1865
|
{
|
1934
1866
|
VALUE v;
|
1935
|
-
list_t *p1, *p2;
|
1936
1867
|
long len;
|
1937
1868
|
|
1938
1869
|
if (rb_type(list2) != T_DATA) return Qnil;
|
1939
1870
|
if (list1 == list2) return INT2FIX(0);
|
1940
1871
|
v = rb_exec_recursive_paired(recursive_cmp, list1, list2, list2);
|
1941
1872
|
if (v != Qundef) return v;
|
1942
|
-
|
1943
|
-
Data_Get_Struct(list2, list_t, p2);
|
1944
|
-
len = p1->len - p2->len;
|
1873
|
+
len = LIST_LEN(list1) - LIST_LEN(list2);
|
1945
1874
|
if (len == 0) return INT2FIX(0);
|
1946
1875
|
if (0 < len) return INT2FIX(1);
|
1947
1876
|
return INT2FIX(-1);
|
@@ -1951,16 +1880,13 @@ static VALUE
|
|
1951
1880
|
list_slice_bang(int argc, VALUE *argv, VALUE self)
|
1952
1881
|
{
|
1953
1882
|
long pos = 0, len = 0;
|
1954
|
-
list_t *ptr;
|
1955
|
-
|
1956
|
-
Data_Get_Struct(self, list_t, ptr);
|
1957
1883
|
|
1958
1884
|
list_modify_check(self);
|
1959
1885
|
if (argc == 1) {
|
1960
1886
|
if (FIXNUM_P(argv[0])) {
|
1961
1887
|
return list_delete_at(self, NUM2LONG(argv[0]));
|
1962
1888
|
} else {
|
1963
|
-
switch (rb_range_beg_len(argv[0], &pos, &len,
|
1889
|
+
switch (rb_range_beg_len(argv[0], &pos, &len, LIST_LEN(self), 0)) {
|
1964
1890
|
case Qtrue: /* valid range */
|
1965
1891
|
break;
|
1966
1892
|
case Qnil: /* invalid range */
|
@@ -1977,17 +1903,17 @@ list_slice_bang(int argc, VALUE *argv, VALUE self)
|
|
1977
1903
|
}
|
1978
1904
|
if (len < 0) return Qnil;
|
1979
1905
|
if (pos < 0) {
|
1980
|
-
pos +=
|
1906
|
+
pos += LIST_LEN(self);
|
1981
1907
|
if (pos < 0) return Qnil;
|
1982
|
-
} else if (
|
1908
|
+
} else if (LIST_LEN(self) < pos) {
|
1983
1909
|
return Qnil;
|
1984
1910
|
}
|
1985
|
-
if (
|
1986
|
-
len =
|
1911
|
+
if (LIST_LEN(self) < pos + len) {
|
1912
|
+
len = LIST_LEN(self) - pos;
|
1987
1913
|
}
|
1988
1914
|
if (len == 0) return list_new();
|
1989
1915
|
VALUE list2 = list_subseq(self, pos, len);
|
1990
|
-
list_mem_clear(
|
1916
|
+
list_mem_clear(self, pos, len);
|
1991
1917
|
return list2;
|
1992
1918
|
}
|
1993
1919
|
|
@@ -1995,17 +1921,13 @@ static VALUE
|
|
1995
1921
|
list_assoc(VALUE self, VALUE key)
|
1996
1922
|
{
|
1997
1923
|
VALUE v;
|
1998
|
-
list_t *ptr;
|
1999
|
-
list_t *p;
|
2000
1924
|
item_t *c;
|
2001
1925
|
|
2002
1926
|
if (list_empty_p(self)) return Qnil;
|
2003
|
-
|
2004
|
-
LIST_FOR(ptr, c) {
|
1927
|
+
LIST_FOR(self, c) {
|
2005
1928
|
v = check_list_type(c->value);
|
2006
1929
|
if (!NIL_P(v)) {
|
2007
|
-
|
2008
|
-
if (0 < p->len && rb_equal(list_first(0,NULL,v), key)) {
|
1930
|
+
if (0 < LIST_LEN(v) && rb_equal(list_first(0,NULL,v), key)) {
|
2009
1931
|
return v;
|
2010
1932
|
}
|
2011
1933
|
}
|
@@ -2017,17 +1939,13 @@ static VALUE
|
|
2017
1939
|
list_rassoc(VALUE self, VALUE value)
|
2018
1940
|
{
|
2019
1941
|
VALUE v;
|
2020
|
-
list_t *ptr;
|
2021
|
-
list_t *p;
|
2022
1942
|
item_t *c;
|
2023
1943
|
|
2024
1944
|
if (list_empty_p(self)) return Qnil;
|
2025
|
-
|
2026
|
-
LIST_FOR(ptr, c) {
|
1945
|
+
LIST_FOR(self, c) {
|
2027
1946
|
v = check_list_type(c->value);
|
2028
1947
|
if (!NIL_P(v)) {
|
2029
|
-
|
2030
|
-
if (1 < p->len && rb_equal(list_elt(v,1), value)) {
|
1948
|
+
if (1 < LIST_LEN(v) && rb_equal(list_elt(v,1), value)) {
|
2031
1949
|
return v;
|
2032
1950
|
}
|
2033
1951
|
}
|
@@ -2038,20 +1956,18 @@ list_rassoc(VALUE self, VALUE value)
|
|
2038
1956
|
static VALUE
|
2039
1957
|
list_plus(VALUE x, VALUE y)
|
2040
1958
|
{
|
2041
|
-
list_t *px, *py;
|
2042
1959
|
item_t *cx, *cy;
|
2043
1960
|
long len;
|
2044
1961
|
VALUE result;
|
2045
1962
|
|
2046
|
-
|
2047
|
-
|
2048
|
-
len = px->len + py->len;
|
1963
|
+
Check_Type(y, T_DATA);
|
1964
|
+
len = LIST_LEN(x) + LIST_LEN(y);
|
2049
1965
|
|
2050
1966
|
result = list_new();
|
2051
|
-
LIST_FOR(
|
1967
|
+
LIST_FOR(x,cx) {
|
2052
1968
|
list_push(result, cx->value);
|
2053
1969
|
}
|
2054
|
-
LIST_FOR(
|
1970
|
+
LIST_FOR(y,cy) {
|
2055
1971
|
list_push(result, cy->value);
|
2056
1972
|
}
|
2057
1973
|
return result;
|
@@ -2063,7 +1979,6 @@ list_times(VALUE self, VALUE times)
|
|
2063
1979
|
VALUE result;
|
2064
1980
|
VALUE tmp;
|
2065
1981
|
long i, len;
|
2066
|
-
list_t *ptr;
|
2067
1982
|
item_t *c;
|
2068
1983
|
|
2069
1984
|
tmp = rb_check_string_type(times);
|
@@ -2079,15 +1994,14 @@ list_times(VALUE self, VALUE times)
|
|
2079
1994
|
rb_raise(rb_eArgError, "negative argument");
|
2080
1995
|
}
|
2081
1996
|
|
2082
|
-
|
2083
|
-
if (LIST_MAX_SIZE / len < ptr->len) {
|
1997
|
+
if (LIST_MAX_SIZE / len < LIST_LEN(self)) {
|
2084
1998
|
rb_raise(rb_eArgError, "argument too big");
|
2085
1999
|
}
|
2086
2000
|
|
2087
2001
|
result = rb_obj_alloc(rb_obj_class(self));
|
2088
|
-
if (0 <
|
2002
|
+
if (0 < LIST_LEN(self)) {
|
2089
2003
|
for (i = 0; i < len; i++) {
|
2090
|
-
LIST_FOR(
|
2004
|
+
LIST_FOR(self, c) {
|
2091
2005
|
list_push(result, c->value);
|
2092
2006
|
}
|
2093
2007
|
}
|
@@ -2106,11 +2020,9 @@ list_tmp_hash_new(void)
|
|
2106
2020
|
static VALUE
|
2107
2021
|
list_add_hash(VALUE hash, VALUE list)
|
2108
2022
|
{
|
2109
|
-
list_t *ptr;
|
2110
2023
|
item_t *c;
|
2111
2024
|
|
2112
|
-
|
2113
|
-
LIST_FOR(ptr, c) {
|
2025
|
+
LIST_FOR(list, c) {
|
2114
2026
|
if (rb_hash_lookup2(hash, c->value, Qundef) == Qundef) {
|
2115
2027
|
rb_hash_aset(hash, c->value, c->value);
|
2116
2028
|
}
|
@@ -2129,11 +2041,9 @@ static VALUE
|
|
2129
2041
|
list_add_hash_by(VALUE hash, VALUE list)
|
2130
2042
|
{
|
2131
2043
|
VALUE v, k;
|
2132
|
-
list_t *ptr;
|
2133
2044
|
item_t *c;
|
2134
2045
|
|
2135
|
-
|
2136
|
-
LIST_FOR(ptr, c) {
|
2046
|
+
LIST_FOR(list, c) {
|
2137
2047
|
v = c->value;
|
2138
2048
|
k = rb_yield(v);
|
2139
2049
|
if (rb_hash_lookup2(hash, k, Qundef) == Qundef) {
|
@@ -2150,33 +2060,20 @@ list_make_hash_by(VALUE list)
|
|
2150
2060
|
return list_add_hash_by(hash, list);
|
2151
2061
|
}
|
2152
2062
|
|
2153
|
-
static inline void
|
2154
|
-
list_recycle_hash(VALUE hash)
|
2155
|
-
{
|
2156
|
-
if (RHASH(hash)->ntbl) {
|
2157
|
-
st_table *tbl = RHASH(hash)->ntbl;
|
2158
|
-
RHASH(hash)->ntbl = 0;
|
2159
|
-
st_free_table(tbl);
|
2160
|
-
}
|
2161
|
-
}
|
2162
|
-
|
2163
2063
|
static VALUE
|
2164
2064
|
list_diff(VALUE list1, VALUE list2)
|
2165
2065
|
{
|
2166
2066
|
VALUE list3;
|
2167
2067
|
volatile VALUE hash;
|
2168
|
-
list_t *ptr;
|
2169
2068
|
item_t *c;
|
2170
2069
|
|
2171
2070
|
hash = list_make_hash(to_list(list2));
|
2172
2071
|
list3 = list_new();
|
2173
2072
|
|
2174
|
-
|
2175
|
-
LIST_FOR(ptr, c) {
|
2073
|
+
LIST_FOR(list1, c) {
|
2176
2074
|
if (st_lookup(RHASH_TBL(hash), c->value, 0)) continue;
|
2177
2075
|
list_push(list3, c->value);
|
2178
2076
|
}
|
2179
|
-
list_recycle_hash(hash);
|
2180
2077
|
return list3;
|
2181
2078
|
}
|
2182
2079
|
|
@@ -2186,24 +2083,20 @@ list_and(VALUE list1, VALUE list2)
|
|
2186
2083
|
VALUE list3, hash;
|
2187
2084
|
st_table *table;
|
2188
2085
|
st_data_t vv;
|
2189
|
-
list_t *p1, *p2;
|
2190
2086
|
item_t *c1;
|
2191
2087
|
|
2192
2088
|
list2 = to_list(list2);
|
2193
2089
|
list3 = list_new();
|
2194
|
-
|
2195
|
-
if (p2->len == 0) return list3;
|
2090
|
+
if (LIST_LEN(list2) == 0) return list3;
|
2196
2091
|
hash = list_make_hash(list2);
|
2197
2092
|
table = RHASH_TBL(hash);
|
2198
2093
|
|
2199
|
-
|
2200
|
-
LIST_FOR(p1, c1) {
|
2094
|
+
LIST_FOR(list1, c1) {
|
2201
2095
|
vv = (st_data_t) c1->value;
|
2202
2096
|
if (st_delete(table, &vv, 0)) {
|
2203
2097
|
list_push(list3, c1->value);
|
2204
2098
|
}
|
2205
2099
|
}
|
2206
|
-
list_recycle_hash(hash);
|
2207
2100
|
|
2208
2101
|
return list3;
|
2209
2102
|
}
|
@@ -2231,28 +2124,24 @@ list_or(VALUE list1, VALUE list2)
|
|
2231
2124
|
{
|
2232
2125
|
VALUE hash, list3;
|
2233
2126
|
st_data_t vv;
|
2234
|
-
list_t *p1, *p2;
|
2235
2127
|
item_t *c1, *c2;
|
2236
2128
|
|
2237
2129
|
list2 = to_list(list2);
|
2238
2130
|
list3 = list_new();
|
2239
2131
|
hash = list_add_hash(list_make_hash(list1), list2);
|
2240
2132
|
|
2241
|
-
|
2242
|
-
Data_Get_Struct(list2, list_t, p2);
|
2243
|
-
LIST_FOR(p1,c1) {
|
2133
|
+
LIST_FOR(list1,c1) {
|
2244
2134
|
vv = (st_data_t)c1->value;
|
2245
2135
|
if (st_delete(RHASH_TBL(hash), &vv, 0)) {
|
2246
2136
|
list_push(list3, c1->value);
|
2247
2137
|
}
|
2248
2138
|
}
|
2249
|
-
LIST_FOR(
|
2139
|
+
LIST_FOR(list2,c2) {
|
2250
2140
|
vv = (st_data_t)c2->value;
|
2251
2141
|
if (st_delete(RHASH_TBL(hash), &vv, 0)) {
|
2252
2142
|
list_push(list3, c2->value);
|
2253
2143
|
}
|
2254
2144
|
}
|
2255
|
-
list_recycle_hash(hash);
|
2256
2145
|
return list3;
|
2257
2146
|
}
|
2258
2147
|
|
@@ -2266,10 +2155,8 @@ static VALUE
|
|
2266
2155
|
list_uniq(VALUE self)
|
2267
2156
|
{
|
2268
2157
|
VALUE hash, uniq;
|
2269
|
-
list_t *ptr;
|
2270
2158
|
|
2271
|
-
|
2272
|
-
if (ptr->len <= 1)
|
2159
|
+
if (LIST_LEN(self) <= 1)
|
2273
2160
|
return list_dup(self);
|
2274
2161
|
|
2275
2162
|
if (rb_block_given_p()) {
|
@@ -2278,7 +2165,6 @@ list_uniq(VALUE self)
|
|
2278
2165
|
hash = list_make_hash(self);
|
2279
2166
|
}
|
2280
2167
|
uniq = list_hash_values(hash);
|
2281
|
-
list_recycle_hash(hash);
|
2282
2168
|
return uniq;
|
2283
2169
|
}
|
2284
2170
|
|
@@ -2286,17 +2172,14 @@ static VALUE
|
|
2286
2172
|
list_uniq_bang(VALUE self)
|
2287
2173
|
{
|
2288
2174
|
long len;
|
2289
|
-
list_t *ptr;
|
2290
2175
|
|
2291
2176
|
list_modify_check(self);
|
2292
|
-
|
2293
|
-
len = ptr->len;
|
2177
|
+
len = LIST_LEN(self);
|
2294
2178
|
if (len <= 1)
|
2295
2179
|
return Qnil;
|
2296
2180
|
|
2297
2181
|
list_replace(self, list_uniq(self));
|
2298
|
-
|
2299
|
-
if (len == ptr->len) {
|
2182
|
+
if (len == LIST_LEN(self)) {
|
2300
2183
|
return Qnil;
|
2301
2184
|
}
|
2302
2185
|
|
@@ -2307,14 +2190,11 @@ static VALUE
|
|
2307
2190
|
list_compact_bang(VALUE self)
|
2308
2191
|
{
|
2309
2192
|
long len;
|
2310
|
-
list_t *ptr;
|
2311
2193
|
|
2312
2194
|
list_modify_check(self);
|
2313
|
-
|
2314
|
-
len = ptr->len;
|
2195
|
+
len = LIST_LEN(self);
|
2315
2196
|
list_delete(self, Qnil);
|
2316
|
-
|
2317
|
-
if (len == ptr->len) {
|
2197
|
+
if (len == LIST_LEN(self)) {
|
2318
2198
|
return Qnil;
|
2319
2199
|
}
|
2320
2200
|
return self;
|
@@ -2331,9 +2211,7 @@ list_compact(VALUE self)
|
|
2331
2211
|
static VALUE
|
2332
2212
|
list_make_shared_copy(VALUE list)
|
2333
2213
|
{
|
2334
|
-
|
2335
|
-
Data_Get_Struct(list, list_t, ptr);
|
2336
|
-
return list_make_partial(list, rb_obj_class(list), 0, ptr->len);
|
2214
|
+
return list_make_partial(list, rb_obj_class(list), 0, LIST_LEN(list));
|
2337
2215
|
}
|
2338
2216
|
|
2339
2217
|
static VALUE
|
@@ -2411,16 +2289,14 @@ static VALUE
|
|
2411
2289
|
list_count(int argc, VALUE *argv, VALUE self)
|
2412
2290
|
{
|
2413
2291
|
VALUE obj;
|
2414
|
-
list_t *ptr;
|
2415
2292
|
item_t *c;
|
2416
2293
|
long n = 0;
|
2417
2294
|
|
2418
|
-
Data_Get_Struct(self, list_t, ptr);
|
2419
2295
|
if (argc == 0) {
|
2420
2296
|
if (!rb_block_given_p()) {
|
2421
2297
|
return list_length(self);
|
2422
2298
|
}
|
2423
|
-
LIST_FOR(
|
2299
|
+
LIST_FOR(self,c) {
|
2424
2300
|
if (RTEST(rb_yield(c->value))) n++;
|
2425
2301
|
}
|
2426
2302
|
} else {
|
@@ -2428,7 +2304,7 @@ list_count(int argc, VALUE *argv, VALUE self)
|
|
2428
2304
|
if (rb_block_given_p()) {
|
2429
2305
|
rb_warn("given block not used");
|
2430
2306
|
}
|
2431
|
-
LIST_FOR(
|
2307
|
+
LIST_FOR(self,c) {
|
2432
2308
|
if (rb_equal(c->value, obj)) n++;
|
2433
2309
|
}
|
2434
2310
|
}
|
@@ -2457,7 +2333,6 @@ static VALUE
|
|
2457
2333
|
list_cycle(int argc, VALUE *argv, VALUE self)
|
2458
2334
|
{
|
2459
2335
|
VALUE nv = Qnil;
|
2460
|
-
list_t *ptr;
|
2461
2336
|
item_t *c;
|
2462
2337
|
long n;
|
2463
2338
|
|
@@ -2471,10 +2346,8 @@ list_cycle(int argc, VALUE *argv, VALUE self)
|
|
2471
2346
|
if (n <= 0) return Qnil;
|
2472
2347
|
}
|
2473
2348
|
|
2474
|
-
|
2475
|
-
|
2476
|
-
Data_Get_Struct(self, list_t, ptr);
|
2477
|
-
LIST_FOR(ptr, c) {
|
2349
|
+
while (0 < LIST_LEN(self) && (n < 0 || 0 < n--)) {
|
2350
|
+
LIST_FOR(self, c) {
|
2478
2351
|
rb_yield(c->value);
|
2479
2352
|
if (list_empty_p(self)) break;
|
2480
2353
|
}
|
@@ -2526,13 +2399,11 @@ list_take(VALUE self, VALUE n)
|
|
2526
2399
|
static VALUE
|
2527
2400
|
list_take_while(VALUE self)
|
2528
2401
|
{
|
2529
|
-
list_t *ptr;
|
2530
2402
|
item_t *c;
|
2531
2403
|
long i = 0;
|
2532
2404
|
|
2533
2405
|
RETURN_ENUMERATOR(self, 0, 0);
|
2534
|
-
|
2535
|
-
LIST_FOR(ptr, c) {
|
2406
|
+
LIST_FOR(self, c) {
|
2536
2407
|
if (!RTEST(rb_yield(c->value))) break;
|
2537
2408
|
i++;
|
2538
2409
|
}
|
@@ -2542,15 +2413,13 @@ list_take_while(VALUE self)
|
|
2542
2413
|
static VALUE
|
2543
2414
|
list_drop(VALUE self, VALUE n)
|
2544
2415
|
{
|
2545
|
-
list_t *ptr;
|
2546
2416
|
VALUE result;
|
2547
2417
|
long pos = NUM2LONG(n);
|
2548
2418
|
|
2549
2419
|
if (pos < 0) {
|
2550
2420
|
rb_raise(rb_eArgError, "attempt to drop negative size");
|
2551
2421
|
}
|
2552
|
-
|
2553
|
-
result = list_subseq(self, pos, ptr->len);
|
2422
|
+
result = list_subseq(self, pos, LIST_LEN(self));
|
2554
2423
|
if (result == Qnil) result = list_new();
|
2555
2424
|
return result;
|
2556
2425
|
}
|
@@ -2559,12 +2428,10 @@ static VALUE
|
|
2559
2428
|
list_drop_while(VALUE self)
|
2560
2429
|
{
|
2561
2430
|
long i = 0;
|
2562
|
-
list_t *ptr;
|
2563
2431
|
item_t *c;
|
2564
2432
|
|
2565
2433
|
RETURN_ENUMERATOR(self, 0, 0);
|
2566
|
-
|
2567
|
-
LIST_FOR(ptr, c) {
|
2434
|
+
LIST_FOR(self, c) {
|
2568
2435
|
if (!RTEST(rb_yield(c->value))) break;
|
2569
2436
|
i++;
|
2570
2437
|
}
|
@@ -2665,6 +2532,12 @@ list_to_list(VALUE self)
|
|
2665
2532
|
return self;
|
2666
2533
|
}
|
2667
2534
|
|
2535
|
+
static VALUE
|
2536
|
+
list_pack(VALUE self, VALUE str)
|
2537
|
+
{
|
2538
|
+
return list_delegate_rb(1, &str, self, rb_intern("pack"));
|
2539
|
+
}
|
2540
|
+
|
2668
2541
|
void
|
2669
2542
|
Init_list(void)
|
2670
2543
|
{
|
@@ -2780,6 +2653,8 @@ Init_list(void)
|
|
2780
2653
|
rb_define_method(cList, "to_list", list_to_list, 0);
|
2781
2654
|
rb_define_method(rb_mEnumerable, "to_list", ary_to_list, -1);
|
2782
2655
|
|
2656
|
+
rb_define_method(cList, "pack", list_pack, 1);
|
2657
|
+
|
2783
2658
|
rb_define_const(cList, "VERSION", rb_str_new2(LIST_VERSION));
|
2784
2659
|
|
2785
2660
|
id_cmp = rb_intern("<=>");
|