1use 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.
13pub 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
18where
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