// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp #pragma once #ifndef NAZARA_BITSET_HPP #define NAZARA_BITSET_HPP #include #include #include #include #include namespace Nz { class AbstractHash; template> class Bitset { static_assert(std::is_integral::value && std::is_unsigned::value, "Block must be a unsigned integral type"); public: class Bit; Bitset(); explicit Bitset(std::size_t bitCount, bool val); explicit Bitset(const char* bits); Bitset(const char* bits, std::size_t bitCount); Bitset(const Bitset& bitset) = default; explicit Bitset(const String& bits); template Bitset(T value); Bitset(Bitset&& bitset) noexcept = default; ~Bitset() noexcept = default; void Clear() noexcept; std::size_t Count() const; void Flip(); std::size_t FindFirst() const; std::size_t FindNext(std::size_t bit) const; Block GetBlock(std::size_t i) const; std::size_t GetBlockCount() const; std::size_t GetCapacity() const; std::size_t GetSize() const; void PerformsAND(const Bitset& a, const Bitset& b); void PerformsNOT(const Bitset& a); void PerformsOR(const Bitset& a, const Bitset& b); void PerformsXOR(const Bitset& a, const Bitset& b); bool Intersects(const Bitset& bitset) const; void Reserve(std::size_t bitCount); void Resize(std::size_t bitCount, bool defaultVal = false); void Reset(); void Reset(std::size_t bit); void Set(bool val = true); void Set(std::size_t bit, bool val = true); void SetBlock(std::size_t i, Block block); void Swap(Bitset& bitset); bool Test(std::size_t bit) const; bool TestAll() const; bool TestAny() const; bool TestNone() const; template T To() const; String ToString() const; void UnboundedReset(std::size_t bit); void UnboundedSet(std::size_t bit, bool val = true); bool UnboundedTest(std::size_t bit) const; Bit operator[](int index); bool operator[](int index) const; Bitset operator~() const; Bitset& operator=(const Bitset& bitset) = default; Bitset& operator=(const String& bits); template Bitset& operator=(T value); Bitset& operator=(Bitset&& bitset) noexcept = default; Bitset& operator&=(const Bitset& bitset); Bitset& operator|=(const Bitset& bitset); Bitset& operator^=(const Bitset& bitset); static constexpr Block fullBitMask = std::numeric_limits::max(); static constexpr std::size_t bitsPerBlock = std::numeric_limits::digits; static constexpr std::size_t npos = std::numeric_limits::max(); private: std::size_t FindFirstFrom(std::size_t blockIndex) const; Block GetLastBlockMask() const; void ResetExtraBits(); static std::size_t ComputeBlockCount(std::size_t bitCount); static std::size_t GetBitIndex(std::size_t bit); static std::size_t GetBlockIndex(std::size_t bit); std::vector m_blocks; std::size_t m_bitCount; }; template class Bitset::Bit { friend Bitset; public: Bit(const Bit& bit) = default; Bit& Flip(); Bit& Reset(); Bit& Set(bool val = true); bool Test() const; template void* operator&() const; operator bool() const; Bit& operator=(bool val); Bit& operator=(const Bit& bit); Bit& operator|=(bool val); Bit& operator&=(bool val); Bit& operator^=(bool val); Bit& operator-=(bool val); private: Bit(Block& block, Block mask) : m_block(block), m_mask(mask) { } Block& m_block; Block m_mask; }; template bool operator==(const Bitset& lhs, const Nz::Bitset& rhs); template bool operator!=(const Bitset& lhs, const Nz::Bitset& rhs); template bool operator<(const Bitset& lhs, const Nz::Bitset& rhs); template bool operator<=(const Bitset& lhs, const Nz::Bitset& rhs); template bool operator>(const Bitset& lhs, const Nz::Bitset& rhs); template bool operator>=(const Bitset& lhs, const Nz::Bitset& rhs); template Bitset operator&(const Bitset& lhs, const Bitset& rhs); template Bitset operator|(const Bitset& lhs, const Bitset& rhs); template Bitset operator^(const Bitset& lhs, const Bitset& rhs); } namespace std { template void swap(Nz::Bitset& lhs, Nz::Bitset& rhs); } #include #endif // NAZARA_BITSET_HPP