yfast 0.6.1
Loading...
Searching...
No Matches
aligned.h
1#ifndef _YFAST_UTILS_ALIGNED_H
2#define _YFAST_UTILS_ALIGNED_H
3
4#include <cstdint>
5
6namespace yfast::utils {
7
8template <typename T>
9struct align_traits;
10
11template <>
12struct align_traits<void> {
13 static constexpr std::size_t ptr_alignment = 1;
14};
15
16template <typename T>
18 static constexpr auto ptr_alignment = alignof(T);
19};
20
21template <unsigned int N, typename T = void>
22struct aligned_ptr {
23 static_assert(align_traits<T>::ptr_alignment % (1 << N) == 0, "Pointer alignment error");
24
25 static constexpr auto Bits = N;
26
27 static constexpr std::uintptr_t BIT_MASK = (1 << N) - 1;
28 static constexpr std::uintptr_t PTR_MASK = ~BIT_MASK;
29
30 std::uintptr_t value;
31
32 aligned_ptr(std::uintptr_t value): value(value) {}
33
34 explicit aligned_ptr(T* ptr = nullptr): value(reinterpret_cast<std::uintptr_t>(ptr)) {}
35
36 template <typename... Args>
37 explicit aligned_ptr(T* ptr, Args... args): value(reinterpret_cast<std::uintptr_t>(ptr)) {
38 static_assert(sizeof...(Args) == N, "Arguments mismatch");
39 const bool bits[] = { static_cast<bool>(args)... };
40 for (unsigned int n = 0; n < N; ++n) {
41 if (bits[n]) {
42 set_bit(n);
43 }
44 }
45 }
46
47 T* get_ptr() const { return reinterpret_cast<T*>(value & PTR_MASK); }
48 [[nodiscard]] bool get_bit(unsigned int n) const { return value & (1 << n); }
49
50 void set_ptr(T* ptr) { value = reinterpret_cast<std::uintptr_t>(ptr) | (value & BIT_MASK); }
51 void set_bit(unsigned int n, bool bit) {
52 const std::uintptr_t mask = 1 << n;
53 if (bit) {
54 value |= mask;
55 }
56 else {
57 value &= ~mask;
58 }
59 }
60 void set_bit(unsigned int n) {
61 const std::uintptr_t mask = 1 << n;
62 value |= mask;
63 }
64 void clear_bit(unsigned int n) {
65 const std::uintptr_t mask = 1 << n;
66 value &= ~mask;
67 }
68};
69
70}
71
72#endif
Definition aligned.h:17