Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-28 09:19:35

0001 // Copyright (c) 2026 OPEN CASCADE SAS
0002 //
0003 // This file is part of Open CASCADE Technology software library.
0004 //
0005 // This library is free software; you can redistribute it and/or modify it under
0006 // the terms of the GNU Lesser General Public License version 2.1 as published
0007 // by the Free Software Foundation, with special exception defined in the file
0008 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0009 // distribution for complete text of the license and disclaimer of any warranty.
0010 //
0011 // Alternatively, this file may be used under the terms of Open CASCADE
0012 // commercial license or contractual agreement.
0013 
0014 #ifndef _BRepGraph_ItemUID_HeaderFile
0015 #define _BRepGraph_ItemUID_HeaderFile
0016 
0017 #include <BRepGraph_NodeId.hxx>
0018 #include <BRepGraph_RefId.hxx>
0019 #include <Standard_Assert.hxx>
0020 #include <Standard_HashUtils.hxx>
0021 
0022 #include <cstdint>
0023 #include <cstddef>
0024 #include <functional>
0025 #include <limits>
0026 
0027 //! Durable BRepGraph item identity covering definition nodes and reference entries.
0028 //!
0029 //! BRepGraph_ItemId is a transient structural address. BRepGraph_ItemUID is the persistent
0030 //! identity assigned at item creation and kept stable across compaction and vector reordering.
0031 //! Representation/use records are not addressed here because they do not have persisted identity.
0032 class BRepGraph_ItemUID
0033 {
0034 public:
0035   //! Addressed persistent identity domain.
0036   enum class Domain : uint8_t
0037   {
0038     None,
0039     Node,
0040     Reference
0041   };
0042 
0043   //! Construct an invalid UID.
0044   BRepGraph_ItemUID() = default;
0045 
0046   //! Construct a node UID.
0047   static BRepGraph_ItemUID Node(const BRepGraph_NodeId::Kind theKind, const size_t theCounter)
0048   {
0049     return BRepGraph_ItemUID(Domain::Node, static_cast<uint8_t>(theKind), theCounter);
0050   }
0051 
0052   //! Construct a reference UID.
0053   static BRepGraph_ItemUID Reference(const BRepGraph_RefId::Kind theKind, const size_t theCounter)
0054   {
0055     return BRepGraph_ItemUID(Domain::Reference, static_cast<uint8_t>(theKind), theCounter);
0056   }
0057 
0058   //! Return an invalid sentinel UID.
0059   static BRepGraph_ItemUID Invalid() { return BRepGraph_ItemUID(); }
0060 
0061   //! Return true if this UID has a non-sentinel counter and a valid domain/kind pair.
0062   [[nodiscard]] bool IsValid() const noexcept
0063   {
0064     if (myCounter == 0)
0065     {
0066       return false;
0067     }
0068 
0069     switch (myDomain)
0070     {
0071       case Domain::Node:
0072         return BRepGraph_NodeId::IsValidKind(static_cast<BRepGraph_NodeId::Kind>(myKind));
0073       case Domain::Reference:
0074         return BRepGraph_RefId::IsValidKind(static_cast<BRepGraph_RefId::Kind>(myKind));
0075       case Domain::None:
0076         return false;
0077     }
0078     return false;
0079   }
0080 
0081   //! Return the addressed identity domain.
0082   [[nodiscard]] Domain ItemDomain() const noexcept { return myDomain; }
0083 
0084   [[nodiscard]] bool IsNode() const noexcept { return myDomain == Domain::Node; }
0085 
0086   [[nodiscard]] bool IsReference() const noexcept { return myDomain == Domain::Reference; }
0087 
0088   //! Return node kind. Valid only for node UIDs.
0089   [[nodiscard]] BRepGraph_NodeId::Kind NodeKind() const noexcept
0090   {
0091     Standard_ASSERT_RETURN(
0092       IsNode() && BRepGraph_NodeId::IsValidKind(static_cast<BRepGraph_NodeId::Kind>(myKind)),
0093       "BRepGraph_ItemUID::NodeKind(): UID is not a valid node UID",
0094       BRepGraph_NodeId::Kind::Solid);
0095     return static_cast<BRepGraph_NodeId::Kind>(myKind);
0096   }
0097 
0098   //! Return reference kind. Valid only for reference UIDs.
0099   [[nodiscard]] BRepGraph_RefId::Kind RefKind() const noexcept
0100   {
0101     Standard_ASSERT_RETURN(
0102       IsReference() && BRepGraph_RefId::IsValidKind(static_cast<BRepGraph_RefId::Kind>(myKind)),
0103       "BRepGraph_ItemUID::RefKind(): UID is not a valid reference UID",
0104       BRepGraph_RefId::Kind::Shell);
0105     return static_cast<BRepGraph_RefId::Kind>(myKind);
0106   }
0107 
0108   //! Return item kind encoded in its own domain enum space.
0109   [[nodiscard]] uint8_t RawKind() const noexcept { return myKind; }
0110 
0111   //! Return the graph-wide monotonic UID counter.
0112   [[nodiscard]] size_t Counter() const noexcept { return myCounter; }
0113 
0114   friend bool operator==(const BRepGraph_ItemUID& theLeft,
0115                          const BRepGraph_ItemUID& theRight) noexcept
0116   {
0117     if (theLeft.myCounter == 0 || theRight.myCounter == 0)
0118     {
0119       return (theLeft.myCounter == 0) == (theRight.myCounter == 0);
0120     }
0121     return theLeft.myDomain == theRight.myDomain && theLeft.myKind == theRight.myKind
0122            && theLeft.myCounter == theRight.myCounter;
0123   }
0124 
0125   friend bool operator!=(const BRepGraph_ItemUID& theLeft,
0126                          const BRepGraph_ItemUID& theRight) noexcept
0127   {
0128     return !(theLeft == theRight);
0129   }
0130 
0131   friend bool operator<(const BRepGraph_ItemUID& theLeft,
0132                         const BRepGraph_ItemUID& theRight) noexcept
0133   {
0134     if (theLeft.myDomain != theRight.myDomain)
0135     {
0136       return static_cast<uint8_t>(theLeft.myDomain) < static_cast<uint8_t>(theRight.myDomain);
0137     }
0138     if (theLeft.myKind != theRight.myKind)
0139     {
0140       return theLeft.myKind < theRight.myKind;
0141     }
0142     return theLeft.myCounter < theRight.myCounter;
0143   }
0144 
0145   //! Compute a hash value compatible with operator==.
0146   [[nodiscard]] size_t HashValue() const noexcept
0147   {
0148     if (myCounter == 0)
0149     {
0150       return opencascade::hash(0);
0151     }
0152 
0153     size_t aCombination[3];
0154     aCombination[0] = opencascade::hash(static_cast<uint32_t>(myDomain));
0155     aCombination[1] = opencascade::hash(static_cast<uint32_t>(myKind));
0156     aCombination[2] = opencascade::hash(myCounter);
0157     return opencascade::hashBytes(aCombination, sizeof(aCombination));
0158   }
0159 
0160 private:
0161   BRepGraph_ItemUID(const Domain theDomain, const uint8_t theKind, const size_t theCounter)
0162       : myCounter(0),
0163         myDomain(theDomain),
0164         myKind(theKind)
0165   {
0166     Standard_ASSERT_VOID(theCounter > 0, "BRepGraph_ItemUID: counter must be > 0 for valid UIDs");
0167     Standard_ASSERT_VOID(theCounter <= std::numeric_limits<uint32_t>::max(),
0168                          "BRepGraph_ItemUID: counter exceeds 32-bit storage");
0169     if (theCounter > 0 && theCounter <= std::numeric_limits<uint32_t>::max())
0170     {
0171       myCounter = static_cast<uint32_t>(theCounter);
0172     }
0173   }
0174 
0175   uint32_t myCounter = 0;            //!< 0 = invalid sentinel; valid counters start at 1.
0176   Domain   myDomain  = Domain::None; //!< Identity domain.
0177   uint8_t  myKind    = 0;            //!< Kind encoded in the selected domain enum space.
0178 };
0179 
0180 static_assert(sizeof(BRepGraph_ItemUID) <= 8, "BRepGraph_ItemUID must stay compact");
0181 
0182 //! std::hash specialization for NCollection_DefaultHasher support.
0183 template <>
0184 struct std::hash<BRepGraph_ItemUID>
0185 {
0186   size_t operator()(const BRepGraph_ItemUID& theUID) const noexcept { return theUID.HashValue(); }
0187 };
0188 
0189 #endif // _BRepGraph_ItemUID_HeaderFile