@@ -75,6 +75,14 @@ round_up(T size, size_t alignment) {
75
75
return x;
76
76
}
77
77
78
+ template <typename T>
79
+ static inline T
80
+ bump_dp (uint8_t *dp) {
81
+ T x = *((T *)dp);
82
+ dp += sizeof (T);
83
+ return x;
84
+ }
85
+
78
86
79
87
// Utility classes
80
88
@@ -125,6 +133,34 @@ struct tag_info {
125
133
const type_param *params; // Array of type parameters.
126
134
};
127
135
136
+ template <typename T>
137
+ class data_pair {
138
+ public:
139
+ T fst, snd;
140
+ inline void operator =(const T rhs) { fst = snd = rhs; }
141
+ };
142
+
143
+ class ptr_pair {
144
+ public:
145
+ uint8_t *fst, *snd;
146
+
147
+ template <typename T>
148
+ class data { typedef data_pair<T> t; };
149
+
150
+ ptr_pair (uint8_t *in_fst, uint8_t *in_snd) : fst(in_fst), snd(in_snd) {}
151
+
152
+ inline void operator =(uint8_t *rhs) { fst = snd = rhs; }
153
+
154
+ inline ptr_pair operator +(size_t n) const {
155
+ return make (fst + n, snd + n);
156
+ }
157
+
158
+ static inline ptr_pair make (uint8_t *fst, uint8_t *snd) {
159
+ ptr_pair self (fst, snd);
160
+ return self;
161
+ }
162
+ };
163
+
128
164
129
165
// Contexts
130
166
@@ -719,16 +755,15 @@ size_of::walk_ivec(bool align, bool is_pod, size_align &elem_sa) {
719
755
// for methods that actually manipulate the data involved.
720
756
721
757
#define DATA_SIMPLE (ty, call ) \
722
- if (align) dp. align_to(sizeof (ty)); \
758
+ if (align) dp = align_to(dp, sizeof (ty)); \
723
759
static_cast <T *>(this )->call; \
724
760
dp += sizeof (ty);
725
761
726
- template <typename T>
727
- class data : public ctxt < data<T> > {
728
- private:
729
- typename T::data_ptr dp;
730
-
762
+ template <typename T,typename U>
763
+ class data : public ctxt < data<T,U> > {
731
764
public:
765
+ U dp;
766
+
732
767
void walk_tag (bool align, tag_info &tinfo);
733
768
void walk_ivec (bool align, bool is_pod, size_align &elem_sa);
734
769
@@ -750,13 +785,13 @@ class data : public ctxt< data<T> > {
750
785
void walk_task (bool align) { DATA_SIMPLE (void *, walk_task (align)); }
751
786
752
787
void walk_fn (bool align) {
753
- if (align) dp. align_to (sizeof (void *));
788
+ if (align) dp = align_to (dp, sizeof (void *));
754
789
static_cast <T *>(this )->walk_fn (align);
755
790
dp += sizeof (void *) * 2 ;
756
791
}
757
792
758
793
void walk_obj (bool align) {
759
- if (align) dp. align_to (sizeof (void *));
794
+ if (align) dp = align_to (dp, sizeof (void *));
760
795
static_cast <T *>(this )->walk_obj (align);
761
796
dp += sizeof (void *) * 2 ;
762
797
}
@@ -766,43 +801,40 @@ class data : public ctxt< data<T> > {
766
801
}
767
802
768
803
template <typename W>
769
- void walk_number (bool align) {
770
- DATA_SIMPLE (W, walk_number<W>(align));
771
- }
804
+ void walk_number (bool align) { DATA_SIMPLE (W, walk_number<W>(align)); }
772
805
};
773
806
774
- template <typename T>
807
+ template <typename T, typename U >
775
808
void
776
- data<T>::walk_ivec(bool align, bool is_pod, size_align &elem_sa) {
809
+ data<T,U >::walk_ivec(bool align, bool is_pod, size_align &elem_sa) {
777
810
if (!elem_sa.is_set ())
778
811
elem_sa = size_of::get (*this );
779
812
else if (elem_sa.alignment == 8 )
780
813
elem_sa.alignment = 4 ; // FIXME: This is an awful hack.
781
814
782
815
// Get a pointer to the interior vector, and skip over it.
783
- if (align) dp.align_to (ALIGNOF (rust_ivec *));
784
- typename T::data_ptr end_dp = dp + sizeof (rust_ivec) - sizeof (uintptr_t ) +
785
- elem_sa.size * 4 ;
816
+ if (align) dp = align_to (dp, ALIGNOF (rust_ivec *));
817
+ U end_dp = dp + sizeof (rust_ivec) - sizeof (uintptr_t ) + elem_sa.size * 4 ;
786
818
787
819
// Call to the implementation.
788
820
static_cast <T *>(this )->walk_ivec (align, is_pod, elem_sa);
789
821
790
822
dp = end_dp;
791
823
}
792
824
793
- template <typename T>
825
+ template <typename T, typename U >
794
826
void
795
- data<T>::walk_tag(bool align, tag_info &tinfo) {
827
+ data<T,U >::walk_tag(bool align, tag_info &tinfo) {
796
828
size_of::compute_tag_size (tinfo);
797
829
798
830
if (tinfo.variant_count > 1 && align)
799
- dp. align_to (ALIGNOF (uint32_t ));
831
+ dp = align_to (dp, ALIGNOF (uint32_t ));
800
832
801
- typename T::data_ptr end_dp = tinfo.tag_sa .size ;
833
+ U end_dp = tinfo.tag_sa .size ;
802
834
803
- typename T ::template data<uint32_t > tag_variant;
835
+ typename U ::template data<uint32_t >::t tag_variant;
804
836
if (tinfo.variant_count > 1 )
805
- tag_variant = dp. template get_bump <uint32_t >();
837
+ tag_variant = bump_dp <uint32_t >(dp );
806
838
else
807
839
tag_variant = 0 ;
808
840
@@ -820,5 +852,11 @@ class copy : public data<copy> {
820
852
821
853
#endif
822
854
855
+
856
+ // Structural comparison glue.
857
+
858
+ class cmp : public data <cmp,ptr_pair> {
859
+ };
860
+
823
861
} // end namespace shape
824
862
0 commit comments