Update to RDoc 2.1.0 r112
[rbx.git] / lib / core_bridge / tuple.rb
blobb333033b6d8d14702d30a288adc9c8d41080a5b9
1 class Tuple
2   attr_reader :size
3   
4   def self.[](*args)
5     tuple = new(0)
6     args.each { |obj| tuple.send :append, obj }
7     tuple
8   end
9   
10   def initialize(num)
11     @size = @index = 0
12     num.times { append nil }
13   end
14   
15   # I'm not sure if these are 100% the right semantics. Please verify. -- flgr
16   def copy_from(other_tuple, start_idx = 0)
17     idx = 0
18     other_tuple.each do |value|
19       append(value) if idx >= start_idx
20       idx += 1
21     end
22   end
23   
24   def at(index)
25     guard(index)
26     locate index
27     @current.value if @current
28   end
29   alias :[] :at
30   
31   def put(index, value)
32     guard(index)
33     locate index
34     @current.value = value if @current
35   end
36   alias :[]= :put
37   
38   def each
39     return if empty?
40     reset
41     loop do
42       yield @current.value
43       break unless forward
44     end
45     self
46   end
47     
48   def empty?
49     size == 0
50   end
51   
52   def to_s
53     "#<Tuple:0x#{object_id.to_s(16)} #{fields} elements>"
54   end
56   def inspect
57     str = "#<Tuple"
58     if fields != 0
59       str << ": #{join(", ", :inspect)}"
60     end
61     str << ">"
62     return str
63   end
64   
65   def join(sep, meth=:to_s)
66     join_upto(sep, fields, meth)
67   end
68   
69   def join_upto(sep, count, meth=:to_s)
70     str = ""
71     return str if count == 0 or empty?
72     count = fields if count >= fields
73     count -= 1
74     i = 0
75     while i < count
76       str << at(i).__send__(meth)
77       str << sep.dup
78       i += 1
79     end
80     str << at(count).__send__(meth)
81     return str
82   end
83   
84   def shift
85     return self unless @head and @head.after
86     @head = @head.after
87     @head.before = nil
88     @size -= 1
89     reset
90     self
91   end
92   
93   def shifted(num)
94     tuple = Tuple.new(num + @size)
95     @size.times { |i| tuple.put num + i, at(i) }
96     tuple
97   end
98   
99   def to_a
100     ary = []
101     each do |ent|
102       ary << ent unless ent.nil?
103     end
104     return ary
105   end
106   
107   def first
108     at(0)
109   end
110   
111   def last
112     at(fields-1)
113   end
114   
115   alias :fields :size
116   alias :length :size
117   
118   private
119   
120   def guard(index)
121     raise InvalidIndexError, "Index must be positive: attempted #{index} for #{self}" if index < 0
122     raise InvalidIndexError, "Index must be less than size: attempted #{index} for #{self}" if index >= size
123   end
124   
125   def reset
126     @index = 0
127     @current = @head
128   end
129   
130   def locate(index)
131     forward while index > @index
132     backward while index < @index
133   end
134   
135   def forward
136     return if @current == @tail
137     if @current.after
138       @index += 1
139       @current = @current.after
140     end
141   end
142   
143   def backward
144     return if @current == @head
145     if @current.before
146       @index -= 1
147       @current = @current.before
148     end
149   end
150   
151   def insert(value, before, after)
152     node = Node.new(before, after, value)
153     @head = node if node.before.nil?
154     @tail = node if node.after.nil?
155     reset unless @current
156     @size += 1
157     node
158   end
159   
160   def append(value)
161     if @tail
162       node = Node.new(@tail, nil, value)
163     else
164       @head = node = Node.new(nil, nil, value)
165     end
166     reset unless @current
167     @size += 1
168     @tail = node
169   end
170   
171   class Node
172     attr_accessor :before, :after, :value
173     
174     def initialize(before, after, value=nil)
175       @value = value
176       @before = before
177       @after = after
178       before.after = self if before
179       after.before = self if after
180     end  
181   end