Skip to content

Commit f3fa204

Browse files
authored
Merge pull request #7 from m-peko/set-and-remove-flag
Support setting and removing specific flag
2 parents 789521a + d9615e2 commit f3fa204

File tree

3 files changed

+85
-2
lines changed

3 files changed

+85
-2
lines changed

README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ int main() {
5151
* [Bitwise Operators](#bitwise-operators)
5252
* [Is Specific Flag Set?](#is-specific-flag-set)
5353
* [All or Empty](#all-or-empty)
54+
* [Set and Remove Specific Flag](#set-and-remove-specific-flag)
5455
* [Toggle Flags](#toggle-flags)
5556
* [Clear Flags](#clear-flags)
5657
* [Building Samples and Tests](#building-samples-and-tests)
@@ -197,6 +198,36 @@ std::cout << flags.contains(Flags::flag_b) << std::endl; // false
197198
std::cout << flags.is_empty() << std::endl; // true
198199
```
199200
201+
### Set and Remove Specific Flag
202+
203+
Not only that one can set and remove specific flag by using bitwise operators, but there are also special member functions `set` and `remove` that have the same purpose.
204+
205+
```cpp
206+
struct Flags : bf::bitflags<uint32_t> {
207+
using bitflags<uint32_t>::bitflags;
208+
209+
BITFLAG(0x00000000, none);
210+
BITFLAG(0x00000001, flag_a);
211+
BITFLAG(0x00000010, flag_b);
212+
};
213+
214+
Flags flags = Flags::empty();
215+
216+
std::cout << flags.contains(Flags::flag_a) << std::endl; // false
217+
std::cout << flags.contains(Flags::flag_b) << std::endl; // false
218+
219+
flags.set(Flags::flag_a);
220+
flags.set(Flags::flag_b);
221+
222+
std::cout << flags.contains(Flags::flag_a) << std::endl; // true
223+
std::cout << flags.contains(Flags::flag_b) << std::endl; // true
224+
225+
flags.remove(Flags::flag_a);
226+
227+
std::cout << flags.contains(Flags::flag_a) << std::endl; // false
228+
std::cout << flags.contains(Flags::flag_b) << std::endl; // true
229+
```
230+
200231
### Toggle Flags
201232

202233
It is possible to toggle specific flag, i.e. if the flag is not already set, it will be set. On the other hand, if the flag is already set, it will be unset.

include/bitflags/bitflags.hpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -372,9 +372,31 @@ class bitflags {
372372
}
373373

374374
/**
375-
* Sets the specified flags if not already present. Otherwise, unsets the specified flags.
375+
* Sets specified flag.
376376
*
377-
* @param rhs Flags to be toggled
377+
* @param rhs Flag to be set
378+
*/
379+
constexpr void set(internal::flag<T> const& rhs) noexcept {
380+
if (!contains(rhs)) {
381+
curr_ ^= rhs;
382+
}
383+
}
384+
385+
/**
386+
* Unsets specified flag.
387+
*
388+
* @param rhs Flag to be unset
389+
*/
390+
constexpr void remove(internal::flag<T> const& rhs) noexcept {
391+
if (contains(rhs)) {
392+
curr_ ^= rhs;
393+
}
394+
}
395+
396+
/**
397+
* Sets specified flag if not already present. Otherwise, unsets the specified flag.
398+
*
399+
* @param rhs Flag to be toggled
378400
*/
379401
constexpr void toggle(internal::flag<T> const& rhs) noexcept {
380402
curr_ ^= rhs;

tests/src/bitflags_test.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,36 @@ TEST_F(BitflagsTest, Contains) {
127127
EXPECT_FALSE(flags.contains(Flags::none, Flags::flag_a, Flags::flag_c));
128128
}
129129

130+
TEST_F(BitflagsTest, Set) {
131+
Flags flags = Flags::none;
132+
133+
EXPECT_FALSE(flags.contains(Flags::flag_a));
134+
EXPECT_FALSE(flags.contains(Flags::flag_b));
135+
EXPECT_FALSE(flags.contains(Flags::flag_c));
136+
137+
flags.set(Flags::flag_a);
138+
flags.set(Flags::flag_b);
139+
140+
EXPECT_TRUE(flags.contains(Flags::flag_a));
141+
EXPECT_TRUE(flags.contains(Flags::flag_b));
142+
EXPECT_FALSE(flags.contains(Flags::flag_c));
143+
}
144+
145+
TEST_F(BitflagsTest, Remove) {
146+
Flags flags = Flags::flag_a | Flags::flag_b;
147+
148+
EXPECT_TRUE(flags.contains(Flags::flag_a));
149+
EXPECT_TRUE(flags.contains(Flags::flag_b));
150+
EXPECT_FALSE(flags.contains(Flags::flag_c));
151+
152+
flags.remove(Flags::flag_a);
153+
flags.remove(Flags::flag_b);
154+
155+
EXPECT_FALSE(flags.contains(Flags::flag_a));
156+
EXPECT_FALSE(flags.contains(Flags::flag_b));
157+
EXPECT_FALSE(flags.contains(Flags::flag_c));
158+
}
159+
130160
TEST_F(BitflagsTest, Toggle) {
131161
Flags flags = Flags::flag_a | Flags::flag_b;
132162

0 commit comments

Comments
 (0)