Repository : http://git.fedorahosted.org/cgit/firewalld-recode.git
On branch : master
commit f7829c08f9d920017ed49f5cdf22dc0c6a6c5c5d Author: Daniel Kopecek dkopecek@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#CountBitsSetKernigha... + + 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_ */