1use std::mem;
2
3#[derive(Clone)]
4pub struct Node<T> {
5 item: T,
6 order: usize,
7 next: Option<Box<Node<T>>>,
8 child: Option<Box<Node<T>>>,
9}
10
11pub fn append<T: Ord>(root: &mut Box<Node<T>>, other: Option<Box<Node<T>>>) {
12 if let Some(other) = other {
13 merge(root, other);
14 coalesce(root);
15 }
16}
17
18pub fn push<T: Ord>(root: &mut Option<Box<Node<T>>>, item: T) {
19 let node = Some(Box::new(Node { item: item, order: 0, next: None, child: None }));
20
21 match *root {
22 None => *root = node,
23 Some(ref mut root) => append(root, node),
24 }
25}
26
27pub fn peek<T: Ord>(root: &Option<Box<Node<T>>>) -> Option<&T> {
28 root.as_ref().map(|mut max| {
29 let mut a = &max.next;
30
31 while let Some(ref b) = *a {
32 if b.item > max.item { max = b; }
33 a = &b.next;
34 }
35
36 &max.item
37 })
38}
39
40pub fn pop<T: Ord>(root: &mut Option<Box<Node<T>>>, len: &mut usize) -> Option<T> {
41 remove_max(root).map(|max| {
42 let max = *max;
43 let Node { item, child, order: _order, next: _next } = max;
44
45 match *root {
46 None => *root = child,
47 Some(ref mut root) => append(root, child),
48 }
49
50 *len -= 1;
51 item
52 })
53}
54
55pub fn iter<T>(root: &Option<Box<Node<T>>>, len: usize) -> Iter<T> {
56 debug_assert!(root.is_some() ^ (len == 0));
57 Iter { nodes: root.as_ref().map(|root| &**root).into_iter().collect(), len: len }
58}
59
60pub fn into_iter<T>(root: Option<Box<Node<T>>>, len: usize) -> IntoIter<T> {
61 debug_assert!(root.is_some() ^ (len == 0));
62 IntoIter { nodes: root.into_iter().collect(), len: len }
63}
64
65pub struct Iter<'a, T: 'a> {
69 nodes: Vec<&'a Node<T>>,
70 len: usize,
71}
72
73impl<'a, T> Clone for Iter<'a, T> {
74 fn clone(&self) -> Self {
75 Iter { nodes: self.nodes.clone(), len: self.len }
76 }
77}
78
79impl<'a, T> Iterator for Iter<'a, T> {
80 type Item = &'a T;
81
82 fn next(&mut self) -> Option<&'a T> {
83 self.nodes.pop().map(|node| {
84 self.len -= 1;
85
86 if let Some(ref next) = node.next { self.nodes.push(next); }
87 if let Some(ref child) = node.child { self.nodes.push(child); }
88
89 &node.item
90 })
91 }
92
93 fn size_hint(&self) -> (usize, Option<usize>) {
94 (self.len, Some(self.len))
95 }
96}
97
98impl<'a, T> ExactSizeIterator for Iter<'a, T> {
99 fn len(&self) -> usize {
100 self.len
101 }
102}
103
104pub struct IntoIter<T> {
108 nodes: Vec<Box<Node<T>>>,
109 len: usize,
110}
111
112impl<T> Iterator for IntoIter<T> {
113 type Item = T;
114
115 fn next(&mut self) -> Option<T> {
116 self.nodes.pop().map(|node| {
117 self.len -= 1;
118
119 let node = *node;
120 let Node { item, next, child, order: _order } = node;
121
122 if let Some(next) = next { self.nodes.push(next); }
123 if let Some(child) = child { self.nodes.push(child); }
124
125 item
126 })
127 }
128
129 fn size_hint(&self) -> (usize, Option<usize>) {
130 (self.len, Some(self.len))
131 }
132}
133
134impl<T> ExactSizeIterator for IntoIter<T> {
135 fn len(&self) -> usize {
136 self.len
137 }
138}
139
140fn merge<T>(mut a: &mut Box<Node<T>>, mut b: Box<Node<T>>) {
147 loop {
148 let a_ = a;
149
150 if a_.order > b.order {
151 mem::swap(a_, &mut b);
152 }
153
154 match a_.next {
155 None => return a_.next = Some(b),
156 Some(ref mut next) => a = next,
157 }
158 }
159}
160
161fn link<T: Ord>(a: &mut Node<T>, mut b: Box<Node<T>>) {
163 debug_assert!(a.order == b.order);
164 debug_assert!(b.next.is_none());
165 debug_assert!(a.item >= b.item);
166
167 b.next = a.child.take();
168 a.child = Some(b);
169 a.order += 1;
170}
171
172fn coalesce<T: Ord>(mut a: &mut Box<Node<T>>) {
180 enum Case {
181 A,
182 B,
183 C,
184 }
185
186 loop {
187 let a_ = a;
188
189 let case = match a_.next {
190 None => return,
191 Some(ref b) =>
192 if a_.order != b.order || b.next.as_ref().map_or(false, |c| c.order == b.order) {
193 Case::A
194 } else if a_.item >= b.item {
195 Case::B
196 } else {
197 Case::C
198 },
199 };
200
201 match case {
202 Case::A => a = a_.next.as_mut().unwrap(),
203 Case::B => {
204 let mut b = a_.next.take().unwrap();
205 a_.next = b.next.take();
206 link(a_, b);
207
208 match a_.next {
209 None => return,
210 Some(ref mut c) => a = c,
211 }
212 }
213 Case::C => {
214 let mut b = a_.next.take().unwrap();
215 mem::swap(a_, &mut b);
216 link(a_, b);
217 a = a_;
218 }
219 }
220 }
221}
222
223fn remove_max<T: Ord>(mut a: &mut Option<Box<Node<T>>>) -> Option<Box<Node<T>>> {
225 a.take().map(|mut max| {
226 *a = max.next.take();
227
228 loop {
229 let a_ = a;
230
231 match *a_ {
232 None => return max,
233 Some(ref mut b) => {
234 if b.item > max.item {
235 max.next = b.next.take();
236 mem::swap(&mut max, b);
237 }
238 }
239 }
240
241 a = &mut a_.as_mut().unwrap().next;
242 }
243 })
244}