Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-13 11:00:09

0001 /// \file NavTuple.h
0002 /// \author Andrei Gheata (andrei.gheata@cern.ch)
0003 /// \date 27.05.2026
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  * @brief Fixed-size tuple of scene-local navigation-table indices.
0017  *
0018  * @details The tuple stores one encoded table index for each active scene. The
0019  * current scene is at `fLevel`; `Top()` returns the index in that scene.
0020  */
0021 template <uint MAX_DEPTH>
0022 struct NavTuple {
0023   NavIndex_t fNavInd[MAX_DEPTH]{0};
0024   uint fLevel{0};
0025 
0026   /// @brief Construct an outside tuple.
0027   /// @details The tuple is initialized with level zero and top index zero,
0028   /// which is the outside-state encoding.
0029   NavTuple() = default;
0030 
0031   /// @brief Copy a tuple.
0032   /// @details The complete fixed-size value representation is copied.
0033   VECCORE_ATT_HOST_DEVICE
0034   NavTuple(NavTuple<MAX_DEPTH> const &other) = default;
0035 
0036   /// @brief Construct a single-component tuple.
0037   /// @details The tuple level is zero and the first component is initialized to
0038   /// the provided scene-local navigation-table index.
0039   VECCORE_ATT_HOST_DEVICE
0040   NavTuple(NavIndex_t ind) : fNavInd{ind}, fLevel{0} {}
0041 
0042   /// @brief Construct a tuple from a container of table indices.
0043   /// @details Container entries are copied in order and must fit the fixed
0044   /// tuple depth.
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   /// @brief Return the fixed tuple capacity.
0055   /// @details This is the maximum number of scene components that can be stored
0056   /// in the tuple object.
0057   VECGEOM_FORCE_INLINE
0058   VECCORE_ATT_HOST_DEVICE
0059   static constexpr uint GetMaxDepth() { return MAX_DEPTH; }
0060 
0061   /// @brief Assign another tuple.
0062   /// @details The complete fixed-size value representation is copied.
0063   VECGEOM_FORCE_INLINE
0064   VECCORE_ATT_HOST_DEVICE
0065   NavTuple<MAX_DEPTH> &operator=(NavTuple<MAX_DEPTH> const &other) = default;
0066 
0067   /// @brief Assign a single-level navigation index.
0068   /// @details The tuple level is reset to zero and the first component is set
0069   /// to `ind`.
0070   /// @param ind Navigation index at first level.
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   /// @brief Return a tuple component.
0081   /// @details Out-of-range access is reported through validation and returns
0082   /// zero when validation is compiled as non-fatal.
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   /// @brief Return a mutable tuple component.
0092   /// @details The caller is responsible for passing an index below
0093   /// `GetMaxDepth()`.
0094   VECGEOM_FORCE_INLINE
0095   VECCORE_ATT_HOST_DEVICE
0096   NavIndex_t &operator[](uint i) { return fNavInd[i]; }
0097 
0098   /// @brief Compare two tuples for exact equality.
0099   /// @details The active tuple level and all active components must match.
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   /// @brief Compare two tuples for inequality.
0112   /// @details This is the negation of exact tuple equality.
0113   VECGEOM_FORCE_INLINE
0114   VECCORE_ATT_HOST_DEVICE
0115   bool operator!=(NavTuple<MAX_DEPTH> const &other) const { return !operator==(other); }
0116 
0117   /// @brief Order tuples lexicographically.
0118   /// @details This ordering is used by helper algorithms that need tuple keys;
0119   /// it does not encode geometry containment by itself.
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   /// @brief Compare with a single table index.
0136   /// @details The tuple is equal to the index only when it has level zero and
0137   /// its first component matches.
0138   VECGEOM_FORCE_INLINE
0139   VECCORE_ATT_HOST_DEVICE
0140   bool operator==(NavIndex_t navind) const { return fLevel == 0 && fNavInd[0] == navind; }
0141 
0142   /// @brief Compare with a single table index for inequality.
0143   /// @details This is the negation of single-index equality.
0144   VECGEOM_FORCE_INLINE
0145   VECCORE_ATT_HOST_DEVICE
0146   bool operator!=(NavIndex_t navind) const { return !operator==(navind); }
0147 
0148   /// @brief Reset the tuple to outside.
0149   /// @details The active level is set to zero and the first component is set to
0150   /// zero.
0151   VECGEOM_FORCE_INLINE
0152   VECCORE_ATT_HOST_DEVICE
0153   void Clear()
0154   {
0155     fLevel     = 0;
0156     fNavInd[0] = 0;
0157   }
0158 
0159   /// @brief Return whether this tuple encodes outside.
0160   /// @details Outside is represented by level zero and top component zero.
0161   VECGEOM_FORCE_INLINE
0162   VECCORE_ATT_HOST_DEVICE
0163   bool IsOutside() const { return (fLevel == 0) && (fNavInd[0] == 0); }
0164 
0165   /// @brief Push a new scene component.
0166   /// @details For a non-outside tuple, the active level is incremented before
0167   /// storing the new scene-local index. For outside, the first component is set.
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   /// @brief Set the active scene component.
0178   /// @details The active tuple level is unchanged.
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   /// @brief Return the active scene component.
0188   /// @details This is the scene-local navigation-table index at `fLevel`.
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 /// @brief Print a tuple to a stream.
0199 /// @details This diagnostic helper prints active tuple components in order.
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 } // namespace vecgeom
0213 
0214 #endif // VECGEOM_NAVIGATION_NAVTUPLE_H_