[−][src]Function moite_moite::sync::split_with
pub fn split_with<L, R, W, F>(value: W, f: F) -> (Part<L, W>, Part<R, W>) where
L: ?Sized,
R: ?Sized,
F: FnOnce(&mut W) -> (&mut L, &mut R),
Splits a value into two owned parts.
Sharing
The internal reference counter is atomic, allowing the left and right parts to be safely shared across threads:
Part<T, W>
isSync
ifT
isSync
;Part<T, W>
isSend
ifT
isSend
andW
isSend
.
There are no W: Sync
bounds because users cannot get a reference to a
split W
, whereas there is a W: Send
bound because the dropping code
for W
may be run on any thread, when its last part is dropped.
Example
use moite_moite::sync::{Part, split_with}; use std::ops::Drop; struct Target<L, R>(Option<(L, R)>); struct PairCell<'t, L, R> { target: &'t mut Option<(L, R)>, left: Option<L>, right: Option<R>, } impl<'t, L, R> PairCell<'t, L, R> { fn split(self) -> (Part<Option<L>, Self>, Part<Option<R>, Self>) { split_with(self, |this| (&mut this.left, &mut this.right)) } } impl<'t, L, R> Drop for PairCell<'t, L, R> { fn drop(&mut self) { let left = self.left.take().expect("no left"); let right = self.right.take().expect("no right"); *self.target = Some((left, right)); } } let mut target = Target(None); { let cell = PairCell { target: &mut target.0, left: None, right: None, }; let (mut left, mut right) = cell.split(); *left = Some("Ram"); *right = Some("Rem"); } let (left, right) = target.0.expect("Where are the twin maids?"); assert_eq!(left, "Ram"); assert_eq!(right, "Rem");