|
- #pragma once
-
- #include "flags.h"
-
- namespace cppcore
- {
-
- namespace __impl
- {
-
- /* op_flag_convert_none */
-
- template<class T_enum, class T_base>
- T_base op_flag_convert_none<T_enum, T_base>
- ::to_base(const T_enum& e)
- { return static_cast<T_base>(e); }
-
- template<class T_enum, class T_base>
- T_enum op_flag_convert_none<T_enum, T_base>
- ::from_index(const ssize_t& index)
- { return static_cast<T_enum>(1 << index); }
-
- /* op_flag_convert_shift */
-
- template<class T_enum, class T_base>
- T_base op_flag_convert_shift<T_enum, T_base>
- ::to_base(const T_enum& e)
- { return static_cast<T_base>(1 << static_cast<int>(e)); }
-
- template<class T_enum, class T_base>
- T_enum op_flag_convert_shift<T_enum, T_base>
- ::from_index(const ssize_t& index)
- { return static_cast<T_enum>(index); }
-
- }
-
- /* flags::iterator */
-
- template<class T_enum, class T_base, class T_op>
- flags<T_enum, T_base, T_op>::iterator
- ::iterator(const base_type& base, bool is_end)
- : _base(base)
- , _pos (is_end ? bit_count : -1)
- { next(); }
-
- template<class T_enum, class T_base, class T_op>
- bool flags<T_enum, T_base, T_op>::iterator
- ::operator==(const iterator& other) const
- { return _base == other._base && _pos == other._pos; }
-
- template<class T_enum, class T_base, class T_op>
- bool flags<T_enum, T_base, T_op>::iterator
- ::operator!=(const iterator& other) const
- { return _base != other._base || _pos != other._pos; }
-
- template<class T_enum, class T_base, class T_op>
- T_enum flags<T_enum, T_base, T_op>::iterator
- ::operator*() const
- {
- assert(_pos < bit_count);
- return op_type::from_index(_pos);
- }
-
- template<class T_enum, class T_base, class T_op>
- typename flags<T_enum, T_base, T_op>::iterator&
- flags<T_enum, T_base, T_op>::iterator
- ::operator++()
- {
- next();
- return *this;
- }
-
- template<class T_enum, class T_base, class T_op>
- typename flags<T_enum, T_base, T_op>::iterator
- flags<T_enum, T_base, T_op>::iterator
- ::operator++(int)
- {
- auto ret = *this;
- next();
- return ret;
- }
-
- template<class T_enum, class T_base, class T_op>
- void flags<T_enum, T_base, T_op>::iterator
- ::next()
- {
- if (_pos >= bit_count)
- return;
- do
- {
- ++_pos;
- } while(_pos < bit_count && !static_cast<bool>(_base & (1 << _pos)));
- }
-
- /* flags */
-
- template<class T_enum, class T_base, class T_op>
- flags<T_enum, T_base, T_op>
- ::flags()
- : value(0)
- { }
-
- template<class T_enum, class T_base, class T_op>
- flags<T_enum, T_base, T_op>
- ::flags(base_type v)
- : value(v)
- { }
-
- template<class T_enum, class T_base, class T_op>
- flags<T_enum, T_base, T_op>
- ::flags(enum_type e)
- : value(T_op::to_base(e))
- { }
-
- template<class T_enum, class T_base, class T_op>
- flags<T_enum, T_base, T_op>
- ::flags(const flags& other)
- : value(other.value)
- { }
-
- template<class T_enum, class T_base, class T_op>
- flags<T_enum, T_base, T_op>
- ::flags(std::initializer_list<enum_type> list)
- : flags()
- {
- for (auto& e : list)
- set(e);
- }
-
- template<class T_enum, class T_base, class T_op>
- auto flags<T_enum, T_base, T_op>
- ::begin() const
- { return iterator(value, false); }
-
- template<class T_enum, class T_base, class T_op>
- auto flags<T_enum, T_base, T_op>
- ::end() const
- { return iterator(value, true); }
-
- template<class T_enum, class T_base, class T_op>
- bool flags<T_enum, T_base, T_op>
- ::is_set(enum_type e) const
- { return static_cast<bool>(value & op_type::to_base(e)); }
-
- template<class T_enum, class T_base, class T_op>
- void flags<T_enum, T_base, T_op>
- ::set(enum_type e)
- { value = static_cast<base_type>(value | op_type::to_base(e)); }
-
- template<class T_enum, class T_base, class T_op>
- void flags<T_enum, T_base, T_op>
- ::clear(enum_type e)
- { value = static_cast<base_type>(value & ~op_type::to_base(e)); }
-
- template<class T_enum, class T_base, class T_op>
- void flags<T_enum, T_base, T_op>
- ::reset()
- { value = 0; }
-
- template<class T_enum, class T_base, class T_op>
- T_base flags<T_enum, T_base, T_op>
- ::operator()() const
- { return value; }
-
- template<class T_enum, class T_base, class T_op>
- flags<T_enum, T_base, T_op>
- ::operator base_type() const
- { return static_cast<base_type>(value); }
-
- template<class T_enum, class T_base, class T_op>
- flags<T_enum, T_base, T_op>
- ::operator bool() const
- { return static_cast<bool>(value); }
-
- template<class T_enum, class T_base, class T_op>
- bool flags<T_enum, T_base, T_op>
- ::operator[](enum_type e) const
- { return is_set(e); }
-
- template<class T_enum, class T_base, class T_op>
- const flags<T_enum, T_base, T_op>& flags<T_enum, T_base, T_op>
- ::empty()
- {
- const flags value(0);
- return value;
- }
-
- template<class T_enum, class T_base, class T_op>
- const flags<T_enum, T_base, T_op>& flags<T_enum, T_base, T_op>
- ::all()
- {
- const flags value(std::numeric_limits<base_type>::max());
- return value;
- }
-
- }
|