Skip to content

Commit 1c8b67b

Browse files
committed
Also wrap copy and copy_nonoverlapping
1 parent 208fe9f commit 1c8b67b

File tree

2 files changed

+142
-139
lines changed

2 files changed

+142
-139
lines changed

src/libcore/intrinsics.rs

-137
Original file line numberDiff line numberDiff line change
@@ -962,147 +962,10 @@ extern "rust-intrinsic" {
962962
/// value is not necessarily valid to be used to actually access memory.
963963
pub fn arith_offset<T>(dst: *const T, offset: isize) -> *const T;
964964

965-
/// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
966-
/// and destination must *not* overlap.
967-
///
968-
/// For regions of memory which might overlap, use [`copy`] instead.
969-
///
970-
/// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`], but
971-
/// with the argument order swapped.
972-
///
973-
/// [`copy`]: ./fn.copy.html
974-
/// [`memcpy`]: https://en.cppreference.com/w/c/string/byte/memcpy
975-
///
976-
/// # Safety
977-
///
978-
/// Behavior is undefined if any of the following conditions are violated:
979-
///
980-
/// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
981-
///
982-
/// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
983-
///
984-
/// * Both `src` and `dst` must be properly aligned.
985-
///
986-
/// * The region of memory beginning at `src` with a size of `count *
987-
/// size_of::<T>()` bytes must *not* overlap with the region of memory
988-
/// beginning at `dst` with the same size.
989-
///
990-
/// Like [`read`], `copy_nonoverlapping` creates a bitwise copy of `T`, regardless of
991-
/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using *both* the values
992-
/// in the region beginning at `*src` and the region beginning at `*dst` can
993-
/// [violate memory safety][read-ownership].
994-
///
995-
/// Note that even if the effectively copied size (`count * size_of::<T>()`) is
996-
/// `0`, the pointers must be non-NULL and properly aligned.
997-
///
998-
/// [`Copy`]: ../marker/trait.Copy.html
999-
/// [`read`]: ../ptr/fn.read.html
1000-
/// [read-ownership]: ../ptr/fn.read.html#ownership-of-the-returned-value
1001-
/// [valid]: ../ptr/index.html#safety
1002-
///
1003-
/// # Examples
1004-
///
1005-
/// Manually implement [`Vec::append`]:
1006-
///
1007-
/// ```
1008-
/// use std::ptr;
1009-
///
1010-
/// /// Moves all the elements of `src` into `dst`, leaving `src` empty.
1011-
/// fn append<T>(dst: &mut Vec<T>, src: &mut Vec<T>) {
1012-
/// let src_len = src.len();
1013-
/// let dst_len = dst.len();
1014-
///
1015-
/// // Ensure that `dst` has enough capacity to hold all of `src`.
1016-
/// dst.reserve(src_len);
1017-
///
1018-
/// unsafe {
1019-
/// // The call to offset is always safe because `Vec` will never
1020-
/// // allocate more than `isize::MAX` bytes.
1021-
/// let dst_ptr = dst.as_mut_ptr().offset(dst_len as isize);
1022-
/// let src_ptr = src.as_ptr();
1023-
///
1024-
/// // Truncate `src` without dropping its contents. We do this first,
1025-
/// // to avoid problems in case something further down panics.
1026-
/// src.set_len(0);
1027-
///
1028-
/// // The two regions cannot overlap because mutable references do
1029-
/// // not alias, and two different vectors cannot own the same
1030-
/// // memory.
1031-
/// ptr::copy_nonoverlapping(src_ptr, dst_ptr, src_len);
1032-
///
1033-
/// // Notify `dst` that it now holds the contents of `src`.
1034-
/// dst.set_len(dst_len + src_len);
1035-
/// }
1036-
/// }
1037-
///
1038-
/// let mut a = vec!['r'];
1039-
/// let mut b = vec!['u', 's', 't'];
1040-
///
1041-
/// append(&mut a, &mut b);
1042-
///
1043-
/// assert_eq!(a, &['r', 'u', 's', 't']);
1044-
/// assert!(b.is_empty());
1045-
/// ```
1046-
///
1047-
/// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append
1048-
#[stable(feature = "rust1", since = "1.0.0")]
1049965
pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
1050966

1051-
/// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
1052-
/// and destination may overlap.
1053-
///
1054-
/// If the source and destination will *never* overlap,
1055-
/// [`copy_nonoverlapping`] can be used instead.
1056-
///
1057-
/// `copy` is semantically equivalent to C's [`memmove`], but with the argument
1058-
/// order swapped. Copying takes place as if the bytes were copied from `src`
1059-
/// to a temporary array and then copied from the array to `dst`.
1060-
///
1061-
/// [`copy_nonoverlapping`]: ./fn.copy_nonoverlapping.html
1062-
/// [`memmove`]: https://en.cppreference.com/w/c/string/byte/memmove
1063-
///
1064-
/// # Safety
1065-
///
1066-
/// Behavior is undefined if any of the following conditions are violated:
1067-
///
1068-
/// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
1069-
///
1070-
/// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
1071-
///
1072-
/// * Both `src` and `dst` must be properly aligned.
1073-
///
1074-
/// Like [`read`], `copy` creates a bitwise copy of `T`, regardless of
1075-
/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the values
1076-
/// in the region beginning at `*src` and the region beginning at `*dst` can
1077-
/// [violate memory safety][read-ownership].
1078-
///
1079-
/// Note that even if the effectively copied size (`count * size_of::<T>()`) is
1080-
/// `0`, the pointers must be non-NULL and properly aligned.
1081-
///
1082-
/// [`Copy`]: ../marker/trait.Copy.html
1083-
/// [`read`]: ../ptr/fn.read.html
1084-
/// [read-ownership]: ../ptr/fn.read.html#ownership-of-the-returned-value
1085-
/// [valid]: ../ptr/index.html#safety
1086-
///
1087-
/// # Examples
1088-
///
1089-
/// Efficiently create a Rust vector from an unsafe buffer:
1090-
///
1091-
/// ```
1092-
/// use std::ptr;
1093-
///
1094-
/// # #[allow(dead_code)]
1095-
/// unsafe fn from_buf_raw<T>(ptr: *const T, elts: usize) -> Vec<T> {
1096-
/// let mut dst = Vec::with_capacity(elts);
1097-
/// dst.set_len(elts);
1098-
/// ptr::copy(ptr, dst.as_mut_ptr(), elts);
1099-
/// dst
1100-
/// }
1101-
/// ```
1102-
#[stable(feature = "rust1", since = "1.0.0")]
1103967
pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
1104968

1105-
#[stable(feature = "rust1", since = "1.0.0")]
1106969
pub fn write_bytes<T>(dst: *mut T, val: u8, count: usize);
1107970

1108971
/// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with

src/libcore/ptr.rs

+142-2
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,151 @@ use mem::{self, MaybeUninit};
7373

7474
use 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

Comments
 (0)