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}