| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef SYNC_INTERNAL_API_PUBLIC_BASE_ENUM_SET_H_ | 5 #ifndef COMPONENTS_SYNC_BASE_ENUM_SET_H_ |
| 6 #define SYNC_INTERNAL_API_PUBLIC_BASE_ENUM_SET_H_ | 6 #define COMPONENTS_SYNC_BASE_ENUM_SET_H_ |
| 7 | 7 |
| 8 #include <bitset> | 8 #include <bitset> |
| 9 #include <cstddef> | 9 #include <cstddef> |
| 10 #include <string> | 10 #include <string> |
| 11 | 11 |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 | 13 |
| 14 namespace syncer { | 14 namespace syncer { |
| 15 | 15 |
| 16 // Forward declarations needed for friend declarations. | 16 // Forward declarations needed for friend declarations. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 38 // (say, fewer than 64), you can efficiently pass around an EnumSet | 38 // (say, fewer than 64), you can efficiently pass around an EnumSet |
| 39 // for that enum around by value. | 39 // for that enum around by value. |
| 40 | 40 |
| 41 template <typename E, E MinEnumValue, E MaxEnumValue> | 41 template <typename E, E MinEnumValue, E MaxEnumValue> |
| 42 class EnumSet { | 42 class EnumSet { |
| 43 public: | 43 public: |
| 44 typedef E EnumType; | 44 typedef E EnumType; |
| 45 static const E kMinValue = MinEnumValue; | 45 static const E kMinValue = MinEnumValue; |
| 46 static const E kMaxValue = MaxEnumValue; | 46 static const E kMaxValue = MaxEnumValue; |
| 47 static const size_t kValueCount = kMaxValue - kMinValue + 1; | 47 static const size_t kValueCount = kMaxValue - kMinValue + 1; |
| 48 static_assert(kMinValue < kMaxValue, | 48 static_assert(kMinValue < kMaxValue, "min value must be less than max value"); |
| 49 "min value must be less than max value"); | |
| 50 | 49 |
| 51 private: | 50 private: |
| 52 // Declaration needed by Iterator. | 51 // Declaration needed by Iterator. |
| 53 typedef std::bitset<kValueCount> EnumBitSet; | 52 typedef std::bitset<kValueCount> EnumBitSet; |
| 54 | 53 |
| 55 public: | 54 public: |
| 56 // Iterator is a forward-only read-only iterator for EnumSet. Its | 55 // Iterator is a forward-only read-only iterator for EnumSet. Its |
| 57 // interface is deliberately distinct from an STL iterator as its | 56 // interface is deliberately distinct from an STL iterator as its |
| 58 // semantics are substantially different. | 57 // semantics are substantially different. |
| 59 // | 58 // |
| (...skipping 18 matching lines...) Expand all Loading... |
| 78 // A default-constructed iterator can't do anything except check | 77 // A default-constructed iterator can't do anything except check |
| 79 // Good(). You need to call First() on an EnumSet to get a usable | 78 // Good(). You need to call First() on an EnumSet to get a usable |
| 80 // iterator. | 79 // iterator. |
| 81 Iterator() : enums_(NULL), i_(kValueCount) {} | 80 Iterator() : enums_(NULL), i_(kValueCount) {} |
| 82 ~Iterator() {} | 81 ~Iterator() {} |
| 83 | 82 |
| 84 // Copy constructor and assignment welcome. | 83 // Copy constructor and assignment welcome. |
| 85 | 84 |
| 86 // Returns true iff the iterator points to an EnumSet and it | 85 // Returns true iff the iterator points to an EnumSet and it |
| 87 // hasn't yet traversed the EnumSet entirely. | 86 // hasn't yet traversed the EnumSet entirely. |
| 88 bool Good() const { | 87 bool Good() const { return enums_ && i_ < kValueCount && enums_->test(i_); } |
| 89 return enums_ && i_ < kValueCount && enums_->test(i_); | |
| 90 } | |
| 91 | 88 |
| 92 // Returns the value the iterator currently points to. Good() | 89 // Returns the value the iterator currently points to. Good() |
| 93 // must hold. | 90 // must hold. |
| 94 E Get() const { | 91 E Get() const { |
| 95 CHECK(Good()); | 92 CHECK(Good()); |
| 96 return FromIndex(i_); | 93 return FromIndex(i_); |
| 97 } | 94 } |
| 98 | 95 |
| 99 // Moves the iterator to the next value in the EnumSet. Good() | 96 // Moves the iterator to the next value in the EnumSet. Good() |
| 100 // must hold. Takes linear time. | 97 // must hold. Takes linear time. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 117 } | 114 } |
| 118 | 115 |
| 119 const EnumBitSet* enums_; | 116 const EnumBitSet* enums_; |
| 120 size_t i_; | 117 size_t i_; |
| 121 }; | 118 }; |
| 122 | 119 |
| 123 // You can construct an EnumSet with 0, 1, 2, or 3 initial values. | 120 // You can construct an EnumSet with 0, 1, 2, or 3 initial values. |
| 124 | 121 |
| 125 EnumSet() {} | 122 EnumSet() {} |
| 126 | 123 |
| 127 explicit EnumSet(E value) { | 124 explicit EnumSet(E value) { Put(value); } |
| 128 Put(value); | |
| 129 } | |
| 130 | 125 |
| 131 EnumSet(E value1, E value2) { | 126 EnumSet(E value1, E value2) { |
| 132 Put(value1); | 127 Put(value1); |
| 133 Put(value2); | 128 Put(value2); |
| 134 } | 129 } |
| 135 | 130 |
| 136 EnumSet(E value1, E value2, E value3) { | 131 EnumSet(E value1, E value2, E value3) { |
| 137 Put(value1); | 132 Put(value1); |
| 138 Put(value2); | 133 Put(value2); |
| 139 Put(value3); | 134 Put(value3); |
| 140 } | 135 } |
| 141 | 136 |
| 142 // Returns an EnumSet with all possible values. | 137 // Returns an EnumSet with all possible values. |
| 143 static EnumSet All() { | 138 static EnumSet All() { |
| 144 EnumBitSet enums; | 139 EnumBitSet enums; |
| 145 enums.set(); | 140 enums.set(); |
| 146 return EnumSet(enums); | 141 return EnumSet(enums); |
| 147 } | 142 } |
| 148 | 143 |
| 149 ~EnumSet() {} | 144 ~EnumSet() {} |
| 150 | 145 |
| 151 // Copy constructor and assignment welcome. | 146 // Copy constructor and assignment welcome. |
| 152 | 147 |
| 153 // Set operations. Put, Retain, and Remove are basically | 148 // Set operations. Put, Retain, and Remove are basically |
| 154 // self-mutating versions of Union, Intersection, and Difference | 149 // self-mutating versions of Union, Intersection, and Difference |
| 155 // (defined below). | 150 // (defined below). |
| 156 | 151 |
| 157 // Adds the given value (which must be in range) to our set. | 152 // Adds the given value (which must be in range) to our set. |
| 158 void Put(E value) { | 153 void Put(E value) { enums_.set(ToIndex(value)); } |
| 159 enums_.set(ToIndex(value)); | |
| 160 } | |
| 161 | 154 |
| 162 // Adds all values in the given set to our set. | 155 // Adds all values in the given set to our set. |
| 163 void PutAll(EnumSet other) { | 156 void PutAll(EnumSet other) { enums_ |= other.enums_; } |
| 164 enums_ |= other.enums_; | |
| 165 } | |
| 166 | 157 |
| 167 // There's no real need for a Retain(E) member function. | 158 // There's no real need for a Retain(E) member function. |
| 168 | 159 |
| 169 // Removes all values not in the given set from our set. | 160 // Removes all values not in the given set from our set. |
| 170 void RetainAll(EnumSet other) { | 161 void RetainAll(EnumSet other) { enums_ &= other.enums_; } |
| 171 enums_ &= other.enums_; | |
| 172 } | |
| 173 | 162 |
| 174 // If the given value is in range, removes it from our set. | 163 // If the given value is in range, removes it from our set. |
| 175 void Remove(E value) { | 164 void Remove(E value) { |
| 176 if (InRange(value)) { | 165 if (InRange(value)) { |
| 177 enums_.reset(ToIndex(value)); | 166 enums_.reset(ToIndex(value)); |
| 178 } | 167 } |
| 179 } | 168 } |
| 180 | 169 |
| 181 // Removes all values in the given set from our set. | 170 // Removes all values in the given set from our set. |
| 182 void RemoveAll(EnumSet other) { | 171 void RemoveAll(EnumSet other) { enums_ &= ~other.enums_; } |
| 183 enums_ &= ~other.enums_; | |
| 184 } | |
| 185 | 172 |
| 186 // Removes all values from our set. | 173 // Removes all values from our set. |
| 187 void Clear() { | 174 void Clear() { enums_.reset(); } |
| 188 enums_.reset(); | |
| 189 } | |
| 190 | 175 |
| 191 // Returns true iff the given value is in range and a member of our set. | 176 // Returns true iff the given value is in range and a member of our set. |
| 192 bool Has(E value) const { | 177 bool Has(E value) const { |
| 193 return InRange(value) && enums_.test(ToIndex(value)); | 178 return InRange(value) && enums_.test(ToIndex(value)); |
| 194 } | 179 } |
| 195 | 180 |
| 196 // Returns true iff the given set is a subset of our set. | 181 // Returns true iff the given set is a subset of our set. |
| 197 bool HasAll(EnumSet other) const { | 182 bool HasAll(EnumSet other) const { |
| 198 return (enums_ & other.enums_) == other.enums_; | 183 return (enums_ & other.enums_) == other.enums_; |
| 199 } | 184 } |
| 200 | 185 |
| 201 // Returns true iff our set is empty. | 186 // Returns true iff our set is empty. |
| 202 bool Empty() const { | 187 bool Empty() const { return !enums_.any(); } |
| 203 return !enums_.any(); | |
| 204 } | |
| 205 | 188 |
| 206 // Returns how many values our set has. | 189 // Returns how many values our set has. |
| 207 size_t Size() const { | 190 size_t Size() const { return enums_.count(); } |
| 208 return enums_.count(); | |
| 209 } | |
| 210 | 191 |
| 211 // Returns an iterator pointing to the first element (if any). | 192 // Returns an iterator pointing to the first element (if any). |
| 212 Iterator First() const { | 193 Iterator First() const { return Iterator(enums_); } |
| 213 return Iterator(enums_); | |
| 214 } | |
| 215 | 194 |
| 216 // Returns true iff our set and the given set contain exactly the same values. | 195 // Returns true iff our set and the given set contain exactly the same values. |
| 217 bool operator==(const EnumSet& other) const { return enums_ == other.enums_; } | 196 bool operator==(const EnumSet& other) const { return enums_ == other.enums_; } |
| 218 | 197 |
| 219 // Returns true iff our set and the given set do not contain exactly the same | 198 // Returns true iff our set and the given set do not contain exactly the same |
| 220 // values. | 199 // values. |
| 221 bool operator!=(const EnumSet& other) const { return enums_ != other.enums_; } | 200 bool operator!=(const EnumSet& other) const { return enums_ != other.enums_; } |
| 222 | 201 |
| 223 private: | 202 private: |
| 224 friend EnumSet Union<E, MinEnumValue, MaxEnumValue>( | 203 friend EnumSet Union<E, MinEnumValue, MaxEnumValue>(EnumSet set1, |
| 225 EnumSet set1, EnumSet set2); | 204 EnumSet set2); |
| 226 friend EnumSet Intersection<E, MinEnumValue, MaxEnumValue>( | 205 friend EnumSet Intersection<E, MinEnumValue, MaxEnumValue>(EnumSet set1, |
| 227 EnumSet set1, EnumSet set2); | 206 EnumSet set2); |
| 228 friend EnumSet Difference<E, MinEnumValue, MaxEnumValue>( | 207 friend EnumSet Difference<E, MinEnumValue, MaxEnumValue>(EnumSet set1, |
| 229 EnumSet set1, EnumSet set2); | 208 EnumSet set2); |
| 230 | 209 |
| 231 explicit EnumSet(EnumBitSet enums) : enums_(enums) {} | 210 explicit EnumSet(EnumBitSet enums) : enums_(enums) {} |
| 232 | 211 |
| 233 static bool InRange(E value) { | 212 static bool InRange(E value) { |
| 234 return (value >= MinEnumValue) && (value <= MaxEnumValue); | 213 return (value >= MinEnumValue) && (value <= MaxEnumValue); |
| 235 } | 214 } |
| 236 | 215 |
| 237 // Converts a value to/from an index into |enums_|. | 216 // Converts a value to/from an index into |enums_|. |
| 238 | 217 |
| 239 static size_t ToIndex(E value) { | 218 static size_t ToIndex(E value) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 274 } | 253 } |
| 275 | 254 |
| 276 template <typename E, E Min, E Max> | 255 template <typename E, E Min, E Max> |
| 277 EnumSet<E, Min, Max> Difference(EnumSet<E, Min, Max> set1, | 256 EnumSet<E, Min, Max> Difference(EnumSet<E, Min, Max> set1, |
| 278 EnumSet<E, Min, Max> set2) { | 257 EnumSet<E, Min, Max> set2) { |
| 279 return EnumSet<E, Min, Max>(set1.enums_ & ~set2.enums_); | 258 return EnumSet<E, Min, Max>(set1.enums_ & ~set2.enums_); |
| 280 } | 259 } |
| 281 | 260 |
| 282 } // namespace syncer | 261 } // namespace syncer |
| 283 | 262 |
| 284 #endif // SYNC_INTERNAL_API_PUBLIC_BASE_ENUM_SET_H_ | 263 #endif // COMPONENTS_SYNC_BASE_ENUM_SET_H_ |
| OLD | NEW |