cfx_storage/utils/
tuple.rs

1// Copyright 2019 Conflux Foundation. All rights reserved.
2// Conflux is free software and distributed under GNU General Public License.
3// See http://www.gnu.org/licenses/
4
5pub 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/// We don't support generics and lifetime yet because it will take some time to
39/// update the macro implementation.
40#[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
60/// This trait is on Tuple.
61pub 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
133// So far we don't support ElementType that is non 'static because rust
134// automatically add 'static to ElementConstrain since it is a trait object.
135// It would require more time to add support for ElementType with lifetime
136// constrain.
137/// ElementConstrain is a trait that can be made into trait object where
138/// the tuple element satisfies.
139pub trait ElementSatisfy<ElementConstrain: ?Sized> {
140    fn to_constrain_object(&self) -> &ElementConstrain;
141    fn to_constrain_object_mut(&mut self) -> &mut ElementConstrain;
142}
143
144// Auto impl transmute for ElementSatisfy<trait obj>.
145// Macro parser doesn't allow 'path' followed by '+',
146// use '|' in generic part instead, e.g. 'generic A, B: traitA | traitB, C;'.
147// FIXME: lifetime support for generic part
148macro_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
190// Library user don't need to look beyond this point. Check test mod for usage.
191
192/// Trait on Index, meaning that the element at Index for ConcernedTuple
193/// satisfies ElementConstrain.
194pub 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
235/// To make it easy for compiler to compute automated implementation.
236pub 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            /// Rust stdlib doesn't derive Default for this many elements.
277            #[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;