fennec
Loading...
Searching...
No Matches
bytes.h
1// =====================================================================================================================
2// fennec, a free and open source game engine
3// Copyright © 2025 Medusa Slockbower
4//
5// This program is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program. If not, see <https://www.gnu.org/licenses/>.
17// =====================================================================================================================
18
19#ifndef FENNEC_MEMORY_BYTES_H
20#define FENNEC_MEMORY_BYTES_H
21
22#include <fennec/lang/assert.h>
23#include <fennec/lang/types.h>
24#include <fennec/lang/hashing.h>
25
26namespace fennec
27{
28
30using byte_t = uint8_t;
31
34struct byte_array {
35public:
36
39 constexpr byte_array()
40 : _carr(nullptr)
41 , _size(0)
42 , _const(true) {
43 }
44
49 constexpr byte_array(void* arr, size_t n)
50 : _arr(static_cast<byte_t*>(arr))
51 , _size(n)
52 , _const(false) {
53 }
54
59 constexpr byte_array(const void* arr, size_t n)
60 : _carr(static_cast<const byte_t*>(arr))
61 , _size(n)
62 , _const(true) {
63 }
64
69 template<typename T, size_t n>
70 constexpr byte_array(T (&arr)[n])
71 : byte_array(arr, n * sizeof(T)) {
72 }
73
78 template<typename T, size_t n>
79 constexpr byte_array(const T (&arr)[n])
80 : byte_array(arr, n * sizeof(T)) {
81 }
82
85 constexpr size_t size() const {
86 return _size;
87 }
88
93 constexpr byte_t& operator[](int i) {
94 assertd(not _const, "Attempted to Access Const-Qualified Memory as Non-Const");
95 assertd(i >= 0 && (size_t)i < _size, "Array Out of Bounds");
96 return _arr[i];
97 }
98
103 constexpr byte_t operator[](int i) const {
104 assertd(not _const, "Attempted to Access Const-Qualified Memory as Non-Const");
105 assertd(i >= 0 && (size_t)i < _size, "Array Out of Bounds");
106 return _carr[i];
107 }
108
113 template<typename T>
114 constexpr T* cast() {
115 void* temp = _arr;
116 return static_cast<T*>(temp);
117 }
118
123 template<typename T>
124 constexpr const T* cast() const {
125 const void* temp = _carr;
126 return static_cast<const T*>(temp);
127 }
128
129private:
130 union { // hack to allow both const qualified and non-const strings
131 byte_t* _arr;
132 const byte_t* _carr;
133 };
134 size_t _size;
135 bool _const;
136};
137
140template<>
142 size_t operator()(const byte_array& bytes) const {
143
144 // Murmur2
145 static constexpr uint64_t m = 0xc6a4a7935bd1e995;
146 static constexpr uint64_t s = 0xff51afd7ed558ccd;
147 static constexpr uint64_t r = 47;
148 const uint64_t n = bytes.size();
149
150 uint64_t h = s ^ (n * m);
151 const uint64_t* x = bytes.cast<uint64_t>();
152 const uint64_t* y = x + (n / sizeof(uint64_t));
153
154 while (x != y) {
155 uint64_t k = *x++;
156
157 k *= m;
158 k ^= k >> r;
159 k *= m;
160
161 h ^= k;
162 h *= m;
163 }
164
165 const uint8_t* b = (const uint8_t*)x;
166 switch (n & 7) {
167 case 7: h ^= uint64_t(b[6]) << 48; __attribute__((fallthrough));
168 case 6: h ^= uint64_t(b[5]) << 40; __attribute__((fallthrough));
169 case 5: h ^= uint64_t(b[4]) << 32; __attribute__((fallthrough));
170 case 4: h ^= uint64_t(b[3]) << 24; __attribute__((fallthrough));
171 case 3: h ^= uint64_t(b[2]) << 16; __attribute__((fallthrough));
172 case 2: h ^= uint64_t(b[1]) << 8; __attribute__((fallthrough));
173 case 1: h ^= uint64_t(b[0]);
174 h *= m;
175 default:
176 break;
177 }
178
179 h ^= h >> r;
180 h *= m;
181 h ^= h >> r;
182
183 return h;
184 }
185};
186
187}
188
189#endif // FENNEC_MEMORY_BYTES_H
Assertions
constexpr genType y()
Definition constants.h:672
container for handling byte arrays
Definition bytes.h:34
constexpr byte_array(void *arr, size_t n)
Buffer Constructor.
Definition bytes.h:49
constexpr T * cast()
Cast Function.
Definition bytes.h:114
constexpr byte_t operator[](int i) const
Const Array Access Operator.
Definition bytes.h:103
constexpr const T * cast() const
Const Cast Function.
Definition bytes.h:124
constexpr byte_array(const T(&arr)[n])
Const Buffer Constructor.
Definition bytes.h:79
constexpr byte_t & operator[](int i)
Array Access Operator.
Definition bytes.h:93
constexpr byte_array(const void *arr, size_t n)
Const Buffer Constructor.
Definition bytes.h:59
constexpr byte_array()
Default Constructor.
Definition bytes.h:39
constexpr size_t size() const
Definition bytes.h:85
constexpr byte_array(T(&arr)[n])
Buffer Constructor.
Definition bytes.h:70
Struct for hashing types, there is no default hashing function.
Definition hashing.h:32
Types
::uint64_t uint64_t
Unsigned 64-bit integer.
Definition types.h:275
unsigned char byte_t
A type capable of holding a single byte.
Definition types.h:216
::uint8_t uint8_t
Unsigned 8-bit integer.
Definition types.h:272