tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

EnumFlags.h (2535B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set ts=8 sts=2 et sw=2 tw=80:
      3 * This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef util_EnumFlags_h
      8 #define util_EnumFlags_h
      9 
     10 #include "mozilla/Attributes.h"
     11 
     12 #include <initializer_list>
     13 #include <type_traits>
     14 
     15 namespace js {
     16 
     17 // Wrapper type for flags fields based on an enum type.
     18 //
     19 // EnumFlags does not (implicitly) convert to/from the underlying integer type.
     20 // That can be supported for specific flags fields by deriving from this class
     21 // and implementing an extra constructor and/or |operator FieldType|.
     22 //
     23 // Note: this type is similar to mfbt/EnumSet.h, but has the same size in debug
     24 // and release builds so is more appropriate for core data structures where we
     25 // don't want this size difference.
     26 template <typename EnumType>
     27 class EnumFlags {
     28 protected:
     29  // Use the enum's underlying type for the flags field. This makes JIT accesses
     30  // more predictable and simplifies the implementation of this class.
     31  static_assert(std::is_enum_v<EnumType>);
     32  using FieldType = std::underlying_type_t<EnumType>;
     33  static_assert(std::is_unsigned_v<FieldType>);
     34 
     35  FieldType flags_ = 0;
     36 
     37  explicit constexpr EnumFlags(FieldType rawFlags) : flags_(rawFlags) {}
     38 
     39 public:
     40  constexpr EnumFlags() = default;
     41 
     42  constexpr MOZ_IMPLICIT EnumFlags(std::initializer_list<EnumType> list) {
     43    for (EnumType flag : list) {
     44      setFlag(flag);
     45    }
     46  }
     47 
     48  constexpr bool hasFlag(EnumType flag) const {
     49    return flags_ & static_cast<FieldType>(flag);
     50  }
     51  constexpr void setFlag(EnumType flag) {
     52    flags_ |= static_cast<FieldType>(flag);
     53  }
     54  constexpr void clearFlag(EnumType flag) {
     55    flags_ &= ~static_cast<FieldType>(flag);
     56  }
     57  constexpr void setFlag(EnumType flag, bool b) {
     58    if (b) {
     59      setFlag(flag);
     60    } else {
     61      clearFlag(flag);
     62    }
     63  }
     64 
     65  constexpr bool hasAnyFlag(const EnumFlags& other) const {
     66    return (flags_ & other.flags_) != 0;
     67  }
     68 
     69  constexpr bool isEmpty() const { return flags_ == 0; }
     70 
     71  constexpr FieldType toRaw() const { return flags_; }
     72  void setRaw(FieldType flag) { flags_ = flag; }
     73 
     74  constexpr bool operator==(const EnumFlags& other) const {
     75    return flags_ == other.flags_;
     76  }
     77  constexpr bool operator!=(const EnumFlags& other) const {
     78    return flags_ != other.flags_;
     79  }
     80 };
     81 
     82 }  // namespace js
     83 
     84 #endif  // util_EnumFlags_h