38namespace BitFieldInternal {
43template <IntegralLike T>
45 static constexpr unsigned size =
sizeof(T) * 8;
50 static constexpr unsigned size = 1;
53template <
typename... T>
55 static constexpr unsigned size() {
return (sizeInBits() + 7) / 8; }
58 static constexpr unsigned sizeInBits() {
return recSize<0, T...>(); }
59 template <
unsigned index>
60 static constexpr unsigned recSize() {
63 template <
unsigned index,
typename One,
typename... Rest>
64 static constexpr unsigned recSize() {
65 return One::Width + recSize<index + 1, Rest...>();
69template <
typename Target,
typename... T>
71 static constexpr unsigned offset() {
return recOffset<0, T...>(); }
74 template <
unsigned index>
75 static constexpr unsigned recOffset() {
78 template <
unsigned index,
typename One,
typename... Rest>
79 static constexpr unsigned recOffset() {
80 if constexpr (std::is_same_v<Target, One>) {
83 return recOffset<index + 1, Rest...>() + One::Width;
88template <std::
integral T, std::
integral U = T>
89using SignedType =
typename std::conditional_t<std::is_signed_v<T>, std::make_signed_t<U>, std::make_unsigned_t<U>>;
91template <
unsigned span>
94 typename std::conditional_t<span <= 16, uint16_t, typename std::conditional_t<span <= 32, uint32_t, void>>>;
96template <
unsigned span, std::
integral T>
99template <
unsigned Offset,
unsigned W
idth,
unsigned storageSize, std::
integral T>
101 static constexpr unsigned offset = Offset;
102 static constexpr unsigned width = Width;
112 static_assert(
bytesCount <= 4,
"Type too large");
113 static_assert(
width > 0,
"Width must be greater than 0");
114 static_assert(
width <= 32,
"Width must be less than or equal to 32");
115 static_assert(
offset +
width <= storageSize * 8,
"Offset + Width must be less than or equal to storage size");
129template <BitFieldInternal::IntegralLike T, unsigned width = BitFieldInternal::DefaultBitSize<T>::size>
134 std::conditional_t<std::is_enum_v<T>,
135 std::underlying_type_t<std::conditional_t<std::is_enum_v<T>, T, BitFieldInternal::Dummy>>,
154template <
typename... T>
156 template <
typename Field>
157 constexpr Field::Type
get()
const {
159 auto ret =
get<offset, Field::Width,
161 return static_cast<Field::Type
>(
ret);
163 template <
typename Field>
164 constexpr void set(Field::Type v_) {
166 auto v =
static_cast<Field::Underlying
>(v_);
167 set<offset, Field::Width,
171 for (
unsigned i = 0; i <
sizeof(storage); i++) {
177 template <
unsigned offset,
unsigned w
idth, std::
integral U>
178 constexpr U
get()
const {
180 if constexpr (helper::isAlignedAndSafe) {
181 return reinterpret_cast<const U*
>(storage)[helper::firstByteOffset /
sizeof(U)] >> helper::shift &
184 return (loadUnaligned<U, helper::bytesCount>(storage + helper::firstByteOffset) >> helper::shift) &
189 template <
unsigned offset,
unsigned w
idth, std::
integral U>
190 constexpr void set(U v) {
191 using helper = BitFieldInternal::BitFieldHelper<offset,
width,
sizeof(storage), U>;
192 if constexpr (helper::fullBytes) {
193 if constexpr (helper::bytesCount == 1) {
194 storage[helper::firstByteOffset] =
static_cast<uint8_t
>(v);
195 }
else if constexpr (helper::bytesCount == 2) {
196 if constexpr (helper::isAlignedAndSafe) {
197 *
reinterpret_cast<U*
>(storage + helper::firstByteOffset) = v;
199 storeUnaligned<U>(storage + helper::firstByteOffset, v);
201 }
else if constexpr (helper::bytesCount == 3) {
202 if constexpr ((helper::firstByteOffset % 2) == 0) {
203 *
reinterpret_cast<uint16_t*
>(storage + helper::firstByteOffset) =
static_cast<uint16_t
>(v);
204 storage[helper::firstByteOffset + 2] =
static_cast<uint8_t
>(v >> 16);
206 storage[helper::firstByteOffset] =
static_cast<uint8_t
>(v);
207 *
reinterpret_cast<uint16_t*
>(storage + helper::firstByteOffset + 1) =
static_cast<uint16_t
>(v >> 8);
209 }
else if constexpr (helper::bytesCount == 4) {
210 if constexpr (helper::isAlignedAndSafe) {
211 *
reinterpret_cast<U*
>(storage + helper::firstByteOffset) = v;
213 storeUnaligned<U>(storage + helper::firstByteOffset, v);
216 }
else if constexpr (helper::isAlignedAndSafe) {
217 U*
ptr =
reinterpret_cast<U*
>(storage);
218 ptr[helper::firstByteOffset /
sizeof(U)] &= ~(helper::mask << helper::shift);
219 ptr[helper::firstByteOffset /
sizeof(U)] |= (v & helper::mask) << helper::shift;
221 U span = loadUnaligned<U, helper::bytesCount>(storage + helper::firstByteOffset);
222 span &= ~(helper::mask << helper::shift);
223 span |= (v & helper::mask) << helper::shift;
224 storeUnaligned<U, helper::bytesCount>(storage + helper::firstByteOffset, span);
Definition bitfield.hh:41
volatile uint32_t * ptr
Definition cop0.c:80
typename std::conditional_t< span<=8, uint8_t, typename std::conditional_t< span<=16, uint16_t, typename std::conditional_t< span<=32, uint32_t, void > > > StorageType
Definition bitfield.hh:94
SignedType< T, StorageType< span > > SignedStorageType
Definition bitfield.hh:97
typename std::conditional_t< std::is_signed_v< T >, std::make_signed_t< U >, std::make_unsigned_t< U > > SignedType
Definition bitfield.hh:89
Definition bitfield.hh:36
Definition bitfield.hh:100
static constexpr bool fullBytes
Definition bitfield.hh:110
static constexpr unsigned firstByteOffset
Definition bitfield.hh:103
static constexpr bool isAlignedAndSafe
Definition bitfield.hh:108
static constexpr unsigned shift
Definition bitfield.hh:106
static constexpr unsigned lastByteOffset
Definition bitfield.hh:104
static constexpr unsigned width
Definition bitfield.hh:102
static constexpr unsigned offset
Definition bitfield.hh:101
static constexpr unsigned bytesCount
Definition bitfield.hh:105
BitFieldHelper()
Definition bitfield.hh:111
static constexpr uint32_t mask
Definition bitfield.hh:107
Definition bitfield.hh:70
static constexpr unsigned offset()
Definition bitfield.hh:71
Definition bitfield.hh:54
static constexpr unsigned size()
Definition bitfield.hh:55
Definition bitfield.hh:44
static constexpr unsigned size
Definition bitfield.hh:45
A bit field that can hold multiple bit field elements of different types.
Definition bitfield.hh:155
constexpr void set(Field::Type v_)
Definition bitfield.hh:164
constexpr Field::Type get() const
Definition bitfield.hh:157
void clear()
Definition bitfield.hh:170
A bit field element to be used in a BitField.
Definition bitfield.hh:130
T Type
Definition bitfield.hh:132
static constexpr unsigned Width
Definition bitfield.hh:131
std::conditional_t< std::is_enum_v< T >, std::underlying_type_t< std::conditional_t< std::is_enum_v< T >, T, BitFieldInternal::Dummy > >, T > Underlying
Definition bitfield.hh:136
static size_t size_t width
Definition syscalls.h:157
static int ret
Definition syscalls.h:72
void uint32_t(classId, spec)