Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update API #24

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 29 additions & 16 deletions include/bitflags/bitflags.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -498,25 +498,38 @@ class bitflags : public ImplT {
*
* @return True if all flags are currently set, otherwise false
*/
NODISCARD constexpr bool is_all() const noexcept {
NODISCARD constexpr bool all_set() const noexcept {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be consistent with other functions, we should name this function is_all_set

return curr_ == ~T{};
}

/**
* Checks whether specified flag is contained within the current
* Checks whether only the specified flag is set in the current
* set of flags.
*
* @param rhs Flag to check
*
* @return True if only the specified flag is in the
* current set of flags, otherwise false
*/
NODISCARD constexpr bool only_set(FlagT<ImplT, T> const& rhs) const noexcept {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this, you have is_set / contains function

return curr_ == rhs;
}

/**
* Checks whether specified flag is in the current
* set of flags. Zero flags are treated as always present.
*
* @param rhs Flag to check
*
* @return True if the specified flags is contained within the
* @return True if the specified flags is in the
* current set of flags, otherwise false
*/
NODISCARD constexpr bool contains(FlagT<ImplT, T> const& rhs) const noexcept {
NODISCARD constexpr bool is_set(FlagT<ImplT, T> const& rhs) const noexcept {
return static_cast<T>(curr_ & rhs) || rhs == empty();
}

/**
* Checks whether all the specified flags are contained within the
* Checks whether all the specified flags are in the
* current set of flags. Zero flags are treated as always present.
*
* @param rhs_1 First flag to check
Expand All @@ -526,8 +539,8 @@ class bitflags : public ImplT {
* current set of flags, otherwise false
*/
template <typename ... U>
NODISCARD constexpr bool contains(FlagT<ImplT, T> const& rhs_1, U const& ... rhs_n) const noexcept {
return contains(rhs_1) && contains(rhs_n...);
NODISCARD constexpr bool is_set(FlagT<ImplT, T> const& rhs_1, U const& ... rhs_n) const noexcept {
return is_set(rhs_1) && is_set(rhs_n...);
}

/**
Expand All @@ -539,15 +552,6 @@ class bitflags : public ImplT {
curr_ |= rhs;
}

/**
* Unsets specified flag.
*
* @param rhs Flag to be unset
*/
NON_CONST_CONSTEXPR void remove(FlagT<ImplT, T> const& rhs) noexcept {
curr_ &= ~rhs;
}

/**
* Sets specified flag if not already present.
* Otherwise, unsets the specified flag.
Expand All @@ -558,6 +562,15 @@ class bitflags : public ImplT {
curr_ ^= rhs;
}

/**
* Clear the specified flag.
*
* @param rhs Flag to be unset
*/
NON_CONST_CONSTEXPR void clear(FlagT<ImplT, T> const& rhs) noexcept {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we take a look at the std::bitset implementation, then it's better to call this function reset

curr_ &= ~rhs;
}

/**
* Clears all flags currently set.
*/
Expand Down
174 changes: 95 additions & 79 deletions tests/src/bitflags_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ TEST_F(BitflagsTest, Empty) {
RawFlags raw_flags = RawFlags::empty();

EXPECT_TRUE(raw_flags.is_empty());
EXPECT_FALSE(raw_flags.is_all());
EXPECT_FALSE(raw_flags.all_set());
EXPECT_FALSE(raw_flags & RawFlags::flag_a);
EXPECT_FALSE(raw_flags & RawFlags::flag_b);
EXPECT_FALSE(raw_flags & RawFlags::flag_c);
Expand All @@ -230,27 +230,27 @@ TEST_F(BitflagsTest, Empty) {
Flags flags = Flags::empty();

EXPECT_TRUE(flags.is_empty());
EXPECT_FALSE(flags.is_all());
EXPECT_FALSE(flags.all_set());
EXPECT_FALSE(flags & Flags::flag_a);
EXPECT_FALSE(flags & Flags::flag_b);
EXPECT_FALSE(flags & Flags::flag_c);
}

TEST_F(BitflagsTest, All) {
TEST_F(BitflagsTest, DISABLED_All) {
// raw flags (without string representation)
RawFlags raw_flags = RawFlags::all();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all method is supposed to return bitflags with all bits set to true. However, this might not be the perfect naming. We should consider renaming is_all_set -> all (this will check if all the bits are set to true) and all -> set (without parameter) - this will set all the bits to true.
+
we can add all/any/none like here

RawFlags raw_flags = RawFlags::flag_a | RawFlags::flag_b | RawFlags::flag_c;

EXPECT_FALSE(raw_flags.is_empty());
EXPECT_TRUE(raw_flags.is_all());
EXPECT_TRUE(raw_flags.all_set());
EXPECT_TRUE(raw_flags & RawFlags::flag_a);
EXPECT_TRUE(raw_flags & RawFlags::flag_b);
EXPECT_TRUE(raw_flags & RawFlags::flag_c);

EXPECT_TRUE(raw_flags & RawFlags::flag_c);
// flags (with string representation)
Flags flags = Flags::all();
Flags flags = Flags::flag_a | Flags::flag_b | Flags::flag_c;

EXPECT_FALSE(flags.is_empty());
EXPECT_TRUE(flags.is_all());
EXPECT_TRUE(flags.all_set());
EXPECT_TRUE(flags & Flags::flag_a);
EXPECT_TRUE(flags & Flags::flag_b);
EXPECT_TRUE(flags & Flags::flag_c);
Expand All @@ -260,156 +260,172 @@ TEST_F(BitflagsTest, Contains) {
// raw flags (without string representation)
RawFlags raw_flags = RawFlags::flag_a | RawFlags::flag_b;

EXPECT_TRUE(raw_flags.contains(RawFlags::none));
EXPECT_TRUE(raw_flags.contains(RawFlags::flag_a));
EXPECT_TRUE(raw_flags.contains(RawFlags::flag_b));
EXPECT_FALSE(raw_flags.contains(RawFlags::flag_c));
EXPECT_TRUE(raw_flags.is_set(RawFlags::none));
EXPECT_TRUE(raw_flags.is_set(RawFlags::flag_a));
EXPECT_TRUE(raw_flags.is_set(RawFlags::flag_b));
EXPECT_FALSE(raw_flags.is_set(RawFlags::flag_c));

EXPECT_TRUE(raw_flags.contains(RawFlags::none, RawFlags::flag_a, RawFlags::flag_b));
EXPECT_FALSE(raw_flags.contains(RawFlags::none, RawFlags::flag_a, RawFlags::flag_c));
EXPECT_TRUE(raw_flags.is_set(RawFlags::none, RawFlags::flag_a, RawFlags::flag_b));
EXPECT_FALSE(raw_flags.is_set(RawFlags::none, RawFlags::flag_a, RawFlags::flag_c));

// flags (with string representation)
Flags flags = Flags::flag_a | Flags::flag_b;

EXPECT_TRUE(flags.contains(Flags::none));
EXPECT_TRUE(flags.contains(Flags::flag_a));
EXPECT_TRUE(flags.contains(Flags::flag_b));
EXPECT_FALSE(flags.contains(Flags::flag_c));
EXPECT_TRUE(flags.is_set(Flags::none));
EXPECT_TRUE(flags.is_set(Flags::flag_a));
EXPECT_TRUE(flags.is_set(Flags::flag_b));
EXPECT_FALSE(flags.is_set(Flags::flag_c));

EXPECT_TRUE(flags.contains(Flags::none, Flags::flag_a, Flags::flag_b));
EXPECT_FALSE(flags.contains(Flags::none, Flags::flag_a, Flags::flag_c));
EXPECT_TRUE(flags.is_set(Flags::none, Flags::flag_a, Flags::flag_b));
EXPECT_FALSE(flags.is_set(Flags::none, Flags::flag_a, Flags::flag_c));
}

TEST_F(BitflagsTest, Set) {
// raw flags (without string representation)
RawFlags raw_flags = RawFlags::none;

EXPECT_FALSE(raw_flags.contains(RawFlags::flag_a));
EXPECT_FALSE(raw_flags.contains(RawFlags::flag_b));
EXPECT_FALSE(raw_flags.contains(RawFlags::flag_c));
EXPECT_FALSE(raw_flags.is_set(RawFlags::flag_a));
EXPECT_FALSE(raw_flags.is_set(RawFlags::flag_b));
EXPECT_FALSE(raw_flags.is_set(RawFlags::flag_c));

raw_flags.set(RawFlags::flag_a);
raw_flags.set(RawFlags::flag_b);

EXPECT_TRUE(raw_flags.contains(RawFlags::flag_a));
EXPECT_TRUE(raw_flags.contains(RawFlags::flag_b));
EXPECT_FALSE(raw_flags.contains(RawFlags::flag_c));
EXPECT_TRUE(raw_flags.is_set(RawFlags::flag_a));
EXPECT_TRUE(raw_flags.is_set(RawFlags::flag_b));
EXPECT_FALSE(raw_flags.is_set(RawFlags::flag_c));

// flags (with string representation)
Flags flags = Flags::none;

EXPECT_FALSE(flags.contains(Flags::flag_a));
EXPECT_FALSE(flags.contains(Flags::flag_b));
EXPECT_FALSE(flags.contains(Flags::flag_c));
EXPECT_FALSE(flags.is_set(Flags::flag_a));
EXPECT_FALSE(flags.is_set(Flags::flag_b));
EXPECT_FALSE(flags.is_set(Flags::flag_c));

flags.set(Flags::flag_a);
flags.set(Flags::flag_b);

EXPECT_TRUE(flags.contains(Flags::flag_a));
EXPECT_TRUE(flags.contains(Flags::flag_b));
EXPECT_FALSE(flags.contains(Flags::flag_c));
EXPECT_TRUE(flags.is_set(Flags::flag_a));
EXPECT_TRUE(flags.is_set(Flags::flag_b));
EXPECT_FALSE(flags.is_set(Flags::flag_c));
}

TEST_F(BitflagsTest, Remove) {
// raw flags (without string representation)
RawFlags raw_flags = RawFlags::flag_a | RawFlags::flag_b | RawFlags::flag_c;

EXPECT_TRUE(raw_flags.contains(RawFlags::flag_a));
EXPECT_TRUE(raw_flags.contains(RawFlags::flag_b));
EXPECT_TRUE(raw_flags.contains(RawFlags::flag_c));
EXPECT_TRUE(raw_flags.is_set(RawFlags::flag_a));
EXPECT_TRUE(raw_flags.is_set(RawFlags::flag_b));
EXPECT_TRUE(raw_flags.is_set(RawFlags::flag_c));

raw_flags.remove(RawFlags::flag_a);
raw_flags.remove(RawFlags::flag_b);
raw_flags.clear(RawFlags::flag_a);
raw_flags.clear(RawFlags::flag_b);

EXPECT_FALSE(raw_flags.contains(RawFlags::flag_a));
EXPECT_FALSE(raw_flags.contains(RawFlags::flag_b));
EXPECT_TRUE(raw_flags.contains(RawFlags::flag_c));
EXPECT_FALSE(raw_flags.is_set(RawFlags::flag_a));
EXPECT_FALSE(raw_flags.is_set(RawFlags::flag_b));
EXPECT_TRUE(raw_flags.is_set(RawFlags::flag_c));

// flags (with string representation)
Flags flags = Flags::flag_a | Flags::flag_b | Flags::flag_c;

EXPECT_TRUE(flags.contains(Flags::flag_a));
EXPECT_TRUE(flags.contains(Flags::flag_b));
EXPECT_TRUE(flags.contains(Flags::flag_c));
EXPECT_TRUE(flags.is_set(Flags::flag_a));
EXPECT_TRUE(flags.is_set(Flags::flag_b));
EXPECT_TRUE(flags.is_set(Flags::flag_c));

flags.remove(Flags::flag_a);
flags.remove(Flags::flag_b);
flags.clear(Flags::flag_a);
flags.clear(Flags::flag_b);

EXPECT_FALSE(flags.contains(Flags::flag_a));
EXPECT_FALSE(flags.contains(Flags::flag_b));
EXPECT_TRUE(flags.contains(Flags::flag_c));
EXPECT_FALSE(flags.is_set(Flags::flag_a));
EXPECT_FALSE(flags.is_set(Flags::flag_b));
EXPECT_TRUE(flags.is_set(Flags::flag_c));
}

TEST_F(BitflagsTest, Toggle) {
// raw flags (without string representation)
RawFlags raw_flags = RawFlags::flag_a | RawFlags::flag_b;

EXPECT_TRUE(raw_flags.contains(RawFlags::flag_a));
EXPECT_TRUE(raw_flags.contains(RawFlags::flag_b));
EXPECT_FALSE(raw_flags.contains(RawFlags::flag_c));
EXPECT_TRUE(raw_flags.is_set(RawFlags::flag_a));
EXPECT_TRUE(raw_flags.is_set(RawFlags::flag_b));
EXPECT_FALSE(raw_flags.is_set(RawFlags::flag_c));

raw_flags.toggle(RawFlags::flag_a);
raw_flags.toggle(RawFlags::flag_c);

EXPECT_FALSE(raw_flags.contains(RawFlags::flag_a));
EXPECT_TRUE(raw_flags.contains(RawFlags::flag_b));
EXPECT_TRUE(raw_flags.contains(RawFlags::flag_c));
EXPECT_FALSE(raw_flags.is_set(RawFlags::flag_a));
EXPECT_TRUE(raw_flags.is_set(RawFlags::flag_b));
EXPECT_TRUE(raw_flags.is_set(RawFlags::flag_c));

raw_flags.toggle(RawFlags::flag_a);
raw_flags.toggle(RawFlags::flag_b);

EXPECT_TRUE(raw_flags.contains(RawFlags::flag_a));
EXPECT_FALSE(raw_flags.contains(RawFlags::flag_b));
EXPECT_TRUE(raw_flags.contains(RawFlags::flag_c));
EXPECT_TRUE(raw_flags.is_set(RawFlags::flag_a));
EXPECT_FALSE(raw_flags.is_set(RawFlags::flag_b));
EXPECT_TRUE(raw_flags.is_set(RawFlags::flag_c));

// flags (with string representation)
Flags flags = Flags::flag_a | Flags::flag_b;

EXPECT_TRUE(flags.contains(Flags::flag_a));
EXPECT_TRUE(flags.contains(Flags::flag_b));
EXPECT_FALSE(flags.contains(Flags::flag_c));
EXPECT_TRUE(flags.is_set(Flags::flag_a));
EXPECT_TRUE(flags.is_set(Flags::flag_b));
EXPECT_FALSE(flags.is_set(Flags::flag_c));

flags.toggle(Flags::flag_a);
flags.toggle(Flags::flag_c);

EXPECT_FALSE(flags.contains(Flags::flag_a));
EXPECT_TRUE(flags.contains(Flags::flag_b));
EXPECT_TRUE(flags.contains(Flags::flag_c));
EXPECT_FALSE(flags.is_set(Flags::flag_a));
EXPECT_TRUE(flags.is_set(Flags::flag_b));
EXPECT_TRUE(flags.is_set(Flags::flag_c));

flags.toggle(Flags::flag_a);
flags.toggle(Flags::flag_b);

EXPECT_TRUE(flags.contains(Flags::flag_a));
EXPECT_FALSE(flags.contains(Flags::flag_b));
EXPECT_TRUE(flags.contains(Flags::flag_c));
EXPECT_TRUE(flags.is_set(Flags::flag_a));
EXPECT_FALSE(flags.is_set(Flags::flag_b));
EXPECT_TRUE(flags.is_set(Flags::flag_c));
}

TEST_F(BitflagsTest, Clear) {
// raw flags (without string representation)
RawFlags raw_flags = RawFlags::flag_a | RawFlags::flag_b;

EXPECT_TRUE(raw_flags.contains(RawFlags::flag_a));
EXPECT_TRUE(raw_flags.contains(RawFlags::flag_b));
EXPECT_FALSE(raw_flags.contains(RawFlags::flag_c));
EXPECT_TRUE(raw_flags.is_set(RawFlags::flag_a));
EXPECT_TRUE(raw_flags.is_set(RawFlags::flag_b));
EXPECT_FALSE(raw_flags.is_set(RawFlags::flag_c));

raw_flags.clear();

EXPECT_TRUE(raw_flags.is_empty());
EXPECT_FALSE(raw_flags.contains(RawFlags::flag_a));
EXPECT_FALSE(raw_flags.contains(RawFlags::flag_b));
EXPECT_FALSE(raw_flags.contains(RawFlags::flag_c));
EXPECT_FALSE(raw_flags.is_set(RawFlags::flag_a));
EXPECT_FALSE(raw_flags.is_set(RawFlags::flag_b));
EXPECT_FALSE(raw_flags.is_set(RawFlags::flag_c));

// flags (with string representation)
Flags flags = Flags::flag_a | Flags::flag_b;

EXPECT_TRUE(flags.contains(Flags::flag_a));
EXPECT_TRUE(flags.contains(Flags::flag_b));
EXPECT_FALSE(flags.contains(Flags::flag_c));
EXPECT_TRUE(flags.is_set(Flags::flag_a));
EXPECT_TRUE(flags.is_set(Flags::flag_b));
EXPECT_FALSE(flags.is_set(Flags::flag_c));

flags.clear();

EXPECT_TRUE(flags.is_empty());
EXPECT_FALSE(flags.contains(Flags::flag_a));
EXPECT_FALSE(flags.contains(Flags::flag_b));
EXPECT_FALSE(flags.contains(Flags::flag_c));
EXPECT_FALSE(flags.is_set(Flags::flag_a));
EXPECT_FALSE(flags.is_set(Flags::flag_b));
EXPECT_FALSE(flags.is_set(Flags::flag_c));
}

TEST_F(BitflagsTest, OnlySet) {
// raw flags (without string representation)
RawFlags raw_flags = RawFlags::flag_a | RawFlags::flag_b;

EXPECT_FALSE(raw_flags.only_set(RawFlags::flag_a));
EXPECT_FALSE(raw_flags.only_set(RawFlags::flag_b));

EXPECT_FALSE(raw_flags.only_set(RawFlags::flag_b));
raw_flags.clear(RawFlags::flag_b);

EXPECT_TRUE(raw_flags.only_set(RawFlags::flag_a));

raw_flags.set(RawFlags::flag_c);
EXPECT_FALSE(raw_flags.only_set(RawFlags::flag_a));
}