Nazara Engine  0.4
A fast, complete, cross-platform API designed for game development
Bitset.hpp
1 // Copyright (C) 2017 Jérôme Leclercq
2 // This file is part of the "Nazara Engine - Core module"
3 // For conditions of distribution and use, see copyright notice in Config.hpp
4 
5 #pragma once
6 
7 #ifndef NAZARA_BITSET_HPP
8 #define NAZARA_BITSET_HPP
9 
10 #include <Nazara/Prerequesites.hpp>
11 #include <Nazara/Core/Algorithm.hpp>
12 #include <Nazara/Core/String.hpp>
13 #include <limits>
14 #include <memory>
15 #include <type_traits>
16 
17 namespace Nz
18 {
19  class AbstractHash;
20 
21  template<typename Block = UInt32, class Allocator = std::allocator<Block>>
22  class Bitset
23  {
24  static_assert(std::is_integral<Block>::value && std::is_unsigned<Block>::value, "Block must be a unsigned integral type");
25 
26  public:
27  class Bit;
28  using PointerSequence = std::pair<const void*, std::size_t>; //< Start pointer, bit offset
29 
30  Bitset();
31  explicit Bitset(std::size_t bitCount, bool val);
32  explicit Bitset(const char* bits);
33  Bitset(const char* bits, std::size_t bitCount);
34  Bitset(const Bitset& bitset) = default;
35  explicit Bitset(const String& bits);
36  template<typename T> Bitset(T value);
37  Bitset(Bitset&& bitset) noexcept = default;
38  ~Bitset() noexcept = default;
39 
40  template<typename T> void AppendBits(T bits, std::size_t bitCount);
41 
42  void Clear() noexcept;
43  std::size_t Count() const;
44  void Flip();
45 
46  std::size_t FindFirst() const;
47  std::size_t FindNext(std::size_t bit) const;
48 
49  Block GetBlock(std::size_t i) const;
50  std::size_t GetBlockCount() const;
51  std::size_t GetCapacity() const;
52  std::size_t GetSize() const;
53 
54  PointerSequence Read(const void* ptr, std::size_t bitCount);
55  PointerSequence Read(const PointerSequence& sequence, std::size_t bitCount);
56 
57  void PerformsAND(const Bitset& a, const Bitset& b);
58  void PerformsNOT(const Bitset& a);
59  void PerformsOR(const Bitset& a, const Bitset& b);
60  void PerformsXOR(const Bitset& a, const Bitset& b);
61 
62  bool Intersects(const Bitset& bitset) const;
63 
64  void Reserve(std::size_t bitCount);
65  void Resize(std::size_t bitCount, bool defaultVal = false);
66 
67  void Reset();
68  void Reset(std::size_t bit);
69 
70  void Reverse();
71 
72  void Set(bool val = true);
73  void Set(std::size_t bit, bool val = true);
74  void SetBlock(std::size_t i, Block block);
75 
76  void ShiftLeft(std::size_t pos);
77  void ShiftRight(std::size_t pos);
78 
79  void Swap(Bitset& bitset);
80 
81  bool Test(std::size_t bit) const;
82  bool TestAll() const;
83  bool TestAny() const;
84  bool TestNone() const;
85 
86  template<typename T> T To() const;
87  String ToString() const;
88 
89  void UnboundedReset(std::size_t bit);
90  void UnboundedSet(std::size_t bit, bool val = true);
91  bool UnboundedTest(std::size_t bit) const;
92 
93  Bit operator[](std::size_t index);
94  bool operator[](std::size_t index) const;
95 
96  Bitset operator~() const;
97 
98  Bitset& operator=(const Bitset& bitset) = default;
99  Bitset& operator=(const String& bits);
100  template<typename T> Bitset& operator=(T value);
101  Bitset& operator=(Bitset&& bitset) noexcept = default;
102 
103  Bitset operator<<(std::size_t pos) const;
104  Bitset& operator<<=(std::size_t pos);
105 
106  Bitset operator>>(std::size_t pos) const;
107  Bitset& operator>>=(std::size_t pos);
108 
109  Bitset& operator&=(const Bitset& bitset);
110  Bitset& operator|=(const Bitset& bitset);
111  Bitset& operator^=(const Bitset& bitset);
112 
113  static constexpr Block fullBitMask = std::numeric_limits<Block>::max();
114  static constexpr std::size_t bitsPerBlock = BitCount<Block>();
115  static constexpr std::size_t npos = std::numeric_limits<std::size_t>::max();
116 
117  static Bitset FromPointer(const void* ptr, std::size_t bitCount, PointerSequence* sequence = nullptr);
118 
119  private:
120  std::size_t FindFirstFrom(std::size_t blockIndex) const;
121  Block GetLastBlockMask() const;
122  void ResetExtraBits();
123 
124  static std::size_t ComputeBlockCount(std::size_t bitCount);
125  static std::size_t GetBitIndex(std::size_t bit);
126  static std::size_t GetBlockIndex(std::size_t bit);
127 
128  std::vector<Block, Allocator> m_blocks;
129  std::size_t m_bitCount;
130  };
131 
132  template<typename Block, class Allocator>
133  class Bitset<Block, Allocator>::Bit
134  {
136 
137  public:
138  Bit(const Bit& bit) = default;
139 
140  Bit& Flip();
141  Bit& Reset();
142  Bit& Set(bool val = true);
143  bool Test() const;
144 
145  template<bool BadCall = true>
146  void* operator&() const;
147 
148  explicit operator bool() const;
149  Bit& operator=(bool val);
150  Bit& operator=(const Bit& bit);
151 
152  Bit& operator|=(bool val);
153  Bit& operator&=(bool val);
154  Bit& operator^=(bool val);
155  Bit& operator-=(bool val);
156 
157  private:
158  Bit(Block& block, Block mask) :
159  m_block(block),
160  m_mask(mask)
161  {
162  }
163 
164  Block& m_block;
165  Block m_mask;
166  };
167 
168  template<typename Block, class Allocator>
169  std::ostream& operator<<(std::ostream& out, const Bitset<Block, Allocator>& bitset);
170 
171  template<typename Block, class Allocator>
173 
174  template<typename Block, class Allocator>
176 
177  template<typename Block, class Allocator>
178  bool operator<(const Bitset<Block, Allocator>& lhs, const Nz::Bitset<Block, Allocator>& rhs);
179 
180  template<typename Block, class Allocator>
181  bool operator<=(const Bitset<Block, Allocator>& lhs, const Nz::Bitset<Block, Allocator>& rhs);
182 
183  template<typename Block, class Allocator>
185 
186  template<typename Block, class Allocator>
188 
189  template<typename Block, class Allocator>
191 
192  template<typename Block, class Allocator>
194 
195  template<typename Block, class Allocator>
197 }
198 
199 namespace std
200 {
201  template<typename Block, class Allocator>
203 }
204 
205 #include <Nazara/Core/Bitset.inl>
206 
207 #endif // NAZARA_BITSET_HPP
Bitset & operator^=(const Bitset &bitset)
Performs an "XOR" with another bitset.
Definition: Bitset.inl:1135
void PerformsXOR(const Bitset &a, const Bitset &b)
Performs the "XOR" operator between two bitsets.
Definition: Bitset.inl:485
void Resize(std::size_t bitCount, bool defaultVal=false)
Resizes the bitset to the size of bitCount.
Definition: Bitset.inl:546
TODO: Inherit SoundEmitter from Node.
Definition: Algorithm.hpp:12
Bitset< Block, Allocator > operator^(const Bitset< Block, Allocator > &lhs, const Bitset< Block, Allocator > &rhs)
Performs the operator "XOR" between two bitsets.
Definition: Bitset.inl:1628
void Flip()
Flips each bit of the bitset.
Definition: Bitset.inl:227
bool operator>(const Bitset< Block, Allocator > &lhs, const Nz::Bitset< Block, Allocator > &rhs)
Compares two bitsets.
Definition: Bitset.inl:1566
static Bitset FromPointer(const void *ptr, std::size_t bitCount, PointerSequence *sequence=nullptr)
Builds a bitset from a byte sequence.
Definition: Bitset.inl:1159
Block GetBlock(std::size_t i) const
Gets the ith block.
Definition: Bitset.inl:290
Bitset operator>>(std::size_t pos) const
Shift all the bits toward the right.
Definition: Bitset.inl:1072
void Reserve(std::size_t bitCount)
Reserves enough blocks to contain bitCount bits.
Definition: Bitset.inl:533
Core class that represents a string.
Definition: String.hpp:22
STL namespace.
T To() const
Converts the bitset to template type.
Definition: Bitset.inl:865
bool operator!=(const Bitset< Block, Allocator > &lhs, const Nz::Bitset< Block, Allocator > &rhs)
Compares two bitsets.
Definition: Bitset.inl:1503
Bitset< Block, Allocator > operator &(const Bitset< Block, Allocator > &lhs, const Bitset< Block, Allocator > &rhs)
Performs the operator "AND" between two bitsets.
Definition: Bitset.inl:1594
std::size_t GetCapacity() const
Gets the capacity of the bitset.
Definition: Bitset.inl:314
void PerformsAND(const Bitset &a, const Bitset &b)
Performs the "AND" operator between two bitsets.
Definition: Bitset.inl:410
Bitset()
Constructs a Bitset object by default.
Definition: Bitset.inl:33
std::size_t GetBlockCount() const
Gets the number of blocks.
Definition: Bitset.inl:303
void Clear() noexcept
Clears the content of the bitset.
Definition: Bitset.inl:197
void UnboundedSet(std::size_t bit, bool val=true)
Sets the bit at the index.
Definition: Bitset.inl:925
Bitset operator~() const
Negates the bitset.
Definition: Bitset.inl:983
void Swap(Bitset &bitset)
Swaps the two bitsets.
Definition: Bitset.inl:779
Bitset & operator>>=(std::size_t pos)
Shift all the bits toward the right.
Definition: Bitset.inl:1090
void Reverse()
Reverse the order of bits in a bitset.
Definition: Bitset.inl:591
bool TestAll() const
Tests each block.
Definition: Bitset.inl:810
bool Intersects(const Bitset &bitset) const
Checks if bitsets have one block in common.
Definition: Bitset.inl:511
bool UnboundedTest(std::size_t bit) const
Tests the ith bit.
Definition: Bitset.inl:947
Bitset< Block, Allocator > operator|(const Bitset< Block, Allocator > &lhs, const Bitset< Block, Allocator > &rhs)
Performs the operator "OR" between two bitsets.
Definition: Bitset.inl:1611
void SetBlock(std::size_t i, Block block)
Set the ith block.
Definition: Bitset.inl:656
Bitset operator<<(std::size_t pos) const
Shift all the bits toward the left.
Definition: Bitset.inl:1035
std::size_t GetSize() const
Gets the number of bits.
Definition: Bitset.inl:325
void AppendBits(T bits, std::size_t bitCount)
Appends bits to the bitset.
Definition: Bitset.inl:154
void PerformsNOT(const Bitset &a)
Performs the "NOT" operator of the bitset.
Definition: Bitset.inl:435
Bitset & operator|=(const Bitset &bitset)
Performs an "OR" with another bitset.
Definition: Bitset.inl:1120
void PerformsOR(const Bitset &a, const Bitset &b)
Performs the "OR" operator between two bitsets.
Definition: Bitset.inl:456
bool Test(std::size_t bit) const
Tests the ith bit.
Definition: Bitset.inl:797
std::size_t FindNext(std::size_t bit) const
Finds the next enabled in the bitset.
Definition: Bitset.inl:256
void Reset()
Resets the bitset to zero bits.
Definition: Bitset.inl:566
void UnboundedReset(std::size_t bit)
Resets the bit at the index.
Definition: Bitset.inl:908
bool TestNone() const
Tests if one bit is not set.
Definition: Bitset.inl:851
String ToString() const
Gives a string representation.
Definition: Bitset.inl:884
std::size_t FindFirst() const
Finds the first bit set to one in the bitset.
Definition: Bitset.inl:241
Core class that represents a set of bits.
Definition: Bitset.hpp:22
std::size_t Count() const
Counts the number of bits set to 1.
Definition: Bitset.inl:209
Bit operator[](std::size_t index)
Gets the ith bit.
Definition: Bitset.inl:961
Bitset & operator<<=(std::size_t pos)
Shift all the bits toward the left.
Definition: Bitset.inl:1053
void ShiftLeft(std::size_t pos)
Shift all the bits toward the left.
Definition: Bitset.inl:675
void ShiftRight(std::size_t pos)
Shift all the bits toward the right.
Definition: Bitset.inl:729
void Set(bool val=true)
Sets the bitset to val.
Definition: Bitset.inl:616
bool operator==(const Bitset< Block, Allocator > &lhs, const Nz::Bitset< Block, Allocator > &rhs)
Compares two bitsets.
Definition: Bitset.inl:1469
bool operator>=(const Bitset< Block, Allocator > &lhs, const Nz::Bitset< Block, Allocator > &rhs)
Compares two bitsets.
Definition: Bitset.inl:1580
PointerSequence Read(const void *ptr, std::size_t bitCount)
Read a byte sequence into a bitset.
Definition: Bitset.inl:346
bool TestAny() const
Tests if one bit is set.
Definition: Bitset.inl:831