L4Re Operating System Framework
Interface and Usage Documentation
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 enum Masks : Base_type
61 {
63 Low_mask = static_cast<Base_type>(~0ULL) >> (sizeof(Base_type)*8 - Bits),
66 };
67
74 typedef typename Best_type<Bits>::Type Bits_type;
75
82 typedef typename Best_type<Bits + Lsb>::Type Shift_type;
83
84private:
85 static_assert(sizeof(Bits_type)*8 >= Bits, "error finding the type to store the bits");
86 static_assert(sizeof(Shift_type)*8 >= Bits + Lsb, "error finding the type to keep the shifted bits");
87 static_assert(sizeof(Bits_type) <= sizeof(Base_type), "size mismatch for Bits_type");
88 static_assert(sizeof(Shift_type) <= sizeof(Base_type), "size mismatch for Shift_type");
89 static_assert(sizeof(Bits_type) <= sizeof(Shift_type), "size mismatch for Shift_type and Bits_type");
90
91public:
99 static constexpr Bits_type get(Shift_type val)
100 { return (val >> Lsb) & Low_mask; }
101
112 static constexpr Base_type get_unshifted(Shift_type val)
113 { return val & Mask; }
114
127 static constexpr Base_type set_dirty(Base_type dest, Shift_type val)
128 {
129 //assert (!(val & ~Low_mask));
130 return (dest & ~Mask) | (val << Lsb);
131 }
132
147 static constexpr Base_type set_unshifted_dirty(Base_type dest, Shift_type val)
148 {
149 //assert (!(val & ~Mask));
150 return (dest & ~Mask) | val;
151 }
152
161 static Base_type set(Base_type dest, Bits_type val)
162 { return set_dirty(dest, val & Low_mask); }
163
173 static Base_type set_unshifted(Base_type dest, Shift_type val)
174 { return set_unshifted_dirty(dest, val & Mask); }
175
187 static constexpr Base_type val_dirty(Shift_type val) { return val << Lsb; }
188
196 static constexpr Base_type val(Bits_type val) { return val_dirty(val & Low_mask); }
197
206 static constexpr Base_type val_unshifted(Shift_type val) { return val & Mask; }
207
209 template< typename TT >
211 {
212 private:
213 TT v;
214
215 public:
216 constexpr Value_base(TT t) : v(t) {}
217 constexpr Bits_type get() const { return Bitfield::get(v); }
218 constexpr Base_type get_unshifted() const { return Bitfield::get_unshifted(v); }
219
220 void set(Bits_type val) { v = Bitfield::set(v, val); }
221 void set_dirty(Bits_type val) { v = Bitfield::set_dirty(v, val); }
222 void set_unshifted(Shift_type val) { v = Bitfield::set_unshifted(v, val); }
223 void set_unshifted_dirty(Shift_type val) { v = Bitfield::set_unshifted_dirty(v, val); }
224 };
225
227 template< typename TT >
228 class Value : public Value_base<TT>
229 {
230 public:
231 constexpr Value(TT t) : Value_base<TT>(t) {}
232 constexpr operator Bits_type () const { return this->get(); }
233 constexpr Value &operator = (Bits_type val) { this->set(val); return *this; }
234 constexpr Value &operator = (Value const &val)
235 { this->set(val.get()); return *this; }
236 Value(Value const &) = default;
237 };
238
240 template< typename TT >
241 class Value_unshifted : public Value_base<TT>
242 {
243 public:
244 constexpr Value_unshifted(TT t) : Value_base<TT>(t) {}
245 constexpr operator Shift_type () const { return this->get_unshifted(); }
246 constexpr Value_unshifted &operator = (Shift_type val) { this->set_unshifted(val); return *this; }
247 constexpr Value_unshifted &operator = (Value_unshifted const &val)
248 { this->set_unshifted(val.get_unshifted()); return *this; }
249 Value_unshifted(Value_unshifted const &) = default;
250 };
251
258
265};
266
267#define CXX_BITFIELD_MEMBER(LSB, MSB, name, data_member) \
268 \
269 \
270 typedef cxx::Bitfield<decltype(data_member), LSB, MSB> name ## _bfm_t; \
271 \
272 constexpr typename name ## _bfm_t::Val name() const { return data_member; } \
273 typename name ## _bfm_t::Val name() const volatile { return data_member; } \
274 \
275 constexpr typename name ## _bfm_t::Ref name() { return data_member; } \
276 typename name ## _bfm_t::Ref_volatile name() volatile { return data_member; } \
277
279#define CXX_BITFIELD_MEMBER_RO(LSB, MSB, name, data_member) \
280 \
281 \
282 typedef cxx::Bitfield<decltype(data_member), LSB, MSB> name ## _bfm_t; \
283 \
284 constexpr typename name ## _bfm_t::Val name() const { return data_member; } \
285 typename name ## _bfm_t::Val name() const volatile { return data_member; } \
286
288#define CXX_BITFIELD_MEMBER_UNSHIFTED(LSB, MSB, name, data_member) \
289 \
290 \
291 typedef cxx::Bitfield<decltype(data_member), LSB, MSB> name ## _bfm_t; \
292 \
293 constexpr typename name ## _bfm_t::Val_unshifted name() const { return data_member; } \
294 typename name ## _bfm_t::Val_unshifted name() const volatile { return data_member; } \
295 \
296 constexpr typename name ## _bfm_t::Ref_unshifted name() { return data_member; } \
297 typename name ## _bfm_t::Ref_unshifted_volatile name() volatile { return data_member; } \
298
300#define CXX_BITFIELD_MEMBER_UNSHIFTED_RO(LSB, MSB, name, data_member) \
301 \
302 \
303 typedef cxx::Bitfield<decltype(data_member), LSB, MSB> name ## _bfm_t; \
304 \
305 constexpr typename name ## _bfm_t::Val_unshifted name() const { return data_member; } \
306 typename name ## _bfm_t::Val_unshifted name() const volatile { return data_member; } \
307
308}
Internal helper type.
Definition bitfield:211
Internal helper type.
Definition bitfield:242
Internal helper type.
Definition bitfield:229
Definition for a member (part) of a bit field.
Definition bitfield:25
@ Msb
index of the MSB
Definition bitfield:56
@ Bits
Number of bits.
Definition bitfield:54
@ Lsb
index of the LSB
Definition bitfield:55
static constexpr Bits_type get(Shift_type val)
Get the bits out of val.
Definition bitfield:99
Value_unshifted< Base_type volatile & > Ref_unshifted_volatile
Volatile reference type to access the bits inside a raw bit field (in place).
Definition bitfield:262
static constexpr Base_type val_unshifted(Shift_type val)
Get the shifted bits for val.
Definition bitfield:206
Value< Base_type volatile & > Ref_volatile
Volatile reference type to access the bits inside a raw bit field.
Definition bitfield:255
Masks
Masks for bitswise operation on internal parts of a bitfield.
Definition bitfield:61
@ Low_mask
Mask value to get Bits bits.
Definition bitfield:63
@ Mask
Mask value to the bits out of a T.
Definition bitfield:65
static Base_type set(Base_type dest, Bits_type val)
Set the bits corresponding to val.
Definition bitfield:161
Best_type< Bits+Lsb >::Type Shift_type
Type to hold at least Bits + Lsb bits.
Definition bitfield:82
Value< Base_type const > Val
Value type to access the bits inside a raw bit field.
Definition bitfield:257
static constexpr Base_type val_dirty(Shift_type val)
Get the shifted bits for val.
Definition bitfield:187
static constexpr Base_type set_unshifted_dirty(Base_type dest, Shift_type val)
Set the bits corresponding to val.
Definition bitfield:147
static constexpr Base_type val(Bits_type val)
Get the shifted bits for val.
Definition bitfield:196
Best_type< Bits >::Type Bits_type
Type to hold at least Bits bits.
Definition bitfield:74
static Base_type set_unshifted(Base_type dest, Shift_type val)
Set the bits corresponding to val.
Definition bitfield:173
Value_unshifted< Base_type & > Ref_unshifted
Reference type to access the bits inside a raw bit field (in place).
Definition bitfield:260
static constexpr Base_type get_unshifted(Shift_type val)
Get the bits in place out of val.
Definition bitfield:112
static constexpr Base_type set_dirty(Base_type dest, Shift_type val)
Set the bits corresponding to val.
Definition bitfield:127
Value_unshifted< Base_type const > Val_unshifted
Value type to access the bits inside a raw bit field (in place).
Definition bitfield:264
Value< Base_type & > Ref
Reference type to access the bits inside a raw bit field.
Definition bitfield:253
Our C++ library.
Definition arith:11