15 #ifndef LARDATA_UTILITIES_TENSORINDICES_H 16 #define LARDATA_UTILITIES_TENSORINDICES_H 22 #include <type_traits> 42 template <
unsigned int RANK>
46 template <
unsigned int RANK,
unsigned int DIM>
66 static constexpr
unsigned int rank() {
return 1U; }
78 template <
typename ITER>
87 template <
typename ITER>
91 return checkOuterIndex(*indexIter);
96 template <
typename ITER>
100 return (*indexIter >= 0) && ((
DimSize_t)*indexIter <
size());
103 template <
unsigned int DIM = 0>
106 return (DIM == 0) ? totalSize() : dim<DIM>();
109 template <
unsigned int DIM>
112 static_assert(DIM == 0,
"Invalid dimension requested");
116 template <
unsigned int DIM>
119 static_assert(DIM == 0,
"Invalid dimension requested");
131 if (has(index))
return index;
132 throw std::out_of_range(
"Requested index " +
std::to_string(index) +
141 template <
unsigned int R,
unsigned int D>
165 template <
unsigned int RANK>
167 static_assert(RANK > 1,
"TensorIndices must have rank 1 or higher");
182 static constexpr
unsigned int rank() {
return RANK; }
199 template <
typename... OTHERDIMS>
201 :
Base_t(first), m(others...), totSize(dim0() * m.
size())
250 template <
typename... OTHERINDICES>
253 return first * minorTensor().size() + minorTensor()(others...);
275 template <
typename ITER>
279 auto const baseSize = (*indexIter) * minorTensor().size();
280 return baseSize + minorTensor()(++indexIter);
305 template <
typename... OTHERINDICES>
308 return Base_t::checkOuterIndex(first) * minorTensor().size() + minorTensor().at(others...);
332 template <
typename ITER>
334 ITER indexIter)
const 336 auto const baseSize = Base_t::checkOuterIndex(*indexIter) * minorTensor().size();
337 return baseSize + minorTensor()(++indexIter);
364 template <
typename... OTHERINDICES>
367 return Base_t::has(first) && minorTensor().has(others...);
392 template <
typename ITER>
394 ITER indexIter)
const 396 return Base_t::has(*indexIter) ? minorTensor().has(++indexIter) :
false;
406 template <
unsigned int DIM>
436 template <
unsigned int DIM>
439 return (index >= 0U) && ((
DimSize_t)index < dim<DIM>());
455 template <
unsigned int DIM = 0>
486 template <
unsigned int R,
unsigned int D>
498 template <
unsigned int RANK1,
500 typename = std::enable_if_t<(RANK1 != RANK2), bool>>
507 template <
unsigned int RANK1,
509 typename = std::enable_if_t<(RANK1 != RANK2), bool>>
528 template <
typename... DIMS>
561 template <
unsigned int RANK,
unsigned int DIM>
562 struct ExtractTensorDimension {
563 static_assert(RANK > DIM,
"Invalid dimension requested");
576 template <
unsigned int RANK>
578 static_assert(RANK > 0,
"Invalid rank 0 for TensorIndices");
594 #endif // LARDATA_UTILITIES_TENSORINDICES_H bool has(Index_t index) const
std::enable_if_t< std::is_convertible< decltype(*(ITER())), DimSize_t >::value, LinIndex_t > at(ITER indexIter) const
Base_t::LinIndex_t LinIndex_t
Type of the linear index.
Namespace for general, non-LArSoft-specific utilities.
std::ptrdiff_t Index_t
Type of a single index in the tensor.
bool operator==(TensorIndices< RANK1 > const &a, TensorIndices< RANK2 > const &b)
Comparison operator with tensors of different rank.
bool hasIndex(Index_t index) const
std::enable_if_t< std::is_convertible< decltype(*(ITER())), DimSize_t >::value, LinIndex_t > operator()(ITER indexIter) const
Types for TensorIndices class.
std::enable_if_t< std::is_convertible< decltype(*(ITER())), DimSize_t >::value, LinIndex_t > at(ITER indexIter) const
Returns the linear index corresponding to the tensor indices.
bool has(Index_t first, OTHERINDICES...others) const
Returns whether the specified set of indices is valid.
bool operator==(TensorIndices< 1U > const &t) const
DimSize_t dimSize
size of the largest dimension
DimSize_t dim0() const
Returns the size of the outer dimension.
TensorIndices(ITER dimIter)
Base_t::Index_t Index_t
Type of a single index in the tensor.
DimSize_t totalSize() const
Returns the total size of this tensor.
TensorIndices(DimSize_t first, OTHERDIMS...others)
Constructor: initialises the dimension of the tensor.
bool hasLinIndex(LinIndex_t linIndex) const
unsigned int Index_t
Type to denote the index of the flag.
std::enable_if_t< std::is_convertible< decltype(*(ITER())), DimSize_t >::value, bool > has(ITER indexIter) const
DimSize_t dim() const
Returns the size of the specified dimension.
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
bool hasIndex(Index_t index) const
Returns whether a index is valid within a specified dimension.
DimSize_t totalSize() const
Returns the total size of this tensor (the same as size())
Index_t checkOuterIndex(Index_t index) const
Converts a tensor element specification into a linear index.
decltype(auto) constexpr to_string(T &&obj)
ADL-aware version of std::to_string.
LinIndex_t operator()(Index_t first, OTHERINDICES...others) const
Returns the linear index corresponding to the tensor indices.
TensorIndicesBasicTypes::LinIndex_t LinIndex_t
std::enable_if_t< std::is_convertible< decltype(*(ITER())), DimSize_t >::value, LinIndex_t > operator()(ITER indexIter) const
Returns the linear index corresponding to the tensor indices.
std::size_t DimSize_t
Type of size of a dimension in the tensor.
DimSize_t totSize
size of this tensor
TensorIndices(ITER dimIter)
Constructor: initialises the dimension of the tensor.
bool operator==(TensorIndices< RANK > const &t) const
Returns whether all sizes of the tensor t are the same as this one.
bool hasLinIndex(LinIndex_t linIndex) const
Returns whether the specified linear index is valid in this tensor.
TensorIndices(DimSize_t dim)
TensorIndicesBasicTypes::Index_t Index_t
MinorTensor_t m
the rest of the tensor indices
TensorIndicesBasicTypes::DimSize_t DimSize_t
static constexpr unsigned int rank()
Rank of this tensor.
bool operator!=(TensorIndices< 1U > const &t) const
bool operator!=(TensorIndices< RANK > const &t) const
Returns whether any size of the tensor t is different from this one.
static constexpr unsigned int rank()
DimSize_t size() const
Returns the size of the minor tensor.
auto makeTensorIndices(DIMS...dims)
Instantiates a TensorIndices class with the specified dimensions.
MinorTensor_t const & minorTensor() const
LinIndex_t operator()(Index_t index) const
bool operator!=(TensorIndices< RANK1 > const &a, TensorIndices< RANK2 > const &b)
Comparison operator with tensors of different rank.
std::size_t LinIndex_t
Type of the linear index.
LinIndex_t at(Index_t first, OTHERINDICES...others) const
Returns the linear index corresponding to the tensor indices.
LinIndex_t at(Index_t index) const
std::enable_if_t< std::is_convertible< decltype(*(ITER())), DimSize_t >::value, bool > has(ITER indexIter) const
Returns whether the specified set of indices is valid.
Base_t::DimSize_t DimSize_t
Type for the specification of a dimension size.