@@ -12,6 +12,11 @@ template <class T> using const_reference = const T&;
1212template <class T > using pointer = T*;
1313template <class T > using const_pointer = const T*;
1414
15+ template <class T > using reference_restrict = T& __restrict__;
16+ template <class T > using const_reference_restrict = const T& __restrict__;
17+ template <class T > using pointer_restrict = T* __restrict__;
18+ template <class T > using const_pointer_restrict = const T* __restrict__;
19+
1520template <class SF >
1621struct RandomAccessAt {
1722 MemLayout::size_t i;
@@ -78,7 +83,9 @@ struct wrapper : public S<F> {
7883 constexpr wrapper () = default;
7984 constexpr wrapper (Base b) : Base{static_cast <Base&&>(b)} {}
8085 template <template <class > class F_other >
81- constexpr wrapper (S<F_other> other) : Base{other.apply (AggregateConstructor<Base>{})} {}
86+ constexpr wrapper (S<F_other>& other) : Base{other.apply (AggregateConstructor<Base>{})} {}
87+ template <template <class > class F_other >
88+ constexpr wrapper (const S<F_other>& other) : Base{other.apply (AggregateConstructor<Base>{})} {}
8289
8390 constexpr wrapper<S, reference> operator [] (size_t i) { return Base::apply (RandomAccessAt<S<reference>>{i}); }
8491 constexpr wrapper<S, const_reference> operator [] (size_t i) const { return Base::apply (RandomAccessAt<S<const_reference>>{i}); }
@@ -107,9 +114,14 @@ struct wrapper<S, reference> : public S<reference> {
107114 constexpr wrapper () = delete;
108115 constexpr wrapper (Base b) : Base{static_cast <Base&&>(b)} {}
109116 constexpr wrapper (S<value>& other) : Base(other.apply(AggregateConstructor<Base>{})) {}
117+ constexpr wrapper (S<reference_restrict> other) : Base(other.apply(AggregateConstructor<Base>{})) {}
110118
111119 constexpr wrapper (const wrapper& other) = default;
112120
121+ constexpr wrapper& operator =(const wrapper<S, value>& other) {
122+ Base::apply (other, CopyAssignment{});
123+ return *this ;
124+ }
113125 constexpr wrapper& operator =(const wrapper& other) {
114126 Base::apply (other, CopyAssignment{});
115127 return *this ;
@@ -118,17 +130,61 @@ struct wrapper<S, reference> : public S<reference> {
118130 Base::apply (other, CopyAssignment{});
119131 return *this ;
120132 }
133+ constexpr wrapper& operator =(const wrapper<S, reference_restrict>& other) {
134+ Base::apply (other, CopyAssignment{});
135+ return *this ;
136+ }
137+ constexpr wrapper& operator =(const wrapper<S, const_reference_restrict>& other) {
138+ Base::apply (other, CopyAssignment{});
139+ return *this ;
140+ }
141+
142+ constexpr wrapper (wrapper&& other) = default;
143+
144+ constexpr wrapper& operator =(wrapper&& other) { return operator =(other); }
145+
146+ constexpr wrapper<S, pointer> operator &() { return Base::apply (GetPointer<S<pointer>>{}); }
147+ // constexpr wrapper<S, const_pointer> operator&() const { return Base::apply(GetPointer<S<const_pointer>>{}); }
148+ };
149+
150+ template <template <template <class > class > class S >
151+ struct wrapper <S, reference_restrict> : public S<reference_restrict> {
152+ using Base = S<reference_restrict>;
153+
154+ constexpr wrapper () = delete;
155+ constexpr wrapper (Base b) : Base{static_cast <Base&&>(b)} {}
156+ constexpr wrapper (S<value>& other) : Base(other.apply(AggregateConstructor<Base>{})) {}
157+ constexpr wrapper (S<reference> other) : Base(other.apply(AggregateConstructor<Base>{})) {}
158+
159+ constexpr wrapper (const wrapper& other) = default;
160+
121161 constexpr wrapper& operator =(const wrapper<S, value>& other) {
122162 Base::apply (other, CopyAssignment{});
123163 return *this ;
124164 }
165+ constexpr wrapper& operator =(const wrapper& other) {
166+ Base::apply (other, CopyAssignment{});
167+ return *this ;
168+ }
169+ constexpr wrapper& operator =(const wrapper<S, reference>& other) {
170+ Base::apply (other, CopyAssignment{});
171+ return *this ;
172+ }
173+ constexpr wrapper& operator =(const wrapper<S, const_reference>& other) {
174+ Base::apply (other, CopyAssignment{});
175+ return *this ;
176+ }
177+ constexpr wrapper& operator =(const wrapper<S, const_reference_restrict>& other) {
178+ Base::apply (other, CopyAssignment{});
179+ return *this ;
180+ }
125181
126182 constexpr wrapper (wrapper&& other) = default;
127183
128184 constexpr wrapper& operator =(wrapper&& other) { return operator =(other); }
129185
130- constexpr wrapper<S, pointer> operator & () { return Base::apply (GetPointer<S<pointer>>{}); }
131- // constexpr wrapper<S, const_pointer> operator& () const { return Base::apply(GetPointer<S<const_pointer>>{}); }
186+ constexpr wrapper<S, pointer> operator &() { return Base::apply (GetPointer<S<pointer>>{}); }
187+ // constexpr wrapper<S, const_pointer> operator&() const { return Base::apply(GetPointer<S<const_pointer>>{}); }
132188};
133189
134190template <template <template <class > class > class S >
@@ -139,6 +195,22 @@ struct wrapper<S, const_reference> : public S<const_reference> {
139195 constexpr wrapper (Base b) : Base{static_cast <Base&&>(b)} {}
140196 constexpr wrapper (const S<value>& other) : Base(other.apply(AggregateConstructor<Base>{})) {}
141197 constexpr wrapper (const S<reference>& other) : Base(other.apply(AggregateConstructor<Base>{})) {}
198+ constexpr wrapper (const S<reference_restrict>& other) : Base(other.apply(AggregateConstructor<Base>{})) {}
199+ constexpr wrapper (const S<const_reference_restrict>& other) : Base(other.apply(AggregateConstructor<Base>{})) {}
200+
201+ constexpr wrapper<S, const_pointer> operator &() const { return Base::apply (GetPointer<S<const_pointer>>{}); }
202+ };
203+
204+ template <template <template <class > class > class S >
205+ struct wrapper <S, const_reference_restrict> : public S<const_reference_restrict> {
206+ using Base = S<const_reference_restrict>;
207+
208+ constexpr wrapper () = delete;
209+ constexpr wrapper (Base b) : Base{static_cast <Base&&>(b)} {}
210+ constexpr wrapper (const S<value>& other) : Base(other.apply(AggregateConstructor<Base>{})) {}
211+ constexpr wrapper (const S<reference>& other) : Base(other.apply(AggregateConstructor<Base>{})) {}
212+ constexpr wrapper (const S<reference_restrict>& other) : Base(other.apply(AggregateConstructor<Base>{})) {}
213+ constexpr wrapper (const S<const_reference>& other) : Base(other.apply(AggregateConstructor<Base>{})) {}
142214
143215 constexpr wrapper<S, const_pointer> operator &() const { return Base::apply (GetPointer<S<const_pointer>>{}); }
144216};
@@ -180,6 +252,19 @@ struct wrapper<S, const_pointer> : public S<const_pointer> {
180252
181253 constexpr wrapper<S, const_reference> operator [] (size_t i) const { return Base::apply (RandomAccessAt<S<const_reference>>{i}); }
182254 constexpr wrapper<S, const_reference> operator *() const { return operator [](0 ); }
255+
256+ constexpr bool operator ==(const wrapper& other) const { return Base::apply (FirstMember{}) == other.apply (FirstMember{}); }
257+ constexpr bool operator !=(const wrapper& other) const { return !this ->operator ==(other); }
258+ constexpr bool operator <(const wrapper& other) const { return Base::apply (FirstMember{}) < other.apply (FirstMember{}); }
259+
260+ constexpr wrapper operator +(ptrdiff_t i) const { return Base::apply (Advance<Base>{i}); }
261+ constexpr wrapper operator -(ptrdiff_t i) const { return operator +(-i); }
262+ constexpr ptrdiff_t operator -(const wrapper& other) const { return Base::apply (FirstMember{}) - other.apply (FirstMember{}); }
263+
264+ constexpr wrapper& operator ++() { Base::apply (PreIncrement<Base>{}); return *this ; }
265+ constexpr wrapper& operator +=(ptrdiff_t i) { return *this = *this + i; }
266+ constexpr wrapper& operator --() { Base::apply (PreDecrement<Base>{}); return *this ; }
267+ constexpr wrapper& operator -=(ptrdiff_t i) { return *this = *this - i; }
183268};
184269
185270enum Flag { soa, aos };
0 commit comments