/rust/registry/src/index.crates.io-1949cf8c6b5b557f/dyn-clone-1.0.20/src/lib.rs
Line | Count | Source |
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.20")] |
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 | | #[cfg(target_has_atomic = "ptr")] |
123 | | use alloc::sync::Arc; |
124 | | use core::ptr; |
125 | | |
126 | | /// This trait is implemented by any type that implements [`std::clone::Clone`]. |
127 | | pub trait DynClone: Sealed { |
128 | | // Not public API |
129 | | #[doc(hidden)] |
130 | | fn __clone_box(&self, _: Private) -> *mut (); |
131 | | } |
132 | | |
133 | | /// `&T` —▸ `T` |
134 | 0 | pub fn clone<T>(t: &T) -> T |
135 | 0 | where |
136 | 0 | T: DynClone, |
137 | | { |
138 | 0 | unsafe { *Box::from_raw(<T as DynClone>::__clone_box(t, Private) as *mut T) } |
139 | 0 | } |
140 | | |
141 | | /// `&T` —▸ `Box<T>` |
142 | 0 | pub fn clone_box<T>(t: &T) -> Box<T> |
143 | 0 | where |
144 | 0 | T: ?Sized + DynClone, |
145 | | { |
146 | 0 | let mut fat_ptr = t as *const T; |
147 | | unsafe { |
148 | 0 | let data_ptr = ptr::addr_of_mut!(fat_ptr) as *mut *mut (); |
149 | 0 | assert_eq!(*data_ptr as *const (), t as *const T as *const ()); |
150 | 0 | *data_ptr = <T as DynClone>::__clone_box(t, Private); |
151 | | } |
152 | 0 | unsafe { Box::from_raw(fat_ptr as *mut T) } |
153 | 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> |
154 | | |
155 | | /// `&mut Arc<T>` —▸ `&mut T` |
156 | | #[cfg(target_has_atomic = "ptr")] |
157 | 0 | pub fn arc_make_mut<T>(arc: &mut Arc<T>) -> &mut T |
158 | 0 | where |
159 | 0 | T: ?Sized + DynClone, |
160 | | { |
161 | | // Atomic. Find out whether the Arc in the argument is the single holder of |
162 | | // a reference count (strong or weak) on the target object. If yes, it is |
163 | | // guaranteed to remain that way throughout the rest of this function |
164 | | // because no other threads could bump the reference count through any other |
165 | | // Arc (because no others exist) or through this Arc (because the current |
166 | | // thread holds an exclusive borrow of it). |
167 | 0 | let is_unique = Arc::get_mut(arc).is_some(); |
168 | 0 | if !is_unique { |
169 | 0 | // Non-atomic. |
170 | 0 | let clone = Arc::from(clone_box(&**arc)); |
171 | 0 | // Atomic. Check the reference counts again to find out whether the old |
172 | 0 | // object needs to be dropped. Probably not, but it can happen if all |
173 | 0 | // the other holders of a reference count went away during the time that |
174 | 0 | // the clone operation took. |
175 | 0 | *arc = clone; |
176 | 0 | } |
177 | | // Non-atomic. TODO: replace with Arc::get_mut_unchecked when stable. |
178 | 0 | let ptr = Arc::as_ptr(arc) as *mut T; |
179 | 0 | unsafe { &mut *ptr } |
180 | 0 | } |
181 | | |
182 | | /// `&mut Rc<T>` —▸ `&mut T` |
183 | 0 | pub fn rc_make_mut<T>(rc: &mut Rc<T>) -> &mut T |
184 | 0 | where |
185 | 0 | T: ?Sized + DynClone, |
186 | | { |
187 | 0 | let is_unique = Rc::get_mut(rc).is_some(); |
188 | 0 | if !is_unique { |
189 | 0 | let clone = Rc::from(clone_box(&**rc)); |
190 | 0 | *rc = clone; |
191 | 0 | } |
192 | 0 | let ptr = Rc::as_ptr(rc) as *mut T; |
193 | 0 | unsafe { &mut *ptr } |
194 | 0 | } |
195 | | |
196 | | impl<T> DynClone for T |
197 | | where |
198 | | T: Clone, |
199 | | { |
200 | 0 | fn __clone_box(&self, _: Private) -> *mut () { |
201 | 0 | Box::<T>::into_raw(Box::new(self.clone())) as *mut () |
202 | 0 | } Unexecuted instantiation: <mp4san::parse::trak::TrakBox as dyn_clone::DynClone>::__clone_box Unexecuted instantiation: <mp4san::parse::stco::StcoBox as dyn_clone::DynClone>::__clone_box Unexecuted instantiation: <mp4san::parse::co64::Co64Box 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: <_ as dyn_clone::DynClone>::__clone_box |
203 | | } |
204 | | |
205 | | impl DynClone for str { |
206 | 0 | fn __clone_box(&self, _: Private) -> *mut () { |
207 | 0 | Box::<str>::into_raw(Box::from(self)) as *mut () |
208 | 0 | } |
209 | | } |
210 | | |
211 | | impl<T> DynClone for [T] |
212 | | where |
213 | | T: Clone, |
214 | | { |
215 | 0 | fn __clone_box(&self, _: Private) -> *mut () { |
216 | 0 | Box::<[T]>::into_raw(self.iter().cloned().collect()) as *mut () |
217 | 0 | } |
218 | | } |