]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
1 | // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT |
2 | // file at the top-level directory of this distribution and at | |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
11 | // FIXME: talk about offset, copy_memory, copy_nonoverlapping_memory | |
12 | ||
54a0048b | 13 | //! Raw, unsafe pointers, `*const T`, and `*mut T`. |
1a4d82fc | 14 | //! |
54a0048b | 15 | //! *[See also the pointer primitive types](../../std/primitive.pointer.html).* |
1a4d82fc | 16 | |
85aaf69f | 17 | #![stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 18 | |
1a4d82fc | 19 | use intrinsics; |
b039eaaf | 20 | use ops::{CoerceUnsized, Deref}; |
c1a9b12d | 21 | use fmt; |
e9174d1e | 22 | use hash; |
9e0c209e | 23 | use marker::{PhantomData, Unsize}; |
e9174d1e | 24 | use mem; |
85aaf69f | 25 | use nonzero::NonZero; |
1a4d82fc | 26 | |
1a4d82fc JJ |
27 | use cmp::Ordering::{self, Less, Equal, Greater}; |
28 | ||
29 | // FIXME #19649: intrinsic docs don't render, so these have no docs :( | |
30 | ||
c34b1796 | 31 | #[stable(feature = "rust1", since = "1.0.0")] |
c34b1796 | 32 | pub use intrinsics::copy_nonoverlapping; |
1a4d82fc | 33 | |
c34b1796 | 34 | #[stable(feature = "rust1", since = "1.0.0")] |
c34b1796 | 35 | pub use intrinsics::copy; |
1a4d82fc | 36 | |
c34b1796 AL |
37 | #[stable(feature = "rust1", since = "1.0.0")] |
38 | pub use intrinsics::write_bytes; | |
1a4d82fc | 39 | |
7453a54e | 40 | #[stable(feature = "drop_in_place", since = "1.8.0")] |
92a42be0 SL |
41 | pub use intrinsics::drop_in_place; |
42 | ||
1a4d82fc JJ |
43 | /// Creates a null raw pointer. |
44 | /// | |
45 | /// # Examples | |
46 | /// | |
47 | /// ``` | |
48 | /// use std::ptr; | |
49 | /// | |
85aaf69f | 50 | /// let p: *const i32 = ptr::null(); |
1a4d82fc JJ |
51 | /// assert!(p.is_null()); |
52 | /// ``` | |
53 | #[inline] | |
85aaf69f | 54 | #[stable(feature = "rust1", since = "1.0.0")] |
e9174d1e | 55 | pub const fn null<T>() -> *const T { 0 as *const T } |
1a4d82fc JJ |
56 | |
57 | /// Creates a null mutable raw pointer. | |
58 | /// | |
59 | /// # Examples | |
60 | /// | |
61 | /// ``` | |
62 | /// use std::ptr; | |
63 | /// | |
85aaf69f | 64 | /// let p: *mut i32 = ptr::null_mut(); |
1a4d82fc JJ |
65 | /// assert!(p.is_null()); |
66 | /// ``` | |
67 | #[inline] | |
85aaf69f | 68 | #[stable(feature = "rust1", since = "1.0.0")] |
e9174d1e | 69 | pub const fn null_mut<T>() -> *mut T { 0 as *mut T } |
1a4d82fc | 70 | |
1a4d82fc | 71 | /// Swaps the values at two mutable locations of the same type, without |
b039eaaf | 72 | /// deinitializing either. They may overlap, unlike `mem::swap` which is |
1a4d82fc JJ |
73 | /// otherwise equivalent. |
74 | /// | |
75 | /// # Safety | |
76 | /// | |
77 | /// This is only unsafe because it accepts a raw pointer. | |
78 | #[inline] | |
85aaf69f | 79 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
80 | pub unsafe fn swap<T>(x: *mut T, y: *mut T) { |
81 | // Give ourselves some scratch space to work with | |
82 | let mut tmp: T = mem::uninitialized(); | |
1a4d82fc JJ |
83 | |
84 | // Perform the swap | |
c34b1796 AL |
85 | copy_nonoverlapping(x, &mut tmp, 1); |
86 | copy(y, x, 1); // `x` and `y` may overlap | |
87 | copy_nonoverlapping(&tmp, y, 1); | |
1a4d82fc JJ |
88 | |
89 | // y and t now point to the same thing, but we need to completely forget `tmp` | |
90 | // because it's no longer relevant. | |
91 | mem::forget(tmp); | |
92 | } | |
93 | ||
94 | /// Replaces the value at `dest` with `src`, returning the old | |
95 | /// value, without dropping either. | |
96 | /// | |
97 | /// # Safety | |
98 | /// | |
99 | /// This is only unsafe because it accepts a raw pointer. | |
100 | /// Otherwise, this operation is identical to `mem::replace`. | |
101 | #[inline] | |
85aaf69f | 102 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 103 | pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T { |
e9174d1e | 104 | mem::swap(&mut *dest, &mut src); // cannot overlap |
1a4d82fc JJ |
105 | src |
106 | } | |
107 | ||
85aaf69f | 108 | /// Reads the value from `src` without moving it. This leaves the |
1a4d82fc JJ |
109 | /// memory in `src` unchanged. |
110 | /// | |
111 | /// # Safety | |
112 | /// | |
113 | /// Beyond accepting a raw pointer, this is unsafe because it semantically | |
114 | /// moves the value out of `src` without preventing further usage of `src`. | |
115 | /// If `T` is not `Copy`, then care must be taken to ensure that the value at | |
116 | /// `src` is not used before the data is overwritten again (e.g. with `write`, | |
117 | /// `zero_memory`, or `copy_memory`). Note that `*src = foo` counts as a use | |
118 | /// because it will attempt to drop the value previously at `*src`. | |
a7813a04 XL |
119 | /// |
120 | /// # Examples | |
121 | /// | |
122 | /// Basic usage: | |
123 | /// | |
124 | /// ``` | |
125 | /// let x = 12; | |
126 | /// let y = &x as *const i32; | |
127 | /// | |
9e0c209e SL |
128 | /// unsafe { |
129 | /// assert_eq!(std::ptr::read(y), 12); | |
130 | /// } | |
a7813a04 | 131 | /// ``` |
1a4d82fc | 132 | #[inline(always)] |
85aaf69f | 133 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
134 | pub unsafe fn read<T>(src: *const T) -> T { |
135 | let mut tmp: T = mem::uninitialized(); | |
c34b1796 | 136 | copy_nonoverlapping(src, &mut tmp, 1); |
1a4d82fc JJ |
137 | tmp |
138 | } | |
139 | ||
1a4d82fc JJ |
140 | /// Overwrites a memory location with the given value without reading or |
141 | /// dropping the old value. | |
142 | /// | |
143 | /// # Safety | |
144 | /// | |
b039eaaf SL |
145 | /// This operation is marked unsafe because it accepts a raw pointer. |
146 | /// | |
147 | /// It does not drop the contents of `dst`. This is safe, but it could leak | |
148 | /// allocations or resources, so care must be taken not to overwrite an object | |
149 | /// that should be dropped. | |
1a4d82fc JJ |
150 | /// |
151 | /// This is appropriate for initializing uninitialized memory, or overwriting | |
152 | /// memory that has previously been `read` from. | |
a7813a04 XL |
153 | /// |
154 | /// # Examples | |
155 | /// | |
156 | /// Basic usage: | |
157 | /// | |
158 | /// ``` | |
159 | /// let mut x = 0; | |
160 | /// let y = &mut x as *mut i32; | |
161 | /// let z = 12; | |
162 | /// | |
163 | /// unsafe { | |
164 | /// std::ptr::write(y, z); | |
9e0c209e | 165 | /// assert_eq!(std::ptr::read(y), 12); |
a7813a04 XL |
166 | /// } |
167 | /// ``` | |
1a4d82fc | 168 | #[inline] |
85aaf69f | 169 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
170 | pub unsafe fn write<T>(dst: *mut T, src: T) { |
171 | intrinsics::move_val_init(&mut *dst, src) | |
172 | } | |
173 | ||
7453a54e SL |
174 | /// Performs a volatile read of the value from `src` without moving it. This |
175 | /// leaves the memory in `src` unchanged. | |
176 | /// | |
177 | /// Volatile operations are intended to act on I/O memory, and are guaranteed | |
178 | /// to not be elided or reordered by the compiler across other volatile | |
54a0048b | 179 | /// operations. |
7453a54e | 180 | /// |
54a0048b SL |
181 | /// # Notes |
182 | /// | |
183 | /// Rust does not currently have a rigorously and formally defined memory model, | |
184 | /// so the precise semantics of what "volatile" means here is subject to change | |
185 | /// over time. That being said, the semantics will almost always end up pretty | |
186 | /// similar to [C11's definition of volatile][c11]. | |
187 | /// | |
188 | /// [c11]: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf | |
7453a54e SL |
189 | /// |
190 | /// # Safety | |
191 | /// | |
192 | /// Beyond accepting a raw pointer, this is unsafe because it semantically | |
193 | /// moves the value out of `src` without preventing further usage of `src`. | |
194 | /// If `T` is not `Copy`, then care must be taken to ensure that the value at | |
195 | /// `src` is not used before the data is overwritten again (e.g. with `write`, | |
196 | /// `zero_memory`, or `copy_memory`). Note that `*src = foo` counts as a use | |
197 | /// because it will attempt to drop the value previously at `*src`. | |
a7813a04 XL |
198 | /// |
199 | /// # Examples | |
200 | /// | |
201 | /// Basic usage: | |
202 | /// | |
203 | /// ``` | |
204 | /// let x = 12; | |
205 | /// let y = &x as *const i32; | |
206 | /// | |
9e0c209e SL |
207 | /// unsafe { |
208 | /// assert_eq!(std::ptr::read_volatile(y), 12); | |
209 | /// } | |
a7813a04 | 210 | /// ``` |
7453a54e | 211 | #[inline] |
54a0048b | 212 | #[stable(feature = "volatile", since = "1.9.0")] |
7453a54e SL |
213 | pub unsafe fn read_volatile<T>(src: *const T) -> T { |
214 | intrinsics::volatile_load(src) | |
215 | } | |
216 | ||
217 | /// Performs a volatile write of a memory location with the given value without | |
218 | /// reading or dropping the old value. | |
219 | /// | |
220 | /// Volatile operations are intended to act on I/O memory, and are guaranteed | |
221 | /// to not be elided or reordered by the compiler across other volatile | |
54a0048b SL |
222 | /// operations. |
223 | /// | |
224 | /// # Notes | |
225 | /// | |
226 | /// Rust does not currently have a rigorously and formally defined memory model, | |
227 | /// so the precise semantics of what "volatile" means here is subject to change | |
228 | /// over time. That being said, the semantics will almost always end up pretty | |
229 | /// similar to [C11's definition of volatile][c11]. | |
7453a54e | 230 | /// |
54a0048b | 231 | /// [c11]: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf |
7453a54e SL |
232 | /// |
233 | /// # Safety | |
234 | /// | |
235 | /// This operation is marked unsafe because it accepts a raw pointer. | |
236 | /// | |
237 | /// It does not drop the contents of `dst`. This is safe, but it could leak | |
238 | /// allocations or resources, so care must be taken not to overwrite an object | |
239 | /// that should be dropped. | |
240 | /// | |
241 | /// This is appropriate for initializing uninitialized memory, or overwriting | |
242 | /// memory that has previously been `read` from. | |
a7813a04 XL |
243 | /// |
244 | /// # Examples | |
245 | /// | |
246 | /// Basic usage: | |
247 | /// | |
248 | /// ``` | |
249 | /// let mut x = 0; | |
250 | /// let y = &mut x as *mut i32; | |
251 | /// let z = 12; | |
252 | /// | |
253 | /// unsafe { | |
254 | /// std::ptr::write_volatile(y, z); | |
9e0c209e | 255 | /// assert_eq!(std::ptr::read_volatile(y), 12); |
a7813a04 XL |
256 | /// } |
257 | /// ``` | |
7453a54e | 258 | #[inline] |
54a0048b | 259 | #[stable(feature = "volatile", since = "1.9.0")] |
7453a54e SL |
260 | pub unsafe fn write_volatile<T>(dst: *mut T, src: T) { |
261 | intrinsics::volatile_store(dst, src); | |
262 | } | |
263 | ||
c34b1796 AL |
264 | #[lang = "const_ptr"] |
265 | impl<T: ?Sized> *const T { | |
1a4d82fc | 266 | /// Returns true if the pointer is null. |
54a0048b SL |
267 | /// |
268 | /// # Examples | |
269 | /// | |
270 | /// Basic usage: | |
271 | /// | |
272 | /// ``` | |
273 | /// let s: &str = "Follow the rabbit"; | |
274 | /// let ptr: *const u8 = s.as_ptr(); | |
275 | /// assert!(!ptr.is_null()); | |
276 | /// ``` | |
85aaf69f | 277 | #[stable(feature = "rust1", since = "1.0.0")] |
c34b1796 AL |
278 | #[inline] |
279 | pub fn is_null(self) -> bool where T: Sized { | |
e9174d1e | 280 | self == null() |
c34b1796 | 281 | } |
1a4d82fc JJ |
282 | |
283 | /// Returns `None` if the pointer is null, or else returns a reference to | |
284 | /// the value wrapped in `Some`. | |
285 | /// | |
286 | /// # Safety | |
287 | /// | |
288 | /// While this method and its mutable counterpart are useful for | |
289 | /// null-safety, it is important to note that this is still an unsafe | |
290 | /// operation because the returned value could be pointing to invalid | |
291 | /// memory. | |
54a0048b SL |
292 | /// |
293 | /// Additionally, the lifetime `'a` returned is arbitrarily chosen and does | |
294 | /// not necessarily reflect the actual lifetime of the data. | |
295 | /// | |
296 | /// # Examples | |
297 | /// | |
298 | /// Basic usage: | |
299 | /// | |
300 | /// ```ignore | |
301 | /// let val: *const u8 = &10u8 as *const u8; | |
302 | /// | |
303 | /// unsafe { | |
304 | /// if let Some(val_back) = val.as_ref() { | |
305 | /// println!("We got back the value: {}!", val_back); | |
306 | /// } | |
307 | /// } | |
308 | /// ``` | |
309 | #[stable(feature = "ptr_as_ref", since = "1.9.0")] | |
c34b1796 | 310 | #[inline] |
54a0048b | 311 | pub unsafe fn as_ref<'a>(self) -> Option<&'a T> where T: Sized { |
c34b1796 AL |
312 | if self.is_null() { |
313 | None | |
314 | } else { | |
54a0048b | 315 | Some(&*self) |
c34b1796 AL |
316 | } |
317 | } | |
1a4d82fc JJ |
318 | |
319 | /// Calculates the offset from a pointer. `count` is in units of T; e.g. a | |
320 | /// `count` of 3 represents a pointer offset of `3 * sizeof::<T>()` bytes. | |
321 | /// | |
322 | /// # Safety | |
323 | /// | |
d9579d0f AL |
324 | /// Both the starting and resulting pointer must be either in bounds or one |
325 | /// byte past the end of an allocated object. If either pointer is out of | |
326 | /// bounds or arithmetic overflow occurs then | |
327 | /// any further use of the returned value will result in undefined behavior. | |
54a0048b SL |
328 | /// |
329 | /// # Examples | |
330 | /// | |
331 | /// Basic usage: | |
332 | /// | |
333 | /// ``` | |
334 | /// let s: &str = "123"; | |
335 | /// let ptr: *const u8 = s.as_ptr(); | |
336 | /// | |
337 | /// unsafe { | |
338 | /// println!("{}", *ptr.offset(1) as char); | |
339 | /// println!("{}", *ptr.offset(2) as char); | |
340 | /// } | |
341 | /// ``` | |
85aaf69f | 342 | #[stable(feature = "rust1", since = "1.0.0")] |
c34b1796 AL |
343 | #[inline] |
344 | pub unsafe fn offset(self, count: isize) -> *const T where T: Sized { | |
345 | intrinsics::offset(self, count) | |
346 | } | |
1a4d82fc JJ |
347 | } |
348 | ||
c34b1796 AL |
349 | #[lang = "mut_ptr"] |
350 | impl<T: ?Sized> *mut T { | |
351 | /// Returns true if the pointer is null. | |
54a0048b SL |
352 | /// |
353 | /// # Examples | |
354 | /// | |
355 | /// Basic usage: | |
356 | /// | |
357 | /// ``` | |
358 | /// let mut s = [1, 2, 3]; | |
359 | /// let ptr: *mut u32 = s.as_mut_ptr(); | |
360 | /// assert!(!ptr.is_null()); | |
361 | /// ``` | |
c34b1796 AL |
362 | #[stable(feature = "rust1", since = "1.0.0")] |
363 | #[inline] | |
364 | pub fn is_null(self) -> bool where T: Sized { | |
e9174d1e | 365 | self == null_mut() |
c34b1796 | 366 | } |
1a4d82fc | 367 | |
c34b1796 AL |
368 | /// Returns `None` if the pointer is null, or else returns a reference to |
369 | /// the value wrapped in `Some`. | |
1a4d82fc JJ |
370 | /// |
371 | /// # Safety | |
372 | /// | |
c34b1796 AL |
373 | /// While this method and its mutable counterpart are useful for |
374 | /// null-safety, it is important to note that this is still an unsafe | |
375 | /// operation because the returned value could be pointing to invalid | |
376 | /// memory. | |
54a0048b SL |
377 | /// |
378 | /// Additionally, the lifetime `'a` returned is arbitrarily chosen and does | |
379 | /// not necessarily reflect the actual lifetime of the data. | |
380 | /// | |
381 | /// # Examples | |
382 | /// | |
383 | /// Basic usage: | |
384 | /// | |
385 | /// ```ignore | |
386 | /// let val: *mut u8 = &mut 10u8 as *mut u8; | |
387 | /// | |
388 | /// unsafe { | |
389 | /// if let Some(val_back) = val.as_ref() { | |
390 | /// println!("We got back the value: {}!", val_back); | |
391 | /// } | |
392 | /// } | |
393 | /// ``` | |
394 | #[stable(feature = "ptr_as_ref", since = "1.9.0")] | |
1a4d82fc | 395 | #[inline] |
54a0048b | 396 | pub unsafe fn as_ref<'a>(self) -> Option<&'a T> where T: Sized { |
1a4d82fc JJ |
397 | if self.is_null() { |
398 | None | |
399 | } else { | |
54a0048b | 400 | Some(&*self) |
1a4d82fc JJ |
401 | } |
402 | } | |
1a4d82fc | 403 | |
c34b1796 AL |
404 | /// Calculates the offset from a pointer. `count` is in units of T; e.g. a |
405 | /// `count` of 3 represents a pointer offset of `3 * sizeof::<T>()` bytes. | |
406 | /// | |
407 | /// # Safety | |
408 | /// | |
409 | /// The offset must be in-bounds of the object, or one-byte-past-the-end. | |
b039eaaf | 410 | /// Otherwise `offset` invokes Undefined Behavior, regardless of whether |
c34b1796 | 411 | /// the pointer is used. |
54a0048b SL |
412 | /// |
413 | /// # Examples | |
414 | /// | |
415 | /// Basic usage: | |
416 | /// | |
417 | /// ``` | |
418 | /// let mut s = [1, 2, 3]; | |
419 | /// let ptr: *mut u32 = s.as_mut_ptr(); | |
420 | /// | |
421 | /// unsafe { | |
422 | /// println!("{}", *ptr.offset(1)); | |
423 | /// println!("{}", *ptr.offset(2)); | |
424 | /// } | |
425 | /// ``` | |
85aaf69f | 426 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 427 | #[inline] |
c34b1796 | 428 | pub unsafe fn offset(self, count: isize) -> *mut T where T: Sized { |
85aaf69f | 429 | intrinsics::offset(self, count) as *mut T |
1a4d82fc JJ |
430 | } |
431 | ||
c34b1796 AL |
432 | /// Returns `None` if the pointer is null, or else returns a mutable |
433 | /// reference to the value wrapped in `Some`. | |
434 | /// | |
435 | /// # Safety | |
436 | /// | |
437 | /// As with `as_ref`, this is unsafe because it cannot verify the validity | |
54a0048b SL |
438 | /// of the returned pointer, nor can it ensure that the lifetime `'a` |
439 | /// returned is indeed a valid lifetime for the contained data. | |
440 | /// | |
441 | /// # Examples | |
442 | /// | |
443 | /// Basic usage: | |
444 | /// | |
445 | /// ``` | |
446 | /// let mut s = [1, 2, 3]; | |
447 | /// let ptr: *mut u32 = s.as_mut_ptr(); | |
a7813a04 XL |
448 | /// let first_value = unsafe { ptr.as_mut().unwrap() }; |
449 | /// *first_value = 4; | |
450 | /// println!("{:?}", s); // It'll print: "[4, 2, 3]". | |
54a0048b SL |
451 | /// ``` |
452 | #[stable(feature = "ptr_as_ref", since = "1.9.0")] | |
1a4d82fc | 453 | #[inline] |
54a0048b | 454 | pub unsafe fn as_mut<'a>(self) -> Option<&'a mut T> where T: Sized { |
1a4d82fc JJ |
455 | if self.is_null() { |
456 | None | |
457 | } else { | |
54a0048b | 458 | Some(&mut *self) |
1a4d82fc JJ |
459 | } |
460 | } | |
461 | } | |
462 | ||
463 | // Equality for pointers | |
85aaf69f | 464 | #[stable(feature = "rust1", since = "1.0.0")] |
c34b1796 | 465 | impl<T: ?Sized> PartialEq for *const T { |
1a4d82fc | 466 | #[inline] |
c34b1796 | 467 | fn eq(&self, other: &*const T) -> bool { *self == *other } |
1a4d82fc JJ |
468 | } |
469 | ||
85aaf69f | 470 | #[stable(feature = "rust1", since = "1.0.0")] |
c34b1796 | 471 | impl<T: ?Sized> Eq for *const T {} |
1a4d82fc | 472 | |
85aaf69f | 473 | #[stable(feature = "rust1", since = "1.0.0")] |
c34b1796 | 474 | impl<T: ?Sized> PartialEq for *mut T { |
1a4d82fc | 475 | #[inline] |
c34b1796 | 476 | fn eq(&self, other: &*mut T) -> bool { *self == *other } |
1a4d82fc JJ |
477 | } |
478 | ||
85aaf69f | 479 | #[stable(feature = "rust1", since = "1.0.0")] |
c34b1796 | 480 | impl<T: ?Sized> Eq for *mut T {} |
1a4d82fc | 481 | |
9e0c209e SL |
482 | /// Compare raw pointers for equality. |
483 | /// | |
484 | /// This is the same as using the `==` operator, but less generic: | |
485 | /// the arguments have to be `*const T` raw pointers, | |
486 | /// not anything that implements `PartialEq`. | |
487 | /// | |
488 | /// This can be used to compare `&T` references (which coerce to `*const T` implicitly) | |
489 | /// by their address rather than comparing the values they point to | |
490 | /// (which is what the `PartialEq for &T` implementation does). | |
491 | /// | |
492 | /// # Examples | |
493 | /// | |
494 | /// ``` | |
495 | /// #![feature(ptr_eq)] | |
496 | /// use std::ptr; | |
497 | /// | |
498 | /// let five = 5; | |
499 | /// let other_five = 5; | |
500 | /// let five_ref = &five; | |
501 | /// let same_five_ref = &five; | |
502 | /// let other_five_ref = &other_five; | |
503 | /// | |
504 | /// assert!(five_ref == same_five_ref); | |
505 | /// assert!(five_ref == other_five_ref); | |
506 | /// | |
507 | /// assert!(ptr::eq(five_ref, same_five_ref)); | |
508 | /// assert!(!ptr::eq(five_ref, other_five_ref)); | |
509 | /// ``` | |
510 | #[unstable(feature = "ptr_eq", reason = "newly added", issue = "36497")] | |
511 | #[inline] | |
512 | pub fn eq<T: ?Sized>(a: *const T, b: *const T) -> bool { | |
513 | a == b | |
514 | } | |
515 | ||
85aaf69f | 516 | #[stable(feature = "rust1", since = "1.0.0")] |
c34b1796 | 517 | impl<T: ?Sized> Clone for *const T { |
1a4d82fc JJ |
518 | #[inline] |
519 | fn clone(&self) -> *const T { | |
520 | *self | |
521 | } | |
522 | } | |
523 | ||
85aaf69f | 524 | #[stable(feature = "rust1", since = "1.0.0")] |
c34b1796 | 525 | impl<T: ?Sized> Clone for *mut T { |
1a4d82fc JJ |
526 | #[inline] |
527 | fn clone(&self) -> *mut T { | |
528 | *self | |
529 | } | |
530 | } | |
531 | ||
e9174d1e SL |
532 | // Impls for function pointers |
533 | macro_rules! fnptr_impls_safety_abi { | |
534 | ($FnTy: ty, $($Arg: ident),*) => { | |
535 | #[stable(feature = "rust1", since = "1.0.0")] | |
536 | impl<Ret, $($Arg),*> Clone for $FnTy { | |
537 | #[inline] | |
538 | fn clone(&self) -> Self { | |
539 | *self | |
540 | } | |
541 | } | |
1a4d82fc | 542 | |
e9174d1e SL |
543 | #[stable(feature = "fnptr_impls", since = "1.4.0")] |
544 | impl<Ret, $($Arg),*> PartialEq for $FnTy { | |
545 | #[inline] | |
546 | fn eq(&self, other: &Self) -> bool { | |
547 | *self as usize == *other as usize | |
548 | } | |
1a4d82fc | 549 | } |
e9174d1e SL |
550 | |
551 | #[stable(feature = "fnptr_impls", since = "1.4.0")] | |
552 | impl<Ret, $($Arg),*> Eq for $FnTy {} | |
553 | ||
554 | #[stable(feature = "fnptr_impls", since = "1.4.0")] | |
555 | impl<Ret, $($Arg),*> PartialOrd for $FnTy { | |
556 | #[inline] | |
557 | fn partial_cmp(&self, other: &Self) -> Option<Ordering> { | |
558 | (*self as usize).partial_cmp(&(*other as usize)) | |
559 | } | |
560 | } | |
561 | ||
562 | #[stable(feature = "fnptr_impls", since = "1.4.0")] | |
563 | impl<Ret, $($Arg),*> Ord for $FnTy { | |
564 | #[inline] | |
565 | fn cmp(&self, other: &Self) -> Ordering { | |
566 | (*self as usize).cmp(&(*other as usize)) | |
567 | } | |
568 | } | |
569 | ||
570 | #[stable(feature = "fnptr_impls", since = "1.4.0")] | |
571 | impl<Ret, $($Arg),*> hash::Hash for $FnTy { | |
572 | fn hash<HH: hash::Hasher>(&self, state: &mut HH) { | |
573 | state.write_usize(*self as usize) | |
574 | } | |
575 | } | |
576 | ||
577 | #[stable(feature = "fnptr_impls", since = "1.4.0")] | |
578 | impl<Ret, $($Arg),*> fmt::Pointer for $FnTy { | |
579 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
580 | fmt::Pointer::fmt(&(*self as *const ()), f) | |
581 | } | |
582 | } | |
583 | ||
584 | #[stable(feature = "fnptr_impls", since = "1.4.0")] | |
585 | impl<Ret, $($Arg),*> fmt::Debug for $FnTy { | |
586 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
587 | fmt::Pointer::fmt(&(*self as *const ()), f) | |
1a4d82fc JJ |
588 | } |
589 | } | |
590 | } | |
1a4d82fc JJ |
591 | } |
592 | ||
e9174d1e | 593 | macro_rules! fnptr_impls_args { |
5bcae85e | 594 | ($($Arg: ident),+) => { |
e9174d1e SL |
595 | fnptr_impls_safety_abi! { extern "Rust" fn($($Arg),*) -> Ret, $($Arg),* } |
596 | fnptr_impls_safety_abi! { extern "C" fn($($Arg),*) -> Ret, $($Arg),* } | |
5bcae85e | 597 | fnptr_impls_safety_abi! { extern "C" fn($($Arg),* , ...) -> Ret, $($Arg),* } |
e9174d1e SL |
598 | fnptr_impls_safety_abi! { unsafe extern "Rust" fn($($Arg),*) -> Ret, $($Arg),* } |
599 | fnptr_impls_safety_abi! { unsafe extern "C" fn($($Arg),*) -> Ret, $($Arg),* } | |
5bcae85e SL |
600 | fnptr_impls_safety_abi! { unsafe extern "C" fn($($Arg),* , ...) -> Ret, $($Arg),* } |
601 | }; | |
602 | () => { | |
603 | // No variadic functions with 0 parameters | |
604 | fnptr_impls_safety_abi! { extern "Rust" fn() -> Ret, } | |
605 | fnptr_impls_safety_abi! { extern "C" fn() -> Ret, } | |
606 | fnptr_impls_safety_abi! { unsafe extern "Rust" fn() -> Ret, } | |
607 | fnptr_impls_safety_abi! { unsafe extern "C" fn() -> Ret, } | |
608 | }; | |
e9174d1e SL |
609 | } |
610 | ||
611 | fnptr_impls_args! { } | |
612 | fnptr_impls_args! { A } | |
613 | fnptr_impls_args! { A, B } | |
614 | fnptr_impls_args! { A, B, C } | |
615 | fnptr_impls_args! { A, B, C, D } | |
616 | fnptr_impls_args! { A, B, C, D, E } | |
617 | fnptr_impls_args! { A, B, C, D, E, F } | |
618 | fnptr_impls_args! { A, B, C, D, E, F, G } | |
619 | fnptr_impls_args! { A, B, C, D, E, F, G, H } | |
620 | fnptr_impls_args! { A, B, C, D, E, F, G, H, I } | |
621 | fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J } | |
622 | fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K } | |
623 | fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K, L } | |
624 | ||
1a4d82fc | 625 | // Comparison for pointers |
85aaf69f | 626 | #[stable(feature = "rust1", since = "1.0.0")] |
c34b1796 | 627 | impl<T: ?Sized> Ord for *const T { |
1a4d82fc JJ |
628 | #[inline] |
629 | fn cmp(&self, other: &*const T) -> Ordering { | |
630 | if self < other { | |
631 | Less | |
632 | } else if self == other { | |
633 | Equal | |
634 | } else { | |
635 | Greater | |
636 | } | |
637 | } | |
638 | } | |
639 | ||
85aaf69f | 640 | #[stable(feature = "rust1", since = "1.0.0")] |
c34b1796 | 641 | impl<T: ?Sized> PartialOrd for *const T { |
1a4d82fc JJ |
642 | #[inline] |
643 | fn partial_cmp(&self, other: &*const T) -> Option<Ordering> { | |
644 | Some(self.cmp(other)) | |
645 | } | |
646 | ||
647 | #[inline] | |
648 | fn lt(&self, other: &*const T) -> bool { *self < *other } | |
649 | ||
650 | #[inline] | |
651 | fn le(&self, other: &*const T) -> bool { *self <= *other } | |
652 | ||
653 | #[inline] | |
654 | fn gt(&self, other: &*const T) -> bool { *self > *other } | |
655 | ||
656 | #[inline] | |
657 | fn ge(&self, other: &*const T) -> bool { *self >= *other } | |
658 | } | |
659 | ||
85aaf69f | 660 | #[stable(feature = "rust1", since = "1.0.0")] |
c34b1796 | 661 | impl<T: ?Sized> Ord for *mut T { |
1a4d82fc JJ |
662 | #[inline] |
663 | fn cmp(&self, other: &*mut T) -> Ordering { | |
664 | if self < other { | |
665 | Less | |
666 | } else if self == other { | |
667 | Equal | |
668 | } else { | |
669 | Greater | |
670 | } | |
671 | } | |
672 | } | |
673 | ||
85aaf69f | 674 | #[stable(feature = "rust1", since = "1.0.0")] |
c34b1796 | 675 | impl<T: ?Sized> PartialOrd for *mut T { |
1a4d82fc JJ |
676 | #[inline] |
677 | fn partial_cmp(&self, other: &*mut T) -> Option<Ordering> { | |
678 | Some(self.cmp(other)) | |
679 | } | |
680 | ||
681 | #[inline] | |
682 | fn lt(&self, other: &*mut T) -> bool { *self < *other } | |
683 | ||
684 | #[inline] | |
685 | fn le(&self, other: &*mut T) -> bool { *self <= *other } | |
686 | ||
687 | #[inline] | |
688 | fn gt(&self, other: &*mut T) -> bool { *self > *other } | |
689 | ||
690 | #[inline] | |
691 | fn ge(&self, other: &*mut T) -> bool { *self >= *other } | |
692 | } | |
693 | ||
7453a54e | 694 | /// A wrapper around a raw non-null `*mut T` that indicates that the possessor |
1a4d82fc | 695 | /// of this wrapper owns the referent. This in turn implies that the |
85aaf69f SL |
696 | /// `Unique<T>` is `Send`/`Sync` if `T` is `Send`/`Sync`, unlike a raw |
697 | /// `*mut T` (which conveys no particular ownership semantics). It | |
698 | /// also implies that the referent of the pointer should not be | |
699 | /// modified without a unique path to the `Unique` reference. Useful | |
700 | /// for building abstractions like `Vec<T>` or `Box<T>`, which | |
1a4d82fc | 701 | /// internally use raw pointers to manage the memory that they own. |
54a0048b | 702 | #[allow(missing_debug_implementations)] |
e9174d1e SL |
703 | #[unstable(feature = "unique", reason = "needs an RFC to flesh out design", |
704 | issue = "27730")] | |
c34b1796 | 705 | pub struct Unique<T: ?Sized> { |
85aaf69f | 706 | pointer: NonZero<*const T>, |
62682a34 SL |
707 | // NOTE: this marker has no consequences for variance, but is necessary |
708 | // for dropck to understand that we logically own a `T`. | |
709 | // | |
710 | // For details, see: | |
711 | // https://github.com/rust-lang/rfcs/blob/master/text/0769-sound-generic-drop.md#phantom-data | |
85aaf69f SL |
712 | _marker: PhantomData<T>, |
713 | } | |
1a4d82fc JJ |
714 | |
715 | /// `Unique` pointers are `Send` if `T` is `Send` because the data they | |
716 | /// reference is unaliased. Note that this aliasing invariant is | |
717 | /// unenforced by the type system; the abstraction using the | |
718 | /// `Unique` must enforce it. | |
e9174d1e | 719 | #[unstable(feature = "unique", issue = "27730")] |
85aaf69f | 720 | unsafe impl<T: Send + ?Sized> Send for Unique<T> { } |
1a4d82fc JJ |
721 | |
722 | /// `Unique` pointers are `Sync` if `T` is `Sync` because the data they | |
723 | /// reference is unaliased. Note that this aliasing invariant is | |
724 | /// unenforced by the type system; the abstraction using the | |
725 | /// `Unique` must enforce it. | |
e9174d1e | 726 | #[unstable(feature = "unique", issue = "27730")] |
85aaf69f SL |
727 | unsafe impl<T: Sync + ?Sized> Sync for Unique<T> { } |
728 | ||
e9174d1e | 729 | #[unstable(feature = "unique", issue = "27730")] |
c34b1796 | 730 | impl<T: ?Sized> Unique<T> { |
9cc50fc6 | 731 | /// Creates a new `Unique`. |
7453a54e SL |
732 | /// |
733 | /// # Safety | |
734 | /// | |
735 | /// `ptr` must be non-null. | |
9cc50fc6 SL |
736 | pub const unsafe fn new(ptr: *mut T) -> Unique<T> { |
737 | Unique { pointer: NonZero::new(ptr), _marker: PhantomData } | |
738 | } | |
85aaf69f | 739 | |
9346a6ac | 740 | /// Dereferences the content. |
85aaf69f SL |
741 | pub unsafe fn get(&self) -> &T { |
742 | &**self.pointer | |
743 | } | |
744 | ||
9346a6ac | 745 | /// Mutably dereferences the content. |
85aaf69f SL |
746 | pub unsafe fn get_mut(&mut self) -> &mut T { |
747 | &mut ***self | |
1a4d82fc | 748 | } |
85aaf69f | 749 | } |
1a4d82fc | 750 | |
92a42be0 SL |
751 | #[unstable(feature = "unique", issue = "27730")] |
752 | impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> { } | |
753 | ||
e9174d1e | 754 | #[unstable(feature = "unique", issue= "27730")] |
85aaf69f SL |
755 | impl<T:?Sized> Deref for Unique<T> { |
756 | type Target = *mut T; | |
757 | ||
758 | #[inline] | |
e9174d1e | 759 | fn deref(&self) -> &*mut T { |
85aaf69f | 760 | unsafe { mem::transmute(&*self.pointer) } |
1a4d82fc JJ |
761 | } |
762 | } | |
9346a6ac AL |
763 | |
764 | #[stable(feature = "rust1", since = "1.0.0")] | |
765 | impl<T> fmt::Pointer for Unique<T> { | |
766 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
767 | fmt::Pointer::fmt(&*self.pointer, f) | |
768 | } | |
769 | } | |
b039eaaf | 770 | |
7453a54e | 771 | /// A wrapper around a raw non-null `*mut T` that indicates that the possessor |
b039eaaf SL |
772 | /// of this wrapper has shared ownership of the referent. Useful for |
773 | /// building abstractions like `Rc<T>` or `Arc<T>`, which internally | |
774 | /// use raw pointers to manage the memory that they own. | |
54a0048b | 775 | #[allow(missing_debug_implementations)] |
b039eaaf SL |
776 | #[unstable(feature = "shared", reason = "needs an RFC to flesh out design", |
777 | issue = "27730")] | |
778 | pub struct Shared<T: ?Sized> { | |
779 | pointer: NonZero<*const T>, | |
780 | // NOTE: this marker has no consequences for variance, but is necessary | |
781 | // for dropck to understand that we logically own a `T`. | |
782 | // | |
783 | // For details, see: | |
784 | // https://github.com/rust-lang/rfcs/blob/master/text/0769-sound-generic-drop.md#phantom-data | |
785 | _marker: PhantomData<T>, | |
786 | } | |
787 | ||
788 | /// `Shared` pointers are not `Send` because the data they reference may be aliased. | |
789 | // NB: This impl is unnecessary, but should provide better error messages. | |
790 | #[unstable(feature = "shared", issue = "27730")] | |
791 | impl<T: ?Sized> !Send for Shared<T> { } | |
792 | ||
793 | /// `Shared` pointers are not `Sync` because the data they reference may be aliased. | |
794 | // NB: This impl is unnecessary, but should provide better error messages. | |
795 | #[unstable(feature = "shared", issue = "27730")] | |
796 | impl<T: ?Sized> !Sync for Shared<T> { } | |
797 | ||
798 | #[unstable(feature = "shared", issue = "27730")] | |
799 | impl<T: ?Sized> Shared<T> { | |
800 | /// Creates a new `Shared`. | |
7453a54e SL |
801 | /// |
802 | /// # Safety | |
803 | /// | |
804 | /// `ptr` must be non-null. | |
b039eaaf SL |
805 | pub unsafe fn new(ptr: *mut T) -> Self { |
806 | Shared { pointer: NonZero::new(ptr), _marker: PhantomData } | |
807 | } | |
808 | } | |
809 | ||
810 | #[unstable(feature = "shared", issue = "27730")] | |
811 | impl<T: ?Sized> Clone for Shared<T> { | |
812 | fn clone(&self) -> Self { | |
813 | *self | |
814 | } | |
815 | } | |
816 | ||
817 | #[unstable(feature = "shared", issue = "27730")] | |
818 | impl<T: ?Sized> Copy for Shared<T> { } | |
819 | ||
b039eaaf SL |
820 | #[unstable(feature = "shared", issue = "27730")] |
821 | impl<T: ?Sized, U: ?Sized> CoerceUnsized<Shared<U>> for Shared<T> where T: Unsize<U> { } | |
822 | ||
823 | #[unstable(feature = "shared", issue = "27730")] | |
824 | impl<T: ?Sized> Deref for Shared<T> { | |
825 | type Target = *mut T; | |
826 | ||
827 | #[inline] | |
828 | fn deref(&self) -> &*mut T { | |
829 | unsafe { mem::transmute(&*self.pointer) } | |
830 | } | |
831 | } | |
832 | ||
833 | #[unstable(feature = "shared", issue = "27730")] | |
834 | impl<T> fmt::Pointer for Shared<T> { | |
835 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
836 | fmt::Pointer::fmt(&*self.pointer, f) | |
837 | } | |
838 | } |