1 // Copyright 2021 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 //! Trivial impls for `std` types.
16 
17 use core::mem;
18 use core::mem::MaybeUninit;
19 use core::pin::Pin;
20 
21 use crate::move_ref::MoveRef;
22 use crate::new::CopyNew;
23 use crate::new::MoveNew;
24 use crate::new::Swap;
25 
26 macro_rules! trivial_move {
27   ($($ty:ty $(where [$($targs:tt)*])?),* $(,)?) => {$(
28     unsafe impl<$($($targs)*)?> MoveNew for $ty {
29       unsafe fn move_new(
30         src: Pin<MoveRef<Self>>,
31         this: Pin<&mut MaybeUninit<Self>>,
32       ) {
33         let src = Pin::into_inner_unchecked(src);
34         let this = Pin::into_inner_unchecked(this);
35         this.write(MoveRef::into_inner(src));
36       }
37     }
38 
39     impl<$($($targs)*)?> Swap for $ty {
40       fn swap_with(self: Pin<&mut Self>, that: Pin<&mut Self>) {
41         unsafe {
42           let zelf = Pin::into_inner_unchecked(self);
43           let that = Pin::into_inner_unchecked(that);
44           mem::swap(zelf, that);
45         }
46       }
47     }
48   )*}
49 }
50 
51 macro_rules! trivial_copy {
52   ($($ty:ty $(where [$($targs:tt)*])?),* $(,)?) => {$(
53     unsafe impl<$($($targs)*)?> MoveNew for $ty {
54       unsafe fn move_new(
55         src: Pin<MoveRef<Self>>,
56         this: Pin<&mut MaybeUninit<Self>>,
57       ) {
58         let src = Pin::into_inner_unchecked(src);
59         let this = Pin::into_inner_unchecked(this);
60         this.write(MoveRef::into_inner(src));
61       }
62     }
63 
64     impl<$($($targs)*)?> Swap for $ty {
65       fn swap_with(self: Pin<&mut Self>, that: Pin<&mut Self>) {
66         unsafe {
67           let zelf = Pin::into_inner_unchecked(self);
68           let that = Pin::into_inner_unchecked(that);
69           mem::swap(zelf, that);
70         }
71       }
72     }
73 
74     unsafe impl<$($($targs)*)?> CopyNew for $ty where Self: Clone {
75       unsafe fn copy_new(
76         src: &Self,
77         this: Pin<&mut MaybeUninit<Self>>,
78       ) {
79         let this = Pin::into_inner_unchecked(this);
80         this.write(src.clone());
81       }
82     }
83   )*}
84 }
85 
86 trivial_move! {
87   &mut T where [T: ?Sized],
88 
89   core::sync::atomic::AtomicI8,
90   core::sync::atomic::AtomicI16,
91   core::sync::atomic::AtomicI32,
92   core::sync::atomic::AtomicI64,
93   core::sync::atomic::AtomicIsize,
94   core::sync::atomic::AtomicU8,
95   core::sync::atomic::AtomicU16,
96   core::sync::atomic::AtomicU32,
97   core::sync::atomic::AtomicU64,
98   core::sync::atomic::AtomicUsize,
99   core::sync::atomic::AtomicPtr<T> where [T],
100 }
101 
102 trivial_copy! {
103   (), char, bool,
104   i8, i16, i32, i64, i128, isize,
105   u8, u16, u32, u64, u128, usize,
106 
107   &T where [T: ?Sized],
108   *const T where [T: ?Sized],
109   *mut T where [T: ?Sized],
110 
111   core::alloc::Layout,
112 
113   core::cell::UnsafeCell<T> where [T],
114   core::cell::Cell<T> where [T],
115   core::cell::RefCell<T> where [T],
116   core::cell::Ref<'_, T> where [T],
117   core::cell::RefMut<'_, T> where [T],
118 
119   core::marker::PhantomData<T> where [T: ?Sized],
120   core::marker::PhantomPinned,
121 
122   core::mem::Discriminant<T> where [T],
123   core::mem::ManuallyDrop<T> where [T],
124   core::mem::MaybeUninit<T> where [T],
125 
126   core::num::NonZeroI8,
127   core::num::NonZeroI16,
128   core::num::NonZeroI32,
129   core::num::NonZeroI64,
130   core::num::NonZeroI128,
131   core::num::NonZeroIsize,
132   core::num::NonZeroU8,
133   core::num::NonZeroU16,
134   core::num::NonZeroU32,
135   core::num::NonZeroU64,
136   core::num::NonZeroU128,
137   core::num::NonZeroUsize,
138   core::num::Wrapping<T> where [T],
139 
140   core::option::Option<T> where [T],
141 
142   core::pin::Pin<T> where [T],
143   core::ptr::NonNull<T> where [T],
144 
145   core::result::Result<T, E> where [T, E],
146 
147   core::time::Duration,
148 }
149 
150 #[cfg(feature = "alloc")]
151 trivial_copy! {
152   alloc::boxed::Box<T> where [T],
153 
154   alloc::collections::binary_heap::BinaryHeap<T> where [T],
155   alloc::collections::btree_map::BTreeMap<K, V> where [K, V],
156   alloc::collections::btree_set::BTreeSet<T> where [T],
157   alloc::collections::linked_list::LinkedList<T> where [T],
158   alloc::collections::vec_deque::VecDeque<T> where [T],
159 
160   alloc::rc::Rc<T> where [T],
161   alloc::rc::Weak<T> where [T],
162   alloc::sync::Arc<T> where [T],
163   alloc::sync::Weak<T> where [T],
164 
165   alloc::string::String,
166   alloc::vec::Vec<T> where [T],
167 }
168