L4Re Operating System Framework
Interface and Usage Documentation
Loading...
Searching...
No Matches
bitfield
1// vi:set ft=cpp: -*- Mode: C++ -*-
2/*
3 * (c) 2012 Alexander Warg <warg@os.inf.tu-dresden.de>,
4 * economic rights: Technische Universität Dresden (Germany)
5 *
6 * License: see LICENSE.spdx (in this directory or the directories above)
7 */
8
9#pragma once
10
11#include "type_list"
12
14namespace cxx {
15
23template<typename T, unsigned LSB, unsigned MSB>
25{
26private:
27 typedef remove_reference_t<T> Base_type;
28
29 static_assert(MSB >= LSB, "boundary mismatch in bit-field definition");
30 static_assert(MSB < sizeof(Base_type) * 8, "MSB outside of bit-field type");
31 static_assert(LSB < sizeof(Base_type) * 8, "LSB outside of bit-field type");
32
38 template<unsigned BITS> struct Best_type
39 {
40 template< typename TY > struct Cmp { enum { value = (BITS <= sizeof(TY)*8) }; };
41 typedef cxx::type_list<
42 unsigned char,
43 unsigned short,
44 unsigned int,
45 unsigned long,
46 unsigned long long
47 > Unsigned_types;
48 typedef cxx::find_type_t<Unsigned_types, Cmp> Type;
49 };
50
51public:
52 enum
53 {
54 Bits = MSB + 1 - LSB,
55 Lsb = LSB,
56 Msb = MSB,
57 };
58
60 static constexpr Base_type Low_mask
61 = Base_type(~0ULL) >> (sizeof(Base_type) * 8 - Bits);
63 static constexpr Base_type Mask = Low_mask << Lsb;
64
71 typedef typename Best_type<Bits>::Type Bits_type;
72
79 typedef typename Best_type<Bits + Lsb>::Type Shift_type;
80
81private:
82 static_assert(sizeof(Bits_type)*8 >= Bits, "error finding the type to store the bits");
83 static_assert(sizeof(Shift_type)*8 >= Bits + Lsb, "error finding the type to keep the shifted bits");
84 static_assert(sizeof(Bits_type) <= sizeof(Base_type), "size mismatch for Bits_type");
85 static_assert(sizeof(Shift_type) <= sizeof(Base_type), "size mismatch for Shift_type");
86 static_assert(sizeof(Bits_type) <= sizeof(Shift_type), "size mismatch for Shift_type and Bits_type");
87
88public:
96 static constexpr Bits_type get(Shift_type val)
97 { return (val >> Lsb) & Low_mask; }
98
109 static constexpr Base_type get_unshifted(Shift_type val)
110 { return val & Mask; }
111
124 static constexpr Base_type set_dirty(Base_type dest, Shift_type val)
125 {
126 //assert (!(val & ~Low_mask));
127 return (dest & ~Mask) | (val << Lsb);
128 }
129
144 static constexpr Base_type set_unshifted_dirty(Base_type dest, Shift_type val)
145 {
146 //assert (!(val & ~Mask));
147 return (dest & ~Mask) | val;
148 }
149
158 static Base_type set(Base_type dest, Bits_type val)
159 { return set_dirty(dest, val & Low_mask); }
160
170 static Base_type set_unshifted(Base_type dest, Shift_type val)
171 { return set_unshifted_dirty(dest, val & Mask); }
172
184 static constexpr Base_type val_dirty(Shift_type val) { return val << Lsb; }
185
193 static constexpr Base_type val(Bits_type val) { return val_dirty(val & Low_mask); }
194
203 static constexpr Base_type val_unshifted(Shift_type val) { return val & Mask; }
204
206 template< typename TT >
207 class Value_base
208 {
209 private:
210 TT v;
211
212 public:
213 constexpr Value_base(TT t) : v(t) {}
214 constexpr Bits_type get() const { return Bitfield::get(v); }
215 constexpr Base_type get_unshifted() const { return Bitfield::get_unshifted(v); }
216
217 void set(Bits_type val) { v = Bitfield::set(v, val); }
218 void set_dirty(Bits_type val) { v = Bitfield::set_dirty(v, val); }
219 void set_unshifted(Shift_type val) { v = Bitfield::set_unshifted(v, val); }
220 void set_unshifted_dirty(Shift_type val) { v = Bitfield::set_unshifted_dirty(v, val); }
221 };
222
224 template< typename TT >
225 class Value : public Value_base<TT>
226 {
227 public:
228 constexpr Value(TT t) : Value_base<TT>(t) {}
229 constexpr operator Bits_type () const { return this->get(); }
230 constexpr Value &operator = (Bits_type val) { this->set(val); return *this; }
231 constexpr Value &operator = (Value const &val)
232 { this->set(val.get()); return *this; }
233 Value(Value const &) = default;
234 };
235
237 template< typename TT >
238 class Value_unshifted : public Value_base<TT>
239 {
240 public:
241 constexpr Value_unshifted(TT t) : Value_base<TT>(t) {}
242 constexpr operator Shift_type () const { return this->get_unshifted(); }
243 constexpr Value_unshifted &operator = (Shift_type val) { this->set_unshifted(val); return *this; }
244 constexpr Value_unshifted &operator = (Value_unshifted const &val)
245 { this->set_unshifted(val.get_unshifted()); return *this; }
246 Value_unshifted(Value_unshifted const &) = default;
247 };
248
250 typedef Value<Base_type &> Ref;
252 typedef Value<Base_type volatile &> Ref_volatile;
254 typedef Value<Base_type const> Val;
255
257 typedef Value_unshifted<Base_type &> Ref_unshifted;
259 typedef Value_unshifted<Base_type volatile &> Ref_unshifted_volatile;
261 typedef Value_unshifted<Base_type const> Val_unshifted;
262};
263
264#define CXX_BITFIELD_MEMBER(LSB, MSB, name, data_member) \
265 \
266 \
267 typedef cxx::Bitfield<decltype(data_member), LSB, MSB> name ## _bfm_t; \
268 \
269 constexpr typename name ## _bfm_t::Val name() const { return data_member; } \
270 typename name ## _bfm_t::Val name() const volatile { return data_member; } \
271 \
272 constexpr typename name ## _bfm_t::Ref name() { return data_member; } \
273 typename name ## _bfm_t::Ref_volatile name() volatile { return data_member; } \
274
275
276#define CXX_BITFIELD_MEMBER_RO(LSB, MSB, name, data_member) \
277 \
278 \
279 typedef cxx::Bitfield<decltype(data_member), LSB, MSB> name ## _bfm_t; \
280 \
281 constexpr typename name ## _bfm_t::Val name() const { return data_member; } \
282 typename name ## _bfm_t::Val name() const volatile { return data_member; } \
283
284
285#define CXX_BITFIELD_MEMBER_UNSHIFTED(LSB, MSB, name, data_member) \
286 \
287 \
288 typedef cxx::Bitfield<decltype(data_member), LSB, MSB> name ## _bfm_t; \
289 \
290 constexpr typename name ## _bfm_t::Val_unshifted name() const { return data_member; } \
291 typename name ## _bfm_t::Val_unshifted name() const volatile { return data_member; } \
292 \
293 constexpr typename name ## _bfm_t::Ref_unshifted name() { return data_member; } \
294 typename name ## _bfm_t::Ref_unshifted_volatile name() volatile { return data_member; } \
295
296
297#define CXX_BITFIELD_MEMBER_UNSHIFTED_RO(LSB, MSB, name, data_member) \
298 \
299 \
300 typedef cxx::Bitfield<decltype(data_member), LSB, MSB> name ## _bfm_t; \
301 \
302 constexpr typename name ## _bfm_t::Val_unshifted name() const { return data_member; } \
303 typename name ## _bfm_t::Val_unshifted name() const volatile { return data_member; } \
304
305}
Definition for a member (part) of a bit field.
Definition bitfield:25
static constexpr Bits_type get(Shift_type val)
Get the bits out of val.
Definition bitfield:96
Value_unshifted< Base_type volatile & > Ref_unshifted_volatile
Definition bitfield:259
static constexpr Base_type val_unshifted(Shift_type val)
Get the shifted bits for val.
Definition bitfield:203
Value< Base_type volatile & > Ref_volatile
Definition bitfield:252
static constexpr Base_type Mask
Definition bitfield:63
static Base_type set(Base_type dest, Bits_type val)
Set the bits corresponding to val.
Definition bitfield:158
Best_type< Bits+Lsb >::Type Shift_type
Definition bitfield:79
Value< Base_type const > Val
Definition bitfield:254
static constexpr Base_type val_dirty(Shift_type val)
Get the shifted bits for val.
Definition bitfield:184
static constexpr Base_type Low_mask
Definition bitfield:61
static constexpr Base_type set_unshifted_dirty(Base_type dest, Shift_type val)
Set the bits corresponding to val.
Definition bitfield:144
static constexpr Base_type val(Bits_type val)
Definition bitfield:193
Best_type< Bits >::Type Bits_type
Definition bitfield:71
static Base_type set_unshifted(Base_type dest, Shift_type val)
Set the bits corresponding to val.
Definition bitfield:170
Value_unshifted< Base_type & > Ref_unshifted
Definition bitfield:257
static constexpr Base_type get_unshifted(Shift_type val)
Get the bits in place out of val.
Definition bitfield:109
static constexpr Base_type set_dirty(Base_type dest, Shift_type val)
Set the bits corresponding to val.
Definition bitfield:124
Value_unshifted< Base_type const > Val_unshifted
Definition bitfield:261
Our C++ library.
Definition arith:11