1 (***********************************************************************)
5 (* François Pottier, projet Cristal, INRIA Rocquencourt *)
7 (* Copyright 2002 Institut National de Recherche en Informatique et *)
8 (* en Automatique. All rights reserved. This file is distributed *)
9 (* under the terms of the GNU Library General Public License, with *)
10 (* the special exception on linking described in file ../LICENSE. *)
12 (***********************************************************************)
18 (* O'Caml currently does not allow the components of a sum type to be
19 mutable. Yet, for optimal space efficiency, we must have cons cells
20 whose [next] field is mutable. This leads us to define a type of
21 cyclic lists, so as to eliminate the [Nil] case and the sum
29 (* A queue is a reference to either nothing or some cell of a cyclic
30 list. By convention, that cell is to be viewed as the last cell in
31 the queue. The first cell in the queue is then found in constant
32 time: it is the next cell in the cyclic list. The queue's length is
33 also recorded, so as to make [length] a constant-time operation.
35 The [tail] field should really be of type ['a cell option], but
36 then it would be [None] when [length] is 0 and [Some] otherwise,
37 leading to redundant memory allocation and accesses. We avoid this
38 overhead by filling [tail] with a dummy value when [length] is 0.
39 Of course, this requires bending the type system's arm slightly,
40 because it does not have dependent sums. *)
54 q
.tail
<- Obj.magic None
57 q
.length
<- q
.length
+ 1;
66 let head = tail.next
in
87 if q
.length
= 0 then raise Empty
;
88 q
.length
<- q
.length
- 1;
90 let head = tail.next
in
92 q
.tail <- Obj.magic None
94 tail.next
<- head.next
;
107 content
= tail.content
;
112 if cell == tail then tail'
114 content
= cell.content
;
115 next
= copy cell.next
118 tail'
.next
<- copy tail.next
;
144 let rec fold accu
cell =
145 let accu = f
accu cell.content
in
149 fold accu cell.next
in
153 let length1 = q1
.length in
155 let tail1 = q1
.tail in
157 if q2
.length > 0 then begin
158 let tail2 = q2
.tail in
159 let head1 = tail1.next
in
160 let head2 = tail2.next
in
164 q2
.length <- q2
.length + length1;