drc/drc.rs
1// Copyright 2018 0-0-1 and Contributors
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8//
9// This file contains a substantial portion of code derived from
10// https://github.com/rust-lang/rust/blob/master/src/liballoc/rc.rs
11// which has the following license header:
12//
13// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
14// file at the top-level directory of this distribution and at
15// http://rust-lang.org/COPYRIGHT.
16//
17// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
18// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
19// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
20// option. This file may not be copied, modified, or distributed
21// except according to those terms.
22
23use std::borrow::Borrow;
24use std::cell::Cell;
25use std::cmp::Ordering;
26use std::ffi::{CStr, CString, OsStr, OsString};
27use std::fmt::{Debug, Display, Formatter, Pointer, Result as FmtResult};
28use std::hash::{Hash, Hasher};
29use std::marker::PhantomData;
30use std::mem;
31use std::ops::Deref;
32use std::panic::{RefUnwindSafe, UnwindSafe};
33use std::path::{Path, PathBuf};
34use std::ptr::{self, NonNull};
35use std::sync::{Arc, Weak as WeakArc};
36
37use weak::Weak;
38
39/// A single-threaded reference-counting pointer with the special ability to be
40/// converted into an [`Arc`]. 'Drc' stands for 'Dynamically Reference
41/// Counted'.
42///
43/// See the [crate-level documentation][crate] for more details.
44///
45/// The inherent methods of `Drc` are all associated functions, which means you
46/// have to call them as e.g. [`Drc::get_mut(&mut value)`][`get_mut`] instead
47/// `value.get_mut()`. This avoids conflict with methods of the inner type `T`.
48///
49/// [crate]: ./index.html
50///
51/// [`get_mut`]: ./struct.Drc.html#method.get_mut
52///
53/// [`Arc`]: https://doc.rust-lang.org/std/sync/struct.Arc.html
54pub struct Drc<T>
55where
56 T: ?Sized,
57{
58 pub(crate) ptr: NonNull<DrcInner<T>>,
59 pub(crate) phantom: PhantomData<T>,
60}
61
62impl<T> Drc<T> {
63 /// Constructs a new `Drc`.
64 ///
65 /// # Examples
66 ///
67 /// ```rust
68 /// use drc::Drc;
69 ///
70 /// let five = Drc::new(5);
71 /// ```
72 pub fn new(value: T) -> Drc<T> {
73 Drc::from_arc(Arc::new(value))
74 }
75}
76
77impl<T> Drc<T>
78where
79 T: ?Sized,
80{
81 /// Clones the internal [`Arc`] (incrementing the atomic strong reference
82 /// count) so that the shared state can be referenced on another thread.
83 /// Then, returns this newly cloned `Arc`. To convert the `Arc` back
84 /// into a `Drc` (with a [`separate`] local state), use [`from`].
85 ///
86 /// # Examples
87 ///
88 /// ```rust
89 /// use drc::Drc;
90 ///
91 /// let five = Drc::new(5);
92 /// let arc_five = Drc::detach(&five);
93 ///
94 /// assert_eq!(*five, *arc_five);
95 /// ```
96 ///
97 /// [`separate`]: ./struct.Drc.html#method.separate
98 ///
99 /// [`Arc`]: https://doc.rust-lang.org/std/sync/struct.Arc.html
100 ///
101 /// [`from`]: https://doc.rust-lang.org/std/convert/trait.From.html#tymethod.from
102 pub fn detach(this: &Drc<T>) -> Arc<T> {
103 Arc::clone(this.arc())
104 }
105
106 /// Clone the internal [`Arc`] (incrementing the atomic strong reference
107 /// count), create new local reference counts, and associate a new `Drc` to
108 /// these new reference counts.
109 ///
110 /// This is not too useful outside of testing, but it is provided
111 /// as a way to simulate the intended process of sending an `Arc` across a
112 /// thread and converting it back into a `Drc` without the need for
113 /// multiple method calls.
114 ///
115 /// [`Drc::linked`][`linked`] will not evaluate true for separated values,
116 /// though [`Drc::ptr_eq`][`ptr_eq`] will.
117 ///
118 /// # Examples
119 ///
120 /// ```rust
121 /// use drc::Drc;
122 ///
123 /// let five = Drc::new(5);
124 /// let separate_five = Drc::separate(&five);
125 ///
126 /// assert!(Drc::ptr_eq(&five, &separate_five));
127 /// assert!(!Drc::linked(&five, &separate_five));
128 /// ```
129 ///
130 /// [`linked`]: ./struct.Drc.html#method.linked
131 /// [`ptr_eq`]: ./struct.Drc.html#method.ptr_eq
132 ///
133 /// [`Arc`]: https://doc.rust-lang.org/std/sync/struct.Arc.html
134 pub fn separate(this: &Drc<T>) -> Drc<T> {
135 Drc::from_arc(Drc::detach(this))
136 }
137}
138
139impl<T> Drc<T> {
140 /// Returns the contained value, if the [`Arc`] associated with the `Drc`
141 /// has exactly one strong reference.
142 ///
143 /// Otherwise, an [`Err`][`Result`] will be returned with the same `Drc`
144 /// that was passed in.
145 ///
146 /// This will succeed even if there are outstanding weak references.
147 ///
148 /// # Examples
149 ///
150 /// ```rust
151 /// use drc::Drc;
152 ///
153 /// // The `Drc` here is the only strong reference to 3, so it is successfully
154 /// // unwrapped.
155 /// let x = Drc::new(3);
156 /// assert_eq!(Drc::try_unwrap(x), Ok(3));
157 ///
158 /// // There are two `Drc` strong references to 4, so it is not successfully
159 /// // unwrapped.
160 /// let x = Drc::new(4);
161 /// let _y = Drc::clone(&x);
162 /// assert_eq!(*Drc::try_unwrap(x).unwrap_err(), 4);
163 ///
164 /// // There is a `Drc` and an `Arc` strong reference to 5, so it is not
165 /// // sucessfully unwrapped.
166 /// let x = Drc::new(5);
167 /// let _y = Drc::detach(&x);
168 /// assert_eq!(*Drc::try_unwrap(x).unwrap_err(), 5);
169 /// ```
170 ///
171 /// [`Arc`]: https://doc.rust-lang.org/std/sync/struct.Arc.html
172 /// [`Result`]: https://doc.rust-lang.org/std/result/enum.Result.html
173 pub fn try_unwrap(this: Drc<T>) -> Result<T, Drc<T>> {
174 if Drc::strong_count(&this, true) == 1 {
175 match Arc::try_unwrap(unsafe { this.take_arc() }) {
176 Ok(value) => {
177 this.strong().set(0);
178 let weak = this.weak().get();
179 if weak == 1 {
180 unsafe {
181 // This strong pointer was the last pointer, weak or
182 // strong, associated with the `Arc`. Simply deallocate
183 // the storage (only integers and `None`s are stored).
184 Box::from_raw(this.ptr.as_ptr());
185 }
186 } else {
187 // Remove implict weak pointer. Explicit ones remain
188 // to clean up the structure.
189 this.weak().set(weak - 1);
190 }
191
192 // Prevent a double free.
193 mem::forget(this);
194
195 // Return the successfully unwrapped value.
196 Ok(value)
197 },
198 Err(arc) => {
199 // Return the `Arc` to its rightful place.
200 unsafe { this.set_arc(arc) };
201
202 Err(this)
203 },
204 }
205 } else {
206 // We know it can't be zero, as *this* `Drc` exists. Therefore, there
207 // is more than one strong pointer, making this a failure.
208
209 Err(this)
210 }
211 }
212}
213
214impl<T> Drc<T>
215where
216 T: ?Sized,
217{
218 /// Creates a new [`Weak`] pointer to this value.
219 ///
220 /// # Examples
221 ///
222 /// ```rust
223 /// use drc::Drc;
224 ///
225 /// let five = Drc::new(5);
226 ///
227 /// let weak_five = Drc::downgrade(&five);
228 /// ```
229 ///
230 /// [`Weak`]: ./struct.Weak.html
231 pub fn downgrade(this: &Drc<T>) -> Weak<T> {
232 unsafe {
233 let storage = this.ptr.as_ptr();
234 (*storage).weak.set((*storage).weak.get() + 1);
235
236 if (*storage).weak_ref.is_none() {
237 (*storage).weak_ref = Some(Arc::downgrade(this.arc()));
238 }
239 }
240
241 Weak { ptr: this.ptr }
242 }
243
244 /// If `local`, gets the number of [`Weak` (`Drc`)][`Weak`] pointers
245 /// associated with the same internal [`Arc`]. Otherwise, gets the number of
246 /// [`Weak` (`Arc`)][`WeakArc`] pointers associated associated with the
247 /// value.
248 ///
249 /// It's worth noting that neither of these values are the total counts of
250 /// weak pointers associated with a given value. Using a `local` value
251 /// of `false` will return the number of `Drc` sets containing at least
252 /// one weak pointer plus the number of `Arc` weak pointers. This is
253 /// not equivalent to the sum of the total counts for each type of weak
254 /// pointer.
255 ///
256 /// # Examples
257 ///
258 /// ```rust
259 /// use drc::Drc;
260 /// use std::sync::Arc;
261 ///
262 /// let five = Drc::new(5);
263 /// let _weak_five_a = Drc::downgrade(&five);
264 /// let _weak_five_b = Drc::downgrade(&five);
265 /// let _weak_five_c = Drc::downgrade(&five);
266 ///
267 /// // No contribution because no weak pointers.
268 /// let _separate_five = Drc::separate(&five);
269 ///
270 /// // detached_five is an Arc that points to the same value.
271 /// let detached_five = Drc::detach(&five);
272 /// let _weak_detached_five = Arc::downgrade(&detached_five);
273 ///
274 /// // 3 values:
275 /// // _weak_five_a, _weak_five_b, _weak_five_c
276 /// assert_eq!(3, Drc::weak_count(&five, true));
277 ///
278 /// // 2 values:
279 /// // (_weak_five_a, _weak_five_b, _weak_five_c), _weak_detached_five
280 /// assert_eq!(2, Drc::weak_count(&five, false));
281 /// ```
282 ///
283 /// [`Weak`]: ./struct.Weak.html
284 ///
285 /// [`Arc`]: https://doc.rust-lang.org/std/sync/struct.Arc.html
286 /// [`WeakArc`]: https://doc.rust-lang.org/std/sync/struct.Weak.html
287 pub fn weak_count(this: &Drc<T>, local: bool) -> usize {
288 if local {
289 this.weak().get() - 1
290 } else {
291 Arc::weak_count(this.arc())
292 }
293 }
294
295 /// If `local`, gets the number of `Drc` pointers associated with the same
296 /// internal [`Arc`]. Otherwise, gets the number of `Arc`s associated with
297 /// the value.
298 ///
299 /// It's worth noting that neither of these values are the total counts of
300 /// strong pointers associated with a given value. Using a `local` value of
301 /// `false` will return the number of `Drc` sets containing at least one
302 /// strong pointer plus the number of `Arc` pointers. This is not
303 /// equivalent to the sum of the total counts for each type of strong
304 /// pointer.
305 ///
306 /// # Examples
307 ///
308 /// ```rust
309 /// use drc::Drc;
310 /// use std::sync::Arc;
311 ///
312 /// let five = Drc::new(5);
313 /// let _also_five = Drc::clone(&five);
314 /// let _still_five = Drc::clone(&five);
315 ///
316 /// // No contribution because no strong pointer.
317 /// let _weak_separate_five = {
318 /// let separate_five = Drc::separate(&five);
319 /// Drc::downgrade(&separate_five)
320 /// };
321 ///
322 /// // This is basically a glorified Arc, basically (Arc,)
323 /// let _strong_separate_five = Drc::separate(&five);
324 ///
325 /// // detached_five is an Arc that points to the same value.
326 /// let detached_five = Drc::detach(&five);
327 /// let _also_detached_five = Arc::clone(&detached_five);
328 ///
329 /// // 3 values:
330 /// // five, _also_five, _still_five
331 /// assert_eq!(3, Drc::strong_count(&five, true));
332 ///
333 /// // 4 values:
334 /// // (five, _also_five, _still_five), (_strong_separate_five,), detached_five,
335 /// // _also_detached_five
336 /// assert_eq!(4, Drc::strong_count(&five, false));
337 /// ```
338 ///
339 /// [`Arc`]: https://doc.rust-lang.org/std/sync/struct.Arc.html
340 pub fn strong_count(this: &Drc<T>, local: bool) -> usize {
341 if local {
342 this.strong().get()
343 } else {
344 Arc::strong_count(this.arc())
345 }
346 }
347
348 /// Returns a mutable reference to the inner value, if there are no other
349 /// `Drc`s, [`Arc`]s, [weak `Drc`][`Weak`]s, or [weak `Arc`][`WeakArc`]s to
350 /// the same value.
351 ///
352 /// Returns [`None`][`Option`] otherwise, because it is not safe to mutate a
353 /// shared value.
354 ///
355 /// See also [`make_mut`], which will [`clone`] the inner value when it's
356 /// shared.
357 ///
358 /// # Examples
359 ///
360 /// ```rust
361 /// use drc::Drc;
362 ///
363 /// let mut x = Drc::new(3);
364 /// *Drc::get_mut(&mut x).unwrap() = 4;
365 /// assert_eq!(*x, 4);
366 ///
367 /// let _y = Drc::clone(&x);
368 /// assert!(Drc::get_mut(&mut x).is_none());
369 /// ```
370 ///
371 /// [`Weak`]: ./struct.Weak.html
372 ///
373 /// [`make_mut`]: ./struct.Drc.html#method.make_mut
374 ///
375 /// [`Arc`]: https://doc.rust-lang.org/std/sync/struct.Arc.html
376 /// [`WeakArc`]: https://doc.rust-lang.org/std/sync/struct.Weak.html
377 /// [`Option`]: https://doc.rust-lang.org/std/option/enum.Option.html
378 ///
379 /// [`clone`]: https://doc.rust-lang.org/std/clone/trait.Clone.html#tymethod.clone
380 pub fn get_mut(this: &mut Drc<T>) -> Option<&mut T> {
381 if Drc::is_unique(this) {
382 // Since no mutation is actually happening, we don't need to do anything
383 // special in this case, unlike in `make_mut`.
384 Arc::get_mut(unsafe { this.arc_mut() })
385 } else {
386 None
387 }
388 }
389
390 /// Returns true if two `Drc`s point to the same value (not just values that
391 /// compare as equal). Note that as long as the **value** is the same,
392 /// association to the same `Arc` is not necessary.
393 ///
394 /// Contrast with [`linked`], which checks if two `Drc`s are associated with
395 /// the same `Arc` (i.e. they were cloned from the same `Drc` without
396 /// [`detach`ment][`detach`] or becoming [`separate`]).
397 ///
398 /// Compare with [`arc_ptr_eq`], which applies the same check for the
399 /// **value** on a `Drc` and [`Arc`].
400 ///
401 /// # Examples
402 ///
403 /// ```rust
404 /// use drc::Drc;
405 ///
406 /// let five = Drc::new(5);
407 ///
408 /// // Associated to same `Arc`.
409 /// let same_five = Drc::clone(&five);
410 ///
411 /// // Associated to different `Arc` but same value.
412 /// let separate_five = Drc::separate(&five);
413 ///
414 /// // A detached and converted `Drc` is the same as a separated `Drc`, so
415 /// // this is also associated to a different `Arc` but same value.
416 /// let detached_five = Drc::from(Drc::detach(&five));
417 ///
418 /// // An equal value located at a different memory address.
419 /// let other_five = Drc::new(5);
420 ///
421 /// assert!(Drc::ptr_eq(&five, &same_five));
422 /// assert!(Drc::ptr_eq(&five, &separate_five));
423 /// assert!(Drc::ptr_eq(&five, &detached_five));
424 /// assert!(!Drc::ptr_eq(&five, &other_five));
425 /// ```
426 ///
427 /// [`linked`]: ./struct.Drc.html#method.linked
428 /// [`detach`]: ./struct.Drc.html#method.detach
429 /// [`separate`]: ./struct.Drc.html#method.separate
430 /// [`arc_ptr_eq`]: ./struct.Drc.html#method.arc_ptr_eq
431 ///
432 /// [`Arc`]: https://doc.rust-lang.org/std/sync/struct.Arc.html
433 pub fn ptr_eq(this: &Drc<T>, other: &Drc<T>) -> bool {
434 Arc::ptr_eq(this.arc(), other.arc())
435 }
436
437 /// Returns true if a `Drc` and an [`Arc`] points to the same value (not
438 /// just values that compare as equal). Note that as long as the
439 /// **value** is the same, association of the passed `Drc` to the `Arc`
440 /// is not necessary (and is in fact impossible, as a reference to the
441 /// internal `Arc` cannot be retrieved externally).
442 ///
443 /// Contrast with [`linked`], which checks if two `Drc`s are associated with
444 /// the same `Arc` (i.e. they were cloned from the same `Drc` without
445 /// [`detach`ment][`detach`] or becoming [`separate`]).
446 ///
447 /// Compare with [`ptr_eq`], which applies the same check for the **value**
448 /// on two `Drc`s.
449 ///
450 /// # Examples
451 ///
452 /// ```rust
453 /// use drc::Drc;
454 /// use std::sync::Arc;
455 ///
456 /// let five = Drc::new(5);
457 ///
458 /// // Points to the same value. This is an `Arc`.
459 /// let detached_five = Drc::detach(&five);
460 ///
461 /// // Points to an equal value located at a different memory address.
462 /// let other_five = Arc::new(5);
463 ///
464 /// assert!(Drc::arc_ptr_eq(&five, &detached_five));
465 /// assert!(!Drc::arc_ptr_eq(&five, &other_five));
466 /// ```
467 ///
468 /// [`linked`]: ./struct.Drc.html#method.linked
469 /// [`detach`]: ./struct.Drc.html#method.detach
470 /// [`separate`]: ./struct.Drc.html#method.separate
471 /// [`ptr_eq`]: ./struct.Drc.html#method.ptr_eq
472 ///
473 /// [`Arc`]: https://doc.rust-lang.org/std/sync/struct.Arc.html
474 pub fn arc_ptr_eq(this: &Drc<T>, other: &Arc<T>) -> bool {
475 Arc::ptr_eq(this.arc(), other)
476 }
477
478 /// Returns true if two `Drc`s are associated with the same [`Arc`] (i.e.
479 /// they were cloned from the same `Drc` without
480 /// [`detach`ment][`detach`] or becoming [`separate`]).
481 ///
482 /// Contrast with [`ptr_eq`] or [`arc_ptr_eq`], which check if two `Drc`s or
483 /// a `Drc` and an `Arc` (respectively) point to the same **value**,
484 /// regardless of whether the internal `Arc` is the same (which is of
485 /// course impossible in `arc_ptr_eq`'s case, as a reference to the
486 /// internal `Arc` cannot be retrieved externally).
487 ///
488 /// Although it was just stated that an internal `Arc` cannot be retrieved
489 /// externally, it's worth explicitly noting that no analogue of
490 /// `arc_ptr_eq` exists for `linked` because a reference to the
491 /// "linked" `Arc` simply cannot be retrieved (`Drc::from(arc)` takes
492 /// ownership of the `Arc`).
493 ///
494 /// # Examples
495 ///
496 /// ```rust
497 /// use drc::Drc;
498 ///
499 /// let five = Drc::new(5);
500 ///
501 /// // Associated to same `Arc`.
502 /// let same_five = Drc::clone(&five);
503 ///
504 /// // Associated to different `Arc` but same value.
505 /// let separate_five = Drc::separate(&five);
506 ///
507 /// // A detached and converted `Drc` is the same as a separated `Drc`, so
508 /// // this is also associated to a different `Arc` but same value.
509 /// let detached_five = Drc::from(Drc::detach(&five));
510 ///
511 /// // An equal value located at a different memory address.
512 /// let other_five = Drc::new(5);
513 ///
514 /// assert!(Drc::linked(&five, &same_five));
515 /// assert!(!Drc::linked(&five, &separate_five));
516 /// assert!(!Drc::linked(&five, &detached_five));
517 /// assert!(!Drc::linked(&five, &other_five));
518 /// ```
519 ///
520 /// [`detach`]: ./struct.Drc.html#method.detach
521 /// [`separate`]: ./struct.Drc.html#method.separate
522 /// [`ptr_eq`]: ./struct.Drc.html#method.ptr_eq
523 /// [`arc_ptr_eq`]: ./struct.Drc.html#method.arc_ptr_eq
524 ///
525 /// [`Arc`]: https://doc.rust-lang.org/std/sync/struct.Arc.html
526 pub fn linked(this: &Drc<T>, other: &Drc<T>) -> bool {
527 this.ptr.as_ptr() == other.ptr.as_ptr()
528 }
529}
530
531impl<T> Drc<T>
532where
533 T: Clone,
534{
535 /// Makes a mutable reference into the given `Drc`.
536 ///
537 /// If there are other `Drc`s, [`Arc`]s, [weak `Drc`][`Weak`]s, or
538 /// [weak `Arc`][`WeakArc`]s to the same value, then `make_mut` will invoke
539 /// [`clone`] on the inner value to ensure unique ownership. This is also
540 /// referred to as clone-on-write.
541 ///
542 /// See also [`get_mut`], which will fail rather than cloning.
543 ///
544 /// # Examples
545 ///
546 /// ```rust
547 /// use drc::Drc;
548 ///
549 /// let mut data = Drc::new(5);
550 ///
551 /// *Drc::make_mut(&mut data) += 1; // Won't clone anything
552 /// let mut other_data = Drc::clone(&data); // Won't clone inner data
553 /// *Drc::make_mut(&mut data) += 1; // Clones inner data
554 /// *Drc::make_mut(&mut data) += 1; // Won't clone anything
555 /// *Drc::make_mut(&mut other_data) *= 2; // Won't clone anything
556 /// let mut detached_data = Drc::detach(&other_data); // Won't clone inner data
557 /// *Drc::make_mut(&mut other_data) += 1; // Clones inner data
558 /// *Drc::make_mut(&mut other_data) += 2; // Won't clone anything
559 ///
560 /// // Now `data`, `other_data`, and `detached_data` all point to different values.
561 /// assert_eq!(*data, 8);
562 /// assert_eq!(*other_data, 15);
563 /// assert_eq!(*detached_data, 12);
564 /// ```
565 ///
566 /// [`Weak`]: ./struct.Weak.html
567 ///
568 /// [`get_mut`]: ./struct.Drc.html#method.get_mut
569 ///
570 /// [`Arc`]: https://doc.rust-lang.org/std/sync/struct.Arc.html
571 /// [`WeakArc`]: https://doc.rust-lang.org/std/sync/struct.Weak.html
572 ///
573 /// [`clone`]: https://doc.rust-lang.org/std/clone/trait.Clone.html#tymethod.clone
574 pub fn make_mut(this: &mut Drc<T>) -> &mut T {
575 if Drc::strong_count(this, true) != 1 {
576 // There are other `Drc`s associated with the same `Arc`, clone data.
577 *this = Drc::new((**this).clone());
578
579 // This is a brand new `Arc`, this should not perform further cloning, but it
580 // will sadly do a few atomic operations that it does not need to do.
581 Arc::make_mut(unsafe { this.arc_mut() })
582 } else {
583 if Drc::weak_count(this, true) != 0 {
584 // There are some weak pointers, so we need to make a new `Drc` as the
585 // `Arc` is guaranteed to change (if our weak pointer count is at least one, so
586 // too must `Arc`'s count) but our local weak pointers would
587 // not care, thus creating the possibility of multiple
588 // aliasing. We need to make a new `Drc` but leave the
589 // weak pointers behind.
590
591 // Steal the `Arc` because we're sticking it into a new pointer without updating
592 // the atomic reference counts.
593 let arc = unsafe { this.take_arc() };
594
595 // Set the strong count to zero; we are moving to a new pointer.
596 this.strong().set(0);
597
598 // Remove the implicit weak pointer, but don't clean up because there are still
599 // more weak pointers that will do that for us.
600 this.weak().set(this.weak().get() - 1);
601
602 // `Drc::from_arc` does not modify the `Arc` at all, it literally sets its bytes
603 // in the newly allocated `DrcInner` and leaves it be.
604 let mut swap = Drc::from_arc(arc);
605
606 // Place the newly crafted `Drc` pointer into the current `Drc`. This is
607 // associated with the same `Arc`, but this time
608 // `Arc::make_mut` is safe to call.
609 mem::swap(this, &mut swap);
610
611 // Forget about the old `Drc` because we already cleaned it up (by setting
612 // strong count to zero, stealing the `Arc`, and removing the
613 // implicit weak pointer).
614 mem::forget(swap);
615 }
616
617 // At this point we have guaranteed that there are 0 weak pointers associated
618 // with the current `Drc`'s `DrcInner`, and that the current `Drc`
619 // is the only strong pointer associated with the same `DrcInner`.
620 // Therefore, any mutation that `Arc::make_mut` may or may not do
621 // to retrieve the value will not be done in a way that allows
622 // multiple aliasing of a mutable reference (remember that the `Arc` does not
623 // know we have our own strong/weak reference system).
624 Arc::make_mut(unsafe { this.arc_mut() })
625 }
626 }
627}
628
629impl<T> Drc<T>
630where
631 T: ?Sized,
632{
633 /// Ensure that **local** weak count == 0 and strong count == 1.
634 fn is_unique(this: &Drc<T>) -> bool {
635 // This only checks the local reference counts, as `Drc::get_mut` has to defer
636 // to `Arc::get_mut` anyway.
637 Drc::weak_count(this, true) == 0 && Drc::strong_count(this, true) == 1
638 }
639
640 /// Create a `Drc` from an `Arc`, without incrementing the atomic reference
641 /// counts (as the `Arc` is hijacked by the `Drc` rather than dissected in
642 /// some hacky way).
643 fn from_arc(arc: Arc<T>) -> Drc<T> {
644 unsafe {
645 Drc {
646 ptr: NonNull::new_unchecked(Box::into_raw(Box::new(DrcInner {
647 strong: Cell::new(1),
648 weak: Cell::new(1),
649 strong_ref: Some(arc),
650 weak_ref: None,
651 }))),
652 phantom: PhantomData,
653 }
654 }
655 }
656
657 /// Retrieve the raw `Cell` that holds the number of weak pointers
658 /// associated with the local `Arc`.
659 fn weak(&self) -> &Cell<usize> {
660 unsafe { &self.ptr.as_ref().weak }
661 }
662
663 /// Retrieve the raw `Cell` that holds the number of strong pointers
664 /// associated with the local `Arc`.
665 fn strong(&self) -> &Cell<usize> {
666 unsafe { &self.ptr.as_ref().strong }
667 }
668
669 /// Retrieves the contained `Arc` without having to unwrap the option due to
670 /// the fact that we guarantee the `Arc`'s existence by this `Drc`'s
671 /// existence.
672 fn arc(&self) -> &Arc<T> {
673 // Compiler should hopefully easily see this as a no-op, but this is a
674 // precaution against an Arc<T> somehow not being subject to null pointer
675 // optimization.
676 assert_eq!(
677 mem::size_of::<Arc<T>>(),
678 mem::size_of::<Option<Arc<T>>>(),
679 "Error within drc::Drc<T>: Null pointer optimization does not apply to Arc<T>! If you \
680 see this panic, please report it to the maintainer(s) of the \"drc\" crate."
681 );
682
683 // This is safe because the value will *always* be Some when a strong
684 // pointer (i.e. self) exists.
685 unsafe { &*(&self.ptr.as_ref().strong_ref as *const _ as *const Arc<T>) }
686 }
687
688 /// Ensure that there is 1 local strong pointer and 0 real local weak
689 /// pointers before calling this method. Otherwise, this simply takes a
690 /// mutable reference to the `Arc` from the `Option` with the same
691 /// justification as `arc`.
692 unsafe fn arc_mut(&mut self) -> &mut Arc<T> {
693 // Compiler should hopefully easily see this as a no-op, but this is a
694 // precaution against an Arc<T> somehow not being subject to null pointer
695 // optimization.
696 assert_eq!(
697 mem::size_of::<Arc<T>>(),
698 mem::size_of::<Option<Arc<T>>>(),
699 "Error within drc::Drc<T>: Null pointer optimization does not apply to Arc<T>! If you \
700 see this panic, please report it to the maintainer(s) of the \"drc\" crate."
701 );
702
703 &mut *(&mut self.ptr.as_mut().strong_ref as *mut _ as *mut Arc<T>)
704 }
705
706 /// Ensure that the strong count is 1 before calling this method OR set it
707 /// to 0. Otherwise, this simply removes the `Arc` from the `Option`
708 /// with the same justification as `arc`.
709 unsafe fn take_arc(&self) -> Arc<T> {
710 // Compiler should hopefully easily see this as a no-op, but this is a
711 // precaution against an Arc<T> somehow not being subject to null pointer
712 // optimization.
713 assert_eq!(
714 mem::size_of::<Arc<T>>(),
715 mem::size_of::<Option<Arc<T>>>(),
716 "Error within drc::Drc<T>: Null pointer optimization does not apply to Arc<T>! If you \
717 see this panic, please report it to the maintainer(s) of the \"drc\" crate."
718 );
719
720 let storage = self.ptr.as_ptr();
721
722 let arc = ptr::read(&(*storage).strong_ref as *const _ as *const Arc<T>);
723 ptr::write(&mut (*storage).strong_ref, None);
724 arc
725 }
726
727 /// This should only be used right after `take_arc`, and only then if the
728 /// `Arc` is untouched.
729 unsafe fn set_arc(&self, arc: Arc<T>) {
730 // Compiler should hopefully easily see this as a no-op, but this is a
731 // precaution against an Arc<T> somehow not being subject to null pointer
732 // optimization.
733 assert_eq!(
734 mem::size_of::<Arc<T>>(),
735 mem::size_of::<Option<Arc<T>>>(),
736 "Error within drc::Drc<T>: Null pointer optimization does not apply to Arc<T>! If you \
737 see this panic, please report it to the maintainer(s) of the \"drc\" crate."
738 );
739
740 ptr::write(
741 &mut (*self.ptr.as_ptr()).strong_ref as *mut _ as *mut Arc<T>,
742 arc,
743 );
744 }
745}
746
747impl<T> Clone for Drc<T>
748where
749 T: ?Sized,
750{
751 /// Makes a clone of the `Drc` pointer.
752 ///
753 /// This creates another pointer to the same inner value and associated with
754 /// the same contained `Arc`. This increases the local strong reference
755 /// count, but does not touch the `Arc` at all.
756 ///
757 /// # Examples
758 ///
759 /// ```rust
760 /// use drc::Drc;
761 ///
762 /// let five = Drc::new(5);
763 ///
764 /// let same_five = Drc::clone(&five);
765 ///
766 /// // `five` and `same_five` share the same `Arc`.
767 /// assert!(Drc::linked(&five, &same_five));
768 ///
769 /// // Local strong reference count of 2:
770 /// // `five`, `same_five`
771 /// assert_eq!(2, Drc::strong_count(&five, true));
772 ///
773 /// // `Arc` strong reference count of 1:
774 /// // (`five`, `same_five`)
775 /// assert_eq!(1, Drc::strong_count(&five, false));
776 /// ```
777 fn clone(&self) -> Drc<T> {
778 self.strong().set(self.strong().get() + 1);
779 Drc {
780 ptr: self.ptr,
781 phantom: PhantomData,
782 }
783 }
784}
785
786impl<T> Drop for Drc<T>
787where
788 T: ?Sized,
789{
790 /// Drops the `Drc`.
791 ///
792 /// This will decrement the local strong reference count. In the case that
793 /// this is the last `Drc` associated with the inner `Arc` (i.e. the
794 /// local strong reference count reaches zero), the inner `Arc` is
795 /// dropped too.
796 ///
797 /// A local [`Weak`] pointer may still exist, and assuming the value still
798 /// persists within the `Arc`'s innards, said local `Weak` pointer might
799 /// still be upgradeable even in the case that this is the last local
800 /// `Drc`. In that case, the stored weak `Arc` will be upgraded to
801 /// repopulate the inner `Arc`.
802 ///
803 /// # Examples
804 ///
805 /// ```rust
806 /// use drc::Drc;
807 ///
808 /// struct Foo;
809 ///
810 /// impl Drop for Foo {
811 /// fn drop(&mut self) {
812 /// println!("dropped!");
813 /// }
814 /// }
815 ///
816 /// let foo = Drc::new(Foo);
817 /// let foo2 = Drc::clone(&foo);
818 ///
819 /// drop(foo); // Doesn't print anything
820 /// drop(foo2); // Prints "dropped!"
821 /// ```
822 ///
823 /// [`Weak`]: ./struct.Weak.html
824 fn drop(&mut self) {
825 unsafe {
826 let strong = self.strong().get();
827 self.strong().set(strong - 1);
828 // In the case that this is the last strong pointer, it falls to us to
829 // clean up the internal `Arc` as well as the implicit weak pointer.
830 if strong == 1
831 /* now it is 0 */
832 {
833 // Drop the contained `Arc`.
834 drop(self.take_arc());
835
836 // Clean up our implicit weak pointer.
837 let weak = self.weak().get();
838 self.weak().set(weak - 1);
839 // In the case that that was the last weak pointer, it falls to us to
840 // deallocate the `DrcInner`. If there are remaining weak pointers, they
841 // can handle it themselves.
842 //
843 // We can not simply materialize the implicit weak pointer because it
844 // will think that the implicit weak pointer is already gone due to
845 // strong count being zero, and if we did not decrement strong count,
846 // it wouldn't think there was any work to be done when it was dropped.
847 if weak == 1
848 /* now it is 0 */
849 {
850 // Recreate the `Box` that the `DrcInner` was originally allocated as,
851 // so that its `Drop` implementation can run.
852 // Since we use only safe types within the `DrcInner`, this will
853 // work as expected.
854 Box::from_raw(self.ptr.as_ptr());
855 }
856 }
857 }
858 }
859}
860
861impl<T> AsRef<T> for Drc<T>
862where
863 T: ?Sized,
864{
865 fn as_ref(&self) -> &T {
866 &**self
867 }
868}
869
870impl<T> Borrow<T> for Drc<T>
871where
872 T: ?Sized,
873{
874 fn borrow(&self) -> &T {
875 &**self
876 }
877}
878
879impl<T> Default for Drc<T>
880where
881 T: Default,
882{
883 /// Creates a new `Drc<T>`, with the `Default` value for `T`.
884 ///
885 /// # Examples
886 ///
887 /// ```rust
888 /// use drc::Drc;
889 ///
890 /// let x: Drc<i32> = Default::default();
891 /// assert_eq!(*x, 0);
892 /// ```
893 fn default() -> Drc<T> {
894 Drc::new(Default::default())
895 }
896}
897
898impl<T> Deref for Drc<T>
899where
900 T: ?Sized,
901{
902 type Target = T;
903
904 fn deref(&self) -> &T {
905 &**(self.arc())
906 }
907}
908
909impl<T> Eq for Drc<T>
910where
911 T: Eq + ?Sized,
912{
913}
914
915impl From<CString> for Drc<CStr> {
916 fn from(c_string: CString) -> Drc<CStr> {
917 Drc::from(Arc::from(c_string))
918 }
919}
920
921impl From<String> for Drc<str> {
922 fn from(string: String) -> Drc<str> {
923 Drc::from(Arc::from(string))
924 }
925}
926
927impl From<OsString> for Drc<OsStr> {
928 fn from(os_string: OsString) -> Drc<OsStr> {
929 Drc::from(Arc::from(os_string))
930 }
931}
932
933impl From<PathBuf> for Drc<Path> {
934 fn from(path: PathBuf) -> Drc<Path> {
935 Drc::from(Arc::from(path))
936 }
937}
938
939impl<'a> From<&'a CStr> for Drc<CStr> {
940 fn from(c_string: &'a CStr) -> Drc<CStr> {
941 Drc::from(Arc::from(c_string))
942 }
943}
944
945impl<'a> From<&'a str> for Drc<str> {
946 fn from(string: &'a str) -> Drc<str> {
947 Drc::from(Arc::from(string))
948 }
949}
950
951impl<'a> From<&'a OsStr> for Drc<OsStr> {
952 fn from(os_string: &'a OsStr) -> Drc<OsStr> {
953 Drc::from(Arc::from(os_string))
954 }
955}
956
957impl<'a> From<&'a Path> for Drc<Path> {
958 fn from(path: &'a Path) -> Drc<Path> {
959 Drc::from(Arc::from(path))
960 }
961}
962
963impl<'a, T> From<&'a [T]> for Drc<[T]>
964where
965 T: Clone,
966{
967 fn from(slice: &'a [T]) -> Drc<[T]> {
968 Drc::from(Arc::from(slice))
969 }
970}
971
972impl<T> From<Arc<T>> for Drc<T>
973where
974 T: ?Sized,
975{
976 fn from(arc: Arc<T>) -> Drc<T> {
977 Drc::from_arc(arc)
978 }
979}
980
981impl<T> From<Box<T>> for Drc<T>
982where
983 T: ?Sized,
984{
985 fn from(box_: Box<T>) -> Drc<T> {
986 Drc::from(Arc::from(box_))
987 }
988}
989
990impl<T> From<T> for Drc<T> {
991 fn from(value: T) -> Drc<T> {
992 Drc::from(Arc::from(value))
993 }
994}
995
996impl<T> From<Vec<T>> for Drc<[T]> {
997 fn from(vec: Vec<T>) -> Drc<[T]> {
998 Drc::from(Arc::from(vec))
999 }
1000}
1001
1002impl<T> Hash for Drc<T>
1003where
1004 T: Hash + ?Sized,
1005{
1006 fn hash<H>(&self, state: &mut H)
1007 where
1008 H: Hasher,
1009 {
1010 (**self).hash(state);
1011 }
1012}
1013
1014impl<T> Ord for Drc<T>
1015where
1016 T: Ord + ?Sized,
1017{
1018 /// Comparison for two `Drc`s.
1019 ///
1020 /// The two are compared by calling `cmp()` on their inner values.
1021 ///
1022 /// # Examples
1023 ///
1024 /// ```rust
1025 /// use std::cmp::Ordering;
1026 ///
1027 /// use drc::Drc;
1028 ///
1029 /// let five = Drc::new(5);
1030 ///
1031 /// assert_eq!(Ordering::Less, five.cmp(&Drc::new(6)));
1032 /// ```
1033 #[inline]
1034 fn cmp(&self, other: &Drc<T>) -> Ordering {
1035 (**self).cmp(&**other)
1036 }
1037}
1038
1039impl<T> PartialEq<Drc<T>> for Drc<T>
1040where
1041 T: PartialEq<T> + ?Sized,
1042{
1043 /// Equality for two `Drc`s.
1044 ///
1045 /// Two `Drc`s are equal if their inner values are equal.
1046 ///
1047 /// # Examples
1048 ///
1049 /// ```rust
1050 /// use drc::Drc;
1051 ///
1052 /// let five = Drc::new(5);
1053 ///
1054 /// assert!(five == Drc::new(5));
1055 /// ```
1056 fn eq(&self, other: &Drc<T>) -> bool {
1057 **self == **other
1058 }
1059
1060 /// Equality for two `Drc`s.
1061 ///
1062 /// Two `Drc`s are unequal if their inner values are unequal.
1063 ///
1064 /// # Examples
1065 ///
1066 /// ```rust
1067 /// use drc::Drc;
1068 ///
1069 /// let five = Drc::new(5);
1070 ///
1071 /// assert!(five != Drc::new(6));
1072 /// ```
1073 fn ne(&self, other: &Drc<T>) -> bool {
1074 **self != **other
1075 }
1076}
1077
1078impl<T> PartialOrd<Drc<T>> for Drc<T>
1079where
1080 T: PartialOrd<T> + ?Sized,
1081{
1082 /// Partial comparison for two `Drc`s.
1083 ///
1084 /// The two are compared by calling `partial_cmp()` on their inner values.
1085 ///
1086 /// # Examples
1087 ///
1088 /// ```rust
1089 /// use std::cmp::Ordering;
1090 ///
1091 /// use drc::Drc;
1092 ///
1093 /// let five = Drc::new(5);
1094 ///
1095 /// assert_eq!(Some(Ordering::Less), five.partial_cmp(&Drc::new(6)));
1096 /// ```
1097 #[inline(always)]
1098 fn partial_cmp(&self, other: &Drc<T>) -> Option<Ordering> {
1099 (**self).partial_cmp(&**other)
1100 }
1101
1102 /// Less-than comparison for two `Drc`s.
1103 ///
1104 /// The two are compared by calling `<` on their inner values.
1105 ///
1106 /// # Examples
1107 ///
1108 /// ```rust
1109 /// use drc::Drc;
1110 ///
1111 /// let five = Drc::new(5);
1112 ///
1113 /// assert!(five < Drc::new(6));
1114 /// ```
1115 #[inline(always)]
1116 fn lt(&self, other: &Drc<T>) -> bool {
1117 **self < **other
1118 }
1119
1120 /// 'Less than or equal to' comparison for two `Drc`s.
1121 ///
1122 /// The two are compared by calling `<=` on their inner values.
1123 ///
1124 /// # Examples
1125 ///
1126 /// ```rust
1127 /// use drc::Drc;
1128 ///
1129 /// let five = Drc::new(5);
1130 ///
1131 /// assert!(five <= Drc::new(6));
1132 /// ```
1133 #[inline(always)]
1134 fn le(&self, other: &Drc<T>) -> bool {
1135 **self <= **other
1136 }
1137
1138 /// Greater-than comparison for two `Drc`s.
1139 ///
1140 /// The two are compared by calling `>` on their inner values.
1141 ///
1142 /// # Examples
1143 ///
1144 /// ```rust
1145 /// use drc::Drc;
1146 ///
1147 /// let five = Drc::new(5);
1148 ///
1149 /// assert!(five > Drc::new(4));
1150 /// ```
1151 #[inline(always)]
1152 fn gt(&self, other: &Drc<T>) -> bool {
1153 **self > **other
1154 }
1155
1156 /// 'Greater-than or equal to' comparison for two `Drc`s.
1157 ///
1158 /// The two are compared by calling `>=` on their inner values.
1159 ///
1160 /// # Examples
1161 ///
1162 /// ```rust
1163 /// use drc::Drc;
1164 ///
1165 /// let five = Drc::new(5);
1166 ///
1167 /// assert!(five >= Drc::new(4));
1168 /// ```
1169 #[inline(always)]
1170 fn ge(&self, other: &Drc<T>) -> bool {
1171 **self >= **other
1172 }
1173}
1174
1175impl<T> Debug for Drc<T>
1176where
1177 T: Debug + ?Sized,
1178{
1179 fn fmt(&self, f: &mut Formatter) -> FmtResult {
1180 write!(f, "{:?}", &**self)
1181 }
1182}
1183
1184impl<T> Display for Drc<T>
1185where
1186 T: Display + ?Sized,
1187{
1188 fn fmt(&self, f: &mut Formatter) -> FmtResult {
1189 write!(f, "{}", &**self)
1190 }
1191}
1192
1193impl<T> Pointer for Drc<T>
1194where
1195 T: ?Sized,
1196{
1197 fn fmt(&self, f: &mut Formatter) -> FmtResult {
1198 write!(f, "{:p}", &**self)
1199 }
1200}
1201
1202impl<T> UnwindSafe for Drc<T>
1203where
1204 T: RefUnwindSafe + ?Sized,
1205{
1206}
1207
1208pub(crate) struct DrcInner<T>
1209where
1210 T: ?Sized,
1211{
1212 pub(crate) strong: Cell<usize>,
1213 pub(crate) weak: Cell<usize>,
1214 pub(crate) strong_ref: Option<Arc<T>>,
1215 pub(crate) weak_ref: Option<WeakArc<T>>,
1216}
1217
1218#[cfg(test)]
1219mod tests {
1220 use super::*;
1221
1222 #[test]
1223 fn new() {
1224 let drc = Drc::new(17usize);
1225
1226 let storage = unsafe { drc.ptr.as_ref() };
1227 assert_eq!(
1228 storage.strong.get(),
1229 1,
1230 "new Drc did not have strong count of 1."
1231 );
1232 assert_eq!(
1233 storage.weak.get(),
1234 1,
1235 "new Drc did not have weak count of 1 (implicit)."
1236 );
1237
1238 assert!(
1239 storage.strong_ref.is_some(),
1240 "new Drc did not have a stored Arc."
1241 );
1242 assert!(storage.weak_ref.is_none(), "new Drc had a stored WeakArc.");
1243
1244 let strong_ref = storage.strong_ref.as_ref().unwrap();
1245 assert_eq!(**strong_ref, 17usize, "new Drc stored value incorrectly.");
1246 assert_eq!(
1247 Arc::strong_count(strong_ref),
1248 1,
1249 "internal Arc had an unexpected strong reference count."
1250 );
1251 assert_eq!(
1252 Arc::weak_count(strong_ref),
1253 0,
1254 "internal Arc had an unexpected weak reference count."
1255 );
1256 }
1257
1258 #[test]
1259 fn detach() {
1260 let drc = Drc::new(17usize);
1261
1262 let storage = unsafe { drc.ptr.as_ref() };
1263 let arc_ptr = &**storage.strong_ref.as_ref().unwrap() as *const _;
1264
1265 let new_arc = Drc::detach(&drc);
1266
1267 assert_eq!(
1268 unsafe { drc.ptr.as_ref() } as *const _,
1269 storage as *const _,
1270 "original Drc changed pointer location when detached."
1271 );
1272 assert_eq!(
1273 &*new_arc as *const _, arc_ptr,
1274 "detached Arc did not have the same pointer value as original Drc."
1275 );
1276 }
1277
1278 #[test]
1279 fn separate() {
1280 let drc_1 = Drc::new(17usize);
1281 let storage_1 = unsafe { drc_1.ptr.as_ref() };
1282 let data_pointer_1 = &**storage_1.strong_ref.as_ref().unwrap() as *const _;
1283
1284 let drc_2 = Drc::separate(&drc_1);
1285 let storage_2 = unsafe { drc_2.ptr.as_ref() };
1286 let data_pointer_2 = &**storage_2.strong_ref.as_ref().unwrap() as *const _;
1287
1288 assert_eq!(
1289 unsafe { drc_1.ptr.as_ref() } as *const _,
1290 storage_1 as *const _,
1291 "original Drc changed local storage location when separated."
1292 );
1293 assert_eq!(
1294 &**storage_1.strong_ref.as_ref().unwrap() as *const _,
1295 data_pointer_1,
1296 "original Drc changed data pointer location when separated."
1297 );
1298
1299 assert_ne!(
1300 storage_1 as *const _, storage_2 as *const _,
1301 "new Drc still shared local storage location with original Drc when separated."
1302 );
1303 assert_eq!(
1304 data_pointer_1, data_pointer_2,
1305 "new Drc did not share data pointer location with original Drc when separated."
1306 );
1307
1308 assert_eq!(
1309 storage_1.strong.get(),
1310 1,
1311 "original Drc had a different strong reference count than expected when separated."
1312 );
1313 assert_eq!(
1314 storage_1.weak.get(),
1315 1,
1316 "original Drc had a different weak reference count than expected when separated."
1317 );
1318 assert!(
1319 storage_1.weak_ref.is_none(),
1320 "original Drc had a WeakArc stored when separated."
1321 );
1322
1323 assert_eq!(
1324 storage_2.strong.get(),
1325 1,
1326 "new Drc had a different strong reference count than expected."
1327 );
1328 assert_eq!(
1329 storage_2.weak.get(),
1330 1,
1331 "new Drc had a different weak reference count than expected."
1332 );
1333 assert!(
1334 storage_2.weak_ref.is_none(),
1335 "new Drc had a WeakArc stored."
1336 );
1337 }
1338
1339 // Duplicate of the documentation example because it sufficiently tests the
1340 // method, but it's still repeated here in case the docs change.
1341 #[test]
1342 fn try_unwrap() {
1343 // The `Drc` here is the only strong reference to 3, so it is successfully
1344 // unwrapped.
1345 let x = Drc::new(3);
1346 assert_eq!(Drc::try_unwrap(x), Ok(3));
1347
1348 // There are two `Drc` strong references to 4, so it is not successfully
1349 // unwrapped.
1350 let x = Drc::new(4);
1351 let _y = Drc::clone(&x);
1352 assert_eq!(*Drc::try_unwrap(x).unwrap_err(), 4);
1353
1354 // There is a `Drc` and an `Arc` strong reference to 5, so it is not
1355 // sucessfully unwrapped.
1356 let x = Drc::new(5);
1357 let _y = Drc::detach(&x);
1358 assert_eq!(*Drc::try_unwrap(x).unwrap_err(), 5);
1359 }
1360
1361 #[test]
1362 fn downgrade() {
1363 let drc = Drc::new(17usize);
1364 let drc_storage = unsafe { drc.ptr.as_ref() };
1365
1366 let weak = Drc::downgrade(&drc);
1367 let weak_storage = unsafe { weak.ptr.as_ref() };
1368
1369 assert_eq!(
1370 unsafe { drc.ptr.as_ref() } as *const _,
1371 drc_storage as *const _,
1372 "Drc changed local storage location when downgraded."
1373 );
1374 assert_eq!(
1375 drc_storage as *const _, weak_storage as *const _,
1376 "Drc did not share a storage location with new, weak Drc when downgraded."
1377 );
1378
1379 assert!(
1380 drc_storage.strong_ref.is_some(),
1381 "Drc storage lost its strong reference when downgraded."
1382 );
1383 assert!(
1384 drc_storage.weak_ref.is_some(),
1385 "Drc storage did not gain a weak reference when downgraded."
1386 );
1387
1388 assert_eq!(
1389 drc_storage.strong.get(),
1390 1,
1391 "Drc had a different strong reference count than expected when downgraded."
1392 );
1393 assert_eq!(
1394 drc_storage.weak.get(),
1395 2,
1396 "Drc had a different weak reference count than expected when downgraded."
1397 );
1398
1399 let strong_ref = drc_storage.strong_ref.as_ref().unwrap();
1400
1401 assert_eq!(
1402 Arc::strong_count(strong_ref),
1403 1,
1404 "internal Arc had an unexpected strong reference count when Drc downgraded."
1405 );
1406 assert_eq!(
1407 Arc::weak_count(strong_ref),
1408 1,
1409 "internal Arc had an unexpected weak reference count when Drc downgraded."
1410 );
1411
1412 let _weak_2 = Drc::downgrade(&drc);
1413
1414 assert_eq!(
1415 unsafe { drc.ptr.as_ref() } as *const _,
1416 drc_storage as *const _,
1417 "original Drc changed local storage location when downgraded a second time."
1418 );
1419
1420 assert!(
1421 drc_storage.strong_ref.is_some(),
1422 "Drc storage lost its strong reference when downgraded a second time."
1423 );
1424 assert!(
1425 drc_storage.weak_ref.is_some(),
1426 "Drc storage did not gain a weak reference when downgraded a second time."
1427 );
1428
1429 assert_eq!(
1430 drc_storage.strong.get(),
1431 1,
1432 "Drc had a different strong reference count than expected when downgraded a second \
1433 time."
1434 );
1435 assert_eq!(
1436 drc_storage.weak.get(),
1437 3,
1438 "Drc had a different weak reference count than expected when downgraded a second time."
1439 );
1440
1441 assert_eq!(
1442 drc_storage.strong_ref.as_ref().unwrap() as *const _,
1443 strong_ref as *const _,
1444 "Drc had a different internal strong Arc when downgraded a second time."
1445 );
1446
1447 assert_eq!(
1448 Arc::strong_count(strong_ref),
1449 1,
1450 "internal Arc had an unexpected strong reference count when Drc downgraded a second \
1451 time."
1452 );
1453 assert_eq!(
1454 Arc::weak_count(strong_ref),
1455 1,
1456 "internal Arc had an unexpected weak reference count when Drc downgraded a second \
1457 time."
1458 );
1459 }
1460
1461 // Duplicate of the documentation example because it sufficiently tests the
1462 // method, but it's still repeated here in case the docs change.
1463 #[test]
1464 fn weak_count() {
1465 let five = Drc::new(5);
1466 let _weak_five_a = Drc::downgrade(&five);
1467 let _weak_five_b = Drc::downgrade(&five);
1468 let _weak_five_c = Drc::downgrade(&five);
1469
1470 // No contribution because no weak pointers.
1471 let _separate_five = Drc::separate(&five);
1472
1473 // detached_five is an Arc that points to the same value.
1474 let detached_five = Drc::detach(&five);
1475 let _weak_detached_five = Arc::downgrade(&detached_five);
1476
1477 // 3 values:
1478 // _weak_five_a, _weak_five_b, _weak_five_c
1479 assert_eq!(3, Drc::weak_count(&five, true));
1480
1481 // 2 values:
1482 // (_weak_five_a, _weak_five_b, _weak_five_c), _weak_detached_five
1483 assert_eq!(2, Drc::weak_count(&five, false));
1484 }
1485
1486 // Duplicate of the documentation example because it sufficiently tests the
1487 // method, but it's still repeated here in case the docs change.
1488 #[test]
1489 fn strong_count() {
1490 let five = Drc::new(5);
1491 let _also_five = Drc::clone(&five);
1492 let _still_five = Drc::clone(&five);
1493
1494 // No contribution because no strong pointer.
1495 let _weak_separate_five = {
1496 let separate_five = Drc::separate(&five);
1497 Drc::downgrade(&separate_five)
1498 };
1499
1500 // This is basically a glorified Arc, basically (Arc,)
1501 let _strong_separate_five = Drc::separate(&five);
1502
1503 // detached_five is an Arc that points to the same value.
1504 let detached_five = Drc::detach(&five);
1505 let _also_detached_five = Arc::clone(&detached_five);
1506
1507 // 3 values:
1508 // five, _also_five, _still_five
1509 assert_eq!(3, Drc::strong_count(&five, true));
1510
1511 // 4 values:
1512 // (five, _also_five, _still_five), (_strong_separate_five,), detached_five,
1513 // _also_detached_five
1514 assert_eq!(4, Drc::strong_count(&five, false));
1515 }
1516
1517 #[test]
1518 fn get_mut() {
1519 // Test case for intended way of working.
1520 {
1521 let mut drc = Drc::new(17usize);
1522 *Drc::get_mut(&mut drc).unwrap() = 117usize;
1523
1524 assert_eq!(*drc, 117usize, "Intended Drc get_mut mutation failed.");
1525 }
1526
1527 // Test case for restriction "No other `Drc`s"
1528 {
1529 // LOCAL
1530 {
1531 let mut drc = Drc::new(17usize);
1532 let mut drc_clone = Drc::clone(&drc);
1533
1534 assert!(
1535 Drc::get_mut(&mut drc).is_none(),
1536 "Drc::get_mut returned Some(_) when another local Drc existed."
1537 );
1538 assert!(
1539 Drc::get_mut(&mut drc_clone).is_none(),
1540 "Drc::get_mut returned Some(_) on Drc clone when original Drc existed."
1541 );
1542 }
1543
1544 // NONLOCAL
1545 {
1546 let mut drc = Drc::new(17usize);
1547 let mut drc_separate = Drc::separate(&drc);
1548
1549 assert!(
1550 Drc::get_mut(&mut drc).is_none(),
1551 "Drc::get_mut returned Some(_) when another nonlocal Drc existed."
1552 );
1553 assert!(
1554 Drc::get_mut(&mut drc_separate).is_none(),
1555 "Drc::get_mut returned Some(_) on separate Drc when original Drc existed."
1556 );
1557 }
1558 }
1559
1560 // Test case for restriction "No other `Arc`s"
1561 {
1562 let mut drc = Drc::new(17usize);
1563 let _arc = Drc::detach(&drc);
1564
1565 assert!(
1566 Drc::get_mut(&mut drc).is_none(),
1567 "Drc::get_mut returned Some(_) when another Arc existed."
1568 );
1569 }
1570
1571 // Test case for restriction "No other weak `Drc`s"
1572 {
1573 // LOCAL
1574 {
1575 let mut drc = Drc::new(17usize);
1576 let weak_drc = Drc::downgrade(&drc);
1577
1578 assert!(
1579 Drc::get_mut(&mut drc).is_none(),
1580 "Drc::get_mut returned Some(_) when a local weak Drc existed."
1581 );
1582 assert!(
1583 Drc::get_mut(&mut Weak::upgrade(&weak_drc).unwrap()).is_none(),
1584 "Drc::get_mut returned Some(_) on upgraded local weak Drc when original Drc \
1585 existed."
1586 );
1587 }
1588
1589 // NONLOCAL
1590 {
1591 let mut drc = Drc::new(17usize);
1592 let weak_drc = Drc::downgrade(&Drc::separate(&drc));
1593
1594 assert!(
1595 Drc::get_mut(&mut drc).is_none(),
1596 "Drc::get_mut returned Some(_) when a nonlocal Drc existed."
1597 );
1598 assert!(
1599 Drc::get_mut(&mut Weak::upgrade(&weak_drc).unwrap()).is_none(),
1600 "Drc::get_mut returned Some(_) on upgraded nonlocal weak Drc when original \
1601 Drc existed."
1602 );
1603 }
1604 }
1605
1606 // Test case for restriction "No other weak `Arc`s"
1607 {
1608 // DETACH THEN DOWNGRADE
1609 {
1610 let mut drc = Drc::new(17usize);
1611 let weak_arc = Arc::downgrade(&Drc::detach(&drc));
1612
1613 assert!(
1614 Drc::get_mut(&mut drc).is_none(),
1615 "Drc::get_mut returned Some(_) when a weak Arc existed."
1616 );
1617 assert!(
1618 Arc::get_mut(&mut WeakArc::upgrade(&weak_arc).unwrap()).is_none(),
1619 "Arc::get_mut returned Some(_) on upgraded weak Arc when original Drc existed."
1620 );
1621 }
1622
1623 // DOWNGRADE THEN DETACH
1624 {
1625 let mut drc = Drc::new(17usize);
1626 let weak_arc = Weak::detach(&Drc::downgrade(&drc));
1627
1628 assert!(
1629 Drc::get_mut(&mut drc).is_none(),
1630 "Drc::get_mut returned Some(_) when a weak Arc existed."
1631 );
1632 assert!(
1633 Arc::get_mut(&mut WeakArc::upgrade(&weak_arc).unwrap()).is_none(),
1634 "Arc::get_mut returned Some(_) on upgraded weak Arc when original Drc existed."
1635 );
1636 }
1637 }
1638 }
1639
1640 #[test]
1641 fn ptr_eq() {
1642 // Test case for separate Drcs created from Arcs.
1643 {
1644 // EQUAL
1645 {
1646 let (drc_1, drc_2): (Drc<usize>, Drc<usize>) = {
1647 let arc = Arc::new(17usize);
1648 let drc_1 = Drc::from(Arc::clone(&arc));
1649 (drc_1, Drc::from(arc))
1650 };
1651
1652 assert!(
1653 Drc::ptr_eq(&drc_1, &drc_2),
1654 "Drcs created from two associated Arcs were not pointer equal."
1655 );
1656 }
1657
1658 // NOT EQUAL
1659 {
1660 let drc_1: Drc<usize> = Drc::from(Arc::new(17usize));
1661 let drc_2: Drc<usize> = Drc::from(Arc::new(17usize));
1662
1663 assert!(
1664 !Drc::ptr_eq(&drc_1, &drc_2),
1665 "Drcs created from two separate Arcs were pointer equal."
1666 );
1667 }
1668 }
1669
1670 // Test case for separate Drcs created manually with detach and from.
1671 {
1672 // EQUAL
1673 {
1674 let drc_1: Drc<usize> = Drc::new(17usize);
1675 let drc_2: Drc<usize> = Drc::from(Drc::detach(&drc_1));
1676
1677 assert!(
1678 Drc::ptr_eq(&drc_1, &drc_2),
1679 "Separate Drcs created manually with 'detach' and 'from' were not pointer \
1680 equal."
1681 );
1682 }
1683
1684 // NOT EQUAL
1685 // NOT APPLICABLE
1686 }
1687
1688 // Test case for separate Drcs created with separate.
1689 {
1690 // EQUAL
1691 {
1692 let drc_1 = Drc::new(17usize);
1693 let drc_2 = Drc::separate(&drc_1);
1694
1695 assert!(
1696 Drc::ptr_eq(&drc_1, &drc_2),
1697 "Separate Drcs created with 'separate' were not pointer equal."
1698 );
1699 }
1700
1701 // NOT EQUAL
1702 // NOT APPLICABLE
1703 }
1704
1705 // Test case for two local Drcs.
1706 {
1707 // EQUAL
1708 {
1709 let drc_1 = Drc::new(17usize);
1710 let drc_2 = Drc::clone(&drc_1);
1711
1712 assert!(
1713 Drc::ptr_eq(&drc_1, &drc_2),
1714 "Linked Drcs created with 'clone' were not pointer equal."
1715 );
1716 }
1717
1718 // NOT EQUAL
1719 {
1720 let drc_1 = Drc::new(17usize);
1721 let drc_2 = Drc::new(17usize);
1722
1723 assert!(
1724 !Drc::ptr_eq(&drc_1, &drc_2),
1725 "Drcs created using two separate 'new' calls were pointer equal."
1726 );
1727 }
1728 }
1729 }
1730
1731 #[test]
1732 fn arc_ptr_eq() {
1733 // Test case for an Arc and Drc created from an Arc.
1734 {
1735 // EQUAL
1736 {
1737 let arc: Arc<usize> = Arc::new(17usize);
1738 let drc: Drc<usize> = Drc::from(Arc::clone(&arc));
1739
1740 assert!(
1741 Drc::arc_ptr_eq(&drc, &arc),
1742 "An Arc and a Drc created from the Arc's clone were not pointer equal."
1743 );
1744 }
1745
1746 // NOT EQUAL
1747 {
1748 let arc: Arc<usize> = Arc::new(17usize);
1749 let drc: Drc<usize> = Drc::from(Arc::new(17usize));
1750
1751 assert!(
1752 !Drc::arc_ptr_eq(&drc, &arc),
1753 "An Arc and a Drc created from a different Arc were pointer equal."
1754 );
1755 }
1756 }
1757
1758 // Test case for an Arc detached from a local Drc, and a local Drc.
1759 {
1760 // EQUAL
1761 {
1762 let drc = Drc::new(17usize);
1763 let arc = Drc::detach(&drc);
1764
1765 assert!(
1766 Drc::arc_ptr_eq(&drc, &arc),
1767 "A Drc and an Arc detached from the Drc were not pointer equal."
1768 );
1769 }
1770
1771 // NOT EQUAL
1772 {
1773 let drc = Drc::new(17usize);
1774 let arc = Drc::detach(&Drc::new(17usize));
1775
1776 assert!(
1777 !Drc::arc_ptr_eq(&drc, &arc),
1778 "A Drc and an Arc detached from a different Drc were pointer equal"
1779 );
1780 }
1781 }
1782
1783 // Test case for an Arc detached from a separated Drc, and a local Drc.
1784 {
1785 // EQUAL
1786 {
1787 let drc = Drc::new(17usize);
1788 let arc = Drc::detach(&Drc::separate(&drc));
1789
1790 assert!(
1791 Drc::arc_ptr_eq(&drc, &arc),
1792 "A Drc and an Arc detached from a Drc separated from the original Drc were \
1793 not pointer equal."
1794 );
1795 }
1796
1797 // NOT EQUAL
1798 {
1799 let drc = Drc::new(17usize);
1800 let arc = Drc::detach(&Drc::separate(&Drc::new(17usize)));
1801
1802 assert!(
1803 !Drc::arc_ptr_eq(&drc, &arc),
1804 "A Drc and an Arc detached from a Drc separated from a different Drc were \
1805 pointer equal."
1806 );
1807 }
1808 }
1809
1810 // Test case for an Arc detached from a cloned local Drc, and a local Drc.
1811 {
1812 // EQUAL
1813 {
1814 let drc = Drc::new(17usize);
1815 let arc = Drc::detach(&Drc::clone(&drc));
1816
1817 assert!(
1818 Drc::arc_ptr_eq(&drc, &arc),
1819 "A Drc and an Arc detached from a clone of the Drc were not pointer equal."
1820 );
1821 }
1822
1823 // NOT EQUAL
1824 {
1825 let drc = Drc::new(17usize);
1826 let arc = Drc::detach(&Drc::clone(&Drc::new(17usize)));
1827
1828 assert!(
1829 !Drc::arc_ptr_eq(&drc, &arc),
1830 "A Drc and an Arc detached from a clone of a different Drc were pointer equal."
1831 );
1832 }
1833 }
1834 }
1835
1836 #[test]
1837 fn linked() {
1838 // Test case for two local Drcs
1839 {
1840 let drc_1 = Drc::new(17usize);
1841 let drc_2 = Drc::clone(&drc_1);
1842
1843 assert!(
1844 Drc::linked(&drc_1, &drc_2),
1845 "Two Drcs that were the strict definition of 'linked' were not considered linked."
1846 );
1847 }
1848
1849 // Test case for Drcs separated due to being created from Arcs.
1850 {
1851 // Associated Arcs
1852 {
1853 let (drc_1, drc_2): (Drc<usize>, Drc<usize>) = {
1854 let arc = Arc::new(17usize);
1855 let drc_1 = Drc::from(Arc::clone(&arc));
1856 (drc_1, Drc::from(arc))
1857 };
1858
1859 assert!(
1860 !Drc::linked(&drc_1, &drc_2),
1861 "Two Drcs separated due to being created from two different but associated \
1862 Arcs were considered linked."
1863 );
1864 }
1865
1866 // Not Associated Arcs
1867 {
1868 let drc_1: Drc<usize> = Drc::from(Arc::new(17usize));
1869 let drc_2: Drc<usize> = Drc::from(Arc::new(17usize));
1870
1871 assert!(
1872 !Drc::linked(&drc_1, &drc_2),
1873 "Two Drcs separated due to being created from two different and unassociated \
1874 Arcs were considered linked."
1875 );
1876 }
1877 }
1878
1879 // Test case for Drcs separated due to one being detached and then converted
1880 // manually.
1881 {
1882 let drc_1: Drc<usize> = Drc::new(17usize);
1883 let drc_2: Drc<usize> = Drc::from(Drc::detach(&drc_1));
1884
1885 assert!(
1886 !Drc::linked(&drc_1, &drc_2),
1887 "Two Drcs separated due to one being detached from the other and then converted \
1888 back into a Drc were considered linked."
1889 );
1890 }
1891
1892 // Test case for Drcs separated due to the 'separate' method.
1893 {
1894 let drc_1 = Drc::new(17usize);
1895 let drc_2 = Drc::separate(&drc_1);
1896
1897 assert!(
1898 !Drc::linked(&drc_1, &drc_2),
1899 "Two Drcs separated with the 'separate' method were considered linked."
1900 );
1901 }
1902
1903 // Test case for two separately created Drcs.
1904 {
1905 // Using 'new'
1906 {
1907 let drc_1 = Drc::new(17usize);
1908 let drc_2 = Drc::new(17usize);
1909
1910 assert!(
1911 !Drc::linked(&drc_1, &drc_2),
1912 "Two Drcs separated due to being made with separate 'new' calls were \
1913 considered linked."
1914 );
1915 }
1916
1917 // One using 'new', one using 'Drc::from(arc)'
1918 {
1919 let drc_1: Drc<usize> = Drc::new(17usize);
1920 let drc_2: Drc<usize> = Drc::from(Arc::new(17usize));
1921
1922 assert!(
1923 !Drc::linked(&drc_1, &drc_2),
1924 "Two Drcs separated due to one being made with 'new' and the other made with \
1925 'Drc::from(arc)' were considered linked."
1926 );
1927 }
1928 }
1929 }
1930
1931 // This is pretty much a slightly altered test for get_mut.
1932 #[test]
1933 fn make_mut() {
1934 // Test case for way of working that does not alter the Drc.
1935 {
1936 let mut drc = Drc::new(17usize);
1937 let storage = drc.ptr.as_ptr();
1938
1939 *Drc::get_mut(&mut drc).unwrap() = 117usize;
1940
1941 assert_eq!(*drc, 117usize, "Intended Drc make_mut mutation failed.");
1942
1943 assert_eq!(
1944 storage,
1945 drc.ptr.as_ptr(),
1946 "Drc storage changed with make_mut when it should not have."
1947 );
1948 }
1949
1950 // Test case for behavior with another Drc. This will alter the original Drc or
1951 // its storage in some way.
1952 {
1953 // LOCAL
1954 {
1955 let mut drc = Drc::new(17usize);
1956 let mut drc_clone = Drc::clone(&drc);
1957
1958 let storage = drc.ptr.as_ptr();
1959
1960 let val_ptr = &*drc as *const _;
1961
1962 *Drc::make_mut(&mut drc) = 117usize;
1963
1964 assert_eq!(*drc, 117usize, "Intended Drc make_mut mutation failed.");
1965 assert_eq!(*drc_clone, 17usize, "Drc make_mut mutation affected clone.");
1966
1967 assert_ne!(
1968 storage,
1969 drc.ptr.as_ptr(),
1970 "Drc make_mut did not change storage when it should have."
1971 );
1972 assert_eq!(
1973 storage,
1974 drc_clone.ptr.as_ptr(),
1975 "Drc make_mut changed storage for clone when it should not have."
1976 );
1977
1978 assert_eq!(
1979 unsafe { &**(*storage).strong_ref.as_ref().unwrap() } as *const _,
1980 val_ptr,
1981 "Drc make_mut changed original storage's Arc pointer when it should not have."
1982 );
1983
1984 *Drc::make_mut(&mut drc_clone) = 1117usize;
1985
1986 assert_eq!(
1987 *drc_clone, 1117usize,
1988 "Intended Drc clone make_mut mutation failed."
1989 );
1990
1991 assert_eq!(
1992 storage,
1993 drc_clone.ptr.as_ptr(),
1994 "Drc clone make_mut changed storage when it should not have."
1995 );
1996 }
1997
1998 // NONLOCAL
1999 {
2000 let mut drc = Drc::new(17usize);
2001 let mut drc_separate = Drc::separate(&drc);
2002
2003 let original_storage = drc.ptr.as_ptr();
2004 let separate_storage = drc_separate.ptr.as_ptr();
2005
2006 let original_storage_ref = unsafe { (&*original_storage) };
2007 let separate_storage_ref = unsafe { (&*separate_storage) };
2008
2009 let val_ptr = &*drc as *const _;
2010
2011 assert!(
2012 Arc::ptr_eq(
2013 original_storage_ref.strong_ref.as_ref().unwrap(),
2014 separate_storage_ref.strong_ref.as_ref().unwrap()
2015 ),
2016 "Values should be linked."
2017 );
2018
2019 *Drc::make_mut(&mut drc) = 117usize;
2020
2021 assert_eq!(*drc, 117usize, "Intended Drc make_mut mutation failed.");
2022 assert_eq!(
2023 *drc_separate, 17usize,
2024 "Drc make_mut mutation affected separated Drc."
2025 );
2026
2027 assert_eq!(
2028 original_storage,
2029 drc.ptr.as_ptr(),
2030 "Drc make_mut changed storage when it should not have."
2031 );
2032 assert_eq!(
2033 separate_storage,
2034 drc_separate.ptr.as_ptr(),
2035 "Drc make_mut changed storage for separate Drc when it should not have."
2036 );
2037
2038 {
2039 let original_storage_arc = original_storage_ref.strong_ref.as_ref().unwrap();
2040 let separate_storage_arc = separate_storage_ref.strong_ref.as_ref().unwrap();
2041 assert!(
2042 !Arc::ptr_eq(original_storage_arc, separate_storage_arc),
2043 "Drc make_mut did not change Arcs."
2044 );
2045
2046 assert_eq!(
2047 &*drc_separate as *const _, val_ptr,
2048 "Drc make_mut changed value pointer for separate Drc when it should not \
2049 have."
2050 );
2051
2052 assert_eq!(
2053 Arc::strong_count(original_storage_arc),
2054 1,
2055 "Drc make_mut did not update strong count properly."
2056 );
2057 assert_eq!(
2058 Arc::strong_count(separate_storage_arc),
2059 1,
2060 "Drc make_mut did not update strong count properly."
2061 );
2062 }
2063
2064 *Drc::make_mut(&mut drc_separate) = 1117usize;
2065
2066 assert_eq!(
2067 *drc_separate, 1117usize,
2068 "Intended separate Drc make_mut mutation failed."
2069 );
2070
2071 assert_eq!(
2072 separate_storage,
2073 drc_separate.ptr.as_ptr(),
2074 "Separate Drc make_mut changed storage when it should not have."
2075 );
2076
2077 assert_eq!(
2078 &*drc_separate as *const _, val_ptr,
2079 "Separate Drc make_mut changed value pointer when it should not have."
2080 );
2081 }
2082 }
2083
2084 // Test case for behavior with another Arc. This will alter the original Drc or
2085 // its storage in some way.
2086 {
2087 // WITHOUT LOCAL WEAK DRC (does not alter storage)
2088 {
2089 let mut drc = Drc::new(17usize);
2090 let mut arc = Drc::detach(&drc);
2091
2092 let original_storage = drc.ptr.as_ptr();
2093
2094 let val_ptr = &*drc as *const _;
2095
2096 assert!(
2097 Drc::arc_ptr_eq(&drc, &arc),
2098 "Values should be pointer equal."
2099 );
2100
2101 *Drc::make_mut(&mut drc) = 117usize;
2102
2103 assert_eq!(*drc, 117usize, "Intended Drc make_mut mutation failed.");
2104 assert_eq!(
2105 *arc, 17usize,
2106 "Drc make_mut mutation affected detached Arc."
2107 );
2108
2109 assert_eq!(
2110 original_storage,
2111 drc.ptr.as_ptr(),
2112 "Drc make_mut mutation changed storage when it should not have."
2113 );
2114
2115 assert_eq!(
2116 &*arc as *const _, val_ptr,
2117 "Drc make_mut mutation changed Arc value pointer when it should not have."
2118 );
2119
2120 *Arc::make_mut(&mut arc) = 1117usize;
2121
2122 assert_eq!(
2123 *arc, 1117usize,
2124 "Intended detached Arc make_mut mutation failed."
2125 );
2126
2127 assert_eq!(
2128 &*arc as *const _, val_ptr,
2129 "Detached Arc make_mut mutation changed value pointer when it should not have."
2130 );
2131 }
2132
2133 // WITH LOCAL WEAK DRC (alters storage)
2134 {
2135 let mut drc = Drc::new(17usize);
2136 let arc = Drc::detach(&drc);
2137
2138 let original_storage = drc.ptr.as_ptr();
2139
2140 let val_ptr = &*drc as *const _;
2141
2142 assert!(
2143 Drc::arc_ptr_eq(&drc, &arc),
2144 "Values should be pointer equal."
2145 );
2146
2147 let drc = {
2148 let weak = Drc::downgrade(&drc);
2149
2150 *Drc::make_mut(&mut drc) = 117usize;
2151
2152 assert_eq!(*drc, 117usize, "Intended Drc make_mut mutation failed.");
2153 assert_eq!(
2154 *arc, 17usize,
2155 "Drc make_mut mutation affected detached Arc."
2156 );
2157
2158 assert_ne!(
2159 original_storage,
2160 drc.ptr.as_ptr(),
2161 "Drc make_mut mutation did not change storage when it should have."
2162 );
2163 assert_eq!(
2164 original_storage,
2165 weak.ptr.as_ptr(),
2166 "Drc make_mut mutation changed weak pointer storage when it should not \
2167 have."
2168 );
2169
2170 assert_eq!(
2171 &*arc as *const _, val_ptr,
2172 "Drc make_mut mutation changed Arc value pointer when it should not have."
2173 );
2174
2175 weak.upgrade().unwrap()
2176 };
2177
2178 assert_eq!(
2179 &*drc as *const _, val_ptr,
2180 "Drc make_mut mutation altered (now-upgraded) weak pointer pointer location."
2181 );
2182
2183 // The remaining functionality should be the same as without weak Drc.
2184 }
2185 }
2186
2187 // Test case for behavior with a weak Drc. This will alter the original Drc or
2188 // its storage in some way.
2189 {
2190 // LOCAL (alters storage and value pointer)
2191 {
2192 let mut drc = Drc::new(17usize);
2193
2194 let original_storage = drc.ptr.as_ptr();
2195
2196 let val_ptr = &*drc as *const _;
2197
2198 let weak = Drc::downgrade(&drc);
2199
2200 *Drc::make_mut(&mut drc) = 117usize;
2201
2202 assert_eq!(*drc, 117usize, "Intended Drc make_mut mutation failed.");
2203
2204 assert_ne!(
2205 original_storage,
2206 drc.ptr.as_ptr(),
2207 "Drc make_mut mutation did not change storage when it should have."
2208 );
2209 assert_eq!(
2210 original_storage,
2211 weak.ptr.as_ptr(),
2212 "Drc make_mut mutation changed weak pointer storage when it should not have."
2213 );
2214
2215 assert_ne!(
2216 &*drc as *const _, val_ptr,
2217 "Drc make_mut mutation did not change value pointer when it should have."
2218 );
2219
2220 assert!(
2221 weak.upgrade().is_none(),
2222 "Drc make_mut mutation should have removed the only strong pointer to the \
2223 original value, thus invalidating the weak pointer."
2224 );
2225 }
2226
2227 // NONLOCAL (does not alter storage but alters value pointer)
2228 {
2229 for i in 0usize..3usize {
2230 let mut drc = Drc::new(17usize);
2231
2232 let original_storage = drc.ptr.as_ptr();
2233
2234 let val_ptr = &*drc as *const _;
2235
2236 let weak = match i {
2237 0 => Drc::downgrade(&Drc::separate(&drc)),
2238 1 => Drc::downgrade(&Drc::from(Drc::detach(&drc))),
2239 2 => Weak::with_weak_arc(Arc::downgrade(&Drc::detach(&drc))),
2240 _ => unreachable!(),
2241 };
2242
2243 let separate_storage = weak.ptr.as_ptr();
2244
2245 *Drc::make_mut(&mut drc) = 117usize;
2246
2247 assert_eq!(*drc, 117usize, "Intended Drc make_mut mutation failed.");
2248
2249 assert_eq!(
2250 original_storage,
2251 drc.ptr.as_ptr(),
2252 "Drc make_mut mutation changed storage when it should not have."
2253 );
2254 assert_eq!(
2255 separate_storage,
2256 weak.ptr.as_ptr(),
2257 "Drc make_mut mutation changed weak pointer storage when it should not \
2258 have."
2259 );
2260
2261 assert_ne!(
2262 &*drc as *const _, val_ptr,
2263 "Drc make_mut mutation did not change value pointer when it should have."
2264 );
2265
2266 assert!(
2267 weak.upgrade().is_none(),
2268 "Drc make_mut mutation should have removed the only strong pointer to the \
2269 original value, thus invalidating the weak pointer."
2270 );
2271 }
2272 }
2273 }
2274
2275 // Test case for behavior with a weak Arc. This will alter the original Drc's
2276 // storage, but not it itself.
2277 {
2278 // Same code, but different ways of creating a weak Arc each time.
2279 for i in 0usize..2usize {
2280 let mut drc = Drc::new(17usize);
2281
2282 let original_storage = drc.ptr.as_ptr();
2283
2284 let val_ptr = &*drc as *const _;
2285
2286 let weak = match i {
2287 0 => Arc::downgrade(&Drc::detach(&drc)),
2288 1 => Drc::downgrade(&drc).detach(),
2289 _ => unreachable!(),
2290 };
2291
2292 *Drc::make_mut(&mut drc) = 117usize;
2293
2294 assert_eq!(*drc, 117usize, "Intended Drc make_mut mutation failed.");
2295
2296 assert_eq!(
2297 original_storage,
2298 drc.ptr.as_ptr(),
2299 "Drc make_mut mutation changed storage when it should not have."
2300 );
2301
2302 assert_ne!(
2303 &*drc as *const _, val_ptr,
2304 "Drc make_mut mutation did not change value pointer when it should have."
2305 );
2306
2307 assert!(
2308 weak.upgrade().is_none(),
2309 "Drc make_mut mutation should have removed the only strong pointer to the \
2310 original value, thus invalidating the weak pointer."
2311 );
2312 }
2313 }
2314 }
2315
2316 // Duplicate of the documentation example because it sufficiently tests the
2317 // method, but it's still repeated here in case the docs change.
2318 #[test]
2319 fn clone() {
2320 let five = Drc::new(5);
2321
2322 let same_five = Drc::clone(&five);
2323
2324 // `five` and `same_five` share the same `Arc`.
2325 assert!(Drc::linked(&five, &same_five));
2326
2327 // Local strong reference count of 2:
2328 // `five`, `same_five`
2329 assert_eq!(2, Drc::strong_count(&five, true));
2330
2331 // `Arc` strong reference count of 1:
2332 // (`five`, `same_five`)
2333 assert_eq!(1, Drc::strong_count(&five, false));
2334 }
2335
2336 // Test inspired and not much more complex than the documentation example,
2337 // because that was considered a sufficient test. The only reason edits were
2338 // needed was because checking println! output is pointless when we could just
2339 // set a bool somewhere.
2340 //
2341 // Note that this is only considered a sufficient test because the side effects
2342 // of the dropping are sufficiently tested in the other code.
2343 #[test]
2344 fn drop() {
2345 struct Foo<'a>(&'a Cell<bool>);
2346
2347 impl<'a> Drop for Foo<'a> {
2348 fn drop(&mut self) {
2349 self.0.set(true);
2350 }
2351 }
2352
2353 let cell = Cell::new(false);
2354
2355 let foo = Drc::new(Foo(&cell));
2356 let foo2 = Drc::clone(&foo);
2357
2358 // Cell is currently false.
2359 assert_eq!(cell.get(), false);
2360
2361 // Cell is not set to true since Foo::drop is not run.
2362 mem::drop(foo);
2363 assert_eq!(cell.get(), false);
2364
2365 // Cell is set to true here since Foo::drop is run.
2366 mem::drop(foo2);
2367 assert_eq!(cell.get(), true);
2368 }
2369
2370 #[test]
2371 fn debug() {
2372 let drc = Drc::new(17usize);
2373
2374 assert_eq!(
2375 format!("{:?}", &*drc),
2376 format!("{:?}", &drc),
2377 "Debug outputs of actual value and Drc are not equal!"
2378 );
2379 }
2380
2381 #[test]
2382 fn display() {
2383 let drc = Drc::new(17usize);
2384
2385 assert_eq!(
2386 format!("{}", &*drc),
2387 format!("{}", &drc),
2388 "Display outputs of actual value and Drc are not equal!"
2389 );
2390 }
2391
2392 #[test]
2393 fn pointer() {
2394 let drc = Drc::new(17usize);
2395
2396 assert_eq!(
2397 format!("{:p}", &*drc),
2398 format!("{:p}", drc),
2399 "Pointer outputs of smart value and Drc are not equal!"
2400 );
2401 }
2402}