76 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			76 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
 | |
| #pragma once
 | |
| 
 | |
| #if !defined(MIJIN_UTIL_BITARRAY_HPP_INCLUDED)
 | |
| #define MIJIN_UTIL_BITARRAY_HPP_INCLUDED 1
 | |
| 
 | |
| #include <array>
 | |
| #include <atomic>
 | |
| #include <cassert>
 | |
| #include <cstddef>
 | |
| 
 | |
| namespace mijin
 | |
| {
 | |
| 
 | |
| //
 | |
| // public defines
 | |
| //
 | |
| 
 | |
| //
 | |
| // public constants
 | |
| //
 | |
| 
 | |
| //
 | |
| // public types
 | |
| //
 | |
| 
 | |
| 
 | |
| template<std::size_t numBits, bool threadSafe = false>
 | |
| struct BitArray
 | |
| {
 | |
| private:
 | |
|     using byte_type = std::conditional_t<threadSafe, std::atomic_uint8_t, std::uint8_t>;
 | |
|     std::array<byte_type, (numBits + 7) / 8> bytes;
 | |
| public:
 | |
|     [[nodiscard]] bool get(std::size_t index) const {
 | |
|         assert(index < numBits);
 | |
|         return (bytes[index / 8] & (1 << (index % 8)));
 | |
|     }
 | |
|     void set(std::size_t index, bool value)
 | |
|     {
 | |
|         byte_type& byte = bytes[index / 8];
 | |
|         const std::uint8_t mask = (1 << (index % 8));
 | |
|         if constexpr (threadSafe)
 | |
|         {
 | |
|             std::uint8_t oldByte = byte.load(std::memory_order_relaxed);
 | |
|             std::uint8_t newByte = 0;
 | |
|             do
 | |
|             {
 | |
|                 if (value) {
 | |
|                     newByte = oldByte | mask;
 | |
|                 }
 | |
|                 else {
 | |
|                     newByte = oldByte & ~mask;
 | |
|                 }
 | |
|             } while (!byte.compare_exchange_weak(oldByte, newByte, std::memory_order_release, std::memory_order_relaxed));
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             if (value) {
 | |
|                 byte |= mask;
 | |
|             }
 | |
|             else {
 | |
|                 byte &= ~mask;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| };
 | |
| 
 | |
| //
 | |
| // public functions
 | |
| //
 | |
| 
 | |
| } // namespace mijin
 | |
| 
 | |
| #endif // !defined(MIJIN_UTIL_BITARRAY_HPP_INCLUDED)
 |