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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 19c155867c4ea51522fcf35eed15b5a2c0ea1ec5
4
- data.tar.gz: 896b93da2032c345bc80783aaef475e0079d469d
3
+ metadata.gz: 1ec49e723056cf0dd0c9fdcb8c7cdd665cd81592
4
+ data.tar.gz: e0e5dd911328bccbfb0cfe6c5d73f35ea1f5ed56
5
5
  SHA512:
6
- metadata.gz: 32552315f59851548203a9f24cd11ebf26a69f77e1680060079e117294c35b7a03f901ece9badf8bb3ec2d0a4d45ef542bf910c0eaccfc2e9d1ed4fabc92b4e0
7
- data.tar.gz: 33bd08bb57fcae3952b2793489cff8ef29c1c9ca594f429fc02d95023d6edd7fc0e826747edbb53d1ecdb5549787cd0276b702de1d8b499ad64d42e78562f59e
6
+ metadata.gz: 1542ee023efa50f6224effd1ac55aa9192a56aa4f0a78b23431885b9748d6b8f17e037f2de0ef856c14d36d4d4dc43e0d86e5adbddedb4ec94029df98457327c
7
+ data.tar.gz: 84e1ca589a2c03b81950457a245049b6534289d8e04a21e201e8ba51db1e2cb4e5660584f91c8ab3b62a0ce86a9bdd2449e577e335e7023629a438eb0ecc7f5d
@@ -1,5 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.9.3
4
3
  - 2.0.0
5
- - 2.1.0
4
+ - 2.1.6
5
+ - 2.2.2
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,1] = 1
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 #=> 1,2
33
+ puts i #=> 5,2
24
34
  end
