/rust/registry/src/index.crates.io-6f17d22bba15001f/dyn-clone-1.0.19/src/lib.rs
Line | Count | Source (jump to first uncovered line) |
1 | | //! [![github]](https://github.com/dtolnay/dyn-clone) [![crates-io]](https://crates.io/crates/dyn-clone) [![docs-rs]](https://docs.rs/dyn-clone) |
2 | | //! |
3 | | //! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github |
4 | | //! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust |
5 | | //! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs |
6 | | //! |
7 | | //! <br> |
8 | | //! |
9 | | //! This crate provides a [`DynClone`] trait that can be used in trait objects, |
10 | | //! and a [`clone_box`] function that can clone any sized or dynamically sized |
11 | | //! implementation of `DynClone`. Types that implement the standard library's |
12 | | //! [`std::clone::Clone`] trait are automatically usable by a `DynClone` trait |
13 | | //! object. |
14 | | //! |
15 | | //! # Example |
16 | | //! |
17 | | //! ``` |
18 | | //! use dyn_clone::DynClone; |
19 | | //! |
20 | | //! trait MyTrait: DynClone { |
21 | | //! fn recite(&self); |
22 | | //! } |
23 | | //! |
24 | | //! impl MyTrait for String { |
25 | | //! fn recite(&self) { |
26 | | //! println!("{} ♫", self); |
27 | | //! } |
28 | | //! } |
29 | | //! |
30 | | //! fn main() { |
31 | | //! let line = "The slithy structs did gyre and gimble the namespace"; |
32 | | //! |
33 | | //! // Build a trait object holding a String. |
34 | | //! // This requires String to implement MyTrait and std::clone::Clone. |
35 | | //! let x: Box<dyn MyTrait> = Box::new(String::from(line)); |
36 | | //! |
37 | | //! x.recite(); |
38 | | //! |
39 | | //! // The type of x2 is a Box<dyn MyTrait> cloned from x. |
40 | | //! let x2 = dyn_clone::clone_box(&*x); |
41 | | //! |
42 | | //! x2.recite(); |
43 | | //! } |
44 | | //! ``` |
45 | | //! |
46 | | //! This crate includes a macro for concisely implementing `impl |
47 | | //! std::clone::Clone for Box<dyn MyTrait>` in terms of `dyn_clone::clone_box`. |
48 | | //! |
49 | | //! ``` |
50 | | //! # use dyn_clone::DynClone; |
51 | | //! # |
52 | | //! // As before. |
53 | | //! trait MyTrait: DynClone { |
54 | | //! /* ... */ |
55 | | //! } |
56 | | //! |
57 | | //! dyn_clone::clone_trait_object!(MyTrait); |
58 | | //! |
59 | | //! // Now data structures containing Box<dyn MyTrait> can derive Clone: |
60 | | //! #[derive(Clone)] |
61 | | //! struct Container { |
62 | | //! trait_object: Box<dyn MyTrait>, |
63 | | //! } |
64 | | //! ``` |
65 | | //! |
66 | | //! The `clone_trait_object!` macro expands to just the following, which you can |
67 | | //! handwrite instead if you prefer: |
68 | | //! |
69 | | //! ``` |
70 | | //! # use dyn_clone::DynClone; |
71 | | //! # |
72 | | //! # trait MyTrait: DynClone {} |
73 | | //! # |
74 | | //! impl Clone for Box<dyn MyTrait> { |
75 | | //! fn clone(&self) -> Self { |
76 | | //! dyn_clone::clone_box(&**self) |
77 | | //! } |
78 | | //! } |
79 | | //! |
80 | | //! // and similar for Box<dyn MyTrait + Send>, Box<dyn MyTrait + Sync>, Box<dyn MyTrait + Send + Sync> |
81 | | //! ``` |
82 | | |
83 | | #![doc(html_root_url = "https://docs.rs/dyn-clone/1.0.19")] |
84 | | #![no_std] |
85 | | #![allow( |
86 | | clippy::missing_panics_doc, |
87 | | clippy::needless_doctest_main, |
88 | | clippy::ptr_as_ptr |
89 | | )] |
90 | | |
91 | | extern crate alloc; |
92 | | |
93 | | #[cfg(doc)] |
94 | | extern crate core as std; |
95 | | |
96 | | #[macro_use] |
97 | | mod macros; |
98 | | |
99 | | // Not public API. |
100 | | #[doc(hidden)] |
101 | | pub mod __private { |
102 | | #[doc(hidden)] |
103 | | pub use core::clone::Clone; |
104 | | #[doc(hidden)] |
105 | | pub use core::marker::{Send, Sync}; |
106 | | |
107 | | #[doc(hidden)] |
108 | | pub type Box<T> = alloc::boxed::Box<T>; |
109 | | } |
110 | | |
111 | | mod sealed { |
112 | | pub trait Sealed {} |
113 | | impl<T: Clone> Sealed for T {} |
114 | | impl Sealed for str {} |
115 | | impl<T: Clone> Sealed for [T] {} |
116 | | pub struct Private; |
117 | | } |
118 | | |
119 | | use crate::sealed::{Private, Sealed}; |
120 | | use alloc::boxed::Box; |
121 | | use alloc::rc::Rc; |
122 | | use alloc::sync::Arc; |
123 | | |
124 | | /// This trait is implemented by any type that implements [`std::clone::Clone`]. |
125 | | pub trait DynClone: Sealed { |
126 | | // Not public API |
127 | | #[doc(hidden)] |
128 | | fn __clone_box(&self, _: Private) -> *mut (); |
129 | | } |
130 | | |
131 | | /// `&T` —▸ `T` |
132 | 0 | pub fn clone<T>(t: &T) -> T |
133 | 0 | where |
134 | 0 | T: DynClone, |
135 | 0 | { |
136 | 0 | unsafe { *Box::from_raw(<T as DynClone>::__clone_box(t, Private) as *mut T) } |
137 | 0 | } |
138 | | |
139 | | /// `&T` —▸ `Box<T>` |
140 | 0 | pub fn clone_box<T>(t: &T) -> Box<T> |
141 | 0 | where |
142 | 0 | T: ?Sized + DynClone, |
143 | 0 | { |
144 | 0 | let mut fat_ptr = t as *const T; |
145 | 0 | unsafe { |
146 | 0 | let data_ptr = &mut fat_ptr as *mut *const T as *mut *mut (); |
147 | 0 | assert_eq!(*data_ptr as *const (), t as *const T as *const ()); |
148 | 0 | *data_ptr = <T as DynClone>::__clone_box(t, Private); |
149 | 0 | } |
150 | 0 | unsafe { Box::from_raw(fat_ptr as *mut T) } |
151 | 0 | } Unexecuted instantiation: dyn_clone::clone_box::<dyn mp4san::parse::mp4box::ParsedBox> Unexecuted instantiation: dyn_clone::clone_box::<dyn mp4san::parse::mp4box::ParsedBox + core::marker::Send> Unexecuted instantiation: dyn_clone::clone_box::<dyn mp4san::parse::mp4box::ParsedBox + core::marker::Sync> Unexecuted instantiation: dyn_clone::clone_box::<dyn mp4san::parse::mp4box::ParsedBox + core::marker::Sync + core::marker::Send> Unexecuted instantiation: dyn_clone::clone_box::<dyn dyn_clone::DynClone> Unexecuted instantiation: dyn_clone::clone_box::<dyn dyn_clone::DynClone + core::marker::Send> Unexecuted instantiation: dyn_clone::clone_box::<dyn dyn_clone::DynClone + core::marker::Sync> Unexecuted instantiation: dyn_clone::clone_box::<dyn dyn_clone::DynClone + core::marker::Sync + core::marker::Send> |
152 | | |
153 | | /// `&mut Arc<T>` —▸ `&mut T` |
154 | 0 | pub fn arc_make_mut<T>(arc: &mut Arc<T>) -> &mut T |
155 | 0 | where |
156 | 0 | T: ?Sized + DynClone, |
157 | 0 | { |
158 | 0 | // Atomic. Find out whether the Arc in the argument is the single holder of |
159 | 0 | // a reference count (strong or weak) on the target object. If yes, it is |
160 | 0 | // guaranteed to remain that way throughout the rest of this function |
161 | 0 | // because no other threads could bump the reference count through any other |
162 | 0 | // Arc (because no others exist) or through this Arc (because the current |
163 | 0 | // thread holds an exclusive borrow of it). |
164 | 0 | let is_unique = Arc::get_mut(arc).is_some(); |
165 | 0 | if !is_unique { |
166 | 0 | // Non-atomic. |
167 | 0 | let clone = Arc::from(clone_box(&**arc)); |
168 | 0 | // Atomic. Check the reference counts again to find out whether the old |
169 | 0 | // object needs to be dropped. Probably not, but it can happen if all |
170 | 0 | // the other holders of a reference count went away during the time that |
171 | 0 | // the clone operation took. |
172 | 0 | *arc = clone; |
173 | 0 | } |
174 | | // Non-atomic. TODO: replace with Arc::get_mut_unchecked when stable. |
175 | 0 | let ptr = Arc::as_ptr(arc) as *mut T; |
176 | 0 | unsafe { &mut *ptr } |
177 | 0 | } |
178 | | |
179 | | /// `&mut Rc<T>` —▸ `&mut T` |
180 | 0 | pub fn rc_make_mut<T>(rc: &mut Rc<T>) -> &mut T |
181 | 0 | where |
182 | 0 | T: ?Sized + DynClone, |
183 | 0 | { |
184 | 0 | let is_unique = Rc::get_mut(rc).is_some(); |
185 | 0 | if !is_unique { |
186 | 0 | let clone = Rc::from(clone_box(&**rc)); |
187 | 0 | *rc = clone; |
188 | 0 | } |
189 | 0 | let ptr = Rc::as_ptr(rc) as *mut T; |
190 | 0 | unsafe { &mut *ptr } |
191 | 0 | } |
192 | | |
193 | | impl<T> DynClone for T |
194 | | where |
195 | | T: Clone, |
196 | | { |
197 | 0 | fn __clone_box(&self, _: Private) -> *mut () { |
198 | 0 | Box::<T>::into_raw(Box::new(self.clone())) as *mut () |
199 | 0 | } Unexecuted instantiation: <mp4san::parse::trak::TrakBox as dyn_clone::DynClone>::__clone_box Unexecuted instantiation: <mp4san::parse::minf::MinfBox as dyn_clone::DynClone>::__clone_box Unexecuted instantiation: <mp4san::parse::mdia::MdiaBox as dyn_clone::DynClone>::__clone_box Unexecuted instantiation: <mp4san::parse::stbl::StblBox as dyn_clone::DynClone>::__clone_box Unexecuted instantiation: <mp4san::parse::co64::Co64Box as dyn_clone::DynClone>::__clone_box Unexecuted instantiation: <mp4san::parse::stco::StcoBox as dyn_clone::DynClone>::__clone_box Unexecuted instantiation: <_ as dyn_clone::DynClone>::__clone_box |
200 | | } |
201 | | |
202 | | impl DynClone for str { |
203 | 0 | fn __clone_box(&self, _: Private) -> *mut () { |
204 | 0 | Box::<str>::into_raw(Box::from(self)) as *mut () |
205 | 0 | } |
206 | | } |
207 | | |
208 | | impl<T> DynClone for [T] |
209 | | where |
210 | | T: Clone, |
211 | | { |
212 | 0 | fn __clone_box(&self, _: Private) -> *mut () { |
213 | 0 | Box::<[T]>::into_raw(self.iter().cloned().collect()) as *mut () |
214 | 0 | } |
215 | | } |