lazy_cogs/collections/
list.rs

1use std::{collections::LinkedList, mem};
2
3use crate::{lazy::LazyClone, lc::Lc};
4
5#[derive(Debug)]
6/// lazy-cogs implementation of a LinkedList. 
7/// It's a collection meant to be used when you need to work with the whole data, not it's elements
8/// 
9/// Cloning a LazyList is always O(1). Modifing or getting piecies of data is O(n). 
10/// Actually, pushing and popping into/from the front or back of the list may be O(1) is the list is mutable
11pub struct LazyList<T: Clone> { 
12    list: Lc<LinkedList<Lc<T>>>,
13}
14
15impl<T: Clone> LazyList<T> {
16    /// Creates a new empty LazyList
17    pub fn new() -> Self {
18        Self{
19            list: Lc::new(LinkedList::new())
20        }
21    }
22
23    /// Obtains a reference to a specific value in the list
24    /// 
25    /// If the index is out of range it returns `None`
26    /// 
27    /// This operation is **always** O(n)
28    pub fn get(&self, index: usize) -> Option<&T> {
29        let list = self.list.read();
30        
31        list.iter().nth(index).map(Lc::read)
32    }
33
34    /// Obtains a mutable reference to a specific value in the list
35    /// 
36    /// If the index is out of range it returns `None`
37    /// 
38    /// This operation is protected, it means, that the other clones aren't affected
39    pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
40        let list = self.list.read_mut();
41        
42        list.iter_mut().nth(index).map(Lc::read_mut)
43    }
44
45    /// Obtains a lazy clone to a specific value in the list
46    pub fn get_lazy(&self, index: usize) -> Option<Lc<T>> {
47        self.list.iter().nth(index).cloned()
48    }
49
50    /// Changes the value at a given position of the list
51    ///
52    /// Returns Ok(()) if the index is in-bounds and Err(()) if not
53    pub fn set(&mut self, index: usize, value: T) -> Result<(), ()>{
54        let mut list = if self.is_mutable() {
55            // We can modify ourselves with no side effects
56            
57            unsafe { 
58                mem::replace(
59                    &mut self.list,
60                    Lc::new(LinkedList::new()))
61                .destroy() 
62            }
63        } else {
64            // We need to clone the vector so we don't mess with other clones
65            self.list.take()
66        };
67
68        let res = match list.iter_mut().nth(index) {
69            Some(elem) => {
70                elem.write(value);
71                Ok(())
72            },
73            None => Err(()),
74        };
75
76        // We need to mutate ourselves, to use the new modified vector, 
77        // and update our state to Mutable
78        self.list = Lc::new(list);
79
80        res
81    }
82
83    /// Pushes a new element at the end of the list
84    pub fn push_back(&mut self, value: T) {
85        let mut list = if self.is_mutable() {
86            unsafe {
87                mem::replace(
88                    &mut self.list, 
89                    Lc::new(LinkedList::new()))
90                    .destroy()
91            }
92        } else {
93            self.list.take()
94        };
95
96        list.push_back(Lc::new(value));
97
98        self.list = Lc::new(list);
99    }
100
101    /// Pushes a new element at the beginning of the list
102    pub fn push_front(&mut self, value: T) {
103        let mut list = if self.is_mutable() {
104            unsafe {
105                mem::replace(
106                    &mut self.list, 
107                    Lc::new(LinkedList::new()))
108                    .destroy()
109            }
110
111        } else {
112            self.list.take()
113        };
114
115        list.push_front(Lc::new(value));
116
117        self.list = Lc::new(list);
118
119    }
120
121    /// Pops an element from the end of the list and returns the lazy clone to the value
122    pub fn pop_back_lazy(&mut self) -> Option<Lc<T>> {
123        let mut list = if self.is_mutable() {
124            unsafe {
125                mem::replace(
126                    &mut self.list, 
127                    Lc::new(LinkedList::new()))
128                    .destroy()
129            }
130        } else {
131            self.list.take()
132        };
133
134        let res = list.pop_back();
135
136        self.list = Lc::new(list);
137
138        res
139    }
140
141    /// Pops an element from the beginning of the list and returns the lazy clone to the value
142    pub fn pop_front_lazy(&mut self) -> Option<Lc<T>> {
143        let mut list = if self.is_mutable() {
144            unsafe {
145                mem::replace(
146                    &mut self.list, 
147                    Lc::new(LinkedList::new()))
148                    .destroy()
149            }
150        } else {
151            self.list.take()
152        };
153
154        let res = list.pop_front();
155
156        self.list = Lc::new(list);
157
158        res
159    }
160
161    #[inline(always)]
162    /// Pops an element from the end of the list and returns the lazy clone to the value
163    pub fn pop_back(&mut self) -> Option<T> {
164        self.pop_back_lazy().map(Lc::unwrap)
165    }
166
167    #[inline(always)]
168    /// Pops an element from the beginning of the list and returns the lazy clone to the value
169    pub fn pop_front(&mut self) -> Option<T> {
170        self.pop_front_lazy().map(Lc::unwrap)
171    }
172
173    #[inline(always)]
174    /// Returns a reference to the first element of the list
175    ///
176    /// Return `None` if the list is empty
177    pub fn front(&self) -> Option<&T> {
178        self.list.read().front().map(Lc::read)
179    }
180
181    #[inline(always)]
182    /// Returns a mutable reference to the first element of the list
183    /// 
184    /// Return `None` if the list is empty
185    /// 
186    /// This operation is protected, it means, that the other clones aren't affected
187    pub fn front_mut(&mut self) -> Option<&mut T> {
188        self.list.read_mut().front_mut().map(Lc::read_mut)
189    }
190
191    #[inline(always)]
192    /// Returns a lazy clone to the first element of the list
193    ///
194    /// Returns `None` if the list is empty
195    pub fn front_lazy(&self) -> Option<Lc<T>> {
196        self.list.read().front().cloned()
197    }
198
199    #[inline(always)]
200    /// Returns a reference to the last element of the list
201    ///
202    /// Return `None` if the list is empty
203    pub fn back(&self) -> Option<&T> {
204        self.list.read().back().map(Lc::read)
205    }
206
207    #[inline(always)]
208    /// Returns a mutable reference to the last element of the list
209    ///
210    /// Return `None` if the list is empty
211    /// 
212    /// This operation is protected, it means, that the other clones aren't affected
213    pub fn back_mut(&mut self) -> Option<&mut T> {
214        self.list.read_mut().back_mut().map(Lc::read_mut)
215    }
216
217    #[inline(always)]
218    /// Returns a lazy clone to the last element of the list
219    ///
220    /// Returns `None` if the list is empty
221    pub fn back_lazy(&self) -> Option<Lc<T>> {
222        self.list.read().back().cloned()
223    }
224
225    #[inline(always)]
226    /// Produces an iterator over the elements of the list
227    pub fn iter(&self) -> impl Iterator<Item = &T> {
228        let list = self.list.read();
229        list.iter().map(Lc::read)
230    }
231
232    #[inline(always)]
233    /// Produces a mutable iterator over the elements of the list
234    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
235        let list = self.list.read_mut();
236        list.iter_mut().map(Lc::read_mut)
237    }
238}
239
240impl<T: Clone> LazyClone for LazyList<T> {
241    fn lazy(&self) -> Self {
242        Self { 
243            list: self.list.lazy()
244        }
245    }
246
247    fn eager(&self) -> Self {
248        Self { 
249            list: self.list.eager()
250        }
251    }
252
253    fn is_mutable(&self) -> bool {
254        self.list.is_mutable()
255    }
256}
257
258impl<T: Clone> From<LinkedList<Lc<T>>> for LazyList<T> {
259    fn from(value: LinkedList<Lc<T>>) -> Self {
260        Self { 
261            list: Lc::new(value) 
262        }
263    }
264}
265
266impl<T: Clone> From<LinkedList<T>> for LazyList<T> {
267    fn from(value: LinkedList<T>) -> Self {
268        Self {
269            list: Lc::new(value.into_iter()
270                .map(Lc::new)
271                .collect()
272            ),
273        }
274    }
275}
276
277impl<T: Clone> From<Vec<Lc<T>>> for LazyList<T> {
278    fn from(value: Vec<Lc<T>>) -> Self {
279        Self { 
280            list: Lc::new(value.into_iter().collect()) 
281        }
282    }
283}
284
285impl<T: Clone> From<Vec<T>> for LazyList<T> {
286    fn from(value: Vec<T>) -> Self {
287        Self {
288            list: Lc::new(value.into_iter()
289                .map(Lc::new)
290                .collect()
291            ),
292        }
293    }
294}
295
296impl<T: Clone> From<&[T]> for LazyList<T> {
297    fn from(value: &[T]) -> Self {
298        value.to_vec()
299            .into_iter()
300            .collect()
301    }
302}
303
304impl<T: Clone> Into<LinkedList<Lc<T>>> for LazyList<T> {
305    fn into(self) -> LinkedList<Lc<T>> {
306        self.list.unwrap()
307            .into_iter()
308            .collect()
309    }
310}
311
312impl<T: Clone> Into<LinkedList<T>> for LazyList<T> {
313    fn into(self) -> LinkedList<T> {
314        self.list.unwrap()
315            .into_iter()
316            .map(|elem| elem.unwrap())
317            .collect()
318    }
319}
320
321impl<T: Clone> FromIterator<T> for LazyList<T> {
322    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
323        LinkedList::from_iter(iter).into()
324    }
325}
326
327impl<T: Clone> IntoIterator for LazyList<T> {
328    type Item = T;
329    type IntoIter = std::collections::linked_list::IntoIter<T>;
330
331    fn into_iter(self) -> Self::IntoIter {
332        self.list.take()
333            .into_iter()
334            .map(Lc::unwrap)
335            .collect::<LinkedList<T>>().into_iter()
336    }
337}
338
339
340#[cfg(test)]
341mod tests {
342    use std::iter::zip;
343
344    use crate::lazy::LazyClone;
345
346    use super::LazyList;
347
348    #[test]
349    fn create() {
350        let mut lv = LazyList::<Box<str>>::from(&["Hello".into(), "World".into(), "Take".into(), "a look at this".into()] as &[Box<str>]);
351        let mut lv2 = lv.lazy();
352        let mut lv3 = lv2.lazy();
353
354        let _ = lv.set(0, "Bye".into());
355        let _ = lv2.set(2, "Give".into());
356        let _ = lv3.set(1, "Värld".into());
357
358        // Check if the boxes are the same, so we are safely reusing memory
359        assert_eq!(lv.get(1).unwrap().as_ref() as *const str, lv2.get(1).unwrap().as_ref() as *const str);
360        // Check if the boxes are not the same, so we cloned what was needed
361        assert_ne!(lv.get(1).unwrap().as_ref() as *const str, lv3.get(1).unwrap().as_ref() as *const str);
362    }
363
364    #[test]
365    #[allow(unused_mut)]
366    #[allow(unused_results)]
367    #[allow(unused_must_use)]
368    fn mutability_check() {
369        let mut lv = LazyList::from(vec!["HI", "Goodbye", "Farwell", "Hello"]);
370        let mut lv2 = lv.lazy();
371        let mut lv3 = lv2.lazy();
372        let mut lv4 = lv2.lazy();
373        
374        lv2.set(3, "Halo");
375        lv.set(0, "Hej");
376
377        assert!(lv.is_mutable());
378        assert!(lv2.is_mutable());
379        assert!(!lv3.is_mutable());
380        assert!(!lv4.is_mutable());
381
382        for e in zip(zip(lv.iter(), lv2.iter()), zip(lv3.iter(), lv4.iter())) {
383            println!("{:?} : {:?} : {:?} : {:?}", e.0.0.as_ptr(), e.0.1.as_ptr(), e.1.0.as_ptr(), e.1.1.as_ptr())
384        }
385    }
386
387    #[test]
388    fn iterators() {
389        let lv = LazyList::from([String::from("rust"), String::from("mojo"), String::from("zig"), String::from("carbon"),String::from("aura")].to_vec());
390
391        lv.iter()
392            .map(|elem| elem.to_uppercase())
393            .for_each(|elem| println!("{:?}", elem));
394
395        lv.into_iter()
396            .map(|elem| elem
397                .chars()
398                .rev()
399                .collect::<String>()
400            )
401            .for_each(|elem| println!("{:?}", elem));
402    }
403
404    #[test]
405    fn collecting() {
406        let v = vec!["Hi", "my", "name", "is", "something"];
407        let lv: LazyList<_> = v.into_iter()
408            .collect();
409
410        dbg!(lv);
411    }
412}