-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCArrayWrapper.hpp
More file actions
321 lines (297 loc) · 10.2 KB
/
CArrayWrapper.hpp
File metadata and controls
321 lines (297 loc) · 10.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
#pragma once
#include "macros.hpp"
#include <initializer_list>
/**
* @brief A generic wrapper for C-style arrays of varying dimensionality.
*
* This primary template is left undefined to catch unsupported numbers of dimensions
* via a static_assert. Specializations exist for 1D, 2D, and 3D arrays.
*
* @tparam T The type of the elements stored in the array.
* @tparam NDIMS The number of dimensions of the array.
* @tparam DIMS Parameter pack specifying the size of each dimension.
*/
template< typename T, int ... DIMS >
struct CArrayWrapper;
/**
* @brief Specialization of CArrayWrapper for 1-dimensional arrays.
*
* Provides operator() and operator[] for element access and stores data contiguously in a single C-style array of size DIM0.
*
* @tparam T The type of the elements stored in the array.
* @tparam DIM0 The size of the single dimension.
*/
template< typename T, int DIM0 >
struct CArrayWrapper< T, DIM0 >
{
// default constructor
constexpr CArrayWrapper() = default;
/**
* @brief Construct a CArrayWrapper from an initializer list.
*
* Allows brace-initialization with a list of values:
* @code
* CArrayWrapper< double, 3 > arr = {1.0, 2.0, 3.0};
* @endcode
*
* @param init An initializer list with exactly DIM0 elements.
*
* @note No runtime bounds checking is performed on the initializer size.
*/
constexpr CArrayWrapper( std::initializer_list< T > init )
{
// static_assert(init.size() == DIM0, "Size mismatch"); // needs c++20
int i = 0;
for( auto const & val : init )
{
data[i++] = val;
}
}
/**
* @brief Copy constructor.
* @param src The source CArrayWrapper to copy from.
*/
constexpr CArrayWrapper( CArrayWrapper const & src )
{
for( std::size_t i = 0; i < DIM0; i++ )
{
data[i] = src.data[i];
}
}
/**
* @brief Read/write access to an element by index.
* @param dim The index (must be in range [0, DIM0)).
* @return Reference to the element at the specified index.
*/
HPCREACT_HOST_DEVICE constexpr inline T & operator()( int const dim ) { return data[dim]; }
/**
* @brief Read-only access to an element by index (const overload).
* @param dim The index (must be in range [0, DIM0)).
* @return Const reference to the element at the specified index.
*/
HPCREACT_HOST_DEVICE constexpr inline T const & operator()( int const dim ) const { return data[dim]; }
/**
* @brief Subscript operator for read/write access.
* @param dim The index (must be in range [0, DIM0)).
* @return Reference to the element at the specified index.
*/
HPCREACT_HOST_DEVICE constexpr inline T & operator[]( int const dim ) { return data[dim]; }
/**
* @brief Subscript operator for read-only access (const overload).
* @param dim The index (must be in range [0, DIM0)).
* @return Const reference to the element at the specified index.
*/
HPCREACT_HOST_DEVICE constexpr inline T const & operator[]( int const dim ) const { return data[dim]; }
/// The underlying 1D C-style array.
T data[DIM0]{};
};
/**
* @brief Specialization of CArrayWrapper for 2-dimensional arrays.
*
* Provides operator() and operator[] for element and row access. Internally,
* it stores a 2D C-style array of size [DIM0][DIM1].
*
* @tparam T The type of the elements stored in the array.
* @tparam DIM0 The size of the first dimension.
* @tparam DIM1 The size of the second dimension.
*/
template< typename T, int DIM0, int DIM1 >
struct CArrayWrapper< T, DIM0, DIM1 >
{
// default constructor
constexpr CArrayWrapper() = default;
/**
* @brief Copy constructor.
* @param src The source CArrayWrapper to copy from.
*/
constexpr CArrayWrapper( CArrayWrapper const & src )
{
for( std::size_t i = 0; i < DIM0; i++ )
{
for ( std::size_t j = 0; j < DIM1; j++)
data[i][j] = src.data[i][j];
}
}
/**
* @brief Construct a 2D CArrayWrapper from nested initializer lists.
*
* Allows brace-initialization with a matrix-like structure:
* @code
* CArrayWrapper<double, 2, 3> mat = {
* {1.0, 2.0, 3.0},
* {4.0, 5.0, 6.0}
* };
* @endcode
*
* @param init A nested initializer list with exactly D0 rows and D1 elements per row.
*
* @note No runtime bounds checking is performed on the initializer dimensions.
*/
constexpr CArrayWrapper( std::initializer_list< std::initializer_list< T > > init )
{
// static_assert(init.size() == DIM0, "Size mismatch"); // needs c++20
int i = 0;
for( auto const & row : init )
{
// static_assert(row.size() == DIM1, "Size mismatch"); // needs c++20
int j = 0;
for( auto const & val : row )
{
data[i][j++] = val;
}
++i;
}
}
/**
* @brief Read/write access to an element by 2D indices.
* @param dim0 Index in the first dimension (range [0, DIM0)).
* @param dim1 Index in the second dimension (range [0, DIM1)).
* @return Reference to the element at the specified 2D location.
*/
HPCREACT_HOST_DEVICE constexpr inline T & operator()( int const dim0, int const dim1 )
{
return data[dim0][dim1];
}
/**
* @brief Read-only access to an element by 2D indices (const overload).
* @param dim0 Index in the first dimension (range [0, DIM0)).
* @param dim1 Index in the second dimension (range [0, DIM1)).
* @return Const reference to the element at the specified 2D location.
*/
HPCREACT_HOST_DEVICE constexpr inline T const & operator()( int const dim0, int const dim1 ) const
{
return data[dim0][dim1];
}
/**
* @brief Subscript operator returning a reference to a row in the 2D array.
* @param dim0 The row index (range [0, DIM0)).
* @return Reference to an array of type T[DIM1].
*
* This allows usage like `obj[dim0][dim1]`.
*/
HPCREACT_HOST_DEVICE constexpr inline T ( & operator[]( int const dim0 ))[DIM1]
{
return data[dim0];
}
/**
* @brief Subscript operator returning a const reference to a row in the 2D array (const overload).
* @param dim0 The row index (range [0, DIM0)).
* @return Const reference to an array of type T[DIM1].
*/
HPCREACT_HOST_DEVICE constexpr inline T const (&operator[]( int const dim0 ) const)[DIM1]
{
return data[dim0];
}
/// The underlying 2D C-style array of size DIM0 x DIM1.
T data[DIM0][DIM1]{};
};
/**
* @brief Specialization of CArrayWrapper for 3-dimensional arrays.
*
* Provides operator() and operator[] for element and row access. Internally,
* it stores a 3D C-style array of size [DIM0][DIM1][DIM2].
*
* @tparam T The type of the elements stored in the array.
* @tparam DIM0 The size of the first dimension.
* @tparam DIM1 The size of the second dimension.
* @tparam DIM2 The size of the third dimension.
*/
template< typename T, int DIM0, int DIM1, int DIM2 >
struct CArrayWrapper< T, DIM0, DIM1, DIM2 >
{
// default constructor
constexpr CArrayWrapper() = default;
/**
* @brief Construct a 3D CArrayWrapper from nested initializer lists.
*
* Enables tensor-like initialization using triple-nested braces:
* @code
* CArrayWrapper<double, 2, 2, 2> cube = {
* {
* {1.0, 2.0},
* {3.0, 4.0}
* },
* {
* {5.0, 6.0},
* {7.0, 8.0}
* }
* };
* @endcode
*
* @param init A three-level nested initializer list with D0 planes, D1 rows per plane,
* and D2 elements per row.
*
* @note This constructor does not perform size validation. Incorrect initializer sizes
* may lead to undefined behavior.
*/
constexpr CArrayWrapper( std::initializer_list< std::initializer_list< std::initializer_list< T > > > init )
{
// static_assert(init.size() == DIM0, "Size mismatch"); // needs c++20
int i = 0;
for( auto const & plane : init )
{
// static_assert(plane.size() == DIM1, "Size mismatch"); // needs c++20
int j = 0;
for( auto const & row : plane )
{
// static_assert(row.size() == DIM2, "Size mismatch"); // needs c++20
int k = 0;
for( auto const & val : row )
{
data[i][j][k++] = val;
}
++j;
}
++i;
}
}
/**
* @brief Read/write access to an element by 3D indices.
* @param dim0 Index in the first dimension (range [0, DIM0)).
* @param dim1 Index in the second dimension (range [0, DIM1)).
* @param dim2 Index in the third dimension (range [0, DIM2)).
* @return Reference to the element at the specified 3D location.
*
* @note Currently, this function incorrectly indexes data[dim0][dim1], missing dim2.
* It should be `data[dim0][dim1][dim2]`. Please correct if intended.
*/
HPCREACT_HOST_DEVICE constexpr inline T & operator()( int const dim0, int const dim1, int const dim2 )
{
// NOTE: This looks like a bug in your original code. Should be data[dim0][dim1][dim2].
return data[dim0][dim1][dim2];
}
/**
* @brief Read-only access to an element by 3D indices (const overload).
* @param dim0 Index in the first dimension (range [0, DIM0)).
* @param dim1 Index in the second dimension (range [0, DIM1)).
* @param dim2 Index in the third dimension (range [0, DIM2)).
* @return Const reference to the element at the specified 3D location.
*/
HPCREACT_HOST_DEVICE constexpr inline T const & operator()( int const dim0, int const dim1, int const dim2 ) const
{
// NOTE: Same potential bug as above. Should be data[dim0][dim1][dim2].
return data[dim0][dim1][dim2];
}
/**
* @brief Subscript operator returning a reference to a 2D slice in the 3D array.
* @param dim0 The slice index (range [0, DIM0)).
* @return Reference to an array of type T[DIM1][DIM2].
*
* This allows usage like `obj[dim0][dim1][dim2]`.
*/
HPCREACT_HOST_DEVICE constexpr inline T ( & operator[]( int const dim0 ))[DIM1][DIM2]
{
return data[dim0];
}
/**
* @brief Subscript operator returning a const reference to a 2D slice in the 3D array (const overload).
* @param dim0 The slice index (range [0, DIM0)).
* @return Const reference to an array of type T[DIM1][DIM2].
*/
HPCREACT_HOST_DEVICE constexpr inline T const (&operator[]( int const dim0 ) const)[DIM1][DIM2]
{
return data[dim0];
}
/// The underlying 3D C-style array of size DIM0 x DIM1 x DIM2.
T data[DIM0][DIM1][DIM2]{};
};