orx_linked_list/list/
consuming.rs

1use super::List;
2use crate::variant::ListVariant;
3use orx_pinned_vec::PinnedVec;
4use orx_selfref_col::{MemoryPolicy, Node};
5
6impl<V, M, P> List<V, M, P>
7where
8    V: ListVariant,
9    M: MemoryPolicy<V>,
10    P: PinnedVec<Node<V>>,
11{
12    /// Returns an arbitrary order consuming iterator of owned elements of the list.
13    ///
14    /// Note that the iterator created by `into_iter_x` is often faster than that created by `into_iter`;
15    /// and hence, can be preferred whenever the iteration order does not matter.
16    ///
17    /// # Examples
18    ///
19    /// ```rust
20    /// use orx_linked_list::*;
21    ///
22    /// let mut list = DoublyList::new();
23    ///
24    /// // a -> b -> c
25    /// list.push_front('c');
26    /// list.push_front('b');
27    /// list.push_back('x');
28    /// list.push_front('a');
29    /// list.pop_back();
30    ///
31    /// let mut vec: Vec<_> = list.into_iter_x().collect();
32    ///
33    /// // although deterministic depending on order of mutations,
34    /// // the order can be considered deterministic.
35    /// assert_eq!(vec.as_slice(), &['c', 'b', 'a']);
36    ///
37    /// vec.sort();
38    /// assert_eq!(vec.as_slice(), &['a', 'b', 'c']);
39    /// ```
40    pub fn into_iter_x(self) -> impl Iterator<Item = V::Item> {
41        let (nodes, _, _) = self.0.into_inner().0.into_inner();
42        nodes.into_iter().filter_map(|x| x.into_data())
43    }
44
45    /// Consumes the linked list and creates a parallel iterator over owned elements in **arbitrary order**.
46    ///
47    /// Note that `into_par_x` is parallel counterpart of [`into_iter_x`].
48    ///
49    /// Please see [`ParIter`] for details of the parallel computation.
50    /// In brief, computation is defined as chain of iterator transformations and parallelization
51    /// is handled by the underlying parallel executor.
52    ///
53    /// Requires **orx-parallel** feature.
54    ///
55    /// [`ParIter`]: orx_parallel::ParIter
56    /// [`into_iter_x`]: crate::List::into_iter_x
57    ///
58    /// # Examples
59    ///
60    /// ```
61    /// use orx_linked_list::*;
62    ///
63    /// let new_list = || DoublyList::from_iter(0..1024);
64    ///
65    /// let expected: usize = new_list().iter_x().sum();
66    ///
67    /// let sum = new_list().into_par_x().sum(); // parallelized computation
68    /// assert_eq!(expected, sum);
69    ///
70    /// let sum = new_list().into_par_x().num_threads(4).sum(); // using at most 4 threads
71    /// assert_eq!(expected, sum);
72    ///
73    /// let sum_doubles = new_list().into_par_x().map(|x| x * 2).sum();
74    /// assert_eq!(2 * expected, sum_doubles);
75    ///
76    /// let expected: usize = new_list().into_iter_x().filter(|x| x % 2 == 0).sum();
77    /// let sum_evens = new_list().into_par_x().filter(|x| x % 2 == 0).sum();
78    /// ```
79    #[cfg(feature = "orx-parallel")]
80    pub fn into_par_x(self) -> impl orx_parallel::ParIter<Item = V::Item>
81    where
82        V::Item: Send + Sync + Clone,
83        Node<V>: Send + Sync,
84        P: orx_concurrent_iter::IntoConcurrentIter<Item = Node<V>>,
85    {
86        use orx_parallel::*;
87        let (pinned, _, _) = self.0.into_inner().0.into_inner();
88        pinned.into_par().filter_map(|x| x.into_data())
89    }
90}