Back to home page

EIC code displayed by LXR

 
 

    


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

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 _BRepGraphInc_BitFlags_HeaderFile
0015 #define _BRepGraphInc_BitFlags_HeaderFile
0016 
0017 #include <NCollection_LinearVector.hxx>
0018 
0019 #include <cstdint>
0020 #include <cstddef>
0021 
0022 //! @brief Contiguous bit-vector for per-entity boolean flags.
0023 //!
0024 //! Stores one bit per entity index in a flat array of 64-bit blocks.
0025 //! Provides O(1) Set/Clear/Test operations and cache-friendly sequential
0026 //! traversal (512 flags per 64-byte cache line via eight 64-bit blocks).
0027 //!
0028 //! Used by BRepGraphInc_Storage to store IsRemoved and IsOwned flags
0029 //! outside the entity structs, improving cache locality during traversal
0030 //! and reducing struct size by eliminating bool-field padding.
0031 //!
0032 //! Public helpers in BRepGraphInc_Storage validate indices before reaching this
0033 //! low-level container. Set, Clear, and Test remain unchecked for hot internal
0034 //! paths that already proved the index is in range.
0035 //!
0036 //! @code
0037 //!   BRepGraphInc_BitFlags aFlags;
0038 //!   aFlags.Resize(1000);
0039 //!   aFlags.Set(42);
0040 //!   if (aFlags.Test(42)) { ... }
0041 //!   aFlags.Clear(42);
0042 //! @endcode
0043 class BRepGraphInc_BitFlags
0044 {
0045   static constexpr uint32_t THE_BITS_PER_BLOCK = 64;
0046   using BlockType                              = uint64_t;
0047 
0048 public:
0049   //! Construct an empty bit-vector.
0050   BRepGraphInc_BitFlags() = default;
0051 
0052   //! Resize the bit-vector to hold at least theCount bits.
0053   //! Newly added bits are initialized to false.
0054   void Resize(const size_t theCount)
0055   {
0056     const size_t aBlockCount = (theCount + THE_BITS_PER_BLOCK - 1) / THE_BITS_PER_BLOCK;
0057     myBlocks.Resize(aBlockCount, 0);
0058     myBitCount = theCount;
0059     maskTailBits();
0060   }
0061 
0062   //! Set the bit at theIndex to true.
0063   void Set(const uint32_t theIndex)
0064   {
0065     const size_t   aBlock = theIndex / THE_BITS_PER_BLOCK;
0066     const uint32_t aBit   = theIndex % THE_BITS_PER_BLOCK;
0067     myBlocks[aBlock] |= (BlockType(1) << aBit);
0068   }
0069 
0070   //! Clear the bit at theIndex to false.
0071   void Clear(const uint32_t theIndex)
0072   {
0073     const size_t   aBlock = theIndex / THE_BITS_PER_BLOCK;
0074     const uint32_t aBit   = theIndex % THE_BITS_PER_BLOCK;
0075     myBlocks[aBlock] &= ~(BlockType(1) << aBit);
0076   }
0077 
0078   //! Return the value of the bit at theIndex.
0079   [[nodiscard]] bool Test(const uint32_t theIndex) const
0080   {
0081     const size_t   aBlock = theIndex / THE_BITS_PER_BLOCK;
0082     const uint32_t aBit   = theIndex % THE_BITS_PER_BLOCK;
0083     return (myBlocks[aBlock] & (BlockType(1) << aBit)) != 0;
0084   }
0085 
0086   //! Set all bits to true.
0087   void SetAll()
0088   {
0089     for (size_t i = 0; i < myBlocks.Size(); ++i)
0090     {
0091       myBlocks[i] = ~BlockType(0);
0092     }
0093     maskTailBits();
0094   }
0095 
0096   //! Clear all bits to false.
0097   void ClearAll()
0098   {
0099     for (size_t i = 0; i < myBlocks.Size(); ++i)
0100     {
0101       myBlocks[i] = 0;
0102     }
0103   }
0104 
0105   //! Return true if any bit is set.
0106   [[nodiscard]] bool HasAnyBitSet() const
0107   {
0108     for (size_t i = 0; i < myBlocks.Size(); ++i)
0109     {
0110       if (myBlocks[i] != 0)
0111       {
0112         return true;
0113       }
0114     }
0115     return false;
0116   }
0117 
0118   //! Return the number of blocks allocated.
0119   [[nodiscard]] size_t NbBlocks() const { return myBlocks.Size(); }
0120 
0121   //! Return the number of valid bits represented by this vector.
0122   [[nodiscard]] size_t BitCount() const { return myBitCount; }
0123 
0124   //! Return true if theIndex is inside the valid bit range.
0125   [[nodiscard]] bool IsValidIndex(const uint32_t theIndex) const { return theIndex < myBitCount; }
0126 
0127   //! Return the raw block array for direct iteration.
0128   [[nodiscard]] const BlockType* Blocks() const { return myBlocks.Data(); }
0129 
0130 private:
0131   void maskTailBits()
0132   {
0133     const uint32_t aTailBits = static_cast<uint32_t>(myBitCount % THE_BITS_PER_BLOCK);
0134     if (aTailBits == 0u || myBlocks.Size() == 0)
0135     {
0136       return;
0137     }
0138 
0139     const BlockType aTailMask = (BlockType(1) << aTailBits) - BlockType(1);
0140     myBlocks[myBlocks.Size() - 1] &= aTailMask;
0141   }
0142 
0143   NCollection_LinearVector<BlockType> myBlocks;
0144   size_t                              myBitCount = 0;
0145 };
0146 
0147 #endif // _BRepGraphInc_BitFlags_HeaderFile