Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::{fmt::Display, ops::{Deref, DerefMut, Index, IndexMut}, slice::SliceIndex, sync::Arc};
- fn main() {
- struct NoisyDrop<T: Display>(T);
- impl<T: Display> Drop for NoisyDrop<T> {
- fn drop(&mut self) {
- println!("I'm dropping this: {}!!!", self.0);
- }
- }
- let v = ["apotheke", "potheke", "otheke", "theke", "heke", "eke", "ke", "e"].iter()
- .map(|s| NoisyDrop(s.to_owned())).collect::<Vec<_>>();
- let (left,right) = v.split_into(4);
- let (left, middle) = left.split_into(2);
- println!("{}", left[0].0);
- for s in middle {
- println!("{}", s.0);
- }
- println!("{}", right[0].0);
- }
- trait SplitExt {
- type Shard;
- /// Split this array into two shards at the given index
- fn split_into(self, at: usize) -> (Self::Shard, Self::Shard);
- }
- /// The raw guts of a Vec<T>
- struct VecDropper<T> {
- ptr: *mut T,
- length: usize,
- capacity: usize,
- }
- impl<T> Drop for VecDropper<T> {
- fn drop(&mut self) {
- unsafe {
- std::mem::drop(Vec::from_raw_parts(self.ptr, self.length, self.capacity));
- }
- }
- }
- pub struct VecShard<T> {
- dropper: Arc<VecDropper<T>>,
- data: *mut T,
- len: usize,
- }
- impl<T> SplitExt for VecShard<T> {
- type Shard = VecShard<T>;
- fn split_into(self, at: usize) -> (Self::Shard, Self::Shard) {
- assert!(at <= self.len);
- let left = VecShard {
- dropper: self.dropper.clone(),
- data: self.data,
- len: at,
- };
- let right = VecShard {
- dropper: self.dropper,
- data: unsafe{ self.data.add(at) },
- len: self.len - at,
- };
- (left, right)
- }
- }
- impl<T> Deref for VecShard<T> {
- type Target = [T];
- fn deref(&self) -> &[T] {
- unsafe { std::slice::from_raw_parts(self.data, self.len) }
- }
- }
- impl<T> DerefMut for VecShard<T> {
- fn deref_mut(&mut self) -> &mut [T] {
- unsafe { std::slice::from_raw_parts_mut(self.data, self.len) }
- }
- }
- impl<T, I: SliceIndex<[T]>> Index<I> for VecShard<T> {
- type Output = <I as std::slice::SliceIndex<[T]>>::Output;
- fn index(&self, idx: I) -> &Self::Output {
- &((**self)[idx])
- }
- }
- impl<T, I: SliceIndex<[T]>> IndexMut<I> for VecShard<T> {
- fn index_mut(&mut self, idx: I) -> &mut Self::Output {
- &mut((**self)[idx])
- }
- }
- impl<T> Iterator for VecShard<T> {
- type Item = T;
- fn next(&mut self) -> Option<T> {
- // oh yes, very clever
- if self.len > 0 {
- let res = unsafe { self.data.read() };
- self.len -= 1;
- self.data = unsafe { self.data.add(1) };
- Some(res)
- } else {
- None
- }
- }
- }
- impl<T> From<Vec<T>> for VecShard<T> {
- fn from(mut v: Vec<T>) -> Self {
- let res = VecShard {
- dropper: Arc::new(VecDropper {
- ptr: v.as_mut_ptr(),
- length: v.len(),
- capacity: v.capacity(),
- }),
- data: v.as_mut_ptr(),
- len: v.len(),
- };
- std::mem::forget(v);
- res
- }
- }
- impl<T> SplitExt for Vec<T> {
- type Shard = VecShard<T>;
- fn split_into(self, at: usize) -> (Self::Shard, Self::Shard) {
- VecShard::from(self).split_into(at)
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement