Chromium Code Reviews| 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..b1aa5a0667692c3d9aaaf07dd0b7a3bb61cb7746 100644 |
| --- a/components/sync/base/enum_set.h |
| +++ b/components/sync/base/enum_set.h |
| @@ -119,28 +119,53 @@ class EnumSet { |
| EnumSet() {} |
| - // Recursively chain constructors. Base case is the empty pack. |
| + ~EnumSet() = default; |
| + |
| + // 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; } |
| + |
| + // Recursively pack a list of enum values into a uint64 so that we can |
| + // constexpr construct our bitset. This packing is done by left shifting 1 by |
|
skym
2017/05/05 23:15:41
Can you rework/remove the "This packing is done by
Patrick Noland
2017/05/08 20:29:19
Done.
|
| + // the current enum value and bitwise or-ing with the bitstring representation |
| + // of the rest of the values. |
| template <class... T> |
| - EnumSet(E head, T... tail) : EnumSet(tail...) { |
| - Put(head); |
| + static constexpr uint64_t bitstring(E head, T... tail) { |
| + return 1ULL << (ToIndex(head)) | bitstring(tail...); |
|
skym
2017/05/05 23:15:41
Not really understanding the precedence of operato
Patrick Noland
2017/05/08 20:29:19
Done.
|
| + } |
| + |
| + template <class... T> |
| + constexpr EnumSet(E head, T... tail) |
| + : EnumSet(EnumBitSet(bitstring(head, tail...))) { |
| + static_assert(kValueCount < 64, |
|
skym
2017/05/05 23:15:41
Is this really the right place for the static asse
Patrick Noland
2017/05/08 20:29:19
Done.
|
| + "Max number of enum values is 64 for constexpr " |
| + "initialization. If your EnumSet is > 64 values, you can " |
| + "fix this by removing the static_asserts and constexpr " |
| + "qualifiers from this file."); |
|
skym
2017/05/05 23:15:41
What impact will this have? Why is this bad?
Patrick Noland
2017/05/08 20:29:19
Done. I explained that it won't affect correctness
|
| } |
| // Returns an EnumSet with all possible values. |
| - static EnumSet All() { |
| - EnumBitSet enums; |
| - enums.set(); |
| - return EnumSet(enums); |
| + static constexpr EnumSet All() { |
| + static_assert(kValueCount < 64, |
| + "Max number of enum values is 64 for constexpr " |
|
skym
2017/05/05 23:15:41
Lets not duplicate quite so much. Maybe have a big
Patrick Noland
2017/05/08 20:29:19
Done.
|
| + "initialization. If your EnumSet is > 64 values, you can " |
| + "fix this by removing the static_asserts and constexpr " |
| + "qualifiers from this file."); |
| + 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) { |
| + static_assert(kValueCount < 64, |
| + "Max number of enum values is 64 for constexpr " |
|
skym
2017/05/05 23:15:41
same
Patrick Noland
2017/05/08 20:29:19
Done.
|
| + "initialization. If your EnumSet is > 64 values, you can " |
| + "fix this by removing the static_asserts and constexpr " |
| + "qualifiers from this file."); |
| + return EnumSet( |
| + EnumBitSet(((1ULL << ToIndex(end)) - (1ULL << ToIndex(start))) | |
|
skym
2017/05/05 23:15:41
Omg this is so clever! Love it! What do you think
Patrick Noland
2017/05/08 20:29:19
Done.
|
| + (1ULL << ToIndex(end)))); |
| } |
| - ~EnumSet() {} |
| - |
| // Copy constructor and assignment welcome. |
| // Set operations. Put, Retain, and Remove are basically |
| @@ -182,8 +207,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 +240,15 @@ class EnumSet { |
| friend EnumSet Difference<E, MinEnumValue, MaxEnumValue>(EnumSet set1, |
| EnumSet set2); |
| - explicit EnumSet(EnumBitSet enums) : enums_(enums) {} |
| + explicit constexpr EnumSet(EnumBitSet enums) : enums_(enums) {} |
| - 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); |