NetBurner 3.5.6
PDF Version
bit_overlay.h
1#ifndef __BITS_H
2#define __BITS_H
3/**************************************************************************/
35#include <basictypes.h>
36
37#define _STR(x) #x
38
39void ser_putstring(const char *);
40void ser_putword(uint32_t);
41void ser_putbyte(uint8_t);
42template<uint8_t e, uint8_t s, uint8_t w>
43class bit_overlay
44{
45 static_assert(e >= s, "Ending bit must be after starting bit");
46 static_assert(e < w, "Ending bit must be less than mapped width");
47
48 public:
49 inline uint32_t asVal()
50 {
51// ser_putstring("\r\n*this: 0x");
52// ser_putword(*(beuint32_t*)this);
53// ser_putstring("\r\n*this >> ");
54// ser_putbyte(s);
55// ser_putstring(": 0x");
56// ser_putword((*((beuint32_t *)this) >> s));
57// ser_putstring("\r\nmask: 0x");
58// ser_putword(((1UL << (e-s+1))-1));
59// ser_putstring("\r\n(*this >> ");
60// ser_putbyte(s);
61// ser_putstring(") & mask: 0x");
62// ser_putword((*((beuint32_t *)this) >> s) & ((1UL << (e-s+1))-1));
63#pragma GCC diagnostic push
64#pragma GCC diagnostic ignored "-Wshift-count-overflow"
65 return (*((uint32_t *)this) >> s) & ((1UL << (e - s + 1)) - 1);
66#pragma GCC diagnostic pop
67 }
68 inline operator uint32_t() { return asVal(); }
69 inline uint32_t operator=(uint32_t rhs)
70 {
71#pragma GCC diagnostic push
72#pragma GCC diagnostic ignored "-Wshift-count-overflow"
73 register uint32_t mask = ((1UL << (e - s + 1)) - 1);
74#pragma GCC diagnostic pop
75 *((uint32_t *)this) &= ~(mask << s);
76 *((uint32_t *)this) |= (rhs & mask) << s;
77 return rhs;
78 }
79 inline bool operator==(uint32_t rhs) { return asVal() == rhs; }
80 inline bool operator>=(uint32_t rhs) { return asVal() >= rhs; }
81 inline bool operator<(uint32_t rhs) { return asVal() < rhs; }
82 inline uint32_t operator<<(uint32_t rhs) { return asVal() << rhs; }
83 inline uint32_t operator*(uint32_t rhs) { return asVal() * rhs; }
84
85} __attribute__((packed));
86
87template<uint8_t e, uint8_t s, uint8_t w>
88inline uint32_t operator*(bit_overlay<e, s, w> lhs, uint32_t rhs)
89{
90 return lhs.asVal() * rhs;
91}
92
93// Specialized template for 8 bit fields
94template<uint8_t e, uint8_t s>
95class bit_overlay<e, s, 8>
96{
97 static_assert(e >= s, "Ending bit must be after starting bit");
98 static_assert(e < 8, "Ending bit must be less than mapped width");
99
100 public:
101 inline uint32_t asVal() { return (*((uint8_t *)this) >> s) & ((1UL << (e - s + 1)) - 1); }
102 inline operator uint8_t() { return asVal(); }
103 inline uint8_t operator=(uint8_t rhs)
104 {
105 register uint8_t mask = ((1UL << (e - s + 1)) - 1);
106 *((uint8_t *)this) &= ~(mask << s);
107 *((uint8_t *)this) |= (rhs & mask) << s;
108 return rhs;
109 }
110 inline bool operator==(uint32_t rhs) { return asVal() == rhs; }
111 inline bool operator>=(uint32_t rhs) { return asVal() >= rhs; }
112 inline bool operator<(uint32_t rhs) { return asVal() < rhs; }
113 inline uint8_t operator<<(uint32_t rhs) { return asVal() << rhs; }
114 inline uint8_t operator*(uint32_t rhs) { return asVal() * rhs; }
115} __attribute__((packed));
116
117// Specialized template for 16 bit fields
118template<uint8_t e, uint8_t s>
119class bit_overlay<e, s, 16>
120{
121 static_assert(e >= s, "Ending bit must be after starting bit");
122 static_assert(e < 16, "Ending bit must be less than mapped width");
123
124 public:
125 inline uint16_t asVal() { return (*((uint16_t *)this) >> s) & ((1UL << (e - s + 1)) - 1); }
126 inline operator uint16_t() { return asVal(); }
127 inline uint16_t operator=(uint16_t rhs)
128 {
129 register uint16_t mask = ((1UL << (e - s + 1)) - 1);
130 *((uint16_t *)this) &= ~(mask << s);
131 *((uint16_t *)this) |= (rhs & mask) << s;
132 return rhs;
133 }
134 inline bool operator==(uint32_t rhs) { return asVal() == rhs; }
135 inline bool operator>=(uint32_t rhs) { return asVal() >= rhs; }
136 inline bool operator<(uint32_t rhs) { return asVal() < rhs; }
137 inline uint16_t operator<<(uint32_t rhs) { return asVal() << rhs; }
138 inline uint16_t operator*(uint32_t rhs) { return asVal() * rhs; }
139} __attribute__((packed));
140
141#include <type_traits>
142static_assert(std::is_pod<bit_overlay<31, 0, 32>>::value, "Data Structure requires constructible elements");
143
144#endif /* ----- #ifndef __BITS_H ----- */