1#![allow(dead_code)]
2#[macro_export]
3macro_rules! as_boxed {
4 ($trait:tt) => {
5 fn clone_boxed(&self) -> Box<dyn $trait>;
6
7 fn to_boxed(self) -> Box<dyn $trait>;
8 };
9
10 ($trait:tt<$($param:tt), *>) => {
11 fn clone_boxed(&self) -> Box<dyn $trait<$($param), *>>;
12
13 fn to_boxed(self) -> Box<dyn $trait<$($param), *>>;
14 };
15
16 (impl $trait:tt) => {
17 fn clone_boxed(&self) -> Box<dyn $trait> {
18 Box::new(self.clone())
19 }
20
21 fn to_boxed(self) -> Box<dyn $trait> {
22 Box::new(self)
23 }
24 };
25
26 (impl $trait:tt<$($param:tt), *>) => {
27 fn clone_boxed(&self) -> Box<dyn $trait<$($param), *>> {
28 Box::new(self.clone())
29 }
30
31 fn to_boxed(self) -> Box<dyn $trait<$($param), *>> {
32 Box::new(self)
33 }
34 };
35
36 (impl Hash for $trait:tt) => {
37impl std::hash::Hash for Box<dyn $trait> {
38 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
39 state.write_u64(self.as_ref().hashcode());
40 }
41}
42 };
43
44 (impl Hash for $trait:tt<$($param:tt), *>) => {
45impl<$($param), *> std::hash::Hash for Box<dyn $trait<$($param), *>> {
46 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
47 state.write_u64(self.as_ref().hashcode());
48 }
49}
50 };
51
52 (impl Hash for $trait:tt<$($param:tt: $constraint0:tt $(+ $constraint:tt)*), *>) => {
53impl<$($param: $constraint0 $(+ $constraint)*), *> std::hash::Hash for Box<dyn $trait<$($param), *>> {
54 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
55 state.write_u64(self.as_ref().hashcode());
56 }
57}
58 };
59
60 (impl Hash for $trait:tt<$($param:tt: ?Sized + $constraint0:tt $(+ $constraint:tt)*), *>) => {
61impl<$($param: ?Sized + $constraint0 $(+ $constraint)*), *> std::hash::Hash for Box<dyn $trait<$($param), *>> {
62 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
63 state.write_u64(self.as_ref().hashcode());
64 }
65}
66 };
67
68 (impl Hash for $trait:tt<$($param:tt: 'static + $constraint0:tt $(+ $constraint:tt)*), *>) => {
69impl<$($param: 'static + $constraint0 $(+ $constraint)*), *> std::hash::Hash for Box<dyn $trait<$($param), *>> {
70 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
71 state.write_u64(self.as_ref().hashcode());
72 }
73}
74 };
75
76 (impl Hash for $trait:tt<$($param:tt: 'static + ?Sized + $constraint0:tt $(+ $constraint:tt)*), *>) => {
77impl<$($param: 'static + ?Sized + $constraint0 $(+ $constraint)*), *> std::hash::Hash for Box<dyn $trait<$($param), *>> {
78 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
79 state.write_u64(self.as_ref().hashcode());
80 }
81}
82 };
83
84 (impl PartialEq for $trait:tt) => {
85impl PartialEq for Box<dyn $trait> {
86 fn eq(&self, other: &Self) -> bool {
87 self.as_ref().equals(other.as_ref().as_any_ref())
88 }
89}
90 };
91
92 (impl PartialEq for $trait:tt<$($param:tt), *>) => {
93impl<$($param), *> PartialEq for Box<dyn $trait<$($param), *>> {
94 fn eq(&self, other: &Self) -> bool {
95 self.as_ref().equals(other.as_ref().as_any_ref())
96 }
97}
98 };
99
100 (impl PartialEq for $trait:tt<$($param:tt: $constraint0:tt $(+ $constraint:tt)*), *>) => {
101impl<$($param: $constraint0 $(+ $constraint)*), *> PartialEq for Box<dyn $trait<$($param), *>> {
102 fn eq(&self, other: &Self) -> bool {
103 self.as_ref().equals(other.as_ref().as_any_ref())
104 }
105}
106 };
107
108 (impl PartialEq for $trait:tt<$($param:tt: ?Sized + $constraint0:tt $(+ $constraint:tt)*), *>) => {
109impl<$($param: ?Sized + $constraint0 $(+ $constraint)*), *> PartialEq for Box<dyn $trait<$($param), *>> {
110 fn eq(&self, other: &Self) -> bool {
111 self.as_ref().equals(other.as_ref().as_any_ref())
112 }
113}
114 };
115
116 (impl PartialEq for $trait:tt<$($param:tt: 'static + $constraint0:tt $(+ $constraint:tt)*), *>) => {
117impl<$($param: 'static + $constraint0 $(+ $constraint)*), *> PartialEq for Box<dyn $trait<$($param), *>> {
118 fn eq(&self, other: &Self) -> bool {
119 self.as_ref().equals(other.as_ref().as_any_ref())
120 }
121}
122 };
123
124 (impl PartialEq for $trait:tt<$($param:tt: 'static + ?Sized + $constraint0:tt $(+ $constraint:tt)*), *>) => {
125impl<$($param: 'static + ?Sized + $constraint0 $(+ $constraint)*), *> PartialEq for Box<dyn $trait<$($param), *>> {
126 fn eq(&self, other: &Self) -> bool {
127 self.as_ref().equals(other.as_ref().as_any_ref())
128 }
129}
130 };
131
132 (impl Eq for $trait:tt) => {
133impl Eq for Box<dyn $trait> { }
134 };
135
136 (impl Eq for $trait:tt<$($param:tt), *>) => {
137impl<$($param), *> Eq for Box<dyn $trait<$($param), *>> { }
138 };
139
140 (impl Eq for $trait:tt<$($param:tt: $constraint0:tt $(+ $constraint:tt)*), *>) => {
141impl<$($param: $constraint0 $(+ $constraint)*), *> Eq for Box<dyn $trait<$($param), *>> { }
142 };
143
144 (impl Eq for $trait:tt<$($param:tt: ?Sized + $constraint0:tt $(+ $constraint:tt)*), *>) => {
145impl<$($param: ?Sized + $constraint0 $(+ $constraint)*), *> Eq for Box<dyn $trait<$($param), *>> { }
146 };
147
148 (impl Eq for $trait:tt<$($param:tt: 'static + $constraint0:tt $(+ $constraint:tt)*), *>) => {
149impl<$($param: 'static + $constraint0 $(+ $constraint)*), *> Eq for Box<dyn $trait<$($param), *>> { }
150 };
151
152 (impl Eq for $trait:tt<$($param:tt: 'static + ?Sized + $constraint0:tt $(+ $constraint:tt)*), *>) => {
153impl<$($param: 'static + ?Sized + $constraint0 $(+ $constraint)*), *> Eq for Box<dyn $trait<$($param), *>> { }
154 };
155
156 (impl Clone for $trait:tt) => {
157impl Clone for Box<dyn $trait> {
158 fn clone(&self) -> Self {
159 $trait::clone_boxed(self.as_ref())
160 }
161}
162 };
163
164 (impl Clone for $trait:tt<$($param:tt), *>) => {
165impl<$($param), *> Clone for Box<dyn $trait<$($param), *>> {
166 fn clone(&self) -> Self {
167 $trait::clone_boxed(self.as_ref())
168 }
169}
170 };
171
172 (impl Clone for $trait:tt<$($param:tt: $constraint0:tt $(+ $constraint:tt)*), *>) => {
173impl<$($param: $constraint0 $(+ $constraint)*), *> Clone for Box<dyn $trait<$($param), *>> {
174 fn clone(&self) -> Self {
175 $trait::clone_boxed(self.as_ref())
176 }
177}
178 };
179
180 (impl Clone for $trait:tt<$($param:tt: ?Sized + $constraint0:tt $(+ $constraint:tt)*), *>) => {
181impl<$($param: ?Sized + $constraint0 $(+ $constraint)*), *> Clone for Box<dyn $trait<$($param), *>> {
182 fn clone(&self) -> Self {
183 $trait::clone_boxed(self.as_ref())
184 }
185}
186 };
187
188 (impl Clone for $trait:tt<$($param:tt: 'static + $constraint0:tt $(+ $constraint:tt)*), *>) => {
189impl<$($param: 'static + $constraint0 $(+ $constraint)*), *> Clone for Box<dyn $trait<$($param), *>> {
190 fn clone(&self) -> Self {
191 $trait::clone_boxed(self.as_ref())
192 }
193}
194 };
195
196 (impl Clone for $trait:tt<$($param:tt: 'static + ?Sized + $constraint0:tt $(+ $constraint:tt)*), *>) => {
197impl<$($param: 'static + ?Sized + $constraint0 $(+ $constraint)*), *> Clone for Box<dyn $trait<$($param), *>> {
198 fn clone(&self) -> Self {
199 $trait::clone_boxed(self.as_ref())
200 }
201}
202 };
203}
204
205#[macro_export]
206macro_rules! as_trait {
207 ($trait: tt) => {
208 fn as_trait_ref(&self) -> &dyn $trait;
209
210 fn as_trait_mut(&mut self) -> &mut dyn $trait;
211 };
212
213 ($trait:tt<$($param:tt), *>) => {
214 fn as_trait_ref(&self) -> &dyn $trait<$($param), *>;
215
216 fn as_trait_mut(&mut self) -> &mut dyn $trait<$($param), *>;
217 };
218
219 (impl $trait: tt) => {
220 fn as_trait_ref(&self) -> &dyn $trait {
221 self
222 }
223
224 fn as_trait_mut(&mut self) -> &mut dyn $trait {
225 self
226 }
227 };
228
229 (impl $trait:tt<$($param:tt), *>) => {
230 fn as_trait_ref(&self) -> &dyn $trait<$($param), *> {
231 self
232 }
233
234 fn as_trait_mut(&mut self) -> &mut dyn $trait<$($param), *> {
235 self
236 }
237 };
238}
239
240#[allow(dead_code)]
241#[cfg(test)]
242mod tests {
243 use crate::any::*;
244 use crate::*;
245 use std::fmt::Debug;
246 use std::marker::*;
247
248 trait SomeType: Key {
249 fn say(&self);
250
251 as_boxed!(SomeType);
252 as_trait!(SomeType);
253 }
254
255 as_boxed!(impl Hash for SomeType);
256 as_boxed!(impl PartialEq for SomeType);
257 as_boxed!(impl Eq for SomeType);
258 as_boxed!(impl Clone for SomeType);
259
260 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
261 struct ST {}
262
263 impl SomeType for ST {
264 fn say(&self) {}
265
266 as_boxed!(impl SomeType);
267 as_trait!(impl SomeType);
268 }
269
270 trait SomeType1<K>: Key {
271 fn say(&self, k: K);
272
273 as_boxed!(SomeType1<K>);
274 as_trait!(SomeType1<K>);
275 }
276
277 as_boxed!(impl Hash for SomeType1<K: 'static>);
278 as_boxed!(impl PartialEq for SomeType1<K: 'static>);
279 as_boxed!(impl Eq for SomeType1<K: 'static>);
280 as_boxed!(impl Clone for SomeType1<K: 'static>);
281
282 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
283 struct ST1<K: KeyConstraint> {
284 k: PhantomData<K>,
285 }
286
287 impl<K: KeyConstraint> SomeType1<K> for ST1<K> {
288 fn say(&self, _k: K) {}
289
290 as_boxed!(impl SomeType1<K>);
291 as_trait!(impl SomeType1<K>);
292 }
293
294 trait SomeType2<K, V>: Key {
295 fn say(&self, k: K, v: V);
296
297 as_boxed!(SomeType2<K, V>);
298 as_trait!(SomeType2<K, V>);
299 }
300
301 as_boxed!(impl Hash for SomeType2<K: 'static, V: 'static>);
302 as_boxed!(impl PartialEq for SomeType2<K: 'static, V: 'static>);
303 as_boxed!(impl Eq for SomeType2<K: 'static, V: 'static>);
304 as_boxed!(impl Clone for SomeType2<K: 'static, V: 'static>);
305
306 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
307 struct ST2<K: KeyConstraint, V: ValueConstraint> {
308 k: PhantomData<K>,
309 v: PhantomData<V>,
310 }
311
312 impl<K: KeyConstraint, V: KeyConstraint> SomeType2<K, V> for ST2<K, V> {
313 fn say(&self, _k: K, _v: V) {}
314
315 as_boxed!(impl SomeType2<K, V>);
316 as_trait!(impl SomeType2<K, V>);
317 }
318
319 trait SomeType3<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint>: Key {
320 fn say(&self, k: K, v: V);
321
322 as_boxed!(SomeType3<K, V>);
323 as_trait!(SomeType3<K, V>);
324 }
325
326 as_boxed!(impl Hash for SomeType3<K: KeyConstraint, V: ValueConstraint>);
327 as_boxed!(impl PartialEq for SomeType3<K: KeyConstraint, V: ValueConstraint>);
328 as_boxed!(impl Eq for SomeType3<K: KeyConstraint, V: ValueConstraint>);
329 as_boxed!(impl Clone for SomeType3<K: KeyConstraint, V: ValueConstraint>);
330
331 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
332 struct ST3<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> {
333 k: PhantomData<K>,
334 v: PhantomData<V>,
335 }
336
337 impl<K: ?Sized + KeyConstraint, V: ?Sized + KeyConstraint> SomeType3<K, V> for ST3<K, V> {
338 fn say(&self, _k: K, _v: V) {}
339
340 as_boxed!(impl SomeType3<K, V>);
341 as_trait!(impl SomeType3<K, V>);
342 }
343
344 trait SomeType4<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint>: Key {
345 fn say(&self, k: K, v: V);
346
347 as_boxed!(SomeType4<K, V>);
348 as_trait!(SomeType4<K, V>);
349 }
350
351 as_boxed!(impl Hash for SomeType4<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint>);
352 as_boxed!(impl PartialEq for SomeType4<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint>);
353 as_boxed!(impl Eq for SomeType4<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint>);
354 as_boxed!(impl Clone for SomeType4<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint>);
355
356 trait SomeType5<K: 'static + KeyConstraint, V: 'static + ValueConstraint>: Key {
357 fn say(&self, k: K, v: V);
358
359 as_boxed!(SomeType5<K, V>);
360 as_trait!(SomeType5<K, V>);
361 }
362
363 as_boxed!(impl Hash for SomeType5<K: 'static + KeyConstraint, V: 'static + ValueConstraint>);
364 as_boxed!(impl PartialEq for SomeType5<K: 'static + KeyConstraint, V: 'static + ValueConstraint>);
365 as_boxed!(impl Eq for SomeType5<K: 'static + KeyConstraint, V: 'static + ValueConstraint>);
366 as_boxed!(impl Clone for SomeType5<K: 'static + KeyConstraint, V: 'static + ValueConstraint>);
367
368 trait SomeType6<K: 'static + ?Sized + KeyConstraint, V: 'static + ?Sized + ValueConstraint>:
369 Key
370 {
371 fn say(&self, k: K, v: V);
372
373 as_boxed!(SomeType6<K, V>);
374 as_trait!(SomeType6<K, V>);
375 }
376
377 as_boxed!(impl Hash for SomeType6<K: 'static + ?Sized + KeyConstraint, V: 'static + ?Sized + ValueConstraint>);
378 as_boxed!(impl PartialEq for SomeType6<K: 'static + ?Sized + KeyConstraint, V: 'static + ?Sized + ValueConstraint>);
379 as_boxed!(impl Eq for SomeType6<K: 'static + ?Sized + KeyConstraint, V: 'static + ?Sized + ValueConstraint>);
380 as_boxed!(impl Clone for SomeType6<K: 'static + ?Sized + KeyConstraint, V: 'static + ?Sized + ValueConstraint>);
381
382 trait SomeType7<
383 K: 'static + ?Sized + KeyConstraint + Debug,
384 V: 'static + ?Sized + ValueConstraint,
385 >: Key
386 {
387 fn say(&self, k: K, v: V);
388
389 as_boxed!(SomeType7<K, V>);
390 as_trait!(SomeType7<K, V>);
391 }
392
393 as_boxed!(impl Hash for SomeType7<K: 'static + ?Sized + KeyConstraint + Debug, V: 'static + ?Sized + ValueConstraint>);
394 as_boxed!(impl PartialEq for SomeType7<K: 'static + ?Sized + KeyConstraint + Debug, V: 'static + ?Sized + ValueConstraint>);
395 as_boxed!(impl Eq for SomeType7<K: 'static + ?Sized + KeyConstraint + Debug, V: 'static + ?Sized + ValueConstraint>);
396 as_boxed!(impl Clone for SomeType7<K: 'static + ?Sized + KeyConstraint + Debug, V: 'static + ?Sized + ValueConstraint>);
397}