11#pragma once
22#include " macros.hpp"
3+ #include < initializer_list>
34
45
56/* *
@@ -26,37 +27,72 @@ struct CArrayWrapper;
2627template < typename T, int DIM0 >
2728struct CArrayWrapper < T, DIM0 >
2829{
30+ // default constructor
31+ constexpr CArrayWrapper () = default;
32+
33+ /* *
34+ * @brief Construct a CArrayWrapper from an initializer list.
35+ *
36+ * Allows brace-initialization with a list of values:
37+ * @code
38+ * CArrayWrapper< double, 3 > arr = {1.0, 2.0, 3.0};
39+ * @endcode
40+ *
41+ * @param init An initializer list with exactly DIM0 elements.
42+ *
43+ * @note No runtime bounds checking is performed on the initializer size.
44+ */
45+ constexpr CArrayWrapper ( std::initializer_list< T > init )
46+ {
47+ // static_assert(init.size() == DIM0, "Size mismatch"); // needs c++20
48+ int i = 0 ;
49+ for ( auto const & val : init )
50+ {
51+ data[i++] = val;
52+ }
53+ }
54+ /* *
55+ * @brief Copy constructor.
56+ * @param src The source CArrayWrapper to copy from.
57+ */
58+ constexpr CArrayWrapper ( CArrayWrapper const & src )
59+ {
60+ for ( std::size_t i = 0 ; i < DIM0; i++ )
61+ {
62+ data[i] = src.data [i];
63+ }
64+ }
2965
3066 /* *
3167 * @brief Read/write access to an element by index.
3268 * @param dim The index (must be in range [0, DIM0)).
3369 * @return Reference to the element at the specified index.
3470 */
35- HPCREACT_HOST_DEVICE inline T & operator ()( int const dim ) { return data[dim]; }
71+ constexpr HPCREACT_HOST_DEVICE inline T & operator ()( int const dim ) { return data[dim]; }
3672
3773 /* *
3874 * @brief Read-only access to an element by index (const overload).
3975 * @param dim The index (must be in range [0, DIM0)).
4076 * @return Const reference to the element at the specified index.
4177 */
42- HPCREACT_HOST_DEVICE inline T const & operator ()( int const dim ) const { return data[dim]; }
78+ constexpr HPCREACT_HOST_DEVICE inline T const & operator ()( int const dim ) const { return data[dim]; }
4379
4480 /* *
4581 * @brief Subscript operator for read/write access.
4682 * @param dim The index (must be in range [0, DIM0)).
4783 * @return Reference to the element at the specified index.
4884 */
49- HPCREACT_HOST_DEVICE inline T & operator []( int const dim ) { return data[dim]; }
85+ constexpr HPCREACT_HOST_DEVICE inline T & operator []( int const dim ) { return data[dim]; }
5086
5187 /* *
5288 * @brief Subscript operator for read-only access (const overload).
5389 * @param dim The index (must be in range [0, DIM0)).
5490 * @return Const reference to the element at the specified index.
5591 */
56- HPCREACT_HOST_DEVICE inline T const & operator []( int const dim ) const { return data[dim]; }
92+ constexpr HPCREACT_HOST_DEVICE inline T const & operator []( int const dim ) const { return data[dim]; }
5793
5894 // / The underlying 1D C-style array.
59- T data[DIM0];
95+ T data[DIM0]{} ;
6096};
6197
6298/* *
@@ -72,13 +108,60 @@ struct CArrayWrapper< T, DIM0 >
72108template < typename T, int DIM0, int DIM1 >
73109struct CArrayWrapper < T, DIM0, DIM1 >
74110{
111+ // default constructor
112+ constexpr CArrayWrapper () = default;
113+
114+ /* *
115+ * @brief Copy constructor.
116+ * @param src The source CArrayWrapper to copy from.
117+ */
118+ constexpr CArrayWrapper ( CArrayWrapper const & src )
119+ {
120+ for ( std::size_t i = 0 ; i < DIM0; i++ )
121+ {
122+ for ( std::size_t j = 0 ; j < DIM1; j++ )
123+ data[i][j] = src.data [i][j];
124+ }
125+ }
126+
127+ /* *
128+ * @brief Construct a 2D CArrayWrapper from nested initializer lists.
129+ *
130+ * Allows brace-initialization with a matrix-like structure:
131+ * @code
132+ * CArrayWrapper<double, 2, 3> mat = {
133+ * {1.0, 2.0, 3.0},
134+ * {4.0, 5.0, 6.0}
135+ * };
136+ * @endcode
137+ *
138+ * @param init A nested initializer list with exactly D0 rows and D1 elements per row.
139+ *
140+ * @note No runtime bounds checking is performed on the initializer dimensions.
141+ */
142+ constexpr CArrayWrapper ( std::initializer_list< std::initializer_list< T > > init )
143+ {
144+ // static_assert(init.size() == DIM0, "Size mismatch"); // needs c++20
145+ int i = 0 ;
146+ for ( auto const & row : init )
147+ {
148+ // static_assert(row.size() == DIM1, "Size mismatch"); // needs c++20
149+ int j = 0 ;
150+ for ( auto const & val : row )
151+ {
152+ data[i][j++] = val;
153+ }
154+ ++i;
155+ }
156+ }
157+
75158 /* *
76159 * @brief Read/write access to an element by 2D indices.
77160 * @param dim0 Index in the first dimension (range [0, DIM0)).
78161 * @param dim1 Index in the second dimension (range [0, DIM1)).
79162 * @return Reference to the element at the specified 2D location.
80163 */
81- HPCREACT_HOST_DEVICE inline T & operator ()( int const dim0, int const dim1 )
164+ constexpr HPCREACT_HOST_DEVICE inline T & operator ()( int const dim0, int const dim1 )
82165 {
83166 return data[dim0][dim1];
84167 }
@@ -89,7 +172,7 @@ struct CArrayWrapper< T, DIM0, DIM1 >
89172 * @param dim1 Index in the second dimension (range [0, DIM1)).
90173 * @return Const reference to the element at the specified 2D location.
91174 */
92- HPCREACT_HOST_DEVICE inline T const & operator ()( int const dim0, int const dim1 ) const
175+ constexpr HPCREACT_HOST_DEVICE inline T const & operator ()( int const dim0, int const dim1 ) const
93176 {
94177 return data[dim0][dim1];
95178 }
@@ -101,7 +184,7 @@ struct CArrayWrapper< T, DIM0, DIM1 >
101184 *
102185 * This allows usage like `obj[dim0][dim1]`.
103186 */
104- HPCREACT_HOST_DEVICE inline T ( & operator []( int const dim0 ))[DIM1]
187+ constexpr HPCREACT_HOST_DEVICE inline T ( & operator []( int const dim0 ))[DIM1]
105188 {
106189 return data[dim0];
107190 }
@@ -111,13 +194,13 @@ struct CArrayWrapper< T, DIM0, DIM1 >
111194 * @param dim0 The row index (range [0, DIM0)).
112195 * @return Const reference to an array of type T[DIM1].
113196 */
114- HPCREACT_HOST_DEVICE inline T const (&operator []( int const dim0 ) const )[DIM1]
197+ constexpr HPCREACT_HOST_DEVICE inline T const (&operator []( int const dim0 ) const )[DIM1]
115198 {
116199 return data[dim0];
117200 }
118201
119202 // / The underlying 2D C-style array of size DIM0 x DIM1.
120- T data[DIM0][DIM1];
203+ T data[DIM0][DIM1]{} ;
121204};
122205
123206/* *
@@ -134,6 +217,54 @@ struct CArrayWrapper< T, DIM0, DIM1 >
134217template < typename T, int DIM0, int DIM1, int DIM2 >
135218struct CArrayWrapper < T, DIM0, DIM1, DIM2 >
136219{
220+ // default constructor
221+ constexpr CArrayWrapper () = default;
222+
223+ /* *
224+ * @brief Construct a 3D CArrayWrapper from nested initializer lists.
225+ *
226+ * Enables tensor-like initialization using triple-nested braces:
227+ * @code
228+ * CArrayWrapper<double, 2, 2, 2> cube = {
229+ * {
230+ * {1.0, 2.0},
231+ * {3.0, 4.0}
232+ * },
233+ * {
234+ * {5.0, 6.0},
235+ * {7.0, 8.0}
236+ * }
237+ * };
238+ * @endcode
239+ *
240+ * @param init A three-level nested initializer list with D0 planes, D1 rows per plane,
241+ * and D2 elements per row.
242+ *
243+ * @note This constructor does not perform size validation. Incorrect initializer sizes
244+ * may lead to undefined behavior.
245+ */
246+ constexpr CArrayWrapper ( std::initializer_list< std::initializer_list< std::initializer_list< T > > > init )
247+ {
248+ // static_assert(init.size() == DIM0, "Size mismatch"); // needs c++20
249+ int i = 0 ;
250+ for ( auto const & plane : init )
251+ {
252+ // static_assert(plane.size() == DIM1, "Size mismatch"); // needs c++20
253+ int j = 0 ;
254+ for ( auto const & row : plane )
255+ {
256+ // static_assert(row.size() == DIM2, "Size mismatch"); // needs c++20
257+ int k = 0 ;
258+ for ( auto const & val : row )
259+ {
260+ data[i][j][k++] = val;
261+ }
262+ ++j;
263+ }
264+ ++i;
265+ }
266+ }
267+
137268 /* *
138269 * @brief Read/write access to an element by 3D indices.
139270 * @param dim0 Index in the first dimension (range [0, DIM0)).
@@ -144,7 +275,7 @@ struct CArrayWrapper< T, DIM0, DIM1, DIM2 >
144275 * @note Currently, this function incorrectly indexes data[dim0][dim1], missing dim2.
145276 * It should be `data[dim0][dim1][dim2]`. Please correct if intended.
146277 */
147- HPCREACT_HOST_DEVICE inline T & operator ()( int const dim0, int const dim1, int const dim2 )
278+ constexpr HPCREACT_HOST_DEVICE inline T & operator ()( int const dim0, int const dim1, int const dim2 )
148279 {
149280 // NOTE: This looks like a bug in your original code. Should be data[dim0][dim1][dim2].
150281 return data[dim0][dim1][dim2];
@@ -157,7 +288,7 @@ struct CArrayWrapper< T, DIM0, DIM1, DIM2 >
157288 * @param dim2 Index in the third dimension (range [0, DIM2)).
158289 * @return Const reference to the element at the specified 3D location.
159290 */
160- HPCREACT_HOST_DEVICE inline T const & operator ()( int const dim0, int const dim1, int const dim2 ) const
291+ constexpr HPCREACT_HOST_DEVICE inline T const & operator ()( int const dim0, int const dim1, int const dim2 ) const
161292 {
162293 // NOTE: Same potential bug as above. Should be data[dim0][dim1][dim2].
163294 return data[dim0][dim1][dim2];
@@ -170,7 +301,7 @@ struct CArrayWrapper< T, DIM0, DIM1, DIM2 >
170301 *
171302 * This allows usage like `obj[dim0][dim1][dim2]`.
172303 */
173- HPCREACT_HOST_DEVICE inline T ( & operator []( int const dim0 ))[DIM1][DIM2]
304+ constexpr HPCREACT_HOST_DEVICE inline T ( & operator []( int const dim0 ))[DIM1][DIM2]
174305 {
175306 return data[dim0];
176307 }
@@ -180,11 +311,11 @@ struct CArrayWrapper< T, DIM0, DIM1, DIM2 >
180311 * @param dim0 The slice index (range [0, DIM0)).
181312 * @return Const reference to an array of type T[DIM1][DIM2].
182313 */
183- HPCREACT_HOST_DEVICE inline T const (&operator []( int const dim0 ) const )[DIM1][DIM2]
314+ constexpr HPCREACT_HOST_DEVICE inline T const (&operator []( int const dim0 ) const )[DIM1][DIM2]
184315 {
185316 return data[dim0];
186317 }
187318
188319 // / The underlying 3D C-style array of size DIM0 x DIM1 x DIM2.
189- T data[DIM0][DIM1][DIM2];
320+ T data[DIM0][DIM1][DIM2]{} ;
190321};
0 commit comments