utils: Add more methods to EnumSet
Add assignment operators and methods for adding, removing and operators for performing set arithmatic. Change-Id: I13d30734354f503180f75480866b54034f647c2a Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/71320 Commit-Queue: Ben Clayton <bclayton@google.com> Reviewed-by: Antonio Maiorano <amaiorano@google.com> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
77e2c6f0b2
commit
62394b2492
|
@ -19,6 +19,7 @@
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace utils {
|
namespace utils {
|
||||||
|
@ -40,25 +41,88 @@ struct EnumSet {
|
||||||
template <typename... VALUES>
|
template <typename... VALUES>
|
||||||
explicit constexpr EnumSet(VALUES... values) : set(Union(values...)) {}
|
explicit constexpr EnumSet(VALUES... values) : set(Union(values...)) {}
|
||||||
|
|
||||||
/// Adds e to this set
|
/// Copy assignment operator.
|
||||||
|
/// @param set the set to assign to this set
|
||||||
|
/// @return this set so calls can be chained
|
||||||
|
inline EnumSet& operator=(const EnumSet& set) = default;
|
||||||
|
|
||||||
|
/// Copy assignment operator.
|
||||||
/// @param e the enum value
|
/// @param e the enum value
|
||||||
/// @return this set so calls can be chained
|
/// @return this set so calls can be chained
|
||||||
inline EnumSet& Add(Enum e) {
|
inline EnumSet& operator=(Enum e) { return *this = EnumSet{e}; }
|
||||||
set |= Bit(e);
|
|
||||||
return *this;
|
/// Adds all the given values to this set
|
||||||
|
/// @param values the values to add
|
||||||
|
/// @return this set so calls can be chained
|
||||||
|
template <typename... VALUES>
|
||||||
|
inline EnumSet& Add(VALUES... values) {
|
||||||
|
return Add(EnumSet(std::forward<VALUES>(values)...));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes e from this set
|
/// Removes all the given values from this set
|
||||||
/// @param e the enum value
|
/// @param values the values to remove
|
||||||
/// @return this set so calls can be chained
|
/// @return this set so calls can be chained
|
||||||
inline EnumSet& Remove(Enum e) {
|
template <typename... VALUES>
|
||||||
set &= ~Bit(e);
|
inline EnumSet& Remove(VALUES... values) {
|
||||||
return *this;
|
return Remove(EnumSet(std::forward<VALUES>(values)...));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Adds all of s to this set
|
||||||
|
/// @param s the enum value
|
||||||
|
/// @return this set so calls can be chained
|
||||||
|
inline EnumSet& Add(EnumSet s) { return (*this = *this + s); }
|
||||||
|
|
||||||
|
/// Removes all of s from this set
|
||||||
|
/// @param s the enum value
|
||||||
|
/// @return this set so calls can be chained
|
||||||
|
inline EnumSet& Remove(EnumSet s) { return (*this = *this - s); }
|
||||||
|
|
||||||
|
/// @param e the enum value
|
||||||
|
/// @returns a copy of this set with e added
|
||||||
|
inline EnumSet operator+(Enum e) const {
|
||||||
|
EnumSet out;
|
||||||
|
out.set = set | Bit(e);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @param e the enum value
|
||||||
|
/// @returns a copy of this set with e removed
|
||||||
|
inline EnumSet operator-(Enum e) const {
|
||||||
|
EnumSet out;
|
||||||
|
out.set = set & ~Bit(e);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @param s the other set
|
||||||
|
/// @returns the union of this set with s (this ∪ rhs)
|
||||||
|
inline EnumSet operator+(EnumSet s) const {
|
||||||
|
EnumSet out;
|
||||||
|
out.set = set | s.set;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @param s the other set
|
||||||
|
/// @returns the set of entries found in this but not in s (this \ s)
|
||||||
|
inline EnumSet operator-(EnumSet s) const {
|
||||||
|
EnumSet out;
|
||||||
|
out.set = set & ~s.set;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @param s the other set
|
||||||
|
/// @returns the intersection of this set with s (this ∩ rhs)
|
||||||
|
inline EnumSet operator&(EnumSet s) const {
|
||||||
|
EnumSet out;
|
||||||
|
out.set = set & s.set;
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @param e the enum value
|
/// @param e the enum value
|
||||||
/// @return true if the set contains `e`
|
/// @return true if the set contains `e`
|
||||||
inline bool Contains(Enum e) { return (set & Bit(e)) != 0; }
|
inline bool Contains(Enum e) const { return (set & Bit(e)) != 0; }
|
||||||
|
|
||||||
|
/// @return true if the set is empty
|
||||||
|
inline bool Empty() const { return set == 0; }
|
||||||
|
|
||||||
/// Equality operator
|
/// Equality operator
|
||||||
/// @param rhs the other EnumSet to compare this to
|
/// @param rhs the other EnumSet to compare this to
|
||||||
|
|
|
@ -44,6 +44,7 @@ TEST(EnumSetTest, ConstructEmpty) {
|
||||||
EXPECT_FALSE(set.Contains(E::A));
|
EXPECT_FALSE(set.Contains(E::A));
|
||||||
EXPECT_FALSE(set.Contains(E::B));
|
EXPECT_FALSE(set.Contains(E::B));
|
||||||
EXPECT_FALSE(set.Contains(E::C));
|
EXPECT_FALSE(set.Contains(E::C));
|
||||||
|
EXPECT_TRUE(set.Empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(EnumSetTest, ConstructWithSingle) {
|
TEST(EnumSetTest, ConstructWithSingle) {
|
||||||
|
@ -51,6 +52,7 @@ TEST(EnumSetTest, ConstructWithSingle) {
|
||||||
EXPECT_FALSE(set.Contains(E::A));
|
EXPECT_FALSE(set.Contains(E::A));
|
||||||
EXPECT_TRUE(set.Contains(E::B));
|
EXPECT_TRUE(set.Contains(E::B));
|
||||||
EXPECT_FALSE(set.Contains(E::C));
|
EXPECT_FALSE(set.Contains(E::C));
|
||||||
|
EXPECT_FALSE(set.Empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(EnumSetTest, ConstructWithMultiple) {
|
TEST(EnumSetTest, ConstructWithMultiple) {
|
||||||
|
@ -58,9 +60,26 @@ TEST(EnumSetTest, ConstructWithMultiple) {
|
||||||
EXPECT_TRUE(set.Contains(E::A));
|
EXPECT_TRUE(set.Contains(E::A));
|
||||||
EXPECT_FALSE(set.Contains(E::B));
|
EXPECT_FALSE(set.Contains(E::B));
|
||||||
EXPECT_TRUE(set.Contains(E::C));
|
EXPECT_TRUE(set.Contains(E::C));
|
||||||
|
EXPECT_FALSE(set.Empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(EnumSetTest, Add) {
|
TEST(EnumSetTest, AssignSet) {
|
||||||
|
EnumSet<E> set;
|
||||||
|
set = EnumSet<E>(E::A, E::C);
|
||||||
|
EXPECT_TRUE(set.Contains(E::A));
|
||||||
|
EXPECT_FALSE(set.Contains(E::B));
|
||||||
|
EXPECT_TRUE(set.Contains(E::C));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(EnumSetTest, AssignEnum) {
|
||||||
|
EnumSet<E> set(E::A);
|
||||||
|
set = E::B;
|
||||||
|
EXPECT_FALSE(set.Contains(E::A));
|
||||||
|
EXPECT_TRUE(set.Contains(E::B));
|
||||||
|
EXPECT_FALSE(set.Contains(E::C));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(EnumSetTest, AddEnum) {
|
||||||
EnumSet<E> set;
|
EnumSet<E> set;
|
||||||
set.Add(E::B);
|
set.Add(E::B);
|
||||||
EXPECT_FALSE(set.Contains(E::A));
|
EXPECT_FALSE(set.Contains(E::A));
|
||||||
|
@ -68,7 +87,7 @@ TEST(EnumSetTest, Add) {
|
||||||
EXPECT_FALSE(set.Contains(E::C));
|
EXPECT_FALSE(set.Contains(E::C));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(EnumSetTest, Remove) {
|
TEST(EnumSetTest, RemoveEnum) {
|
||||||
EnumSet<E> set(E::A, E::B);
|
EnumSet<E> set(E::A, E::B);
|
||||||
set.Remove(E::B);
|
set.Remove(E::B);
|
||||||
EXPECT_TRUE(set.Contains(E::A));
|
EXPECT_TRUE(set.Contains(E::A));
|
||||||
|
@ -76,6 +95,73 @@ TEST(EnumSetTest, Remove) {
|
||||||
EXPECT_FALSE(set.Contains(E::C));
|
EXPECT_FALSE(set.Contains(E::C));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(EnumSetTest, AddEnums) {
|
||||||
|
EnumSet<E> set;
|
||||||
|
set.Add(E::B, E::C);
|
||||||
|
EXPECT_FALSE(set.Contains(E::A));
|
||||||
|
EXPECT_TRUE(set.Contains(E::B));
|
||||||
|
EXPECT_TRUE(set.Contains(E::C));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(EnumSetTest, RemoveEnums) {
|
||||||
|
EnumSet<E> set(E::A, E::B);
|
||||||
|
set.Remove(E::C, E::B);
|
||||||
|
EXPECT_TRUE(set.Contains(E::A));
|
||||||
|
EXPECT_FALSE(set.Contains(E::B));
|
||||||
|
EXPECT_FALSE(set.Contains(E::C));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(EnumSetTest, AddEnumSet) {
|
||||||
|
EnumSet<E> set;
|
||||||
|
set.Add(EnumSet<E>{E::B, E::C});
|
||||||
|
EXPECT_FALSE(set.Contains(E::A));
|
||||||
|
EXPECT_TRUE(set.Contains(E::B));
|
||||||
|
EXPECT_TRUE(set.Contains(E::C));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(EnumSetTest, RemoveEnumSet) {
|
||||||
|
EnumSet<E> set(E::A, E::B);
|
||||||
|
set.Remove(EnumSet<E>{E::B, E::C});
|
||||||
|
EXPECT_TRUE(set.Contains(E::A));
|
||||||
|
EXPECT_FALSE(set.Contains(E::B));
|
||||||
|
EXPECT_FALSE(set.Contains(E::C));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(EnumSetTest, OperatorPlusEnum) {
|
||||||
|
EnumSet<E> set = EnumSet<E>{E::B} + E::C;
|
||||||
|
EXPECT_FALSE(set.Contains(E::A));
|
||||||
|
EXPECT_TRUE(set.Contains(E::B));
|
||||||
|
EXPECT_TRUE(set.Contains(E::C));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(EnumSetTest, OperatorMinusEnum) {
|
||||||
|
EnumSet<E> set = EnumSet<E>{E::A, E::B} - E::B;
|
||||||
|
EXPECT_TRUE(set.Contains(E::A));
|
||||||
|
EXPECT_FALSE(set.Contains(E::B));
|
||||||
|
EXPECT_FALSE(set.Contains(E::C));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(EnumSetTest, OperatorPlusSet) {
|
||||||
|
EnumSet<E> set = EnumSet<E>{E::B} + EnumSet<E>{E::B, E::C};
|
||||||
|
EXPECT_FALSE(set.Contains(E::A));
|
||||||
|
EXPECT_TRUE(set.Contains(E::B));
|
||||||
|
EXPECT_TRUE(set.Contains(E::C));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(EnumSetTest, OperatorMinusSet) {
|
||||||
|
EnumSet<E> set = EnumSet<E>{E::A, E::B} - EnumSet<E>{E::B, E::C};
|
||||||
|
EXPECT_TRUE(set.Contains(E::A));
|
||||||
|
EXPECT_FALSE(set.Contains(E::B));
|
||||||
|
EXPECT_FALSE(set.Contains(E::C));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(EnumSetTest, OperatorAnd) {
|
||||||
|
EnumSet<E> set = EnumSet<E>{E::A, E::B} & EnumSet<E>{E::B, E::C};
|
||||||
|
EXPECT_FALSE(set.Contains(E::A));
|
||||||
|
EXPECT_TRUE(set.Contains(E::B));
|
||||||
|
EXPECT_FALSE(set.Contains(E::C));
|
||||||
|
}
|
||||||
|
|
||||||
TEST(EnumSetTest, EqualitySet) {
|
TEST(EnumSetTest, EqualitySet) {
|
||||||
EXPECT_TRUE(EnumSet<E>(E::A, E::B) == EnumSet<E>(E::A, E::B));
|
EXPECT_TRUE(EnumSet<E>(E::A, E::B) == EnumSet<E>(E::A, E::B));
|
||||||
EXPECT_FALSE(EnumSet<E>(E::A, E::B) == EnumSet<E>(E::A, E::C));
|
EXPECT_FALSE(EnumSet<E>(E::A, E::B) == EnumSet<E>(E::A, E::C));
|
||||||
|
|
Loading…
Reference in New Issue