Repository :
http://git.fedorahosted.org/cgit/firewalld-recode.git
On branch : master
---------------------------------------------------------------
commit f7829c08f9d920017ed49f5cdf22dc0c6a6c5c5d
Author: Daniel Kopecek <dkopecek(a)redhat.com>
Date: Wed Sep 24 14:13:49 2014 +0200
Added FlagSet type
---------------------------------------------------------------
src/Common/Types.hpp | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 109 insertions(+), 0 deletions(-)
diff --git a/src/Common/Types.hpp b/src/Common/Types.hpp
index b007503..e064804 100644
--- a/src/Common/Types.hpp
+++ b/src/Common/Types.hpp
@@ -69,6 +69,115 @@ namespace firewalld
return std::make_shared<pointer_type>(std::forward<Args>(args)...);
}
+ // Flag set
+ // based on
https://stackoverflow.com/a/4226975
+ template <typename enum_type>
+ class FlagSet
+ {
+ public:
+ typedef decltype(enum_type()|enum_type()) store_type;
+
+ // Default constructor (all 0s)
+ FlagSet() : FlagSet(store_type(0))
+ {
+ }
+
+ // Initializer list constructor
+ FlagSet(const std::initializer_list<enum_type>& initList)
+ {
+ _flags = std::accumulate(initList.begin(), initList.end(), store_type(0),
+ [](enum_type x, enum_type y)
+ {
+ return x | y;
+ });
+ }
+
+ // Value constructor
+ explicit FlagSet(store_type value) : _flags(value)
+ {
+ }
+
+ // Explicit conversion operator
+ operator store_type() const
+ {
+ return _flags;
+ }
+
+ FlagSet& set()
+ {
+ _flags = ~store_type(0);
+ return *this;
+ }
+
+ FlagSet& set(enum_type flag, bool val = true)
+ {
+ _flags = (val ? (_flags | flag) : (_flags & ~flag));
+ return *this;
+ }
+
+ FlagSet& reset()
+ {
+ _flags = store_type(0);
+ return *this;
+ }
+
+ FlagSet& unset(enum_type flag)
+ {
+ _flags &= ~flag;
+ return *this;
+ }
+
+ FlagSet& flip()
+ {
+ _flags = ~_flags;
+ return *this;
+ }
+
+ FlagSet& flip(enum_type flag)
+ {
+ _flags ^= flag;
+ return *this;
+ }
+
+ size_t count() const
+ {
+ //
http://www-graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKerni...
+
+ store_type bits = _flags;
+ size_t total = 0;
+ for (; bits != 0; ++total)
+ {
+ bits &= bits - 1; // clear the least significant bit set
+ }
+ return total;
+ }
+
+ constexpr size_t size() const
+ {
+ return sizeof(enum_type)*8;
+ }
+
+ bool test(enum_type flag) const
+ {
+ return (_flags & flag) > 0;
+ }
+
+ private:
+ store_type _flags;
+ };
+
+ template<typename enum_type>
+ FlagSet<enum_type> operator & (const FlagSet<enum_type>& lhs, const
FlagSet<enum_type>& rhs)
+ {
+ return FlagSet<enum_type>(FlagSet<enum_type>::store_type(lhs) &
FlagSet<enum_type>::store_type(rhs));
+ }
+
+ template<typename enum_type>
+ FlagSet<enum_type> operator | (const FlagSet<enum_type>& lhs, const
FlagSet<enum_type>& rhs)
+ {
+ return FlagSet<enum_type>(FlagSet<enum_type>::store_type(lhs) |
FlagSet<enum_type>::store_type(rhs));
+ }
+
} /* namespace firewalld */
#endif /* _FIREWALLD_TYPES_H_ */