File indexing completed on 2026-11-13 11:00:09
0001
0002
0003
0004
0005 #ifndef VECGEOM_NAVIGATION_NAVTUPLE_H_
0006 #define VECGEOM_NAVIGATION_NAVTUPLE_H_
0007
0008 #include "VecGeom/base/Config.h"
0009 #include "VecGeom/base/Global.h"
0010
0011 #include <ostream>
0012
0013 namespace vecgeom {
0014
0015
0016
0017
0018
0019
0020
0021 template <uint MAX_DEPTH>
0022 struct NavTuple {
0023 NavIndex_t fNavInd[MAX_DEPTH]{0};
0024 uint fLevel{0};
0025
0026
0027
0028
0029 NavTuple() = default;
0030
0031
0032
0033 VECCORE_ATT_HOST_DEVICE
0034 NavTuple(NavTuple<MAX_DEPTH> const &other) = default;
0035
0036
0037
0038
0039 VECCORE_ATT_HOST_DEVICE
0040 NavTuple(NavIndex_t ind) : fNavInd{ind}, fLevel{0} {}
0041
0042
0043
0044
0045 template <typename Container>
0046 VECCORE_ATT_HOST_DEVICE NavTuple(Container const *cont) : fNavInd{0}, fLevel{0}
0047 {
0048 VECGEOM_ASSERT(cont->size() <= MAX_DEPTH);
0049 for (NavIndex_t navind : *cont)
0050 fNavInd[fLevel++] = navind;
0051 if (fLevel > 0) fLevel--;
0052 }
0053
0054
0055
0056
0057 VECGEOM_FORCE_INLINE
0058 VECCORE_ATT_HOST_DEVICE
0059 static constexpr uint GetMaxDepth() { return MAX_DEPTH; }
0060
0061
0062
0063 VECGEOM_FORCE_INLINE
0064 VECCORE_ATT_HOST_DEVICE
0065 NavTuple<MAX_DEPTH> &operator=(NavTuple<MAX_DEPTH> const &other) = default;
0066
0067
0068
0069
0070
0071 VECGEOM_FORCE_INLINE
0072 VECCORE_ATT_HOST_DEVICE
0073 NavTuple<MAX_DEPTH> &operator=(NavIndex_t ind)
0074 {
0075 fLevel = 0;
0076 fNavInd[0] = ind;
0077 return *this;
0078 }
0079
0080
0081
0082
0083 VECGEOM_FORCE_INLINE
0084 VECCORE_ATT_HOST_DEVICE
0085 NavIndex_t operator[](uint i) const
0086 {
0087 VECGEOM_VALIDATE(i < MAX_DEPTH, << "NavTuple::operator[] out of range");
0088 return (i < MAX_DEPTH) ? fNavInd[i] : 0;
0089 }
0090
0091
0092
0093
0094 VECGEOM_FORCE_INLINE
0095 VECCORE_ATT_HOST_DEVICE
0096 NavIndex_t &operator[](uint i) { return fNavInd[i]; }
0097
0098
0099
0100 VECGEOM_FORCE_INLINE
0101 VECCORE_ATT_HOST_DEVICE
0102 bool operator==(NavTuple<MAX_DEPTH> const &other) const
0103 {
0104 if (fLevel != other.fLevel) return false;
0105 for (int i = fLevel; i >= 0; i--) {
0106 if (fNavInd[i] != other.fNavInd[i]) return false;
0107 }
0108 return true;
0109 }
0110
0111
0112
0113 VECGEOM_FORCE_INLINE
0114 VECCORE_ATT_HOST_DEVICE
0115 bool operator!=(NavTuple<MAX_DEPTH> const &other) const { return !operator==(other); }
0116
0117
0118
0119
0120 VECGEOM_FORCE_INLINE
0121 VECCORE_ATT_HOST_DEVICE
0122 bool operator<(NavTuple<MAX_DEPTH> const &other) const
0123 {
0124 if (fLevel == other.fLevel) {
0125 for (unsigned i = 0; i < MAX_DEPTH && i <= fLevel; ++i) {
0126 if (fNavInd[i] < other.fNavInd[i]) return true;
0127 if (fNavInd[i] > other.fNavInd[i]) return false;
0128 }
0129 } else {
0130 return fLevel < other.fLevel;
0131 }
0132 return false;
0133 }
0134
0135
0136
0137
0138 VECGEOM_FORCE_INLINE
0139 VECCORE_ATT_HOST_DEVICE
0140 bool operator==(NavIndex_t navind) const { return fLevel == 0 && fNavInd[0] == navind; }
0141
0142
0143
0144 VECGEOM_FORCE_INLINE
0145 VECCORE_ATT_HOST_DEVICE
0146 bool operator!=(NavIndex_t navind) const { return !operator==(navind); }
0147
0148
0149
0150
0151 VECGEOM_FORCE_INLINE
0152 VECCORE_ATT_HOST_DEVICE
0153 void Clear()
0154 {
0155 fLevel = 0;
0156 fNavInd[0] = 0;
0157 }
0158
0159
0160
0161 VECGEOM_FORCE_INLINE
0162 VECCORE_ATT_HOST_DEVICE
0163 bool IsOutside() const { return (fLevel == 0) && (fNavInd[0] == 0); }
0164
0165
0166
0167
0168 VECGEOM_FORCE_INLINE
0169 VECCORE_ATT_HOST_DEVICE
0170 void Push(NavIndex_t value)
0171 {
0172 if (!IsOutside()) fLevel++;
0173 VECGEOM_VALIDATE(fLevel < MAX_DEPTH, << "NavTuple::Push out of range");
0174 if (fLevel < MAX_DEPTH) fNavInd[fLevel] = value;
0175 }
0176
0177
0178
0179 VECGEOM_FORCE_INLINE
0180 VECCORE_ATT_HOST_DEVICE
0181 void Set(NavIndex_t value)
0182 {
0183 VECGEOM_VALIDATE(fLevel < MAX_DEPTH, << "NavTuple::Set out of range");
0184 if (fLevel < MAX_DEPTH) fNavInd[fLevel] = value;
0185 }
0186
0187
0188
0189 VECGEOM_FORCE_INLINE
0190 VECCORE_ATT_HOST_DEVICE
0191 NavIndex_t Top() const
0192 {
0193 VECGEOM_VALIDATE(fLevel < MAX_DEPTH, << "NavTuple::Top out of range");
0194 return (fLevel < MAX_DEPTH) ? fNavInd[fLevel] : 0;
0195 }
0196 };
0197
0198
0199
0200 template <unsigned int MAX_DEPTH>
0201 std::ostream &operator<<(std::ostream &os, NavTuple<MAX_DEPTH> const &nav_tuple)
0202 {
0203 os << "(" << nav_tuple[0];
0204 for (unsigned i = 1; i < nav_tuple.fLevel; ++i)
0205 os << " ," << nav_tuple[i];
0206 os << ")";
0207 return os;
0208 }
0209
0210 using NavTuple_t = NavTuple<VECGEOM_NAVTUPLE_MAXDEPTH>;
0211
0212 }
0213
0214 #endif