M5Utility 0.0.2 git rev:5c1a751
Loading...
Searching...
No Matches
bit_segment.hpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD
3 *
4 * SPDX-License-Identifier: MIT
5 */
11#ifndef M5_UTILITY_BIT_SEGMENT_HPP
12#define M5_UTILITY_BIT_SEGMENT_HPP
13
14#include <cstddef>
15#include <type_traits>
16
17namespace m5 {
18namespace utility {
19
27template <size_t LowerBits, typename T>
29public:
31 using base_type = typename std::remove_const<typename std::remove_reference<T>::type>::type;
32 constexpr static bool SIGNED = std::is_signed<base_type>::value;
33 static_assert(std::is_integral<base_type>::value, "Base type must be integral");
34 static_assert(LowerBits > 0, "LowerBits must be not zero");
35 static_assert(LowerBits <= (sizeof(base_type) * 8 - (SIGNED ? 1 : 0)), "LowerBits too large");
36 using unsigned_type = typename std::make_unsigned<base_type>::type;
37 constexpr static unsigned_type UPPER_BITS = sizeof(unsigned_type) * 8U - LowerBits - (SIGNED ? 1 : 0);
38 constexpr static unsigned_type LOWER_BITS = static_cast<unsigned_type>(LowerBits);
39 constexpr static unsigned_type UPPER_SHIFT = LOWER_BITS;
40 constexpr static unsigned_type UPPER_MASK = ((unsigned_type)1 << UPPER_BITS) - 1;
41 constexpr static unsigned_type LOWER_MASK = ((unsigned_type)1 << LOWER_BITS) - 1;
43
46 inline constexpr BitSegment() = default;
48 inline constexpr BitSegment(const BitSegment& o) : _v(o._v)
49 {
50 }
52 inline constexpr BitSegment(const base_type v) : _v(v)
53 {
54 }
56
59 BitSegment& operator=(const BitSegment& o)
60 {
61 if (this != &o) {
62 _v = o._v;
63 }
64 return *this;
65 }
66 BitSegment& operator=(const base_type v)
67 {
68 _v = v;
69 return *this;
70 }
72
75
76 inline constexpr explicit operator bool() const
77 {
78 return _v;
79 }
81 inline constexpr operator base_type() const
82 {
83 return _v;
84 }
86
89
90 inline constexpr unsigned_type upper() const
91 {
92 return (_v >> UPPER_SHIFT) & UPPER_MASK;
93 }
95 inline constexpr unsigned_type lower() const
96 {
97 return _v & LOWER_MASK;
98 }
100 inline constexpr base_type raw() const
101 {
102 return _v;
103 }
105
108
109 inline void upper(const unsigned_type v)
110 {
111 _v = (_v & ~(UPPER_MASK << UPPER_SHIFT)) | ((v & UPPER_MASK) << UPPER_SHIFT);
112 }
114 inline void lower(const unsigned_type v)
115 {
116 _v = (_v & ~LOWER_MASK) | (v & LOWER_MASK);
117 }
119 inline void raw(const base_type v)
120 {
121 _v = v;
122 }
124
125private:
126 base_type _v{};
127};
128
132template <size_t LowerBits, typename T>
133bool operator==(const BitSegment<LowerBits, T>& a, const BitSegment<LowerBits, T>& b)
134{
135 return a.raw() == b.raw();
136}
137template <size_t LowerBits, typename T>
138bool operator!=(const BitSegment<LowerBits, T>& a, const BitSegment<LowerBits, T>& b)
139{
140 return !(a == b);
141}
142template <size_t LowerBits, typename T>
143bool operator<(const BitSegment<LowerBits, T>& a, const BitSegment<LowerBits, T>& b)
144{
145 return a.raw() < b.raw();
146}
147template <size_t LowerBits, typename T>
148bool operator>(const BitSegment<LowerBits, T>& a, const BitSegment<LowerBits, T>& b)
149{
150 return b < a;
151}
152template <size_t LowerBits, typename T>
153bool operator<=(const BitSegment<LowerBits, T>& a, const BitSegment<LowerBits, T>& b)
154{
155 return !(a > b);
156}
157template <size_t LowerBits, typename T>
158bool operator>=(const BitSegment<LowerBits, T>& a, const BitSegment<LowerBits, T>& b)
159{
160 return !(a < b);
161}
163
167template <size_t LowerBits, typename T>
168bool operator==(const BitSegment<LowerBits, T>& a, const int b)
169{
170 return a.raw() == b;
171}
172template <size_t LowerBits, typename T>
173bool operator!=(const BitSegment<LowerBits, T>& a, const int b)
174{
175 return !(a == b);
176}
177template <size_t LowerBits, typename T>
178bool operator<(const BitSegment<LowerBits, T>& a, const int b)
179{
180 return a.raw() < b;
181}
182template <size_t LowerBits, typename T>
183bool operator>(const BitSegment<LowerBits, T>& a, const int b)
184{
185 return b < a;
186}
187template <size_t LowerBits, typename T>
188bool operator<=(const BitSegment<LowerBits, T>& a, const int b)
189{
190 return !(a > b);
191}
192template <size_t LowerBits, typename T>
193bool operator>=(const BitSegment<LowerBits, T>& a, const int b)
194{
195 return !(a < b);
196}
198
202template <size_t LowerBits, typename T>
203bool operator==(const int a, const BitSegment<LowerBits, T>& b)
204{
205 return a == b.raw();
206}
207template <size_t LowerBits, typename T>
208bool operator!=(const int a, const BitSegment<LowerBits, T>& b)
209{
210 return !(a == b);
211}
212template <size_t LowerBits, typename T>
213bool operator<(const int a, const BitSegment<LowerBits, T>& b)
214{
215 return a < b.raw();
216}
217template <size_t LowerBits, typename T>
218bool operator>(const int a, const BitSegment<LowerBits, T>& b)
219{
220 return b < a;
221}
222
223template <size_t LowerBits, typename T>
224bool operator<=(const int a, const BitSegment<LowerBits, T>& b)
225{
226 return !(a > b);
227}
228template <size_t LowerBits, typename T>
229bool operator>=(const int a, const BitSegment<LowerBits, T>& b)
230{
231 return !(a < b);
232}
234
235} // namespace utility
236} // namespace m5
237#endif
Definition bit_segment.hpp:28
void upper(const unsigned_type v)
Set the value of upper segment.
Definition bit_segment.hpp:109
void raw(const base_type v)
Set the raw value.
Definition bit_segment.hpp:119
constexpr unsigned_type upper() const
Gets the value of upper segment.
Definition bit_segment.hpp:90
constexpr unsigned_type lower() const
Gets the value of lower segment.
Definition bit_segment.hpp:95
void lower(const unsigned_type v)
Set the value of lower segment.
Definition bit_segment.hpp:114
constexpr BitSegment()=default
default
constexpr BitSegment(const base_type v)
Implicit conversion.
Definition bit_segment.hpp:52
constexpr base_type raw() const
Gets the raw value.
Definition bit_segment.hpp:100
constexpr BitSegment(const BitSegment &o)
Copy.
Definition bit_segment.hpp:48
Top level namespace of M5.
Definition bit_segment.hpp:17
For utilities.