1pub use placeholders::PLACEHOLDERS;
6
7pub trait IndexGetExt<T>: TupleIndex {
8 type ElementType;
9
10 fn get_impl<'a>(x: &'a T) -> &'a Self::ElementType;
11 fn get_mut_impl<'a>(x: &'a mut T) -> &'a mut Self::ElementType;
12}
13
14pub trait TestTupleIndexExt<ConcernedTuple> {}
15
16pub trait TupleIndexExt: Sized {
17 type IndexMax: TupleIndex;
18
19 fn size_tuple() -> usize;
20
21 fn size(&self) -> usize;
22
23 fn get<I: TupleIndex>(
24 &self,
25 ) -> &<Self as TupleGetIndexExt<I>>::ElementType
26 where Self: TupleGetIndexExt<I> {
27 self.get_impl()
28 }
29
30 fn get_mut<I: TupleIndex>(
31 &mut self,
32 ) -> &mut <Self as TupleGetIndexExt<I>>::ElementType
33 where Self: TupleGetIndexExt<I> {
34 self.get_mut_impl()
35 }
36}
37
38#[cfg(test)]
41macro_rules! make_tuple_with_index_ext {
42 ( $tuple_struct_name:ident($($element_type:ty$(: $pub_vis:tt)*),*) ) => {
43 #[derive(Default, Clone)]
44 pub struct $tuple_struct_name($($($pub_vis )*$element_type),*);
45
46 make_get_index_ext_all!{
47 $tuple_struct_name($($element_type),*),
48 (
49 placeholder!(_0), placeholder!(_1), placeholder!(_2),
50 placeholder!(_3), placeholder!(_4), placeholder!(_5),
51 placeholder!(_6), placeholder!(_7), placeholder!(_8),
52 placeholder!(_9), placeholder!(_10), placeholder!(_11),
53 placeholder!(_12), placeholder!(_13)
54 ),
55 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)
56 }
57 }
58}
59
60pub trait TupleGetIndexExt<I: TupleIndex> {
62 type ElementType: ?Sized;
63
64 fn get_impl(&self) -> &Self::ElementType;
65 fn get_mut_impl(&mut self) -> &mut Self::ElementType;
66}
67
68pub trait IterCallFamilyTrait<
69 ConcernedTuple,
70 ElementConstrain: ElementConstrainMark + ?Sized,
71>
72{
73 fn prepare_iter(&mut self) {}
74
75 fn iter_step<
76 Index: OfElementSatisfiesOnTuple<ConcernedTuple, ElementConstrain>,
77 >(
78 &mut self, placeholder: &'static Index, index: usize,
79 );
80
81 fn finish_iter(&mut self) {}
82}
83
84pub trait TupleIterateFromTo<ElementConstrain: ElementConstrainMark + ?Sized>:
85 TupleIndexExt + Sized
86{
87 fn iter_from_to<
88 FromIndex: TupleIndex,
89 ToIndex: TupleIndex,
90 F: IterCallFamilyTrait<Self, ElementConstrain>,
91 >(
92 _from: &FromIndex, _to: &ToIndex, f: F,
93 ) where Self: TupleIterFromTo<FromIndex, ToIndex, ElementConstrain> {
94 <Self as TupleIterFromTo<FromIndex, ToIndex, ElementConstrain>>::iterate_from_to(f);
95 }
96}
97
98pub trait TupleIterate<ElementConstrain: ElementConstrainMark + ?Sized>:
99 Sized
100{
101 fn iterate<F: IterCallFamilyTrait<Self, ElementConstrain>>(f: F);
102}
103
104pub trait TupleIterFromTo<
105 FromIndex: TupleIndex,
106 ToIndex: TupleIndex,
107 ElementConstrain: ElementConstrainMark + ?Sized,
108>: Sized
109{
110 fn iterate_from_to<F: IterCallFamilyTrait<Self, ElementConstrain>>(f: F);
111}
112
113impl<T: TupleIndexExt, ElementConstrain: ElementConstrainMark + ?Sized>
114 TupleIterateFromTo<ElementConstrain> for T
115{
116}
117
118impl<
119 T: TupleIndexExt
120 + TupleIterFromTo<
121 placeholders::_0,
122 <Self as TupleIndexExt>::IndexMax,
123 ElementConstrain,
124 >,
125 ElementConstrain: ElementConstrainMark + ?Sized,
126 > TupleIterate<ElementConstrain> for T
127{
128 fn iterate<F: IterCallFamilyTrait<Self, ElementConstrain>>(f: F) {
129 Self::iterate_from_to(f);
130 }
131}
132
133pub trait ElementSatisfy<ElementConstrain: ?Sized> {
140 fn to_constrain_object(&self) -> &ElementConstrain;
141 fn to_constrain_object_mut(&mut self) -> &mut ElementConstrain;
142}
143
144macro_rules! enable_impl_transmute_for_element_satisfy {
149 (
150 generic $( $N:ident $(: $b0:path $(|$b:path)* )? ),*;
151 trait $lifetime:lifetime + $trait:path;
152 for $generic_type:ty;
153 ) => {
154 impl<$( $N $(: $b0 $(+$b)* )? ),*> ElementSatisfy<dyn $trait + $lifetime> for $generic_type
155 {
156 fn to_constrain_object(
157 &self,
158 ) -> &(dyn $lifetime + $trait) {
159 unsafe {
160 std::mem::transmute(
161 self as &(dyn '_ + $trait),
162 )
163 }
164 }
165
166 fn to_constrain_object_mut(
167 &mut self,
168 ) -> &mut (dyn $lifetime + $trait) {
169 unsafe {
170 std::mem::transmute(
171 self as &mut (dyn '_ + $trait),
172 )
173 }
174 }
175 }
176 };
177
178 (
179 generic $( $N:ident $(: $b0:path $(|$b:path)* )? ),*;
180 trait $lifetime:lifetime + $trait:path;
181 ) => {
182 enable_impl_transmute_for_element_satisfy! {
183 generic $( $N $(: $b0 $(|$b)* )? ),* , TempGeneric:$trait;
184 trait $lifetime + $trait;
185 for TempGeneric;
186 }
187 }
188}
189
190pub trait OfElementSatisfiesOnTuple<ConcernedTuple, ElementConstrain: ?Sized>:
195 TupleIndex + Sized
196{
197 type ElementType: ElementSatisfy<ElementConstrain> + ?Sized;
198
199 fn getter_for_tuple(
200 t: &ConcernedTuple,
201 ) -> &dyn TupleGetIndexExt<Self, ElementType = Self::ElementType>;
202 fn getter_for_tuple_mut(
203 t: &mut ConcernedTuple,
204 ) -> &mut dyn TupleGetIndexExt<Self, ElementType = Self::ElementType>;
205}
206
207impl<
208 Index: TupleIndex,
209 ElementConstrain: ElementConstrainMark + ?Sized,
210 ElementType: ElementSatisfy<ElementConstrain> + ?Sized,
211 ConcernedTuple: TupleGetIndexExt<Self, ElementType = ElementType>,
212 > OfElementSatisfiesOnTuple<ConcernedTuple, ElementConstrain> for Index
213{
214 type ElementType = ElementType;
215
216 fn getter_for_tuple(
217 t: &ConcernedTuple,
218 ) -> &dyn TupleGetIndexExt<
219 Self,
220 ElementType = <ConcernedTuple as TupleGetIndexExt<Self>>::ElementType,
221 > {
222 t
223 }
224
225 fn getter_for_tuple_mut(
226 t: &mut ConcernedTuple,
227 ) -> &mut dyn TupleGetIndexExt<
228 Self,
229 ElementType = <ConcernedTuple as TupleGetIndexExt<Self>>::ElementType,
230 > {
231 t
232 }
233}
234
235pub trait ElementConstrainMark {}
237
238pub struct ElementNoConstrain();
239impl ElementConstrainMark for ElementNoConstrain {}
240
241impl<T> ElementSatisfy<ElementNoConstrain> for T {
242 fn to_constrain_object(&self) -> &ElementNoConstrain { unreachable!() }
243
244 fn to_constrain_object_mut(&mut self) -> &mut ElementNoConstrain {
245 unreachable!()
246 }
247}
248
249pub trait TupleIndexUpTo<Index: TupleIndex> {}
250
251pub trait TupleIndex: Debug {}
252
253#[macro_use]
254mod macros {
255 macro_rules! placeholder {
256 ($t:ident) => {
257 $crate::utils::tuple::placeholders::$t
258 };
259 }
260
261 macro_rules! make_placeholder {
262 ($index:tt) => {
263 #[derive(Default, Debug)]
264 pub struct $index();
265
266 impl TupleIndex for $index {}
267
268 impl TupleIndexUpTo<$index> for AllPlaceholders {}
269 };
270 }
271
272 macro_rules! make_placeholders {
273 ($($index:tt),*) => {
274 $( make_placeholder!{$index} )*
275
276 #[derive(Default)]
278 pub struct AllPlaceholders($(pub placeholder!($index)),*);
279
280 pub const PLACEHOLDERS: AllPlaceholders
281 = AllPlaceholders($((placeholder!($index))()),*);
282 }
283 }
284
285 #[cfg(test)]
286 macro_rules! make_get_index_ext {
287 (
288 $tuple_type:ty,
289 $element_type:ty,
290 $place_holder:ty,
291 $place_holder_as_field:tt
292 ) => {
293 impl TupleIndexUpTo<$place_holder> for $tuple_type {}
294
295 impl IndexGetExt<$tuple_type> for $place_holder {
296 type ElementType = $element_type;
297
298 fn get_impl<'a>(x: &'a $tuple_type) -> &'a Self::ElementType {
299 &x.$place_holder_as_field
300 }
301
302 fn get_mut_impl<'a>(
303 x: &'a mut $tuple_type,
304 ) -> &'a mut Self::ElementType {
305 &mut x.$place_holder_as_field
306 }
307 }
308
309 impl TupleGetIndexExt<$place_holder> for $tuple_type {
310 type ElementType = $element_type;
311
312 fn get_impl(&self) -> &Self::ElementType {
313 &self.$place_holder_as_field
314 }
315
316 fn get_mut_impl(&mut self) -> &mut Self::ElementType {
317 &mut self.$place_holder_as_field
318 }
319 }
320 };
321 }
322
323 #[cfg(test)]
324 macro_rules! make_get_index_ext_all {
325 (
326 $tuple_struct_name:ident(),
327 ($place_holder_max:ty $(, $place_holder_rest:ty)*),
328 ($size:tt $(, $place_holder_as_field_rest:tt)*)
329 ) => {
330 impl TupleIndexExt for $tuple_struct_name {
331 type IndexMax = $place_holder_max;
332
333 fn size_tuple() -> usize { $size }
334
335 fn size(&self) -> usize { $size }
336 }
337
338 impl TupleIndexUpTo<$place_holder_max> for $tuple_struct_name {}
339 };
340 (
341 $tuple_struct_name:ident($element_type:ty $(, $element_type_rest:ty)*),
342 ($place_holder:ty $(, $place_holder_rest:ty)*),
343 ($place_holder_as_field:tt $(, $place_holder_as_field_rest:tt)*)
344 ) => {
345 make_get_index_ext!{
346 $tuple_struct_name, $element_type, $place_holder, $place_holder_as_field
347 }
348
349 make_get_index_ext_all!{
350 $tuple_struct_name($($element_type_rest),*),
351 ($($place_holder_rest),*),
352 ($($place_holder_as_field_rest),*)
353 }
354 }
355 }
356
357 macro_rules! tuple_from_to_iter_impl {
358 (
359 (($($place_holder:ty),*) ()),
360 (($($place_holder_as_field:tt),*) ())
361 ) => {};
362 (
363 (() ($place_holder_last:ty $(, $place_holder_rest:ty)*)),
364 (() ($place_holder_as_field_last:tt $(, $place_holder_as_field_rest:tt)*))
365 ) => {
366 impl<T: TupleIndexUpTo<$place_holder_last>, ElementConstrain: ElementConstrainMark + ?Sized>
367 TupleIterFromTo<$place_holder_last, $place_holder_last, ElementConstrain> for T {
368 fn iterate_from_to<F: IterCallFamilyTrait<Self, ElementConstrain>>(mut f: F) {
369 f.prepare_iter();
370 f.finish_iter();
371 }
372 }
373
374 tuple_from_to_iter_impl!{
375 (($place_holder_last) ($($place_holder_rest),*)),
376 (($place_holder_as_field_last) ($($place_holder_as_field_rest),*))
377 }
378 };
379 (
380 (($place_holder_first:ty $(, $place_holder:ty)*) ($place_holder_last:ty $(, $place_holder_rest:ty)*)),
381 (($place_holder_as_field_first:tt $(, $place_holder_as_field:tt)*) ($place_holder_as_field_last:tt $(, $place_holder_as_field_rest:tt)*))
382 ) => {
383 impl<T: TupleIndexUpTo<$place_holder_last>, ElementConstrain: ElementConstrainMark + ?Sized>
384 TupleIterFromTo<
385 $place_holder_first, $place_holder_last, ElementConstrain,
386 > for T where
387 T: TupleGetIndexExt<$place_holder_first>,
388 $(T: TupleGetIndexExt<$place_holder>,)*
389 $place_holder_first: OfElementSatisfiesOnTuple<T, ElementConstrain>,
390 $($place_holder: OfElementSatisfiesOnTuple<T, ElementConstrain>,)*
391 {
392 fn iterate_from_to<F: IterCallFamilyTrait<Self, ElementConstrain>>(mut f: F) {
393 f.prepare_iter();
394 f.iter_step(&placeholder!(PLACEHOLDERS).$place_holder_as_field_first, $place_holder_as_field_first);
395 $(f.iter_step(&placeholder!(PLACEHOLDERS).$place_holder_as_field, $place_holder_as_field);)*
396 f.finish_iter();
397 }
398 }
399
400 tuple_from_to_iter_impl!{
401 (($place_holder_first, $($place_holder,)* $place_holder_last) ($($place_holder_rest),*)),
402 (($place_holder_as_field_first, $($place_holder_as_field,)* $place_holder_as_field_last) ($($place_holder_as_field_rest),*))
403 }
404 }
405 }
406
407 macro_rules! tuple_iter_impl {
408 (
409 (($($place_holder:ty),*) ()),
410 (($($place_holder_as_field:tt),*) ())
411 ) => {};
412 (
413 (() ($place_holder_last:ty $(, $place_holder_rest:ty)*)),
414 (() ($place_holder_as_field_last:tt $(, $place_holder_as_field_rest:tt)*))
415 ) => {
416 tuple_from_to_iter_impl!{
417 (() ($place_holder_last, $($place_holder_rest),*)),
418 (() ($place_holder_as_field_last, $($place_holder_as_field_rest),*))
419 }
420
421 tuple_iter_impl!{
422 (($place_holder_last) ($($place_holder_rest),*)),
423 (($place_holder_as_field_last) ($($place_holder_as_field_rest),*))
424 }
425 };
426 (
427 (($($place_holder:ty),+) ($place_holder_last:ty $(, $place_holder_rest:ty)*)),
428 (($($place_holder_as_field:tt),+) ($place_holder_as_field_last:tt $(, $place_holder_as_field_rest:tt)*))
429 ) => {
430 tuple_from_to_iter_impl!{
431 (() ($place_holder_last $(, $place_holder_rest)*)),
432 (() ($place_holder_as_field_last $(, $place_holder_as_field_rest)*))
433 }
434
435 tuple_iter_impl!{
436 (($($place_holder,)* $place_holder_last) ($($place_holder_rest),*)),
437 (($($place_holder_as_field,)* $place_holder_as_field_last) ($($place_holder_as_field_rest),*))
438 }
439 }
440 }
441}
442
443pub mod placeholders {
444 use super::*;
445
446 make_placeholders! {_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13}
447
448 tuple_iter_impl! {
449 (() (
450 placeholder!(_0), placeholder!(_1), placeholder!(_2),
451 placeholder!(_3), placeholder!(_4), placeholder!(_5),
452 placeholder!(_6), placeholder!(_7), placeholder!(_8),
453 placeholder!(_9), placeholder!(_10), placeholder!(_11),
454 placeholder!(_12), placeholder!(_13)
455 )),
456 (() (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13))
457 }
458}
459
460#[cfg(test)]
461mod test {
462 use super::*;
463
464 make_tuple_with_index_ext!(Test(i32, f64, Vec<u8>, Box<[u8]>));
465 make_tuple_with_index_ext!(Test2(f64, Vec<u8>, Box<[u8]>, i32));
466
467 trait ElementIsDebug: Debug {}
468 impl ElementConstrainMark for dyn ElementIsDebug {}
469 impl ElementIsDebug for i32 {}
470 impl ElementIsDebug for f64 {}
471 impl ElementIsDebug for Vec<u8> {}
472 impl ElementIsDebug for Box<[u8]> {}
473
474 trait ElementToPrint {
475 fn to_string(&self) -> String;
476 }
477 impl ElementConstrainMark for dyn ElementToPrint {}
478
479 impl ElementToPrint for i32 {
480 fn to_string(&self) -> String { ToString::to_string(self) }
481 }
482 impl ElementToPrint for f64 {
483 fn to_string(&self) -> String { ToString::to_string(self) }
484 }
485 impl ElementToPrint for Vec<u8> {
486 fn to_string(&self) -> String {
487 unsafe { std::str::from_utf8_unchecked(self.as_slice()) }
488 .to_string()
489 }
490 }
491 impl ElementToPrint for Box<[u8]> {
492 fn to_string(&self) -> String {
493 unsafe { std::str::from_utf8_unchecked(self.as_ref()) }.to_string()
494 }
495 }
496
497 impl<Element: 'static + ElementToPrint> ElementSatisfy<dyn ElementToPrint>
498 for Element
499 {
500 fn to_constrain_object(&self) -> &(dyn 'static + ElementToPrint) {
501 self
502 }
503
504 fn to_constrain_object_mut(
505 &mut self,
506 ) -> &mut (dyn 'static + ElementToPrint) {
507 self
508 }
509 }
510
511 impl<Element: 'static + ElementIsDebug> ElementSatisfy<dyn ElementIsDebug>
512 for Element
513 {
514 fn to_constrain_object(&self) -> &(dyn 'static + ElementIsDebug) {
515 self
516 }
517
518 fn to_constrain_object_mut(
519 &mut self,
520 ) -> &mut (dyn 'static + ElementIsDebug) {
521 self
522 }
523 }
524
525 #[test]
526 fn test() {
527 let t = Test(
528 11,
529 2.3,
530 "5 8".into(),
531 "13 21".to_string().into_boxed_str().into_boxed_bytes(),
532 );
533
534 struct F<'a> {
535 t: &'a Test,
536 }
537
538 impl IterCallFamilyTrait<Test, dyn ElementToPrint> for F<'_> {
539 fn prepare_iter(&mut self) {}
540
541 fn iter_step<
542 Index: OfElementSatisfiesOnTuple<Test, dyn ElementToPrint>,
543 >(
544 &mut self, _placeholder: &'static Index, index: usize,
545 ) {
546 println!(
547 "Test field {}: {}",
548 index,
549 Index::getter_for_tuple(self.t)
550 .get_impl()
551 .to_constrain_object()
552 .to_string()
553 );
554 }
555
556 fn finish_iter(&mut self) {}
557 }
558
559 Test::iterate(F { t: &t });
560 Test::iter_from_to(&PLACEHOLDERS.0, &PLACEHOLDERS.2, F { t: &t });
561
562 struct G<'a> {
563 t: &'a Test,
564 }
565
566 impl IterCallFamilyTrait<Test, dyn ElementIsDebug> for G<'_> {
567 fn prepare_iter(&mut self) {}
568
569 fn iter_step<
570 Index: OfElementSatisfiesOnTuple<Test, dyn ElementIsDebug>,
571 >(
572 &mut self, _placeholder: &'static Index, index: usize,
573 ) {
574 println!(
575 "Test field {}: {:?}",
576 index,
577 Index::getter_for_tuple(self.t)
578 .get_impl()
579 .to_constrain_object()
580 );
581 }
582
583 fn finish_iter(&mut self) {}
584 }
585
586 Test::iterate(G { t: &t });
587
588 IterCallFamilyTrait::iter_step(&mut F { t: &t }, &PLACEHOLDERS.1, 1);
589
590 #[derive(Default)]
591 struct Counter {
592 iter_counts: u8,
593 finish_called: bool,
594 }
595
596 impl IterCallFamilyTrait<Test, ElementNoConstrain> for &mut Counter {
597 fn prepare_iter(&mut self) {
598 self.iter_counts = 0;
599 self.finish_called = false;
600 }
601
602 fn iter_step<
603 Index: OfElementSatisfiesOnTuple<Test, ElementNoConstrain>,
604 >(
605 &mut self, _placeholder: &'static Index, _index: usize,
606 ) {
607 self.iter_counts += 1;
608 }
609
610 fn finish_iter(&mut self) { self.finish_called = true; }
611 }
612
613 impl Counter {
614 fn assert(&self, counts: u8) {
615 assert_eq!(self.finish_called, true);
616 assert_eq!(self.iter_counts, counts);
617 }
618 }
619
620 let mut counter = Counter::default();
621
622 Test::iter_from_to(&PLACEHOLDERS.0, &PLACEHOLDERS.0, &mut counter);
623 counter.assert(0);
624 Test::iter_from_to(&PLACEHOLDERS.0, &PLACEHOLDERS.3, &mut counter);
625 counter.assert(3);
626 Test::iter_from_to(&PLACEHOLDERS.0, &PLACEHOLDERS.4, &mut counter);
627 counter.assert(4);
628 Test::iter_from_to(&PLACEHOLDERS.1, &PLACEHOLDERS.1, &mut counter);
629 counter.assert(0);
630 Test::iter_from_to(&PLACEHOLDERS.1, &PLACEHOLDERS.4, &mut counter);
631 counter.assert(3);
632 Test::iter_from_to(&PLACEHOLDERS.3, &PLACEHOLDERS.3, &mut counter);
633 counter.assert(0);
634 Test::iter_from_to(&PLACEHOLDERS.3, &PLACEHOLDERS.4, &mut counter);
635 counter.assert(1);
636 Test::iter_from_to(&PLACEHOLDERS.4, &PLACEHOLDERS.4, &mut counter);
637 counter.assert(0);
638
639 println!("Test total fields {}", Test::size_tuple());
640
641 let t2 = Test2(
642 t.get::<placeholders::_1>().clone(),
643 t.get::<placeholders::_2>().clone(),
644 t.get::<placeholders::_3>().clone(),
645 t.get::<placeholders::_0>().clone(),
646 );
647
648 assert_eq!(*t2.get::<placeholder!(_0)>(), 2.3);
649 assert_eq!(*t2.get::<placeholder!(_1)>(), "5 8".as_bytes());
650 assert_eq!(&**t2.get::<placeholder!(_2)>(), "13 21".as_bytes());
651 assert_eq!(*t2.get::<placeholder!(_3)>(), 11);
652 }
653}
654
655use std::fmt::Debug;