1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
|
#pragma once
#include <nall/memory.hpp>
namespace nall {
struct bitvector {
bitvector() = default;
bitvector(uint size) { resize(size); }
bitvector(const bitvector& source) { operator=(source); }
bitvector(bitvector&& source) { operator=(move(source)); }
~bitvector() { reset(); }
auto operator=(const bitvector& source) -> bitvector& {
bits = source.bits;
pool = (uint8_t*)memory::resize(pool, bytes());
memory::copy(pool, source.pool, bytes());
return *this;
}
auto operator=(bitvector&& source) -> bitvector& {
pool = source.pool;
bits = source.bits;
source.pool = nullptr;
source.bits = 0;
return *this;
}
explicit operator bool() const { return bits > 0; }
auto empty() const -> bool { return bits == 0; }
auto size() const -> uint { return bits; }
auto bytes() const -> uint { return (bits + 7) / 8; }
auto data() -> uint8_t* { return pool; }
auto data() const -> const uint8_t* { return pool; }
auto reset() -> void {
if(pool) free(pool);
pool = nullptr;
bits = 0;
}
auto resize(uint size) -> void {
uint from = bits;
bits = size;
for(uint n = size; n < from; n++) clear(n); //on reduce
pool = (uint8_t*)memory::resize(pool, bytes());
for(uint n = from; n < size; n++) clear(n); //on expand
}
auto get(uint position) const -> bool {
return pool[position >> 3] & (0x80 >> (position & 7));
}
auto clear() -> void {
memory::fill(pool, bytes(), 0x00);
}
auto set() -> void {
memory::fill(pool, bytes(), 0xff);
for(uint n = bits; n < bytes() * 8; n++) clear(n);
}
auto clear(uint position) -> void {
pool[position >> 3] &= ~(0x80 >> (position & 7));
}
auto set(uint position) -> void {
pool[position >> 3] |= (0x80 >> (position & 7));
}
auto invert(uint position) -> void {
get(position) ? clear(position) : set(position);
}
auto set(uint position, bool value) -> void {
value ? set(position) : clear(position);
}
struct reference {
reference(bitvector& self, uint position) : self(self), position(position) {}
operator bool() const { return self.get(position); }
auto operator=(bool value) -> reference& { self.set(position, value); return *this; }
protected:
bitvector& self;
uint position;
};
auto operator[](uint position) -> reference {
return reference(*this, position);
}
auto operator[](uint position) const -> bool {
return get(position);
}
struct iterator {
iterator(bitvector& self, uint position) : self(self), position(position) {}
auto operator!=(const iterator& source) const -> bool { return position != source.position; }
auto operator++() -> iterator& { position++; return *this; }
auto operator*() -> reference { return self.operator[](position); }
protected:
bitvector& self;
uint position;
};
auto begin() -> iterator { return iterator(*this, 0); }
auto end() -> iterator { return iterator(*this, bits); }
protected:
uint8_t* pool = nullptr;
uint bits = 0;
};
}
|