| Index: components/sync/base/enum_set.h
|
| diff --git a/components/sync/base/enum_set.h b/components/sync/base/enum_set.h
|
| index c6e7b77688a3e1102a52c509fcab15a359d64757..83e319090259ffb82c0007887f0e7b701bb62777 100644
|
| --- a/components/sync/base/enum_set.h
|
| +++ b/components/sync/base/enum_set.h
|
| @@ -119,28 +119,42 @@ class EnumSet {
|
|
|
| EnumSet() {}
|
|
|
| - // Recursively chain constructors. Base case is the empty pack.
|
| + ~EnumSet() = default;
|
| +
|
| + static constexpr uint64_t single_val_bitstring(E val) {
|
| + return 1ULL << (ToIndex(val));
|
| + }
|
| +
|
| + // Base case for recursive packing of a list of enum values. The uint64_t
|
| + // corresponding to an empty list is 0.
|
| + static constexpr uint64_t bitstring() { return 0ULL; }
|
| +
|
| + // As of writing, constexpr expressions can't contain anything other than a
|
| + // return statement (and static asserts). To pack a variable number of enum
|
| + // value arguments into a bitstring, we use template varargs with a recursive
|
| + // constructor. Each recursive call packs one more enum into the bitstring,
|
| + // and the individual results are combined with bitwise or.
|
| template <class... T>
|
| - EnumSet(E head, T... tail) : EnumSet(tail...) {
|
| - Put(head);
|
| + static constexpr uint64_t bitstring(E head, T... tail) {
|
| + return (single_val_bitstring(head)) | bitstring(tail...);
|
| }
|
|
|
| + template <class... T>
|
| + constexpr EnumSet(E head, T... tail)
|
| + : EnumSet(EnumBitSet(bitstring(head, tail...))) {}
|
| +
|
| // Returns an EnumSet with all possible values.
|
| - static EnumSet All() {
|
| - EnumBitSet enums;
|
| - enums.set();
|
| - return EnumSet(enums);
|
| + static constexpr EnumSet All() {
|
| + return EnumSet(EnumBitSet((1ULL << kValueCount) - 1));
|
| }
|
|
|
| // Returns an EnumSet with all the values from start to end, inclusive.
|
| - static EnumSet FromRange(E start, E end) {
|
| - EnumSet set;
|
| - set.PutRange(start, end);
|
| - return set;
|
| + static constexpr EnumSet FromRange(E start, E end) {
|
| + return EnumSet(EnumBitSet(
|
| + ((single_val_bitstring(end)) - (single_val_bitstring(start))) |
|
| + (single_val_bitstring(end))));
|
| }
|
|
|
| - ~EnumSet() {}
|
| -
|
| // Copy constructor and assignment welcome.
|
|
|
| // Set operations. Put, Retain, and Remove are basically
|
| @@ -182,8 +196,8 @@ class EnumSet {
|
| void Clear() { enums_.reset(); }
|
|
|
| // Returns true iff the given value is in range and a member of our set.
|
| - bool Has(E value) const {
|
| - return InRange(value) && enums_.test(ToIndex(value));
|
| + constexpr bool Has(E value) const {
|
| + return InRange(value) && enums_[ToIndex(value)];
|
| }
|
|
|
| // Returns true iff the given set is a subset of our set.
|
| @@ -215,19 +229,22 @@ class EnumSet {
|
| friend EnumSet Difference<E, MinEnumValue, MaxEnumValue>(EnumSet set1,
|
| EnumSet set2);
|
|
|
| - explicit EnumSet(EnumBitSet enums) : enums_(enums) {}
|
| + // A bitset can't be constexpr constructed if it has size > 64, since the
|
| + // constexpr constructor uses a uint64_t. If your EnumSet has > 64 values, you
|
| + // can safely remove the constepxr qualifiers from this file, at the cost of
|
| + // some minor optimizations.
|
| + explicit constexpr EnumSet(EnumBitSet enums) : enums_(enums) {
|
| + static_assert(kValueCount < 64,
|
| + "Max number of enum values is 64 for constexpr ");
|
| + }
|
|
|
| - static bool InRange(E value) {
|
| + static constexpr bool InRange(E value) {
|
| return (value >= MinEnumValue) && (value <= MaxEnumValue);
|
| }
|
|
|
| // Converts a value to/from an index into |enums_|.
|
|
|
| - static size_t ToIndex(E value) {
|
| - DCHECK_GE(value, MinEnumValue);
|
| - DCHECK_LE(value, MaxEnumValue);
|
| - return value - MinEnumValue;
|
| - }
|
| + static constexpr size_t ToIndex(E value) { return value - MinEnumValue; }
|
|
|
| static E FromIndex(size_t i) {
|
| DCHECK_LT(i, kValueCount);
|
|
|