| 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 | |