1 use crate::error::OutOfMemory; 2 use core::mem; 3 4 /// A trait for values that can be cloned, but contain owned, heap-allocated 5 /// values whose allocations may fail during cloning. 6 pub trait TryClone: Sized { 7 /// Attempt to clone `self`, returning an error if any allocation fails 8 /// during cloning. 9 fn try_clone(&self) -> Result<Self, OutOfMemory>; 10 } 11 12 impl<T> TryClone for *mut T 13 where 14 T: ?Sized, 15 { 16 #[inline] 17 fn try_clone(&self) -> Result<Self, OutOfMemory> { 18 Ok(*self) 19 } 20 } 21 22 impl<T> TryClone for core::ptr::NonNull<T> 23 where 24 T: ?Sized, 25 { 26 #[inline] 27 fn try_clone(&self) -> Result<Self, OutOfMemory> { 28 Ok(*self) 29 } 30 } 31 32 impl<'a, T> TryClone for &'a T 33 where 34 T: ?Sized, 35 { 36 #[inline] 37 fn try_clone(&self) -> Result<Self, OutOfMemory> { 38 Ok(*self) 39 } 40 } 41 42 macro_rules! impl_try_clone_via_clone { 43 ( $( $ty:ty ),* $(,)? ) => { 44 $( 45 impl TryClone for $ty { 46 #[inline] 47 fn try_clone(&self) -> Result<Self, OutOfMemory> { 48 Ok(self.clone()) 49 } 50 } 51 )* 52 }; 53 } 54 55 impl_try_clone_via_clone! { 56 bool, char, 57 u8, u16, u32, u64, u128, usize, 58 i8, i16, i32, i64, i128, isize, 59 f32, f64, 60 } 61 62 macro_rules! tuples { 63 ( $( $( $t:ident ),* );*) => { 64 $( 65 impl<$($t),*> TryClone for ( $($t,)* ) 66 where 67 $( $t: TryClone ),* 68 { 69 #[inline] 70 fn try_clone(&self) -> Result<Self, OutOfMemory> { 71 #[allow(non_snake_case, reason = "macro code")] 72 let ( $($t,)* ) = self; 73 Ok(( $( $t.try_clone()?, )* )) 74 } 75 } 76 )* 77 }; 78 } 79 80 tuples! { 81 A; 82 A, B; 83 A, B, C; 84 A, B, C, D; 85 A, B, C, D, E; 86 A, B, C, D, E, F; 87 A, B, C, D, E, F, G; 88 A, B, C, D, E, F, G, H; 89 A, B, C, D, E, F, G, H, I; 90 A, B, C, D, E, F, G, H, I, J; 91 } 92 93 impl<T> TryClone for mem::ManuallyDrop<T> 94 where 95 T: TryClone, 96 { 97 fn try_clone(&self) -> Result<Self, OutOfMemory> { 98 Ok(mem::ManuallyDrop::new((**self).try_clone()?)) 99 } 100 } 101 102 #[cfg(feature = "std")] 103 impl_try_clone_via_clone! { 104 std::hash::RandomState 105 } 106 107 impl_try_clone_via_clone! { 108 hashbrown::DefaultHashBuilder 109 } 110