-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathcompile_time_utilities.hpp
More file actions
91 lines (73 loc) · 1.92 KB
/
compile_time_utilities.hpp
File metadata and controls
91 lines (73 loc) · 1.92 KB
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
#pragma once
#include <limits.h>
#include <cstddef>
#include <type_traits>
namespace ctu {
namespace _detail {
template<typename... types>
constexpr size_t _size_of_impl() {
size_t result = 0;
constexpr size_t sizes[]{ sizeof(types)... };
for (auto size : sizes) {
result += size;
}
return result;
}
template<>
constexpr size_t _size_of_impl<>() {
return 0;
}
} // namespace detail
template<typename... types>
constexpr const size_t size_of = _detail::_size_of_impl<types...>();
template<typename... types>
constexpr const size_t bits_of = size_of<types...> * CHAR_BIT;
namespace _detail {
template<typename type>
struct _bit_mask_all {
static constexpr type value = type(~type(0));
};
template<typename type, int width>
struct _bit_mask_partial {
static constexpr type value = type((type(1) << width) - 1);
};
template<typename type, int width>
struct _bit_mask_error {
static_assert(width <= ctu::bits_of<type>);
static_assert(width >= 0);
};
} // namespace detail
template<typename type, int width>
constexpr type bit_mask_v = std::conditional_t<
(width <= bits_of<type>) && (width >= 0),
std::conditional_t<
width == bits_of<type>,
_detail::_bit_mask_all<type>,
_detail::_bit_mask_partial<type, width>
>,
_detail::_bit_mask_error<type, width>
>::value;
template<typename type>
constexpr type bit_mask(int width) {
return type((type(1) << width) - 1);
}
template<typename type>
constexpr int log2(type val) {
if (val < 0) {
return int(bits_of<type> - 1);
} else if (val == 0) {
return int(bits_of<type>);
} else if (val == 1) {
return 0;
} else {
return 1 + log2(val >> 1);
}
}
template<auto val>
constexpr int log2_v = log2(val);
template<typename type>
constexpr type round_up_bits(type val, int bits) {
const type mask = bit_mask<type>(bits);
return (val + mask) & ~mask;
}
} // namespace ctu