|
24 | 24 | #include "CArrayHelper.hpp" |
25 | 25 |
|
26 | 26 | #include <utility> |
27 | | - |
| 27 | +#include <cmath> |
28 | 28 |
|
29 | 29 |
|
30 | 30 | namespace shiva |
@@ -94,12 +94,14 @@ struct CArray |
94 | 94 | * @brief accessor for m_data |
95 | 95 | * @return reference to m_data |
96 | 96 | */ |
| 97 | + SHIVA_CONSTEXPR_HOSTDEVICE_FORCEINLINE |
97 | 98 | DATA_BUFFER & data() { return m_data; } |
98 | 99 |
|
99 | 100 | /** |
100 | 101 | * @brief const accessor for m_data |
101 | 102 | * @return reference to const m_data |
102 | 103 | */ |
| 104 | + SHIVA_CONSTEXPR_HOSTDEVICE_FORCEINLINE |
103 | 105 | DATA_BUFFER const & data() const { return m_data; } |
104 | 106 |
|
105 | 107 | /** |
@@ -156,11 +158,98 @@ struct CArray |
156 | 158 | return m_data[ CArrayHelper::linearIndexHelper< DIMS... >::eval( indices ... ) ]; |
157 | 159 | } |
158 | 160 |
|
| 161 | +private: |
| 162 | + /** |
| 163 | + * @struct SubArrayHelper |
| 164 | + * @brief This struct is used to help with the creation of subarrays. |
| 165 | + */ |
| 166 | + struct SubArrayHelper |
| 167 | + { |
| 168 | + /// This alias is used to create a const subarray type. |
| 169 | + |
| 170 | + template< int ... SUB_DIMS > |
| 171 | + using const_type = CArray< T const, T const * const, SUB_DIMS... >; |
| 172 | + |
| 173 | + /// This alias is used to create a subarray type. |
| 174 | + template< int ... SUB_DIMS > |
| 175 | + using type = CArray< T, T * const, SUB_DIMS... >; |
| 176 | + }; |
| 177 | + |
| 178 | + /** |
| 179 | + * @brief Helper function to enable operator[]. |
| 180 | + * @tparam CARRAY_TYPE The type of the array to create. Either const_type or type. |
| 181 | + * @param index The index to access. |
| 182 | + * @return A reference to the data at the specified index or the subarray. |
| 183 | + */ |
| 184 | + template< template< int ... > typename CARRAY_TYPE > |
| 185 | + SHIVA_CONSTEXPR_HOSTDEVICE_FORCEINLINE |
| 186 | + decltype(auto) squareBracketOperatorHelper( index_type index ) const; |
| 187 | + |
| 188 | +public: |
| 189 | + /** |
| 190 | + * @brief operator[] to access the data in the array or to slice a multidimensional array. |
| 191 | + * @param index The index to access. |
| 192 | + * @return A reference to the data at the specified index or the subarray. |
| 193 | + */ |
| 194 | + SHIVA_CONSTEXPR_HOSTDEVICE_FORCEINLINE |
| 195 | + decltype(auto) operator[]( index_type index ) const |
| 196 | + { |
| 197 | + return squareBracketOperatorHelper< SubArrayHelper::template const_type >( index ); |
| 198 | + } |
| 199 | + |
| 200 | + /** |
| 201 | + * @brief operator[] to access the data in the array or to slice a mutlidimensional array. |
| 202 | + * @param index The index to access. |
| 203 | + * @return A reference to the data at the specified index or the subarray. |
| 204 | + */ |
| 205 | + SHIVA_CONSTEXPR_HOSTDEVICE_FORCEINLINE |
| 206 | + decltype(auto) operator[]( index_type index ) |
| 207 | + { |
| 208 | + if constexpr ( std::is_reference_v< decltype(squareBracketOperatorHelper< SubArrayHelper::template type >( index )) > ) |
| 209 | + { |
| 210 | + return const_cast< T & >(squareBracketOperatorHelper< SubArrayHelper::template type >( index )); |
| 211 | + } |
| 212 | + else |
| 213 | + { |
| 214 | + return squareBracketOperatorHelper< SubArrayHelper::template type >( index ); |
| 215 | + } |
| 216 | + } |
| 217 | + |
| 218 | + |
159 | 219 | private: |
160 | 220 | /// The data in the array. |
161 | 221 | DATA_BUFFER m_data; |
162 | 222 | }; |
163 | 223 |
|
| 224 | +/// @copydoc CArray::squareBracketOperatorHelper |
| 225 | +template< typename T, typename DATA_BUFFER, int ... DIMS > |
| 226 | +template< template< int ... > typename CARRAY_TYPE > |
| 227 | +SHIVA_CONSTEXPR_HOSTDEVICE_FORCEINLINE |
| 228 | +decltype(auto) |
| 229 | +CArray< T, DATA_BUFFER, DIMS ... >::squareBracketOperatorHelper( index_type index ) const |
| 230 | +{ |
| 231 | + static_assert( sizeof...(DIMS) >= 1, "operator[] is only valid for sizeof...(DIMS) >= 1" ); |
| 232 | + |
| 233 | +#if defined( SHIVA_USE_BOUNDS_CHECK ) |
| 234 | + constexpr int DIM = CArrayHelper::IntPeeler< DIMS... >::first; |
| 235 | + SHIVA_ASSERT_MSG( index >= 0 && index < DIM, |
| 236 | + "Index out of bounds: 0 < index(%jd) < dim(%jd)", |
| 237 | + static_cast< intmax_t >( index ), |
| 238 | + static_cast< intmax_t >( DIM ) ); |
| 239 | +#endif |
| 240 | + |
| 241 | + if constexpr ( sizeof...(DIMS) > 1 ) |
| 242 | + { |
| 243 | + using SubArrayDims = typename CArrayHelper::IntPeeler< DIMS... >::rest; |
| 244 | + using SubArrayType = typename CArrayHelper::ApplyDims< SubArrayDims, CARRAY_TYPE >::type; |
| 245 | + return SubArrayType( const_cast< T * >( &m_data[ index * CArrayHelper::stride< DIMS..., 1 >() ] ) ); |
| 246 | + } |
| 247 | + else |
| 248 | + { |
| 249 | + return operator()( index ); |
| 250 | + } |
| 251 | +} |
| 252 | + |
164 | 253 | /** |
165 | 254 | * @brief Alias for a scalar. |
166 | 255 | * @tparam T Type held in the scalar |
|
0 commit comments