File indexing completed on 2026-11-01 10:04:13
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include "corecel/Assert.hh"
0010 #include "corecel/Types.hh"
0011 #include "corecel/cont/Array.hh"
0012
0013 #include "detail/HyperslabIndexerImpl.hh"
0014
0015 namespace celeritas
0016 {
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 template<std::size_t N>
0029 class HyperslabIndexer
0030 {
0031 public:
0032
0033
0034 using Coords = Array<size_type, N>;
0035
0036
0037 public:
0038
0039 explicit inline CELER_FUNCTION HyperslabIndexer(
0040 Array<size_type, N> const& dims);
0041
0042
0043
0044
0045 inline CELER_FUNCTION size_type operator()(Coords const& coords) const;
0046
0047
0048 template<typename... Args>
0049 inline CELER_FUNCTION size_type operator()(Args... args) const;
0050
0051 private:
0052
0053
0054 Array<size_type, N> const& dims_;
0055 };
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065 template<std::size_t N>
0066 class HyperslabInverseIndexer
0067 {
0068 public:
0069
0070
0071 using Coords = Array<size_type, N>;
0072
0073
0074 public:
0075
0076 explicit inline CELER_FUNCTION HyperslabInverseIndexer(
0077 Array<size_type, N> const& dims);
0078
0079
0080
0081
0082 inline CELER_FUNCTION Coords operator()(size_type index) const;
0083
0084 private:
0085
0086
0087 Array<size_type, N> const& dims_;
0088 };
0089
0090
0091
0092
0093
0094
0095
0096 template<std::size_t N>
0097 CELER_FUNCTION HyperslabIndexer<N>::HyperslabIndexer(Coords const& dims)
0098 : dims_(dims)
0099 {
0100 for (auto dim : dims_)
0101 {
0102 CELER_EXPECT(dim > 0);
0103 }
0104 }
0105
0106
0107
0108
0109
0110 template<std::size_t N>
0111 CELER_FUNCTION size_type HyperslabIndexer<N>::operator()(
0112 Coords const& coords) const
0113 {
0114 CELER_EXPECT(coords[0] < dims_[0]);
0115 size_type result = coords[0];
0116
0117 for (size_type i = 1; i < N; ++i)
0118 {
0119 CELER_EXPECT(coords[i] < dims_[i]);
0120 result = dims_[i] * result + coords[i];
0121 }
0122 return result;
0123 }
0124
0125
0126
0127
0128
0129 template<std::size_t N>
0130 template<typename... Args>
0131 CELER_FUNCTION size_type HyperslabIndexer<N>::operator()(Args... args) const
0132 {
0133 static_assert(sizeof...(Args) == N,
0134 "Number of coordinates must match number of dimensions");
0135
0136 return this->operator()(Coords{static_cast<size_type>(args)...});
0137 }
0138
0139
0140
0141
0142
0143 template<std::size_t N>
0144 CELER_FUNCTION HyperslabInverseIndexer<N>::HyperslabInverseIndexer(
0145 Array<size_type, N> const& dims)
0146 : dims_(dims)
0147 {
0148 for (auto dim : dims_)
0149 {
0150 CELER_EXPECT(dim > 0);
0151 }
0152 }
0153
0154
0155
0156
0157
0158 template<std::size_t N>
0159 CELER_FUNCTION typename HyperslabInverseIndexer<N>::Coords
0160 HyperslabInverseIndexer<N>::operator()(size_type index) const
0161 {
0162 CELER_EXPECT(index <= detail::hyperslab_size(dims_));
0163 Coords coords;
0164
0165 for (size_type i = dims_.size() - 1; i > 0; i--)
0166 {
0167 coords[i] = index % dims_[i];
0168 index = (index - coords[i]) / dims_[i];
0169 }
0170
0171 coords[0] = index;
0172
0173 return coords;
0174 }
0175
0176
0177 }