1.10
bitfields.h
1/*
2 * Copyright (C) 2022 Microchip Technology Inc. All rights reserved.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6#ifndef EGT_BITFIELDS_H
7#define EGT_BITFIELDS_H
8
14#include <egt/detail/enum.h>
15#include <egt/detail/meta.h>
16#include <egt/detail/string.h>
17#include <egt/signal.h>
18#include <list>
19#include <iosfwd>
20#include <sstream>
21#include <string>
22
23namespace egt
24{
25inline namespace v1
26{
27
28template<class T> class BitFields;
29
31{
32public:
33 constexpr BitField operator|(const BitField& rhs) const noexcept
34 {
35 return BitField(m_mask | rhs.m_mask, m_value | rhs.m_value);
36 }
37
38 constexpr bool operator==(const BitField& rhs) const noexcept
39 {
40 return (m_mask == rhs.m_mask) && (m_value == rhs.m_value);
41 }
42
43protected:
44 constexpr BitField(uint32_t mask, uint32_t value) noexcept
45 : m_mask(mask)
46 , m_value(value)
47 {}
48
49 constexpr BitField(uint32_t bit) noexcept
50 : m_mask(bit)
51 , m_value(bit)
52 {}
53
54 uint32_t m_mask;
55 uint32_t m_value;
56
57 template<class T> friend class BitFields;
58};
59
60template<class T>
61std::list<T> get(const BitFields<T>& fields);
62
63template<class T>
65{
66public:
67 constexpr BitFields() noexcept = default;
68
80 explicit BitFields(const std::string& str)
81 {
82 from_string(str);
83 }
84
88 explicit BitFields(const char* str)
89 {
90 from_string(str);
91 }
92
93 constexpr BitFields(const T& field)
94 : m_word(static_cast<const BitField&>(field).m_value)
95 {
96 }
97
99 constexpr BitFields(const BitFields& rhs) noexcept
100 : m_word(rhs.m_word)
101 {
102 // signals are not copied!
103 }
104
106 // NOLINTNEXTLINE(cert-oop54-cpp)
108 {
109 if (&rhs != this)
110 {
111 // signals are not copied!
114 }
115 return *this;
116 }
117
118 BitFields(BitFields&&) noexcept = default;
119 BitFields& operator=(BitFields&&) noexcept = default;
120 ~BitFields() noexcept = default;
121
122 bool operator==(const BitFields& rhs) const
123 {
124 return m_word == rhs.m_word;
125 }
126
127 bool operator!=(const BitFields& rhs) const
128 {
129 return !(*this == rhs);
130 }
131
132 bool empty() const
133 {
134 return m_word == 0;
135 }
136
137 EGT_NODISCARD constexpr bool is_set(const T& field) const noexcept
138 {
139 const auto& f = static_cast<const BitField&>(field);
140 return (m_word & f.m_mask) == f.m_value;
141 }
142
144 bool set(const T& field)
145 {
146 const auto& f = static_cast<const BitField&>(field);
147 return update((m_word & ~f.m_mask) | f.m_value);
148 }
149
151 bool clear(const T& field)
152 {
153 const auto& f = static_cast<const BitField&>(field);
154 return update(m_word & ~f.m_mask);
155 }
156
158 bool clear()
159 {
160 return update(0);
161 }
162
164 constexpr BitFields<T> operator|(const T& field) const noexcept
165 {
166 BitFields<T> ret(*this);
167 ret.set(field);
168 return ret;
169 }
170
172 constexpr static const char BITFIELDS_DELIMITER = '|';
173
177 EGT_NODISCARD std::string to_string() const
178 {
179 std::ostringstream ss;
180 if (!empty())
181 {
182 bool first = true;
183 const auto container = get(*this);
184 for (const auto& item : container)
185 {
186 if (first)
187 first = false;
188 else
190 ss << detail::enum_to_string(item);
191 }
192 }
193 return ss.str();
194 }
195
201 void from_string(const std::string& str)
202 {
203 clear();
204 std::vector<std::string> tokens;
206 for (const auto& field : tokens)
207 set(detail::enum_from_string<T>(detail::trim(field)));
208 }
209
210protected:
211
212 bool update(uint32_t new_word)
213 {
214 if (detail::change_if_diff(m_word, new_word))
215 {
217 return true;
218 }
219 return false;
220 }
221
222 uint32_t m_word{0};
223};
224
225}
226}
227
228#endif
Definition bitfields.h:31
uint32_t m_value
Definition bitfields.h:55
constexpr bool operator==(const BitField &rhs) const noexcept
Definition bitfields.h:38
constexpr BitField(uint32_t bit) noexcept
Definition bitfields.h:49
constexpr BitField operator|(const BitField &rhs) const noexcept
Definition bitfields.h:33
constexpr BitField(uint32_t mask, uint32_t value) noexcept
Definition bitfields.h:44
uint32_t m_mask
Definition bitfields.h:54
Definition bitfields.h:65
EGT_NODISCARD constexpr bool is_set(const T &field) const noexcept
Definition bitfields.h:137
BitFields & operator=(const BitFields &rhs)
Assignment operator.
Definition bitfields.h:107
constexpr BitFields< T > operator|(const T &field) const noexcept
Or operator.
Definition bitfields.h:164
static constexpr const char BITFIELDS_DELIMITER
Delimiter used to separate bit-fields in string representation.
Definition bitfields.h:172
bool clear(const T &field)
Clear a single bit-field.
Definition bitfields.h:151
void from_string(const std::string &str)
Convert from string.
Definition bitfields.h:201
bool empty() const
Definition bitfields.h:132
EGT_NODISCARD std::string to_string() const
Convert the bit-fields to strings.
Definition bitfields.h:177
bool update(uint32_t new_word)
Definition bitfields.h:212
Signal on_change
Event signal.
Definition bitfields.h:74
constexpr BitFields(const T &field)
Definition bitfields.h:93
BitFields(BitFields &&) noexcept=default
constexpr BitFields() noexcept=default
bool clear()
Clear all bit-fields.
Definition bitfields.h:158
constexpr BitFields(const BitFields &rhs) noexcept
Copy constructor.
Definition bitfields.h:99
BitFields(const char *str)
Definition bitfields.h:88
bool operator!=(const BitFields &rhs) const
Definition bitfields.h:127
uint32_t m_word
Definition bitfields.h:222
bool set(const T &field)
Set a single bit-field.
Definition bitfields.h:144
Signal class used for defining a signal and dispatching events.
Definition signal.h:30
void invoke(Args... args)
Invoke all handlers with the specified args.
Definition signal.h:85
EGT_API std::string trim(const std::string &source, const std::string &t=" \t\n\r")
Trim delimiters off both sides of a std::string.
EGT_API void tokenize(const std::string &str, char delimiter, std::vector< std::string > &tokens)
Tokenize a std::string.
constexpr bool change_if_diff(T &old, const T &to)
Utility to test and change a value if it is different.
Definition meta.h:194
constexpr const char * enum_to_string(T const &e)
Convert an enum to a string.
Definition enum.h:55
std::list< T > get(const BitFields< T > &fields)
EGT framework namespace.
Definition animation.h:24