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 * This file is part of TUD:OS and distributed under the terms of the
7 * GNU General Public License 2.
8 * Please see the COPYING-GPL-2 file for details.
9 *
10 * As a special exception, you may use this file as part of a free software
11 * library without restriction. Specifically, if other files instantiate
12 * templates or use macros or inline functions from this file, or you compile
13 * this file and link it with other files to produce an executable, this
14 * file does not by itself cause the resulting executable to be covered by
15 * the GNU General Public License. This exception does not however
16 * invalidate any other reasons why the executable file might be covered by
17 * the GNU General Public License.
18 */
19
20#pragma once
21
22#include "type_list"
23
25namespace cxx {
26
34template<typename T, unsigned LSB, unsigned MSB>
36{
37private:
38 typedef remove_reference_t<T> Base_type;
39
40 static_assert(MSB >= LSB, "boundary mismatch in bit-field definition");
41 static_assert(MSB < sizeof(Base_type) * 8, "MSB outside of bit-field type");
42 static_assert(LSB < sizeof(Base_type) * 8, "LSB outside of bit-field type");
43
49 template<unsigned BITS> struct Best_type
50 {
51 template< typename TY > struct Cmp { enum { value = (BITS <= sizeof(TY)*8) }; };
52 typedef cxx::type_list<
53 unsigned char,
54 unsigned short,
55 unsigned int,
56 unsigned long,
57 unsigned long long
58 > Unsigned_types;
59 typedef cxx::find_type_t<Unsigned_types, Cmp> Type;
60 };
61
62public:
63 enum
64 {
65 Bits = MSB + 1 - LSB,
66 Lsb = LSB,
67 Msb = MSB,
68 };
69
71 enum Masks : Base_type
72 {
74 Low_mask = static_cast<Base_type>(~0ULL) >> (sizeof(Base_type)*8 - Bits),
77 };
78
85 typedef typename Best_type<Bits>::Type Bits_type;
86
93 typedef typename Best_type<Bits + Lsb>::Type Shift_type;
94
95private:
96 static_assert(sizeof(Bits_type)*8 >= Bits, "error finding the type to store the bits");
97 static_assert(sizeof(Shift_type)*8 >= Bits + Lsb, "error finding the type to keep the shifted bits");
98 static_assert(sizeof(Bits_type) <= sizeof(Base_type), "size mismatch for Bits_type");
99 static_assert(sizeof(Shift_type) <= sizeof(Base_type), "size mismatch for Shift_type");
100 static_assert(sizeof(Bits_type) <= sizeof(Shift_type), "size mismacht for Shift_type and Bits_type");
101
102public:
110 static constexpr Bits_type get(Shift_type val)
111 { return (val >> Lsb) & Low_mask; }
112
123 static constexpr Base_type get_unshifted(Shift_type val)
124 { return val & Mask; }
125
138 static constexpr Base_type set_dirty(Base_type dest, Shift_type val)
139 {
140 //assert (!(val & ~Low_mask));
141 return (dest & ~Mask) | (val << Lsb);
142 }
143
158 static constexpr Base_type set_unshifted_dirty(Base_type dest, Shift_type val)
159 {
160 //assert (!(val & ~Mask));
161 return (dest & ~Mask) | val;
162 }
163
172 static Base_type set(Base_type dest, Bits_type val)
173 { return set_dirty(dest, val & Low_mask); }
174
184 static Base_type set_unshifted(Base_type dest, Shift_type val)
185 { return set_unshifted_dirty(dest, val & Mask); }
186
198 static constexpr Base_type val_dirty(Shift_type val) { return val << Lsb; }
199
207 static constexpr Base_type val(Bits_type val) { return val_dirty(val & Low_mask); }
208
217 static constexpr Base_type val_unshifted(Shift_type val) { return val & Mask; }
218
220 template< typename TT >
222 {
223 private:
224 TT v;
225
226 public:
227 constexpr Value_base(TT t) : v(t) {}
228 constexpr Bits_type get() const { return Bitfield::get(v); }
229 constexpr Base_type get_unshifted() const { return Bitfield::get_unshifted(v); }
230
231 void set(Bits_type val) { v = Bitfield::set(v, val); }
232 void set_dirty(Bits_type val) { v = Bitfield::set_dirty(v, val); }
233 void set_unshifted(Shift_type val) { v = Bitfield::set_unshifted(v, val); }
234 void set_unshifted_dirty(Shift_type val) { v = Bitfield::set_unshifted_dirty(v, val); }
235 };
236
238 template< typename TT >
239 class Value : public Value_base<TT>
240 {
241 public:
242 constexpr Value(TT t) : Value_base<TT>(t) {}
243 constexpr operator Bits_type () const { return this->get(); }
244 constexpr Value &operator = (Bits_type val) { this->set(val); return *this; }
245 constexpr Value &operator = (Value const &val)
246 { this->set(val.get()); return *this; }
247 Value(Value const &) = default;
248 };
249
251 template< typename TT >
252 class Value_unshifted : public Value_base<TT>
253 {
254 public:
255 constexpr Value_unshifted(TT t) : Value_base<TT>(t) {}
256 constexpr operator Shift_type () const { return this->get_unshifted(); }
257 constexpr Value_unshifted &operator = (Shift_type val) { this->set_unshifted(val); return *this; }
258 constexpr Value_unshifted &operator = (Value_unshifted const &val)
259 { this->set_unshifted(val.get_unshifted()); return *this; }
260 Value_unshifted(Value_unshifted const &) = default;
261 };
262
269
276};
277
278#define CXX_BITFIELD_MEMBER(LSB, MSB, name, data_member) \
279 \
280 \
281 typedef cxx::Bitfield<decltype(data_member), LSB, MSB> name ## _bfm_t; \
282 \
283 constexpr typename name ## _bfm_t::Val name() const { return data_member; } \
284 typename name ## _bfm_t::Val name() const volatile { return data_member; } \
285 \
286 constexpr typename name ## _bfm_t::Ref name() { return data_member; } \
287 typename name ## _bfm_t::Ref_volatile name() volatile { return data_member; } \
288
290#define CXX_BITFIELD_MEMBER_RO(LSB, MSB, name, data_member) \
291 \
292 \
293 typedef cxx::Bitfield<decltype(data_member), LSB, MSB> name ## _bfm_t; \
294 \
295 constexpr typename name ## _bfm_t::Val name() const { return data_member; } \
296 typename name ## _bfm_t::Val name() const volatile { return data_member; } \
297
299#define CXX_BITFIELD_MEMBER_UNSHIFTED(LSB, MSB, name, data_member) \
300 \
301 \
302 typedef cxx::Bitfield<decltype(data_member), LSB, MSB> name ## _bfm_t; \
303 \
304 constexpr typename name ## _bfm_t::Val_unshifted name() const { return data_member; } \
305 typename name ## _bfm_t::Val_unshifted name() const volatile { return data_member; } \
306 \
307 constexpr typename name ## _bfm_t::Ref_unshifted name() { return data_member; } \
308 typename name ## _bfm_t::Ref_unshifted_volatile name() volatile { return data_member; } \
309
311#define CXX_BITFIELD_MEMBER_UNSHIFTED_RO(LSB, MSB, name, data_member) \
312 \
313 \
314 typedef cxx::Bitfield<decltype(data_member), LSB, MSB> name ## _bfm_t; \
315 \
316 constexpr typename name ## _bfm_t::Val_unshifted name() const { return data_member; } \
317 typename name ## _bfm_t::Val_unshifted name() const volatile { return data_member; } \
318
319}
Internal helper type.
Definition bitfield:222
Internal helper type.
Definition bitfield:253
Internal helper type.
Definition bitfield:240
Definition for a member (part) of a bit field.
Definition bitfield:36
static constexpr Bits_type get(Shift_type val)
Get the bits out of val.
Definition bitfield:110
@ Msb
index of the MSB
Definition bitfield:67
@ Bits
Number of bits.
Definition bitfield:65
@ Lsb
index of the LSB
Definition bitfield:66
Value_unshifted< Base_type volatile & > Ref_unshifted_volatile
Volatile reference type to access the bits inside a raw bit field (in place).
Definition bitfield:273
static constexpr Base_type val_unshifted(Shift_type val)
Get the shifted bits for val.
Definition bitfield:217
Value< Base_type volatile & > Ref_volatile
Volatile reference type to access the bits inside a raw bit field.
Definition bitfield:266
Masks
Masks for bitswise operation on internal parts of a bitfield.
Definition bitfield:72
@ Low_mask
Mask value to get Bits bits.
Definition bitfield:74
@ Mask
Mask value to the bits out of a T.
Definition bitfield:76
static Base_type set(Base_type dest, Bits_type val)
Set the bits corresponding to val.
Definition bitfield:172
Best_type< Bits+Lsb >::Type Shift_type
Type to hold at least Bits + Lsb bits.
Definition bitfield:93
Value< Base_type const > Val
Value type to access the bits inside a raw bit field.
Definition bitfield:268
static constexpr Base_type val_dirty(Shift_type val)
Get the shifted bits for val.
Definition bitfield:198
static constexpr Base_type set_unshifted_dirty(Base_type dest, Shift_type val)
Set the bits corresponding to val.
Definition bitfield:158
static constexpr Base_type val(Bits_type val)
Get the shifted bits for val.
Definition bitfield:207
Best_type< Bits >::Type Bits_type
Type to hold at least Bits bits.
Definition bitfield:85
static Base_type set_unshifted(Base_type dest, Shift_type val)
Set the bits corresponding to val.
Definition bitfield:184
Value_unshifted< Base_type & > Ref_unshifted
Reference type to access the bits inside a raw bit field (in place).
Definition bitfield:271
static constexpr Base_type get_unshifted(Shift_type val)
Get the bits in place out of val.
Definition bitfield:123
static constexpr Base_type set_dirty(Base_type dest, Shift_type val)
Set the bits corresponding to val.
Definition bitfield:138
Value_unshifted< Base_type const > Val_unshifted
Value type to access the bits inside a raw bit field (in place).
Definition bitfield:275
Value< Base_type & > Ref
Reference type to access the bits inside a raw bit field.
Definition bitfield:264
Our C++ library.
Definition arith:22