CeresEngine 0.2.0
A game development framework
Loading...
Searching...
No Matches
BitView.hpp
Go to the documentation of this file.
1//
2// CeresEngine - A game development framework
3//
4// Created by Rogiel Sulzbach.
5// Copyright (c) 2018-2022 Rogiel Sulzbach. All rights reserved.
6//
7
8// Based on https://github.com/TheLartians/BitLens
9
10#pragma once
11
12#include <climits>
13#include <cstddef>
14#include <iterator>
15#include <type_traits>
16#include <utility>
17
18namespace CeresEngine {
19
20 template<class Word> struct WordSize { static constexpr size_t value = sizeof(Word) * CHAR_BIT; };
21
23 template<class Word> class BitReference {
24 private:
25 size_t offset;
26 Word& value;
27
28 public:
29 constexpr BitReference(Word& v, const size_t o) noexcept : offset(o), value(v) {
30 static_assert(std::is_integral<Word>::value && std::is_unsigned<Word>::value, "Only unsigned integer value types are supported");
31 }
32
33 constexpr BitReference(const BitReference&) noexcept = default;
35
37 value = (value & ~(Word(1) << offset)) | (Word(v) << offset);
38 return *this;
39 }
40
41 constexpr operator bool() const noexcept { return (value >> offset) & Word(1); }
42 BitReference& operator=(const BitReference& v) noexcept { return *this = bool(v); }
43 };
44
46 template<class Word> void swap(BitReference<Word>& a, BitReference<Word>& b) {
47 bool tmp = a;
48 a = b;
49 b = tmp;
50 }
51
52 template<class ContainerIterator> class BitIterator {
53 private:
54 using Word = typename std::remove_reference<decltype(*std::declval<ContainerIterator>())>::type;
55 static constexpr auto WORD_SIZE = WordSize<Word>::value;
57 size_t mIndex;
58
59 public:
60 using iterator_category = std::random_access_iterator_tag;
64
65 constexpr BitIterator(ContainerIterator i, const size_t o) noexcept : mIterator(i), mIndex(o) {}
66
67 BitIterator& operator++(int) noexcept {
68 BitIterator copy(*this);
69 mIndex++;
70 return copy;
71 }
72
74 ++mIndex;
75 return *this;
76 }
77
78 BitIterator& operator--(int) noexcept {
79 BitIterator copy(*this);
80 mIndex--;
81 return copy;
82 }
83
85 --mIndex;
86 return *this;
87 }
88
89 [[nodiscard]] BitIterator operator+(const int n) const noexcept { return BitIterator(mIterator, mIndex + n); }
90 [[nodiscard]] BitIterator operator-(const int n) const noexcept { return BitIterator(mIterator, mIndex - n); }
91 [[nodiscard]] size_t operator-(const BitIterator& other) const noexcept { return mIndex - other.mIndex; }
92
93 [[nodiscard]] constexpr bool operator!=(const BitIterator& other) const { return mIterator != other.mIterator || mIndex != other.mIndex; }
94 [[nodiscard]] constexpr bool operator==(const BitIterator& other) const { return mIterator == other.mIterator && mIndex == other.mIndex; }
95
99 };
100
101 template<class Container> class BitView {
102 private:
103 Container& mContainer;
104
105 public:
106 using Word = typename std::remove_reference<decltype(std::declval<Container>()[0])>::type;
107 static constexpr auto WORD_SIZE = WordSize<Word>::value;
108
109 constexpr BitView(Container& container) noexcept : mContainer(container) {}
110
113
116 void resize(size_t N, const bool v = false) noexcept(noexcept(mContainer.resize(0, 0))) {
117 Word offset = N % WORD_SIZE == 0 ? 0 : 1;
118 mContainer.resize(N / WORD_SIZE + offset, v ? ~0 : 0);
119 }
120
122 [[nodiscard]] constexpr BitReference<Word> operator[](size_t i) noexcept(noexcept(mContainer[0])) {
123 Word offset = i % WORD_SIZE;
124 return BitReference<Word>(mContainer[i / WORD_SIZE], offset);
125 }
126
128 [[nodiscard]] constexpr BitReference<const Word> operator[](size_t i) const noexcept(noexcept(mContainer[0])) {
129 Word offset = i % WORD_SIZE;
131 }
132
133 [[nodiscard]] constexpr auto begin() noexcept(noexcept(mContainer.begin())) { return BitIterator(mContainer.begin(), 0); }
134 [[nodiscard]] constexpr auto end() noexcept(noexcept(mContainer.begin())) { return BitIterator(mContainer.begin(), size()); }
135
136 [[nodiscard]] constexpr auto begin() const noexcept(noexcept(mContainer.begin())) { return BitIterator(mContainer.begin(), 0); }
137 [[nodiscard]] constexpr auto end() const noexcept(noexcept(mContainer.begin())) { return BitIterator(mContainer.begin(), size()); }
138
140 [[nodiscard]] Container& data() noexcept { return mContainer; }
141
143 [[nodiscard]] const Container& data() const noexcept { return mContainer; }
144 };
145
147 template<class C> class BitContainer : public BitView<C> {
148 private:
150
151 public:
153 constexpr BitContainer(const BitContainer& other) noexcept(noexcept(C(std::declval<const C&>())))
154 : mDataContainer(other.data()), BitView<C>(mDataContainer) {}
155 constexpr BitContainer(BitContainer&& other) noexcept(noexcept(C(std::declval<C&&>())))
156 : mDataContainer(std::move(other.data())), BitView<C>(mDataContainer) {}
157
158 template<typename... Args> BitContainer(Args&&... args) : mDataContainer(std::forward<Args...>(args...)), BitView<C>(mDataContainer) {}
159 };
160
161} // namespace CeresEngine
Creates a BitView that owns its data.
Definition BitView.hpp:147
C mDataContainer
Definition BitView.hpp:149
constexpr BitContainer(const BitContainer &other) noexcept(noexcept(C(std::declval< const C & >())))
Definition BitView.hpp:153
BitContainer(Args &&... args)
Definition BitView.hpp:158
constexpr BitContainer() noexcept(noexcept(C()))
Definition BitView.hpp:152
constexpr BitContainer(BitContainer &&other) noexcept(noexcept(C(std::declval< C && >())))
Definition BitView.hpp:155
Definition BitView.hpp:52
constexpr BitReference< Word > operator*() const noexcept
Definition BitView.hpp:96
BitReference< Word > value_type
Definition BitView.hpp:61
std::random_access_iterator_tag iterator_category
Definition BitView.hpp:60
BitIterator & operator--(int) noexcept
Definition BitView.hpp:78
BitIterator operator++() noexcept
Definition BitView.hpp:73
BitIterator operator-(const int n) const noexcept
Definition BitView.hpp:90
constexpr bool operator!=(const BitIterator &other) const
Definition BitView.hpp:93
size_t difference_type
Definition BitView.hpp:62
BitIterator & operator++(int) noexcept
Definition BitView.hpp:67
BitIterator operator+(const int n) const noexcept
Definition BitView.hpp:89
size_t operator-(const BitIterator &other) const noexcept
Definition BitView.hpp:91
BitIterator operator--() noexcept
Definition BitView.hpp:84
constexpr BitIterator(ContainerIterator i, const size_t o) noexcept
Definition BitView.hpp:65
ContainerIterator mIterator
Definition BitView.hpp:56
typename std::remove_reference< decltype(*std::declval< ContainerIterator >())>::type Word
Definition BitView.hpp:54
size_t mIndex
Definition BitView.hpp:57
static constexpr auto WORD_SIZE
Definition BitView.hpp:55
constexpr bool operator==(const BitIterator &other) const
Definition BitView.hpp:94
A reference for a single bit.
Definition BitView.hpp:23
constexpr BitReference(const BitReference &) noexcept=default
constexpr BitReference(Word &v, const size_t o) noexcept
Definition BitView.hpp:29
constexpr BitReference(BitReference &&) noexcept=default
Word & value
Definition BitView.hpp:26
BitReference & operator=(const BitReference &v) noexcept
Definition BitView.hpp:42
size_t offset
Definition BitView.hpp:25
Definition BitView.hpp:101
size_t size() const noexcept(noexcept(mContainer.size()))
Returns the number of bits that fit in the container.
Definition BitView.hpp:112
constexpr auto begin() noexcept(noexcept(mContainer.begin()))
Definition BitView.hpp:133
constexpr BitReference< Word > operator[](size_t i) noexcept(noexcept(mContainer[0]))
Returns a BitReference to the bit at position i.
Definition BitView.hpp:122
constexpr auto begin() const noexcept(noexcept(mContainer.begin()))
Definition BitView.hpp:136
constexpr BitView(Container &container) noexcept
Definition BitView.hpp:109
static constexpr auto WORD_SIZE
Definition BitView.hpp:107
typename std::remove_reference< decltype(std::declval< Container >()[0])>::type Word
Definition BitView.hpp:106
void resize(size_t N, const bool v=false) noexcept(noexcept(mContainer.resize(0, 0)))
Resizes the container to hold at least N bits.
Definition BitView.hpp:116
Container & data() noexcept
Get the underlying data container.
Definition BitView.hpp:140
constexpr auto end() const noexcept(noexcept(mContainer.begin()))
Definition BitView.hpp:137
constexpr BitReference< const Word > operator[](size_t i) const noexcept(noexcept(mContainer[0]))
Returns a BitReference to the bit at position i.
Definition BitView.hpp:128
const Container & data() const noexcept
Get the underlying data container.
Definition BitView.hpp:143
Container & mContainer
Definition BitView.hpp:103
constexpr auto end() noexcept(noexcept(mContainer.begin()))
Definition BitView.hpp:134
Definition Application.hpp:19
void swap(BitReference< Word > &a, BitReference< Word > &b)
Swaps only the referenced bit.
Definition BitView.hpp:46
void copy(const A &a, B &b, T &&t=T())
Copies values from one container to another.
Definition Iterator.hpp:564
constexpr size_t hash(const T &v)
Generates a hash for the provided type.
Definition Hash.hpp:25
Definition Span.hpp:668
Definition BitView.hpp:20
static constexpr size_t value
Definition BitView.hpp:20