memlayout
Minimal CPU/GPU header-only example library
Loading...
Searching...
No Matches
wrapper.h
Go to the documentation of this file.
1#ifndef WRAPPER_H
2#define WRAPPER_H
3
4namespace memlayout {
5
6using size_t = decltype(sizeof(0));
7using ptrdiff_t = decltype(static_cast<int*>(nullptr) - static_cast<int*>(nullptr));
8
9template <class T> using value = T;
10template <class T> using reference = T&;
11template <class T> using const_reference = const T&;
12template <class T> using pointer = T*;
13template <class T> using const_pointer = const T*;
14
15template <class ReturnType>
18 template <class... Args>
19 constexpr ReturnType operator()(Args& ...args) const { return {args[i]...}; }
20 template <class... Args>
21 constexpr ReturnType operator()(const Args& ...args) const { return {args[i]...}; }
22};
23
24template <class ReturnType>
25struct GetPointer {
26 template <class... Args>
27 constexpr ReturnType operator()(Args& ...args) const { return {&args...}; }
28 template <class... Args>
29 constexpr ReturnType operator()(const Args& ...args) const { return {&args...}; }
30};
31
32template <class ReturnType>
34 template <class... Args>
35 constexpr ReturnType operator()(Args& ...args) const { return {args...}; }
36 template <class... Args>
37 constexpr ReturnType operator()(const Args& ...args) const { return {args...}; }
38};
39
41 template <class T, class... Args>
42 constexpr T& operator()(T& t, Args& ...args) const { return t; }
43 template <class T, class... Args>
44 constexpr const T& operator()(const T& t, const Args& ...args) const { return t; }
45};
46
47template <class ReturnType>
49 template <class... Args>
50 constexpr ReturnType operator()(Args& ...args) const { return {++args...}; }
51};
52
53template <class ReturnType>
55 template <class... Args>
56 constexpr ReturnType operator()(Args& ...args) const { return {--args...}; }
57};
58
59template <class ReturnType>
60struct Advance {
62 template <class... Args>
63 constexpr ReturnType operator()(const Args& ...args) const { return {(args + i)...}; }
64};
65
67 template <class Left, class Right>
68 constexpr Left& operator()(Left& left, const Right& right) const { return left = right; }
69};
70
71enum class Layout { aos = 0, soa = 1 };
72
73template <
74 template <template <class> class> class Struct,
75 template <class> class Container,
77>
78struct Wrapper;
79
80template <
81 template <template <class> class> class Struct,
82 template <class> class Container
83>
84struct Wrapper<Struct, Container, Layout::aos> : public Container<Struct<value>> {
85 static constexpr Layout layout_type = Layout::aos;
86 using Base = Container<Struct<value>>;
87 using Base::Base;
88
89 constexpr Wrapper() = default;
90 template <template <class> class other_Container>
92
93 constexpr Wrapper<Struct, reference> operator[] (size_t i) { return Base::operator[](i); }
94 constexpr Wrapper<Struct, const_reference> operator[] (size_t i) const { return Base::operator[](i); }
95
98};
99
100template <template <template <class> class> class Struct>
101struct Wrapper<Struct, pointer, Layout::aos> {
102 static constexpr Layout layout_type = Layout::aos;
103
106
107 operator Data&() { return data; }
108 operator const Data&() const { return data; }
109
110 constexpr bool operator==(const Wrapper& other) const { return data == other.data; }
111 constexpr bool operator!=(const Wrapper& other) const { return data != other.data; }
112 constexpr bool operator<(const Wrapper& other) const { return data < other.data; }
113
114 constexpr Wrapper operator+(ptrdiff_t i) const { return {data + i}; }
115 constexpr Wrapper operator-(ptrdiff_t i) const { return {data - i}; }
116 constexpr ptrdiff_t operator-(const Wrapper& other) const { return {data - other.data}; }
117
118 constexpr Wrapper& operator++() { return {++data}; }
119 constexpr Wrapper& operator+=(ptrdiff_t i) { return {data += i}; }
120 constexpr Wrapper& operator--() { return {--data}; }
121 constexpr Wrapper& operator-=(ptrdiff_t i) { return {data -= i}; }
122
123 constexpr Wrapper<Struct, reference> operator[] (size_t i) { return data[i]; }
124 constexpr Wrapper<Struct, const_reference> operator[] (size_t i) const { return data[i]; }
125
128};
129
130template <
131 template <template <class> class> class Struct,
132 template <class> class Container
133>
134struct Wrapper<Struct, Container, Layout::soa> : public Struct<Container> {
135 static constexpr Layout layout_type = Layout::soa;
136 using Base = Struct<Container>;
137 using Base::Base;
138
139 constexpr Wrapper() = default;
140 constexpr Wrapper(Base b) : Base{static_cast<Base&&>(b)} {}
141 template <template <class> class other_Container>
142 constexpr Wrapper(Struct<other_Container>& other) : Base{other.apply(AggregateConstructor<Base>{})} {}
143 template <template <class> class other_Container>
144 constexpr Wrapper(const Struct<other_Container>& other) : Base{other.apply(AggregateConstructor<Base>{})} {}
145
146 constexpr Wrapper<Struct, reference> operator[] (size_t i) { return Base::apply(RandomAccessAt<Struct<reference>>{i}); }
147 constexpr Wrapper<Struct, const_reference> operator[] (size_t i) const { return Base::apply(RandomAccessAt<Struct<const_reference>>{i}); }
148
151};
152
153template <template <template <class> class> class Struct>
154struct Wrapper<Struct, value, Layout::soa> : public Struct<value> {
155 using Base = Struct<value>;
156
157 constexpr Wrapper() = default;
158 constexpr Wrapper(Base b) : Base{static_cast<Base&&>(b)} {}
159 constexpr Wrapper(const Struct<reference>& other) : Base(other.apply(AggregateConstructor<Base>{})) {}
160 constexpr Wrapper(const Struct<const_reference>& other) : Base(other.apply(AggregateConstructor<Base>{})) {}
161};
162
163template <template <template <class> class> class Struct>
164struct Wrapper<Struct, reference, Layout::soa> : public Struct<reference> {
165 using Base = Struct<reference>;
166
167 constexpr Wrapper() = delete;
168 constexpr Wrapper(Base b) : Base{static_cast<Base&&>(b)} {}
169 constexpr Wrapper(Struct<value>& other) : Base(other.apply(AggregateConstructor<Base>{})) {}
170
171 constexpr Wrapper(const Wrapper& other) = default;
172
173 constexpr Wrapper& operator=(const Wrapper<Struct, value>& other) {
174 Base::apply(other, CopyAssignment{});
175 return *this;
176 }
177 constexpr Wrapper& operator=(const Wrapper& other) {
178 Base::apply(other, CopyAssignment{});
179 return *this;
180 }
182 Base::apply(other, CopyAssignment{});
183 return *this;
184 }
185
186 constexpr Wrapper(Wrapper&& other) = default;
187
188 constexpr Wrapper& operator=(Wrapper&& other) { return operator=(other); }
189
190 constexpr Wrapper<Struct, pointer> operator&() { return Base::apply(GetPointer<Struct<pointer>>{}); }
191 //constexpr Wrapper<Struct, const_pointer> operator&() const { return Base::apply(GetPointer<Struct<const_pointer>>{}); }
192 constexpr pointer<Wrapper<Struct, reference>> operator->() { return this; }
193};
194
195template <template <template <class> class> class Struct>
196struct Wrapper<Struct, const_reference, Layout::soa> : public Struct<const_reference> {
197 using Base = Struct<const_reference>;
198
199 constexpr Wrapper() = delete;
200 constexpr Wrapper(Base b) : Base{static_cast<Base&&>(b)} {}
201 constexpr Wrapper(const Struct<value>& other) : Base(other.apply(AggregateConstructor<Base>{})) {}
202 constexpr Wrapper(const Struct<reference>& other) : Base(other.apply(AggregateConstructor<Base>{})) {}
203
204 constexpr Wrapper<Struct, const_pointer> operator&() const { return Base::apply(GetPointer<Struct<const_pointer>>{}); }
206};
207
208template <template <template <class> class> class Struct>
209struct Wrapper<Struct, pointer, Layout::soa> : public Struct<pointer> {
210 using Base = Struct<pointer>;
211
212 constexpr Wrapper() = default;
213 constexpr Wrapper(Base b) : Base{static_cast<Base&&>(b)} {}
214
215 constexpr Wrapper<Struct, reference> operator[] (size_t i) { return Base::apply(RandomAccessAt<Struct<reference>>{i}); }
216 constexpr const Wrapper<Struct, const_reference> operator[] (size_t i) const { return Base::apply(RandomAccessAt<Struct<const_reference>>{i}); }
217
222
223 constexpr bool operator==(const Wrapper& other) const { return Base::apply(FirstMember{}) == other.apply(FirstMember{}); }
224 constexpr bool operator!=(const Wrapper& other) const { return !this->operator==(other); }
225 constexpr bool operator<(const Wrapper& other) const { return Base::apply(FirstMember{}) < other.apply(FirstMember{}); }
226
227 constexpr Wrapper operator+(ptrdiff_t i) const { return Base::apply(Advance<Base>{i}); }
228 constexpr Wrapper operator-(ptrdiff_t i) const { return operator+(-i); }
229 constexpr ptrdiff_t operator-(const Wrapper& other) const { return Base::apply(FirstMember{}) - other.apply(FirstMember{}); }
230
231 constexpr Wrapper& operator++() { Base::apply(PreIncrement<Base>{}); return *this; }
232 constexpr Wrapper& operator+=(ptrdiff_t i) { return *this = *this + i; }
233 constexpr Wrapper& operator--() { Base::apply(PreDecrement<Base>{}); return *this; }
234 constexpr Wrapper& operator-=(ptrdiff_t i) { return *this = *this - i; }
235};
236
237template <template <template <class> class> class Struct>
238struct Wrapper<Struct, const_pointer, Layout::soa> : public Struct<const_pointer> {
239 using Base = Struct<const_pointer>;
240
241 constexpr Wrapper() = default;
242 constexpr Wrapper(Base b) : Base{static_cast<Base&&>(b)} {}
243 constexpr Wrapper(const Struct<pointer>& other) : Base(other.apply(AggregateConstructor<Base>{})) {}
244
245 constexpr Wrapper<Struct, const_reference> operator[] (size_t i) const { return Base::apply(RandomAccessAt<Struct<const_reference>>{i}); }
248
249 constexpr bool operator==(const Wrapper& other) const { return Base::apply(FirstMember{}) == other.apply(FirstMember{}); }
250 constexpr bool operator!=(const Wrapper& other) const { return !this->operator==(other); }
251 constexpr bool operator<(const Wrapper& other) const { return Base::apply(FirstMember{}) < other.apply(FirstMember{}); }
252
253 constexpr Wrapper operator+(ptrdiff_t i) const { return Base::apply(Advance<Base>{i}); }
254 constexpr Wrapper operator-(ptrdiff_t i) const { return operator+(-i); }
255 constexpr ptrdiff_t operator-(const Wrapper& other) const { return Base::apply(FirstMember{}) - other.apply(FirstMember{}); }
256
257 constexpr Wrapper& operator++() { Base::apply(PreIncrement<Base>{}); return *this; }
258 constexpr Wrapper& operator+=(ptrdiff_t i) { return *this = *this + i; }
259 constexpr Wrapper& operator--() { Base::apply(PreDecrement<Base>{}); return *this; }
260 constexpr Wrapper& operator-=(ptrdiff_t i) { return *this = *this - i; }
261};
262
263} // namespace Wrapper
264
265#define WRAPPER_APPLY_UNARY(...)\
266 template <class Function>\
267 constexpr auto apply(Function&& f) { return f(__VA_ARGS__); }\
268 template <class Function>\
269 constexpr auto apply(Function&& f) const { return f(__VA_ARGS__); }\
270
271#define WRAPPER_EXPAND(m) f(m, other.m)
272
273#define WRAPPER_APPLY_BINARY(STRUCT_NAME, ...)\
274 template <template <class> class other_Container, class Function>\
275 constexpr STRUCT_NAME apply(STRUCT_NAME<other_Container>& other, Function&& f) { return {__VA_ARGS__}; }\
276 template <template <class> class other_Container, class Function>\
277 constexpr STRUCT_NAME apply(STRUCT_NAME<other_Container>& other, Function&& f) const { return {__VA_ARGS__}; }\
278 template <template <class> class other_Container, class Function>\
279 constexpr STRUCT_NAME apply(const STRUCT_NAME<other_Container>& other, Function&& f) { return {__VA_ARGS__}; }\
280 template <template <class> class other_Container, class Function>\
281 constexpr STRUCT_NAME apply(const STRUCT_NAME<other_Container>& other, Function&& f) const { return {__VA_ARGS__}; }\
282
283#endif // WRAPPER_H
const T & const_reference
Definition wrapper.h:11
const T * const_pointer
Definition wrapper.h:13
T * pointer
Definition wrapper.h:12
T & reference
Definition wrapper.h:10
decltype(static_cast< int * >(nullptr) - static_cast< int * >(nullptr)) ptrdiff_t
Definition wrapper.h:7
T value
Definition wrapper.h:9
decltype(sizeof(0)) size_t
Definition wrapper.h:6
constexpr ReturnType operator()(const Args &...args) const
Definition wrapper.h:63
ptrdiff_t i
Definition wrapper.h:61
constexpr ReturnType operator()(Args &...args) const
Definition wrapper.h:35
constexpr ReturnType operator()(const Args &...args) const
Definition wrapper.h:37
constexpr Left & operator()(Left &left, const Right &right) const
Definition wrapper.h:68
constexpr const T & operator()(const T &t, const Args &...args) const
Definition wrapper.h:44
constexpr T & operator()(T &t, Args &...args) const
Definition wrapper.h:42
constexpr ReturnType operator()(Args &...args) const
Definition wrapper.h:27
constexpr ReturnType operator()(const Args &...args) const
Definition wrapper.h:29
constexpr ReturnType operator()(Args &...args) const
Definition wrapper.h:56
constexpr ReturnType operator()(Args &...args) const
Definition wrapper.h:50
constexpr ReturnType operator()(const Args &...args) const
Definition wrapper.h:21
constexpr ReturnType operator()(Args &...args) const
Definition wrapper.h:19
memlayout::size_t i
Definition wrapper.h:17
constexpr Wrapper< Struct, const_reference > operator*(ptrdiff_t) const
Definition wrapper.h:97
constexpr Wrapper< Struct, reference > operator[](size_t i)
Definition wrapper.h:93
constexpr Wrapper(Wrapper< Struct, other_Container, Layout::aos > &other)
Definition wrapper.h:91
constexpr Wrapper< Struct, reference > operator*()
Definition wrapper.h:96
constexpr Wrapper< Struct, reference > operator[](size_t i)
Definition wrapper.h:146
constexpr Wrapper< Struct, reference > operator*()
Definition wrapper.h:149
constexpr Wrapper(const Struct< other_Container > &other)
Definition wrapper.h:144
constexpr Wrapper< Struct, const_reference > operator*(ptrdiff_t) const
Definition wrapper.h:150
constexpr Wrapper(Struct< other_Container > &other)
Definition wrapper.h:142
constexpr Wrapper< Struct, const_reference > operator*() const
Definition wrapper.h:246
constexpr Wrapper & operator+=(ptrdiff_t i)
Definition wrapper.h:258
constexpr bool operator!=(const Wrapper &other) const
Definition wrapper.h:250
constexpr Wrapper< Struct, const_reference > operator[](size_t i) const
Definition wrapper.h:245
constexpr bool operator<(const Wrapper &other) const
Definition wrapper.h:251
constexpr bool operator==(const Wrapper &other) const
Definition wrapper.h:249
constexpr Wrapper operator+(ptrdiff_t i) const
Definition wrapper.h:253
constexpr Wrapper operator-(ptrdiff_t i) const
Definition wrapper.h:254
constexpr Wrapper(const Struct< pointer > &other)
Definition wrapper.h:243
constexpr Wrapper & operator-=(ptrdiff_t i)
Definition wrapper.h:260
constexpr Wrapper< Struct, const_reference > operator->() const
Definition wrapper.h:247
constexpr ptrdiff_t operator-(const Wrapper &other) const
Definition wrapper.h:255
constexpr Wrapper(const Struct< value > &other)
Definition wrapper.h:201
constexpr Wrapper< Struct, const_pointer > operator&() const
Definition wrapper.h:204
constexpr const_pointer< Wrapper< Struct, const_reference > > operator->() const
Definition wrapper.h:205
constexpr Wrapper(const Struct< reference > &other)
Definition wrapper.h:202
constexpr Wrapper< Struct, reference > operator*()
Definition wrapper.h:126
constexpr Wrapper operator+(ptrdiff_t i) const
Definition wrapper.h:114
constexpr bool operator!=(const Wrapper &other) const
Definition wrapper.h:111
constexpr Wrapper operator-(ptrdiff_t i) const
Definition wrapper.h:115
constexpr Wrapper< Struct, const_reference > operator*(ptrdiff_t) const
Definition wrapper.h:127
constexpr Wrapper & operator-=(ptrdiff_t i)
Definition wrapper.h:121
constexpr bool operator==(const Wrapper &other) const
Definition wrapper.h:110
constexpr bool operator<(const Wrapper &other) const
Definition wrapper.h:112
constexpr ptrdiff_t operator-(const Wrapper &other) const
Definition wrapper.h:116
constexpr Wrapper & operator+=(ptrdiff_t i)
Definition wrapper.h:119
constexpr Wrapper & operator-=(ptrdiff_t i)
Definition wrapper.h:234
constexpr Wrapper< Struct, const_reference > operator->() const
Definition wrapper.h:221
constexpr Wrapper & operator+=(ptrdiff_t i)
Definition wrapper.h:232
constexpr Wrapper< Struct, reference > operator*()
Definition wrapper.h:218
constexpr Wrapper< Struct, const_reference > operator*() const
Definition wrapper.h:219
constexpr Wrapper< Struct, reference > operator[](size_t i)
Definition wrapper.h:215
constexpr Wrapper operator-(ptrdiff_t i) const
Definition wrapper.h:228
constexpr Wrapper operator+(ptrdiff_t i) const
Definition wrapper.h:227
constexpr ptrdiff_t operator-(const Wrapper &other) const
Definition wrapper.h:229
constexpr bool operator<(const Wrapper &other) const
Definition wrapper.h:225
constexpr bool operator==(const Wrapper &other) const
Definition wrapper.h:223
constexpr Wrapper< Struct, reference > operator->()
Definition wrapper.h:220
constexpr bool operator!=(const Wrapper &other) const
Definition wrapper.h:224
constexpr Wrapper(Struct< value > &other)
Definition wrapper.h:169
constexpr Wrapper & operator=(const Wrapper< Struct, const_reference > &other)
Definition wrapper.h:181
constexpr Wrapper(const Wrapper &other)=default
constexpr Wrapper & operator=(const Wrapper &other)
Definition wrapper.h:177
constexpr Wrapper & operator=(Wrapper &&other)
Definition wrapper.h:188
constexpr pointer< Wrapper< Struct, reference > > operator->()
Definition wrapper.h:192
constexpr Wrapper & operator=(const Wrapper< Struct, value > &other)
Definition wrapper.h:173
constexpr Wrapper(Wrapper &&other)=default
constexpr Wrapper< Struct, pointer > operator&()
Definition wrapper.h:190
constexpr Wrapper(const Struct< reference > &other)
Definition wrapper.h:159
constexpr Wrapper(const Struct< const_reference > &other)
Definition wrapper.h:160