@@ -73,11 +73,151 @@ use mem::{self, MaybeUninit};
7373
7474use cmp:: Ordering :: { self , Less , Equal , Greater } ;
7575
76+ /// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
77+ /// and destination must *not* overlap.
78+ ///
79+ /// For regions of memory which might overlap, use [`copy`] instead.
80+ ///
81+ /// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`], but
82+ /// with the argument order swapped.
83+ ///
84+ /// [`copy`]: ./fn.copy.html
85+ /// [`memcpy`]: https://en.cppreference.com/w/c/string/byte/memcpy
86+ ///
87+ /// # Safety
88+ ///
89+ /// Behavior is undefined if any of the following conditions are violated:
90+ ///
91+ /// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
92+ ///
93+ /// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
94+ ///
95+ /// * Both `src` and `dst` must be properly aligned.
96+ ///
97+ /// * The region of memory beginning at `src` with a size of `count *
98+ /// size_of::<T>()` bytes must *not* overlap with the region of memory
99+ /// beginning at `dst` with the same size.
100+ ///
101+ /// Like [`read`], `copy_nonoverlapping` creates a bitwise copy of `T`, regardless of
102+ /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using *both* the values
103+ /// in the region beginning at `*src` and the region beginning at `*dst` can
104+ /// [violate memory safety][read-ownership].
105+ ///
106+ /// Note that even if the effectively copied size (`count * size_of::<T>()`) is
107+ /// `0`, the pointers must be non-NULL and properly aligned.
108+ ///
109+ /// [`Copy`]: ../marker/trait.Copy.html
110+ /// [`read`]: ../ptr/fn.read.html
111+ /// [read-ownership]: ../ptr/fn.read.html#ownership-of-the-returned-value
112+ /// [valid]: ../ptr/index.html#safety
113+ ///
114+ /// # Examples
115+ ///
116+ /// Manually implement [`Vec::append`]:
117+ ///
118+ /// ```
119+ /// use std::ptr;
120+ ///
121+ /// /// Moves all the elements of `src` into `dst`, leaving `src` empty.
122+ /// fn append<T>(dst: &mut Vec<T>, src: &mut Vec<T>) {
123+ /// let src_len = src.len();
124+ /// let dst_len = dst.len();
125+ ///
126+ /// // Ensure that `dst` has enough capacity to hold all of `src`.
127+ /// dst.reserve(src_len);
128+ ///
129+ /// unsafe {
130+ /// // The call to offset is always safe because `Vec` will never
131+ /// // allocate more than `isize::MAX` bytes.
132+ /// let dst_ptr = dst.as_mut_ptr().offset(dst_len as isize);
133+ /// let src_ptr = src.as_ptr();
134+ ///
135+ /// // Truncate `src` without dropping its contents. We do this first,
136+ /// // to avoid problems in case something further down panics.
137+ /// src.set_len(0);
138+ ///
139+ /// // The two regions cannot overlap because mutable references do
140+ /// // not alias, and two different vectors cannot own the same
141+ /// // memory.
142+ /// ptr::copy_nonoverlapping(src_ptr, dst_ptr, src_len);
143+ ///
144+ /// // Notify `dst` that it now holds the contents of `src`.
145+ /// dst.set_len(dst_len + src_len);
146+ /// }
147+ /// }
148+ ///
149+ /// let mut a = vec!['r'];
150+ /// let mut b = vec!['u', 's', 't'];
151+ ///
152+ /// append(&mut a, &mut b);
153+ ///
154+ /// assert_eq!(a, &['r', 'u', 's', 't']);
155+ /// assert!(b.is_empty());
156+ /// ```
157+ ///
158+ /// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append
76159#[ stable( feature = "rust1" , since = "1.0.0" ) ]
77- pub use intrinsics:: copy_nonoverlapping;
160+ #[ inline]
161+ pub unsafe fn copy_nonoverlapping < T > ( src : * const T , dst : * mut T , count : usize ) {
162+ intrinsics:: copy_nonoverlapping ( src, dst, count) ;
163+ }
78164
165+ /// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
166+ /// and destination may overlap.
167+ ///
168+ /// If the source and destination will *never* overlap,
169+ /// [`copy_nonoverlapping`] can be used instead.
170+ ///
171+ /// `copy` is semantically equivalent to C's [`memmove`], but with the argument
172+ /// order swapped. Copying takes place as if the bytes were copied from `src`
173+ /// to a temporary array and then copied from the array to `dst`.
174+ ///
175+ /// [`copy_nonoverlapping`]: ./fn.copy_nonoverlapping.html
176+ /// [`memmove`]: https://en.cppreference.com/w/c/string/byte/memmove
177+ ///
178+ /// # Safety
179+ ///
180+ /// Behavior is undefined if any of the following conditions are violated:
181+ ///
182+ /// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
183+ ///
184+ /// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
185+ ///
186+ /// * Both `src` and `dst` must be properly aligned.
187+ ///
188+ /// Like [`read`], `copy` creates a bitwise copy of `T`, regardless of
189+ /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the values
190+ /// in the region beginning at `*src` and the region beginning at `*dst` can
191+ /// [violate memory safety][read-ownership].
192+ ///
193+ /// Note that even if the effectively copied size (`count * size_of::<T>()`) is
194+ /// `0`, the pointers must be non-NULL and properly aligned.
195+ ///
196+ /// [`Copy`]: ../marker/trait.Copy.html
197+ /// [`read`]: ../ptr/fn.read.html
198+ /// [read-ownership]: ../ptr/fn.read.html#ownership-of-the-returned-value
199+ /// [valid]: ../ptr/index.html#safety
200+ ///
201+ /// # Examples
202+ ///
203+ /// Efficiently create a Rust vector from an unsafe buffer:
204+ ///
205+ /// ```
206+ /// use std::ptr;
207+ ///
208+ /// # #[allow(dead_code)]
209+ /// unsafe fn from_buf_raw<T>(ptr: *const T, elts: usize) -> Vec<T> {
210+ /// let mut dst = Vec::with_capacity(elts);
211+ /// dst.set_len(elts);
212+ /// ptr::copy(ptr, dst.as_mut_ptr(), elts);
213+ /// dst
214+ /// }
215+ /// ```
79216#[ stable( feature = "rust1" , since = "1.0.0" ) ]
80- pub use intrinsics:: copy;
217+ #[ inline]
218+ pub unsafe fn copy < T > ( src : * const T , dst : * mut T , count : usize ) {
219+ intrinsics:: copy ( src, dst, count) ;
220+ }
81221
82222/// Sets `count * size_of::<T>()` bytes of memory starting at `dst` to
83223/// `val`.
0 commit comments