immutable_seq/
seq.rs

1
2use std::iter;
3use std::ops;
4use std::convert;
5use std::cmp;
6use std::fmt;
7
8use lazy::Lazy;
9
10use finger_tree;
11use finger_tree::FingerTree;
12use node;
13use measure::Measure;
14
15#[derive(Debug)]
16struct Item<T>(T);
17
18impl<T> Measure<usize> for Item<T> {
19    fn measure(&self) -> usize {1}
20}
21
22/// A data-structure implementing an immutable sequence of values.
23///
24/// An amortized running time is given for each operation, with *n* referring to the length of the sequence and *i* being the integral index used by some operations. These bounds hold even in a persistent (shared) setting.
25///
26/// This implementation is based on Haskell's Data.Sequence library (http://hackage.haskell.org/package/containers/docs/Data-Sequence.html), and the following paper:
27/// * Ralf Hinze and Ross Paterson, "Finger trees: a simple general-purpose data structure", Journal of Functional Programming 16:2 (2006) pp 197-217. http://staff.city.ac.uk/~ross/papers/FingerTree.html
28pub struct Seq<T> (Lazy<FingerTree<Item<T>,usize>>);
29
30impl<T:'static> Seq<T> {
31    /// The empty sequence. Time: *O(1)*
32    pub fn empty() -> Seq<T> {
33        Seq(finger_tree::empty())
34    }
35
36    /// A sequence with a single value. Time *O(1)*
37    pub fn singleton(x: T) -> Seq<T> {
38        Seq(finger_tree::single(node::leaf(Item(x))))
39    }
40
41    /// A new sequence that is `self` with `x` added to the front. Time: *O(1)*
42    pub fn push_front(&self, x: T) -> Seq<T> {
43        Seq(finger_tree::cons_node(node::leaf(Item(x)), self.inner().clone()))
44    }
45
46    /// A new sequence that is `self` with `x` added to the back. Time: *O(1)*
47    pub fn push_back(&self, x: T) -> Seq<T> {
48        Seq(finger_tree::snoc_node(self.inner().clone(), node::leaf(Item(x))))
49    }
50
51    /// The concatenation of `self` with `other`. Time: *O(log(min(n1,n2)))*
52    pub fn append(&self, other: &Seq<T>) -> Seq<T> {
53        Seq(finger_tree::tree_tree(self.inner().clone(), other.inner().clone()))
54    }
55
56    /// Is the sequence empty?. Time: *O(1)*
57    pub fn is_empty(&self) -> bool {
58        self.inner().measure() == 0
59    }
60
61    /// The number of elements in the sequence. Time: *O(1)*
62    pub fn len(&self) -> usize {
63        self.inner().measure()
64    }
65
66    /// The first element in the sequence, if it exists. Time: *O(1)*
67    pub fn front(&self) -> Option<&T> {
68        finger_tree::front(self.inner()).map(|&Item(ref x)| x)
69    }
70
71    /// The back element, if it exsts. Time: *O(1)*
72    pub fn back(&self) -> Option<&T> {
73        finger_tree::back(self.inner()).map(|&Item(ref x)| x)
74    }
75
76    /// A new sequence that is `self` with the front element removed, together with the front element (if it exists). Time: *O(1)*
77    pub fn pop_front(&self) -> Seq<T> {
78        Seq(finger_tree::pop_front(self.inner()))
79    }
80
81    /// A new sequence that is `self` with the back element removed, together with the back element (if it exists). Time: *O(1)*
82    pub fn pop_back(&self) -> Seq<T> {
83        Seq(finger_tree::pop_back(self.inner()))
84    }
85
86    /// A new sequence with the element at index `i` replaced by `f(self[i])`. Time: *O(log(min(i,n-i)))*
87    ///
88    /// If `i` is out of range, returns a clone of `self`.
89    pub fn adjust<F>(&self, i: usize, func: F) -> Seq<T>
90        where F: FnOnce(&T) -> T
91    {
92        if i >= self.len() {
93            return self.clone()
94        }
95        Seq(finger_tree::adjust(move |&Item(ref x)| Item(func(x)), move |j| {i < j}, 0, self.inner()))
96    }
97
98    /// A new sequence with the element at index `i` replaced by `x`. Time: *O(log(min(i,n-i)))*
99    ///
100    /// If `i` is out of range, returns a clone of `self`.
101    pub fn update(&self, i: usize, x: T) -> Seq<T> {
102        self.adjust(i, move |_| x)
103    }
104
105    /// A new sequence consisting of only the first `count` elements. Time: *O(log(min(count, n - count)))*
106    ///
107    /// If `count >= self.len()`, then returns a clone of `self`.
108    pub fn truncate(&self, count: usize) -> Seq<T> {
109        let (before,_) = self.split(count);
110        before
111    }
112
113    /// A new sequence consisting of only the last `count` elements. Time: *O(log(min(count,n - count)))*
114    ///
115    /// If `count >= self.len()`, then returns a clone of `self`.
116    pub fn skip(&self, count: usize) -> Seq<T> {
117        let (_,after) = self.split(count);
118        after
119    }
120
121    /// Two new sequences, consisting of the first `count` elements, and the remaining elements, respectively. Time: *O(log(min(count,n-count)))*
122    ///
123    /// If `count >= self.len()`, then the first sequence is a clone of `self` and the second is empty.
124    pub fn split(&self, n: usize) -> (Seq<T>, Seq<T>) {
125        if n >= self.len() {
126            return (self.clone(), Seq::empty())
127        }
128        let (before,x,after) = finger_tree::split(&move |i| {n < i}, 0, self.inner());
129        (Seq(before), Seq(finger_tree::cons_node(x.clone(), after)))
130    }
131
132    /// A new sequence with the element at index `i` removed, together with the element at index `i`, if it exists. Time: *O(log(min(i,n-i)))*
133    ///
134    /// If `i` is out of range, then the returned sequence is a clone of `self`, and the element is `None`.
135    pub fn remove(&self, i: usize) -> Seq<T> {
136        if i >= self.len() {
137            return self.clone()
138        }
139        let (before,_,after) = finger_tree::split(&move |j| {i < j}, 0, self.inner());
140        Seq(finger_tree::tree_tree(before, after))
141    }
142
143    /// A new sequence with `x` inserted at index `i`. Time: *O(log(min(i,n-i)))*
144    ///
145    /// If `i < self.len()`, then `x` will immediately precede `self[i]` in the new sequence.
146    ///
147    /// if `i >= self.len()`, then `x` will be the last element in the new sequence.
148    pub fn insert(&self, i: usize, x: T) -> Seq<T> {
149        if i >= self.len() {
150            return self.push_back(x)
151        }
152        let (before,y,after) = finger_tree::split(&move |j| {i < j}, 0, self.inner());
153        let before = finger_tree::snoc_node(before, node::leaf(Item(x)));
154        let after = finger_tree::cons_node(y.clone(), after);
155        Seq(finger_tree::tree_tree(before, after))
156    }
157
158    /// Get the element at index `i`, if it exists. Time: *O(log(min(i,n-i)))*
159    pub fn get(&self, i: usize) -> Option<&T> {
160        if i >= self.len() {
161            return None
162        }
163        match finger_tree::lookup(move |j| {i < j}, 0, self.inner()) {
164            (&Item(ref x), _) => Some(x)
165        }
166    }
167
168    /// An iterator over the sequence. Time: *O(1)*
169    pub fn iter(&self) -> Iter<T> {
170        self.into_iter()
171    }
172
173    fn inner(&self) -> &Lazy<FingerTree<Item<T>,usize>> {
174        match *self {
175            Seq(ref inner) => inner
176        }
177    }
178}
179
180/// Creates a `Seq` containing the arguments
181///
182/// ```
183/// # #[macro_use]
184/// # extern crate immutable_seq;
185/// # use immutable_seq::Seq;
186/// # fn main() {
187/// let seq: Seq<i32> = seq![1, 2, 3];
188/// # }
189/// ```
190///
191/// Alternatively, a `Seq` consisting of several copies of the same value can be created using the following syntax:
192///
193/// ```
194/// # #[macro_use]
195/// # extern crate immutable_seq;
196/// # use immutable_seq::Seq;
197/// # fn main() {
198/// let seq: Seq<i32> = seq![1 ; 3];
199/// assert_eq!(seq![1 ; 3], seq![1, 1, 1]);
200/// # }
201/// ```
202#[macro_export]
203macro_rules! seq {
204    () => {
205        $crate::Seq::empty()
206    };
207    ($e0: expr $(, $e: expr)*) => {
208        seq!($($e),*).push_front($e0)
209    };
210    ($e: expr ; $n: expr) => {
211        ::std::iter::repeat($e).take($n).collect::<$crate::Seq<_>>()
212    };
213}
214
215impl<T:'static> Clone for Seq<T> {
216    fn clone(&self) -> Seq<T> {
217        Seq(self.inner().clone())
218    }
219}
220
221impl<T:'static> PartialEq for Seq<T>
222    where T: PartialEq
223{
224    fn eq(&self, other: &Seq<T>) -> bool {
225        self.iter().eq(other.iter())
226    }
227}
228
229impl<T:'static> Eq for Seq<T>
230    where T: Eq
231{}
232
233impl<T:'static> PartialOrd for Seq<T>
234    where T: PartialOrd
235{
236    fn partial_cmp(&self, other: &Seq<T>) -> Option<cmp::Ordering> {
237        self.iter().partial_cmp(other.iter())
238    }
239}
240
241impl<T:'static> Ord for Seq<T>
242    where T: Ord
243{
244    fn cmp(&self, other: &Seq<T>) -> cmp::Ordering {
245        self.iter().cmp(other.iter())
246    }
247}
248
249impl<T:'static> fmt::Debug for Seq<T>
250    where T: fmt::Debug
251{
252    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
253        fmt.debug_list().entries(self.iter()).finish()
254    }
255}
256
257#[derive(Debug)]
258pub struct Iter<'a, T: 'a> {
259    inner: finger_tree::Iter<'a, Item<T>, usize>
260}
261
262impl<'a,T:'static> Iter<'a,T> {
263    fn new(seq: &'a Seq<T>) -> Iter<'a,T> {
264        Iter {
265            inner: seq.inner().iter()
266        }
267    }
268}
269
270impl<'a,T:'a> Iterator for Iter<'a,T> {
271    type Item = &'a T;
272
273    fn next(&mut self) -> Option<&'a T> {
274        match self.inner.next() {
275            None => None,
276            Some(&Item(ref x)) => Some(x)
277        }
278    }
279}
280
281impl<'a, T: 'static> iter::IntoIterator for &'a Seq<T> {
282    type Item = &'a T;
283
284    type IntoIter = Iter<'a, T>;
285
286    fn into_iter(self) -> Iter<'a,T> {
287        Iter::new(self)
288    }
289}
290
291impl<T:'static> iter::FromIterator<T> for Seq<T> {
292    fn from_iter<I>(iter: I) -> Self
293        where I: IntoIterator<Item=T> {
294        let mut iter = iter.into_iter();
295        let mut seq = Seq::empty();
296        while let Some(x) = iter.next() {
297            seq = seq.push_back(x);
298        }
299        seq
300    }
301}
302
303impl<T:'static> convert::From<Vec<T>> for Seq<T> {
304    fn from(v: Vec<T>) -> Seq<T> {
305        v.into_iter().collect()
306    }
307}
308
309impl<T:'static> ops::Index<usize> for Seq<T> {
310    type Output = T;
311    fn index(&self, index: usize) -> &T {
312        self.get(index).expect("Out of bounds access")
313    }
314}
315
316// impl<T> ops::Index<ops::Range<usize>> for Seq<T> {
317//     type Output = Seq<T>;
318//     fn index(&self, index: ops::Range<usize>) -> &Seq<T> {
319//         if index.start >= index.end {
320//             Seq::empty()
321//         } else if index.start == 0 {
322//             self.index(ops::RangeTo(index.end))
323//         } else if index.end >= self.len() {
324//             self.index(ops::RangeFrom(index.start))
325//         } else {
326//             self.truncate(index.end).truncate_front(index.end - index.start)
327//         }
328//     }
329// }
330
331// impl<T> ops::Index<ops::RangeTo<usize>> for Seq<T> {
332//     type Output = Seq<T>;
333//     fn index(&self, index: ops::RangeTo<usize>) -> &Seq<T> {
334//         if index.end >= self.len() {
335//             self.index(ops::RangeFull)
336//         } else {
337//             self.truncate(index.end)
338//         }
339//     }
340// }
341
342// impl<T> ops::Index<ops::RangeFrom<usize>> for Seq<T> {
343//     type Output = Seq<T>;
344//     fn index(&self, index: ops::RangeFrom<usize>) -> &Seq<T> {
345//         if index.begin >= self.len() {
346//             Seq::empty()
347//         }
348//         if index.begin == 0 {
349//             self.index(ops::RangeFull)
350//         } else {
351//             self.truncate_front(self.len() - index.start)
352//         }
353//     }
354// }
355
356// impl<T> ops::Index<ops::RangeFull> for Seq<T> {
357//     type Output = Seq<T>;
358//     fn index(&self, index: ops::RangeFull) -> &Seq<T> {
359//         self.clone()
360//     }
361// }