15 #include "atlas/array/ArrayViewDefs.h" 16 #include "atlas/array/Range.h" 17 #include "atlas/library/config.h" 22 template <
typename Value,
int Rank>
25 template <
typename Value>
28 operator Value&() {
return value; }
30 void operator=(
const T a ) {
53 template <
typename Value,
int Rank>
65 template <
int Rank,
typename... Args>
70 template <
typename Last>
71 static constexpr
int apply() {
72 return std::is_base_of<RangeBase, Last>::value;
75 template <
typename... Args>
80 #define ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION( RANK ) \ 82 struct deduce_slice_rank<RANK> { \ 83 template <typename First, typename... Args> \ 84 static constexpr int apply() { \ 85 return std::is_base_of<RangeBase, First>::value + deduce_slice_rank<RANK - 1>::apply<Args...>(); \ 88 template <typename... Args> \ 89 struct SliceRank_impl<RANK, Args...> { \ 90 static constexpr int value{deduce_slice_rank<RANK>::apply<Args...>()}; \ 93 ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION( 2 );
94 ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION( 3 );
95 ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION( 4 );
96 ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION( 5 );
97 ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION( 6 );
98 ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION( 7 );
99 ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION( 8 );
100 ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION( 9 );
101 #undef ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION 103 template <
typename... Args>
105 static constexpr
int value{
SliceRank_impl<
sizeof...( Args ), Args...>::value};
109 template <
typename View>
114 template <
typename... Args>
119 template <
typename... Args>
120 typename Slice<Args...>::type apply(
const Args... args )
const {
121 using slicer_t = Slicer<
typename Slice<Args...>::type, (
SliceRank<Args...>::value == 0 )>;
123 View::RANK <=
sizeof...( Args ),
124 "Not enough arguments passed to slice() function. Pehaps you forgot to add a array::Range::all()" );
125 return slicer_t::apply( view_, args... );
129 template <
typename... Args>
131 using type =
typename std::array<
idx_t,
SliceRank<Args...>::value>;
134 template <
typename ReturnType,
bool ToScalar = false>
136 template <
typename... Args>
137 static ReturnType apply( View& view,
const Args... args ) {
138 return ReturnType( view.data() + offset( view, args... ), shape( view, args... ).data(),
139 strides( view, args... ).data() );
143 template <
typename ReturnType>
144 struct Slicer<ReturnType, true> {
145 template <
typename... Args>
146 static ReturnType apply( View& view,
const Args... args ) {
147 return ReturnType{*( view.data() + offset( view, args... ) )};
151 template <
typename Int>
152 static idx_t offset_part( View& view,
int& i_view, Int idx ) {
153 return idx * view.stride( i_view++ );
156 static idx_t offset_part( View& view,
int& i_view,
Range range ) {
return range.start() * view.stride( i_view++ ); }
158 static idx_t offset_part( View& view,
int& i_view,
RangeAll range ) {
159 return range.start() * view.stride( i_view++ );
162 static idx_t offset_part( View& view,
int& i_view,
RangeTo range ) {
163 return range.start() * view.stride( i_view++ );
166 static idx_t offset_part( View& view,
int& i_view,
RangeFrom range ) {
167 return range.start() * view.stride( i_view++ );
172 template <
int Dim,
typename Int,
typename... Ints>
173 static idx_t offset_remaining( View& view,
int& i_view,
const Int idx,
const Ints... next_idx ) {
174 const idx_t p = offset_part( view, i_view, idx );
175 return p + offset_remaining<Dim + 1>( view, i_view, next_idx... );
178 template <
int Dim,
typename Int>
179 static idx_t offset_remaining( View& view,
int& i_view,
const Int last_idx ) {
180 return offset_part( view, i_view, last_idx );
183 template <
typename... Args>
184 static idx_t offset( View& view,
const Args... args ) {
186 return offset_remaining<0>( view, i_view, args... );
189 template <
int Dim,
typename Shape,
typename Int>
190 static void update_shape( View&, Shape&,
int& i_view,
int& ,
const Int& ) {
194 template <
int Dim,
typename Shape>
195 static void update_shape( View&, Shape& shape,
int& i_view,
int& i_slice,
const Range range ) {
196 shape[i_slice] = range.end() - range.start();
200 template <
int Dim,
typename Shape>
201 static void update_shape( View& view, Shape& shape,
int& i_view,
int& i_slice,
const RangeAll range ) {
202 shape[i_slice] = range.end( view, i_view ) - range.start();
206 template <
int Dim,
typename Shape>
207 static void update_shape( View& view, Shape& shape,
int& i_view,
int& i_slice,
const RangeFrom range ) {
208 shape[i_slice] = range.end( view, i_view ) - range.start();
212 template <
int Dim,
typename Shape>
213 static void update_shape( View&, Shape& shape,
int& i_view,
int& i_slice,
const RangeTo range ) {
214 shape[i_slice] = range.end() - range.start();
219 template <
int Dim,
typename Shape>
220 static void update_shape( View&, Shape& shape,
int& ,
int& i_slice,
const RangeDummy ) {
226 template <
int Dim,
typename Shape,
typename Int,
typename... Ints>
227 static void shape_part( View& view, Shape& shape,
int& i_view,
int& i_slice,
const Int idx,
228 const Ints... next_idx ) {
229 update_shape<Dim>( view, shape, i_view, i_slice, idx );
230 shape_part<Dim + 1>( view, shape, i_view, i_slice, next_idx... );
233 template <
int Dim,
typename Shape,
typename Int>
234 static void shape_part( View& view, Shape& shape,
int& i_view,
int& i_slice,
const Int idx ) {
235 update_shape<Dim>( view, shape, i_view, i_slice, idx );
238 template <
typename... Args>
239 static typename array<Args...>::type shape( View& view,
const Args... args ) {
240 typename array<Args...>::type result;
243 shape_part<0>( view, result, i_view, i_slice, args... );
247 template <
int Dim,
typename Str
ides,
typename Int>
248 static void update_strides( View&, Strides&,
int& i_view,
int& ,
const Int& ) {
252 template <
int Dim,
typename Str
ides>
253 static void update_strides( View& view, Strides& strides,
int& i_view,
int& i_slice,
const Range& ) {
254 strides[i_slice] = view.stride( i_view );
258 template <
int Dim,
typename Str
ides>
259 static void update_strides( View& view, Strides& strides,
int& i_view,
int& i_slice,
const RangeFrom& ) {
260 strides[i_slice] = view.stride( i_view );
264 template <
int Dim,
typename Str
ides>
265 static void update_strides( View& view, Strides& strides,
int& i_view,
int& i_slice,
const RangeTo& ) {
266 strides[i_slice] = view.stride( i_view );
270 template <
int Dim,
typename Str
ides>
271 static void update_strides( View& view, Strides& strides,
int& i_view,
int& i_slice,
const RangeAll& ) {
272 strides[i_slice] = view.stride( i_view );
276 template <
int Dim,
typename Str
ides>
277 static void update_strides( View& , Strides& strides,
int& ,
int& i_slice,
279 strides[i_slice] = 0;
283 template <
int Dim,
typename Strides,
typename Int,
typename... Ints>
284 static void strides_part( View& view, Strides& strides,
int& i_view,
int& i_slice,
const Int idx,
285 const Ints... next_idx ) {
286 update_strides<Dim>( view, strides, i_view, i_slice, idx );
287 strides_part<Dim + 1>( view, strides, i_view, i_slice, next_idx... );
290 template <
int Dim,
typename Str
ides,
typename Int>
291 static void strides_part( View& view, Strides& strides,
int& i_view,
int& i_slice,
const Int idx ) {
292 update_strides<Dim>( view, strides, i_view, i_slice, idx );
295 template <
typename... Args>
296 static typename array<Args...>::type strides( View& view,
const Args... args ) {
297 typename array<Args...>::type result;
300 strides_part<0>( view, result, i_view, i_slice, args... );
Definition: ArraySlicer.h:66
Definition: ArraySlicer.h:110
Definition: ArraySlicer.h:26
Definition: ArraySlicer.h:104
Definition: ArraySlicer.h:63
Multi-dimensional access existing POD array pointer.
Definition: ArraySlicer.h:23
Contains all atlas classes and methods.
Definition: atlas-grids.cc:33
Definition: ArraySlicer.h:54
long idx_t
Integer type for indices in connectivity tables.
Definition: config.h:42
Definition: ArrayViewDefs.h:20
Definition: ArraySlicer.h:115