1 | use crate::{ |
2 | consumer::Consumer, |
3 | producer::Producer, |
4 | ring_buffer::{RbRead, RbRef, RbWrite}, |
5 | }; |
6 | |
7 | /// Moves at most `count` items from the `src` consumer to the `dst` producer. |
8 | /// |
9 | /// Consumer and producer may be of different buffers as well as of the same one. |
10 | /// `count` is the number of items being moved, if `None` - as much as possible items will be moved. |
11 | /// |
12 | /// Returns number of items been moved. |
13 | pub fn transfer<T, Rs: RbRef, Rd: RbRef>( |
14 | src: &mut Consumer<T, Rs>, |
15 | dst: &mut Producer<T, Rd>, |
16 | count: Option<usize>, |
17 | ) -> usize |
18 | where |
19 | Rs::Rb: RbRead<T>, |
20 | Rd::Rb: RbWrite<T>, |
21 | { |
22 | let (src_left: &[MaybeUninit], src_right: &[MaybeUninit]) = unsafe { src.as_uninit_slices() }; |
23 | let (dst_left: &mut [MaybeUninit], dst_right: &mut [MaybeUninit]) = unsafe { dst.free_space_as_slices() }; |
24 | let src_iter: impl Iterator- >
= src_left.iter().chain(src_right.iter()); |
25 | let dst_iter: impl Iterator- >
= dst_left.iter_mut().chain(dst_right.iter_mut()); |
26 | |
27 | let mut actual_count: usize = 0; |
28 | for (src_elem: &MaybeUninit, dst_place: &mut MaybeUninit) in src_iter.zip(dst_iter) { |
29 | if let Some(count: usize) = count { |
30 | if actual_count >= count { |
31 | break; |
32 | } |
33 | } |
34 | unsafe { dst_place.write(val:src_elem.as_ptr().read()) }; |
35 | actual_count += 1; |
36 | } |
37 | unsafe { src.advance(actual_count) }; |
38 | unsafe { dst.advance(actual_count) }; |
39 | actual_count |
40 | } |
41 | |