15 #ifndef LARDATA_UTILITIES_TENSORINDICES_H 16 #define LARDATA_UTILITIES_TENSORINDICES_H 23 #include <type_traits> 45 template <
unsigned int RANK>
50 template <
unsigned int RANK,
unsigned int DIM>
72 static constexpr
unsigned int rank() {
return 1U; }
79 typename = std::enable_if_t
87 template <
typename ITER>
89 <std::is_convertible<decltype(*(ITER())), DimSize_t>::value,
LinIndex_t>
90 operator() (ITER indexIter)
const {
return *indexIter; }
94 template <
typename ITER>
96 <std::is_convertible<decltype(*(ITER())), DimSize_t>::value,
LinIndex_t>
97 at(ITER indexIter)
const 98 {
return checkOuterIndex(*indexIter); }
103 template <
typename ITER>
105 <std::is_convertible<decltype(*(ITER())), DimSize_t>::value,
bool>
107 {
return (*indexIter >= 0) && ((
DimSize_t) *indexIter <
size()); }
110 template <
unsigned int DIM = 0>
113 template <
unsigned int DIM>
116 static_assert(DIM == 0,
"Invalid dimension requested");
120 template <
unsigned int DIM>
123 static_assert(DIM == 0,
"Invalid dimension requested");
128 {
return has((
Index_t) linIndex); }
138 if (has(index))
return index;
139 throw std::out_of_range(
"Requested index " +
std::to_string(index)
148 template <
unsigned int R,
unsigned int D>
173 template <
unsigned int RANK>
175 static_assert(RANK > 1,
"TensorIndices must have rank 1 or higher");
192 static constexpr
unsigned int rank() {
return RANK; }
210 template <
typename... OTHERDIMS>
212 :
Base_t(first),
m(others...), totSize(dim0() *
m.
size()) {}
237 typename = std::enable_if_t
241 :
Base_t(dimIter),
m(++dimIter), totSize(dim0() *
m.
size()) {}
264 template <
typename... OTHERINDICES>
266 {
return first * minorTensor().size() + minorTensor()(others...); }
288 template <
typename ITER>
290 <std::is_convertible<decltype(*(ITER())), DimSize_t>::value,
LinIndex_t>
291 operator() (ITER indexIter)
const 293 auto const baseSize = (*indexIter) * minorTensor().size();
294 return baseSize + minorTensor()(++indexIter);
320 template <
typename... OTHERINDICES>
323 return Base_t::checkOuterIndex(first) * minorTensor().size()
324 + minorTensor().at(others...);
348 template <
typename ITER>
350 <std::is_convertible<decltype(*(ITER())), DimSize_t>::value,
LinIndex_t>
351 at(ITER indexIter)
const 354 = Base_t::checkOuterIndex(*indexIter) * minorTensor().size();
355 return baseSize + minorTensor()(++indexIter);
383 template <
typename... OTHERINDICES>
385 {
return Base_t::has(first) && minorTensor().has(others...); }
409 template <
typename ITER>
411 <std::is_convertible<decltype(*(ITER())), DimSize_t>::value,
bool>
413 {
return Base_t::has(*indexIter)? minorTensor().has(++indexIter):
false; }
423 template <
unsigned int DIM>
452 template <
unsigned int DIM>
454 {
return (index >= 0U) && ((
DimSize_t) index < dim<DIM>()); }
470 template <
unsigned int DIM = 0>
473 return (DIM == 0)? totalSize():
479 {
return (linIndex >= 0U) && ((
DimSize_t) linIndex <
size()); }
499 template <
unsigned int R,
unsigned int D>
514 unsigned int RANK1,
unsigned int RANK2,
515 typename = std::enable_if_t<(RANK1 != RANK2), bool>
522 unsigned int RANK1,
unsigned int RANK2,
523 typename = std::enable_if_t<(RANK1 != RANK2), bool>
542 template <
typename... DIMS>
579 template <
unsigned int RANK,
unsigned int DIM>
580 struct ExtractTensorDimension {
581 static_assert(RANK > DIM,
"Invalid dimension requested");
592 template <
unsigned int RANK>
594 static_assert(RANK > 0,
"Invalid rank 0 for TensorIndices");
610 #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
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.
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.
TensorIndicesBasicTypes::LinIndex_t LinIndex_t
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 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.
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
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.
std::string to_string(ModuleType const mt)
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.