Fcitx
flags.h
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2015-2015 CSSlayer <wengxt@gmail.com>
3  *
4  * SPDX-License-Identifier: LGPL-2.1-or-later
5  *
6  */
7 #ifndef _FCITX_UTILS_FLAG_H_
8 #define _FCITX_UTILS_FLAG_H_
9 
10 #include <initializer_list>
11 #include <type_traits>
12 #include <fcitx-utils/macros.h>
13 
14 /// \addtogroup FcitxUtils
15 /// \{
16 /// \file
17 /// \brief Helper template class to make easier to use type safe enum flags.
18 ///
19 /// Commonly, One can not do any arithmetic calculation with enum class type
20 /// without using static_cast. To make enum flags easier, this template class
21 /// Stores the actual flag value with enum.
22 ///
23 /// Example:
24 /// \code{.cpp}
25 /// enum class EnumTypeFlag { /* ... */ };
26 /// using EnumTypeFlags = Flags<EnumTypeFlag>;
27 /// \endcode
28 
29 namespace fcitx {
30 
31 /// \brief Class provides bit flag support for Enum.
32 template <typename Enum>
33 class Flags {
34 public:
35  using storage_type = typename std::underlying_type_t<Enum>;
36  constexpr Flags(Enum f) : flags_(static_cast<storage_type>(f)) {}
37  explicit Flags(storage_type i = 0) : flags_(i) {}
38  constexpr Flags(const std::initializer_list<Enum> &l) : flags_(0) {
39  for (Enum e : l) {
40  operator|=(e);
41  }
42  }
43 
44  FCITX_INLINE_DEFINE_DEFAULT_DTOR_COPY_AND_MOVE(Flags)
45 
46  constexpr inline operator storage_type() const { return flags_; }
47  constexpr inline storage_type toInteger() const { return flags_; }
48 
49  Flags &operator=(Enum f) {
50  flags_ = static_cast<storage_type>(f);
51  return *this;
52  }
53  Flags &operator=(storage_type f) {
54  flags_ = f;
55  return *this;
56  }
57 
58  constexpr bool operator!() const { return !flags_; }
59  constexpr Flags &operator&=(Flags flag) {
60  flags_ &= flag.flags_;
61  return *this;
62  }
63  Flags &operator&=(Enum flag) {
64  flags_ &= static_cast<storage_type>(flag);
65  return *this;
66  }
67  Flags &operator|=(Flags flag) {
68  flags_ |= flag.flags_;
69  return *this;
70  }
71  constexpr Flags &operator|=(Enum flag) {
72  flags_ |= static_cast<storage_type>(flag);
73  return *this;
74  }
75  Flags &operator^=(Flags flag) {
76  flags_ ^= flag.flags_;
77  return *this;
78  }
79  Flags &operator^=(Enum flag) {
80  flags_ ^= static_cast<storage_type>(flag);
81  return *this;
82  }
83  constexpr inline Flags operator|(Flags f) const {
84  return Flags(flags_ | f.flags_);
85  }
86  constexpr inline Flags operator|(Enum f) const {
87  return Flags(flags_ | static_cast<storage_type>(f));
88  }
89  constexpr inline Flags operator^(Flags f) const {
90  return Flags(flags_ ^ f.flags_);
91  }
92  constexpr inline Flags operator^(Enum f) const {
93  return Flags(flags_ ^ static_cast<storage_type>(f));
94  }
95  constexpr inline Flags operator&(Flags f) const {
96  return Flags(flags_ & f.flags_);
97  }
98  constexpr inline Flags operator&(Enum f) const {
99  return Flags(flags_ & static_cast<storage_type>(f));
100  }
101  constexpr inline Flags operator~() const { return Flags(~flags_); }
102 
103  constexpr inline Flags unset(Enum f) const {
104  return Flags(flags_ & (~static_cast<storage_type>(f)));
105  }
106 
107  constexpr inline Flags unset(Flags f) const {
108  return Flags(flags_ & (~f.flags_));
109  }
110 
111  template <typename T>
112  constexpr inline bool test(T f) const {
113  return (*this & f) == f;
114  }
115  template <typename T>
116  constexpr inline bool testAny(T f) const {
117  return (*this & f) != 0;
118  }
119 
120  constexpr bool operator==(const Flags &f) const {
121  return flags_ == f.flags_;
122  }
123  constexpr bool operator==(Enum f) const {
124  return flags_ == static_cast<storage_type>(f);
125  }
126  constexpr bool operator!=(const Flags &f) const { return !operator==(f); }
127  constexpr bool operator!=(Enum f) const { return !operator==(f); }
128 
129 private:
130  storage_type flags_;
131 };
132 } // namespace fcitx
133 
134 #endif // _FCITX_UTILS_FLAG_H_
Definition: action.cpp:17
Class provides bit flag support for Enum.
Definition: flags.h:33