54 #include <initializer_list> 56 #include <type_traits> 58 #include "atlas/array/ArrayUtil.h" 59 #include "atlas/array/ArrayViewDefs.h" 61 #include "atlas/array/Range.h" 62 #include "atlas/array/helpers/ArraySlicer.h" 63 #include "atlas/library/config.h" 97 template <
typename Value,
int Rank>
100 using is_non_const_value_type =
typename std::is_same<T, typename std::remove_const<Value>::type>;
102 #define ENABLE_IF_NON_CONST \ 103 template <bool EnableBool = true, \ 104 typename std::enable_if<( !std::is_const<Value>::value && EnableBool ), int>::type* = nullptr> 106 #define ENABLE_IF_CONST_WITH_NON_CONST( T ) \ 107 template <typename T, \ 108 typename std::enable_if<( std::is_const<Value>::value && is_non_const_value_type<T>::value ), \ 109 int>::type* = nullptr> 113 using value_type = Value;
114 using non_const_value_type =
typename std::remove_const<Value>::type;
115 static constexpr
bool is_const = std::is_const<Value>::value;
116 static constexpr
bool is_non_const = !std::is_const<Value>::value;
117 static constexpr
int RANK{Rank};
120 using slicer_t =
typename helpers::ArraySlicer<ArrayView<Value, Rank>>;
121 using const_slicer_t =
typename helpers::ArraySlicer<const ArrayView<const Value, Rank>>;
123 template <
typename... Args>
125 using type =
typename slicer_t::template
Slice<Args...>::type;
128 template <
typename... Args>
129 struct const_slice_t {
130 using type =
typename const_slicer_t::template
Slice<Args...>::type;
136 ArrayView(
const ArrayView& other ) :
137 data_( other.data_ ), size_( other.size_ ), shape_( other.shape_ ), strides_( other.strides_ ) {}
139 ENABLE_IF_CONST_WITH_NON_CONST( value_type )
140 ArrayView(
const ArrayView<value_type, Rank>& other ) : data_( other.data() ), size_( other.size() ) {
141 for (
idx_t j = 0; j < Rank; ++j ) {
142 shape_[j] = other.shape( j );
143 strides_[j] = other.stride( j );
147 #ifndef DOXYGEN_SHOULD_SKIP_THIS 149 ArrayView( value_type* data,
const ArrayShape& shape,
const ArrayStrides& strides ) : data_( data ) {
151 for (
int j = 0; j < Rank; ++j ) {
152 shape_[j] = shape[j];
153 strides_[j] = strides[j];
154 size_ *= size_t( shape_[j] );
159 ENABLE_IF_CONST_WITH_NON_CONST( value_type )
160 operator const ArrayView<value_type, Rank>&()
const {
return *(
const ArrayView<value_type, Rank>*)(
this ); }
166 template <
typename... Idx>
168 check_bounds( idx... );
169 return data_[index( idx... )];
173 template <
typename... Ints>
175 return data_[index( idx... )];
181 #ifndef DOXYGEN_SHOULD_SKIP_THIS 182 template <
typename Int,
bool EnableBool = true>
183 typename std::enable_if<( Rank == 1 && EnableBool ), const value_type&>::type
operator[]( Int idx )
const {
186 template <
typename Int>
187 value_type operator[]( Int idx )
const {
190 return data_[idx * strides_[0]];
196 #ifndef DOXYGEN_SHOULD_SKIP_THIS 197 template <
typename Int,
bool EnableBool = true>
198 typename std::enable_if<( Rank == 1 && EnableBool ), value_type&>::type
operator[]( Int idx ) {
201 template <
typename Int>
202 value_type operator[]( Int idx ) {
205 return data_[idx * strides_[0]];
218 template <
unsigned int Dim>
224 template <
unsigned int Dim>
226 return strides_[
Dim];
230 size_t size()
const {
return size_; }
235 const idx_t* strides()
const {
return strides_.data(); }
237 const idx_t* shape()
const {
return shape_.data(); }
240 template <
typename Int>
246 template <
typename Int>
248 return strides_[idx];
252 value_type
const*
data()
const {
return data_; }
255 value_type*
data() {
return data_; }
257 bool valid()
const {
return true; }
263 bool contiguous()
const {
return ( size_ ==
size_t( shape_[0] ) *
size_t( strides_[0] ) ?
true :
false ); }
266 void assign(
const value_type& value );
269 void assign(
const std::initializer_list<value_type>& list );
271 void dump( std::ostream& os )
const;
291 template <
typename... Args>
292 #ifndef DOXYGEN_SHOULD_SKIP_THIS 293 typename slice_t<Args...>::type
slice( Args... args ) {
296 auto slice( Args... args ) {
298 return slicer_t( *this ).apply( args... );
303 template <
typename... Args>
304 #ifndef DOXYGEN_SHOULD_SKIP_THIS 305 typename const_slice_t<Args...>::type
slice( Args... args )
const {
308 auto slice( Args... args )
const {
310 return const_slicer_t( *this ).apply( args... );
316 template <
int Dim,
typename Int,
typename... Ints>
317 constexpr
idx_t index_part( Int idx, Ints... next_idx )
const {
318 return idx * strides_[Dim] + index_part<Dim + 1>( next_idx... );
321 template <
int Dim,
typename Int>
322 constexpr
idx_t index_part( Int last_idx )
const {
323 return last_idx * strides_[Dim];
326 template <
typename... Ints>
327 constexpr
idx_t index( Ints... idx )
const {
328 return index_part<0>( idx... );
331 #if ATLAS_ARRAYVIEW_BOUNDS_CHECKING 332 template <
typename... Ints>
333 void check_bounds( Ints... idx )
const {
334 static_assert(
sizeof...( idx ) == Rank,
"Expected number of indices is different from rank of array" );
335 return check_bounds_part<0>( idx... );
338 template <
typename... Ints>
339 void check_bounds( Ints... idx )
const {
340 static_assert(
sizeof...( idx ) == Rank,
"Expected number of indices is different from rank of array" );
344 template <
typename... Ints>
345 void check_bounds_force( Ints... idx )
const {
346 static_assert(
sizeof...( idx ) == Rank,
"Expected number of indices is different from rank of array" );
347 return check_bounds_part<0>( idx... );
350 template <
int Dim,
typename Int,
typename... Ints>
351 void check_bounds_part( Int idx, Ints... next_idx )
const {
352 if (
idx_t( idx ) >= shape_[Dim] ) {
353 throw_OutOfRange(
"ArrayView", array_dim<Dim>(), idx, shape_[Dim] );
355 check_bounds_part<Dim + 1>( next_idx... );
358 template <
int Dim,
typename Int>
359 void check_bounds_part( Int last_idx )
const {
360 if (
idx_t( last_idx ) >= shape_[Dim] ) {
361 throw_OutOfRange(
"ArrayView", array_dim<Dim>(), last_idx, shape_[Dim] );
369 std::array<idx_t, Rank> shape_;
370 std::array<idx_t, Rank> strides_;
375 #undef ENABLE_IF_NON_CONST 376 #undef ENABLE_IF_CONST_WITH_NON_CONST idx_t stride() const
Return stride for values in dimension Dim (template argument)
Definition: NativeArrayView.h:225
static constexpr idx_t rank()
Return the number of dimensions.
Definition: NativeArrayView.h:233
size_t size() const
Return total number of values (accumulated over all dimensions)
Definition: NativeArrayView.h:230
idx_t stride(Int idx) const
Return stride for values in dimension idx.
Definition: NativeArrayView.h:247
idx_t shape() const
Return number of values in dimension Dim (template argument)
Definition: NativeArrayView.h:219
const_slice_t< Args... >::type slice(Args... args) const
Obtain a slice from this view: view.slice( Range, Range, ... )
Definition: NativeArrayView.h:305
slice_t< Args... >::type slice(Args... args)
Obtain a slice from this view: view.slice( Range, Range, ...
Definition: NativeArrayView.h:293
const value_type & operator()(Ints... idx) const
Multidimensional index operator: view(i,j,k,...)
Definition: NativeArrayView.h:174
std::enable_if<(Rank==1 &&EnableBool), value_type & >::type operator[](Int idx)
Access to data using square bracket [idx] operator {m-label m-warning} Rank==1
Definition: NativeArrayView.h:198
idx_t shape(Int idx) const
Return number of values in dimension idx.
Definition: NativeArrayView.h:241
Definition: test_array_slicer.cc:22
bool contiguous() const
Return true when all values are contiguous in memory.
Definition: NativeArrayView.h:263
value_type & operator()(Idx... idx)
Multidimensional index operator: view(i,j,k,...)
Definition: NativeArrayView.h:167
value_type const * data() const
Access to internal data. {m-label m-danger} dangerous
Definition: NativeArrayView.h:252
Contains all atlas classes and methods.
Definition: atlas-grids.cc:33
long idx_t
Integer type for indices in connectivity tables.
Definition: config.h:42
std::enable_if<(Rank==1 &&EnableBool), const value_type & >::type operator[](Int idx) const
Access to data using square bracket [idx] operator {m-label m-warning} Rank==1.
Definition: NativeArrayView.h:183
Definition: ArrayViewDefs.h:20
This file contains the LocalView class, a class that allows to wrap any contiguous raw data into a vi...
value_type * data()
Access to internal data. {m-label m-danger} dangerous
Definition: NativeArrayView.h:255