| Index: base/set_template.h
|
| diff --git a/base/set_template.h b/base/set_template.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..3b67d4507f3da6627a7b02a2c6a4dc3f468e85e9
|
| --- /dev/null
|
| +++ b/base/set_template.h
|
| @@ -0,0 +1,229 @@
|
| +// Copyright (c) 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#ifndef BASE_SET_TEMPLATE_H_
|
| +#define BASE_SET_TEMPLATE_H_
|
| +
|
| +#include <initializer_list>
|
| +#include <type_traits>
|
| +
|
| +namespace base {
|
| +
|
| +template <class T, unsigned char maxEl>
|
| +class SetCore {
|
| + public:
|
| + typedef
|
| + typename std::conditional<((maxEl / 8 + 1) == 1), unsigned char,
|
| + typename std::conditional<((maxEl / 8 + 1) == 2), unsigned short,
|
| + unsigned int>::type>::type _Ty;
|
| +
|
| + private:
|
| + static_assert(std::is_enum<T>::value, "T must be an enumeration");
|
| + static_assert(maxEl < 32, "Sets can only contain up to 32 elements");
|
| +
|
| + protected:
|
| + SetCore() : data(0) {}
|
| +
|
| + public:
|
| + _Ty data;
|
| +};
|
| +
|
| +template <class T, T maxEl>
|
| +class SetOf : public SetCore<T, static_cast<unsigned char>(maxEl)> {
|
| + static constexpr unsigned char NumElms =
|
| + static_cast<unsigned char>(maxEl) + 1;
|
| + static constexpr unsigned char MaxEl = NumElms - 1;
|
| +
|
| + public:
|
| + class ElemRef {
|
| + friend class SetOf<T, maxEl>;
|
| + public:
|
| + ~ElemRef() {}
|
| +
|
| + ElemRef& operator=(bool rhs) {
|
| + if (rhs)
|
| + set_->Include(el_);
|
| + else
|
| + set_->Exclude(el_);
|
| + return *this;
|
| + }
|
| +
|
| + ElemRef& operator=(const ElemRef& elemref) {
|
| + return set_->operator=(bool(elemref));
|
| + }
|
| +
|
| + operator bool() const {
|
| + return set_->Contains(el_);
|
| + }
|
| +
|
| + private:
|
| + ElemRef() : set_(nullptr), el_(static_cast<T>(0)) {}
|
| + ElemRef(SetOf<T, maxEl>& set, T el) : set_(&set), el_(el) {}
|
| +
|
| + SetOf<T, maxEl>* set_;
|
| + T el_;
|
| + };
|
| +
|
| + SetOf() : SetCore<T, MaxEl>() {}
|
| +
|
| + SetOf(const SetOf& src) : SetCore<T, MaxEl>() {
|
| + this->data = src.data;
|
| + }
|
| +
|
| + explicit SetOf(const int& src) : SetCore<T, MaxEl>() {
|
| + union {
|
| + typename SetCore<T, MaxEl>::_Ty data;
|
| + unsigned int IntData;
|
| + } overlay;
|
| + overlay.IntData = src;
|
| + this->data = overlay.data;
|
| + }
|
| +
|
| + SetOf(const std::initializer_list<T>& src) : SetCore<T, MaxEl>() {
|
| + Include(src);
|
| + }
|
| +
|
| + SetOf& operator=(const SetOf& rhs) {
|
| + if (this != &rhs)
|
| + this->data = rhs.data;
|
| + return *this;
|
| + }
|
| +
|
| + SetOf& operator+=(const SetOf& rhs) {
|
| + this->data |= rhs.data;
|
| + return *this;
|
| + }
|
| +
|
| + SetOf& operator-=(const SetOf& rhs) {
|
| + this->data ^= rhs.data;
|
| + return *this;
|
| + }
|
| +
|
| + SetOf& operator*=(const SetOf& rhs) {
|
| + this->data &= rhs.data;
|
| + return *this;
|
| + }
|
| +
|
| + SetOf operator+(const SetOf& rhs) {
|
| + SetOf<T, maxEl> s;
|
| + s.data = this->data | rhs.data;
|
| + return s;
|
| + }
|
| +
|
| + SetOf operator-(const SetOf& rhs) {
|
| + SetOf<T, maxEl> s;
|
| + s.data = this->data ^ rhs.data;
|
| + return s;
|
| + }
|
| +
|
| + SetOf operator*(const SetOf& rhs) {
|
| + SetOf<T, maxEl> s;
|
| + s.data = this->data & rhs.data;
|
| + return s;
|
| + }
|
| +
|
| + SetOf& operator<<(const T el) {
|
| + return Include(el);
|
| + }
|
| +
|
| + SetOf& operator>>(const T el) {
|
| + return Exclude(el);
|
| + }
|
| +
|
| + bool operator==(const SetOf& rhs) const {
|
| + static const typename SetCore<T, MaxEl>::_Ty Mask =
|
| + static_cast<typename SetCore<T, MaxEl>::_Ty>(-1) >>
|
| + (sizeof(this->data) * 8 - NumElms);
|
| + return !(this->data != rhs.data &&
|
| + (Mask & this->data) != (Mask & rhs.data));
|
| + }
|
| +
|
| + bool operator!=(const SetOf& rhs) const {
|
| + return !operator==(rhs);
|
| + }
|
| +
|
| + constexpr bool operator[](const T el) const {
|
| + return Contains(el);
|
| + }
|
| +
|
| + ElemRef operator[](T el) {
|
| + return ElemRef(*this, el);
|
| + }
|
| +
|
| + SetOf& Clear() {
|
| + this->data = 0;
|
| + return *this;
|
| + }
|
| +
|
| + bool Contains(const T el) const {
|
| + return static_cast<int>(el) >= 0 && static_cast<int>(el) < NumElms &&
|
| + (this->data & static_cast<int>(1) << static_cast<int>(el)) != 0;
|
| + }
|
| +
|
| + bool ContainsAll(const std::initializer_list<T>& els) const {
|
| + for (const T& el : els)
|
| + if (!Contains(el))
|
| + return false;
|
| + return true;
|
| + }
|
| +
|
| + bool ContainsSome(const std::initializer_list<T>& els) const {
|
| + for (const T& el : els)
|
| + if (Contains(el))
|
| + return true;
|
| + return false;
|
| + }
|
| +
|
| + bool Equals(const std::initializer_list<T>& rhs) const {
|
| + SetOf<T, maxEl> s(rhs);
|
| + return operator==(s);
|
| + }
|
| +
|
| + bool Equals(const std::initializer_list<T>& mask,
|
| + const std::initializer_list<T>& rhs) const {
|
| + SetOf<T, maxEl> s_mask(mask);
|
| + SetOf<T, maxEl> s_rhs(rhs);
|
| + return (s_mask * *this) == s_rhs;
|
| + }
|
| +
|
| + bool Equals(const SetOf& mask,
|
| + const std::initializer_list<T>& rhs) const {
|
| + SetOf<T, maxEl> s_rhs(rhs);
|
| + return (mask * *this) == s_rhs;
|
| + }
|
| +
|
| + bool Equals(const SetOf& rhs) const {
|
| + return *this == rhs;
|
| + }
|
| +
|
| + SetOf& Exclude(const T el) {
|
| + if (static_cast<int>(el) >= 0 && static_cast<int>(el) < NumElms)
|
| + this->data &= ~(static_cast<int>(1) << static_cast<int>(el));
|
| + return *this;
|
| + }
|
| +
|
| + SetOf& Exclude(const std::initializer_list<T>& els) {
|
| + for (const T& el : els)
|
| + Exclude(el);
|
| + return *this;
|
| + }
|
| +
|
| + SetOf& Include(const T el) {
|
| + if (static_cast<int>(el) >= 0 && static_cast<int>(el) < NumElms)
|
| + this->data |= (static_cast<int>(1) << static_cast<int>(el));
|
| + return *this;
|
| + }
|
| +
|
| + SetOf& Include(const std::initializer_list<T>& els) {
|
| + for (const T& el : els)
|
| + Include(el);
|
| + return *this;
|
| + }
|
| +
|
| + bool IsEmpty() const { return this->data == 0; }
|
| +};
|
| +
|
| +} // namespace base
|
| +
|
| +#endif // BASE_SET_TEMPLATE_H_
|
|
|