25
- puts List[1,2,3].map {|i| i * i}.inject(:+) #=> 14
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`: is for duck typing this.
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 )
@@ -1,7 +1,7 @@
1
1
  #include "ruby.h"
2
2
  #include "ruby/encoding.h"
3
3
 
4
- #define LIST_VERSION "0.1.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
- long len;
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
- list_t *ptr;
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 (ptr->len == 0) return INT2FIX(0);
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("ptr->len:%ld\n",ptr->len);
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->len == 0 && ptr->first != NULL) check_print(ptr, msg, __LINE__);
136
- if (ptr->len != 0 && ptr->first == NULL) check_print(ptr, msg, __LINE__);
137
- if (ptr->len == 0 && ptr->last != NULL) check_print(ptr, msg, __LINE__);
138
- if (ptr->len != 0 && ptr->last == NULL) check_print(ptr, msg, __LINE__);
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 = ptr->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(list_t *ptr, long beg, long len)
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
- if (beg == 0 && len == ptr->len) {
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
- ptr->len = 0;
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 == ptr->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
- ptr->len -= len;
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->len = 0;
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
- ptr->len++;
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(ptr, c) {
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(ptr, c) {
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
- ptr->len = 0;
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 == ptr_copy->len) {
511
+ if (olen == LIST_LEN(copy)) {
516
512
  i = 0;
517
- LIST_FOR(ptr_copy, c_copy) {
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
- Data_Get_Struct(copy, list_t, ptr_copy);
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 == ptr_copy->len) {
558
- LIST_FOR_DOUBLE(ptr_orig, c_orig, ptr_copy, c_copy, {
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(ptr_orig, c_orig) {
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(ptr, c) {
574
+ LIST_FOR(self, c) {
585
575
  s = rb_inspect(c->value);
586
- if (ptr->first == c) rb_enc_copy(str, s);
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
- list_t *ptr;
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
- Data_Get_Struct(self, list_t, ptr);
613
- ary = rb_ary_new2(ptr->len);
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
- Data_Get_Struct(list1, list_t, p1);
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(p1, c1, p2, c2, {
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 ary;
653
- ary = rb_funcall2(list_to_a(list), id, argc, argv);
654
- return to_list(ary);
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
- Data_Get_Struct(self, list_t, ptr);
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(ptr, c) {
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
- list_elt_ptr(list_t* ptr, long offset)
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 = ptr->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(ptr, c) {
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 += ptr->len;
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(ptr, c) {
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 = ptr->len;
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 += ptr->len;
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, ptr->len, 0)) {
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
- Data_Get_Struct(self, list_t, ptr);
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 = ptr->len;
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 = ptr->len; i < beg; 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(ptr, c) {
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
- ptr->first = item_first;
859
+ LIST_PTR(self)->first = item_first;
885
860
  } else {
886
861
  first->next = item_first;
887
862
  }
888
863
  if (rlen == 0) {
889
- ptr->last = first;
890
- ptr->last->next = NULL;
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
- ptr->len += rlen - len;
869
+ LIST_LEN(self) += rlen - len;
895
870
  } else {
896
871
  i = -1;
897
- LIST_FOR(ptr, c) {
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
- Data_Get_Struct(self, list_t, ptr);
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 (ptr->len <= idx) {
929
- for (i = ptr->len; i <= idx; 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(ptr, c) {
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, ptr->len, 1)) {
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 += ptr->len;
972
+ idx += LIST_LEN(self);
1000
973
  }
1001
- if (idx < 0 || ptr->len <= idx) {
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 ? ptr->len : 0), -ptr->len, ptr->len);
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 = ptr->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 = ptr->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
- Data_Get_Struct(obj, list_t, ptr_obj);
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
- Data_Get_Struct(obj, list_t, ptr_obj);
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, ptr_self->len, 0, obj);
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
- Data_Get_Struct(self, list_t, ptr);
1101
- if (ptr->len == 0) return Qnil;
1102
- result = ptr->last->value;
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(ptr, ptr->len - n, n);
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
- Data_Get_Struct(self, list_t, ptr);
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(ptr, 0, 1);
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 *ptr_res;
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, ptr_res);
1153
- for (i = 0; i < ptr_res->len; 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
- ptr->len++;
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 = ptr->len;
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(ptr->len);
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 (ptr->len == 0)
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
- Data_Get_Struct(self, list_t, ptr);
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
- Data_Get_Struct(self, list_t, ptr);
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 (ptr->len < i) {
1247
- i = ptr->len;
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(list_elt_ptr(ptr, i), val)) {
1216
+ if (rb_equal(list_elt(self, i), val)) {
1259
1217
  return LONG2NUM(i);
1260
1218
  }
1261
- len = ptr->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, list_elt_ptr(ptr, 0));
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
- Data_Get_Struct(list, list_t, ptr);
1321
- if (ptr->len == 0) return;
1276
+ if (LIST_LEN(list) == 0) return;
1322
1277
 
1323
- LIST_FOR(ptr, c) {
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
- Data_Get_Struct(self, list_t, ptr);
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) * (ptr->len - 1);
1340
+ len += RSTRING_LEN(sep) * (LIST_LEN(self) - 1);
1388
1341
  }
1389
- LIST_FOR(ptr, c) {
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 + ptr->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, ptr->len, result);
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
- Data_Get_Struct(self, list_t, ptr);
1428
- if (ptr->len == 0) return self;
1379
+ if (LIST_LEN(self) == 0) return self;
1429
1380
  tmp = list_to_a(self);
1430
- len = ptr->len;
1431
- LIST_FOR(ptr, c) {
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 (ptr->len == 0) return result;
1447
- LIST_FOR(ptr, c) {
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
- if (ptr->len == 0) return self;
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
- Data_Get_Struct(self, list_t, ptr);
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
- Data_Get_Struct(self, list_t, ptr);
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(ptr, c) {
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(ptr, c) {
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 == ptr->len) return Qnil;
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, ptr->len, 1)) {
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 (ptr->len < j) {
1559
+ if (LIST_LEN(self) < j) {
1618
1560
  list_push(result, Qnil);
1619
1561
  } else {
1620
- list_push(result, list_elt_ptr(ptr, j));
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 (ptr->len == 0) return Qnil;
1581
+ if (LIST_LEN(self) == 0) return Qnil;
1640
1582
 
1641
- len = ptr->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
- ptr->len--;
1599
+ LIST_LEN(self)--;
1658
1600
  } else {
1659
1601
  before = c;
1660
1602
  }
1661
1603
  }
1662
1604
 
1663
- if (ptr->len == len) {
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 = ptr->len;
1683
- if (ptr->len == 0) return Qnil;
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
- ptr->len--;
1648
+ LIST_LEN(self)--;
1707
1649
  break;
1708
1650
  } else {
1709
1651
  before = c;
1710
1652
  }
1711
1653
  }
1712
1654
 
1713
- if (ptr->len == len) {
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
- Data_Get_Struct(self, list_t, ptr);
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 = ptr->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
- ptr->len--;
1705
+ LIST_LEN(self)--;
1766
1706
  } else {
1767
1707
  before = c;
1768
1708
  }
1769
1709
  }
1770
1710
 
1771
- if (ptr->len == len) {
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 = ptr->len;
1787
+ len = LIST_LEN(self);
1851
1788
  break;
1852
1789
  case 2:
1853
- if (rb_range_beg_len(arg1, &beg, &len, ptr->len, 1)) {
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 = ptr->len + beg;
1797
+ beg = LIST_LEN(self) + beg;
1861
1798
  if (beg < 0) beg = 0;
1862
1799
  }
1863
- len = NIL_P(arg2) ? ptr->len - beg : NUM2LONG(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 (ptr->len < end) {
1874
- for (i = 0; i < end - ptr->len; i++) {
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(ptr, c) {
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
- Data_Get_Struct(self, list_t, ptr);
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
- Data_Get_Struct(list1, list_t, p1);
1917
- Data_Get_Struct(list2, list_t, p2);
1918
- len = p1->len;
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(p1,c1,p2,c2,{
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
- Data_Get_Struct(list1, list_t, p1);
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, ptr->len, 0)) {
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 += ptr->len;
1906
+ pos += LIST_LEN(self);
1981
1907
  if (pos < 0) return Qnil;
1982
- } else if (ptr->len < pos) {
1908
+ } else if (LIST_LEN(self) < pos) {
1983
1909
  return Qnil;
1984
1910
  }
1985
- if (ptr->len < pos + len) {
1986
- len = ptr->len - pos;
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(ptr, pos, len);
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
- Data_Get_Struct(self, list_t, ptr);
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
- Data_Get_Struct(v, list_t, p);
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
- Data_Get_Struct(self, list_t, ptr);
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
- Data_Get_Struct(v, list_t, p);
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
- Data_Get_Struct(x, list_t, px);
2047
- Data_Get_Struct(y, list_t, py);
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(px,cx) {
1967
+ LIST_FOR(x,cx) {
2052
1968
  list_push(result, cx->value);
2053
1969
  }
2054
- LIST_FOR(py,cy) {
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
- Data_Get_Struct(self, list_t, ptr);
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 < ptr->len) {
2002
+ if (0 < LIST_LEN(self)) {
2089
2003
  for (i = 0; i < len; i++) {
2090
- LIST_FOR(ptr, c) {
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
- Data_Get_Struct(list, list_t, ptr);
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
- Data_Get_Struct(list, list_t, ptr);
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
- Data_Get_Struct(list1, list_t, ptr);
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
- Data_Get_Struct(list2, list_t, p2);
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
- Data_Get_Struct(list1, list_t, p1);
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
- Data_Get_Struct(list1, list_t, p1);
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(p2,c2) {
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
- Data_Get_Struct(self, list_t, ptr);
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
- Data_Get_Struct(self, list_t, ptr);
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
- Data_Get_Struct(self, list_t, ptr);
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
- Data_Get_Struct(self, list_t, ptr);
2314
- len = ptr->len;
2195
+ len = LIST_LEN(self);
2315
2196
  list_delete(self, Qnil);
2316
- Data_Get_Struct(self, list_t, ptr);
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
- list_t *ptr;
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(ptr,c) {
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(ptr,c) {
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
- Data_Get_Struct(self, list_t, ptr);
2475
- while (0 < ptr->len && (n < 0 || 0 < n--)) {
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
- Data_Get_Struct(self, list_t, ptr);
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
- Data_Get_Struct(self, list_t, ptr);
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
- Data_Get_Struct(self, list_t, ptr);
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("<=>");