1 #ifndef AUDIOGRAPHER_FLAG_FIELD_H
2 #define AUDIOGRAPHER_FLAG_FIELD_H
8 #include <boost/operators.hpp>
10 #include "audiographer/visibility.h"
12 namespace AudioGrapher {
14 /** Flag field capable of holding 32 flags.
15 * Easily grown in size to 64 flags by changing storage_type.
17 class LIBAUDIOGRAPHER_API FlagField
18 : public boost::less_than_comparable<FlagField>
19 , boost::equivalent<FlagField>
20 , boost::equality_comparable<FlagField>
25 typedef uint32_t storage_type;
27 /// Bi-directional iterator for flag set. Iterates over flags that are set in this field.
29 : public std::iterator<std::bidirectional_iterator_tag, Flag>
30 , public boost::less_than_comparable<iterator>
31 , boost::equivalent<iterator>
32 , boost::equality_comparable<iterator>
35 iterator (FlagField const & parent, Flag position) : parent (parent), position (position) {}
36 iterator (iterator const & other) : parent (other.parent), position (other.position) {}
38 value_type operator*() const { return position; }
39 value_type const * operator->() const { return &position; }
41 iterator & operator++()
45 } while (!parent.has (position) && position != max());
48 iterator operator++(int) { iterator copy (*this); ++(*this); return copy; }
50 iterator & operator--()
54 } while (!parent.has (position) && position != max());
57 iterator operator--(int) { iterator copy (*this); --(*this); return copy; }
59 bool operator< (iterator const & other) const { return position < other.position; }
62 FlagField const & parent;
68 FlagField() : _flags (0) {}
69 FlagField(FlagField const & other) : _flags (other._flags) {}
71 inline bool has (Flag flag) const { return _flags & (1 << flag); }
72 inline storage_type flags () const { return _flags; }
73 inline operator bool() const { return _flags; }
74 inline void set (Flag flag) { _flags |= (1 << flag); }
75 inline void remove (Flag flag) { _flags &= ~(1 << flag); }
76 inline void reset () { _flags = 0; }
78 /// Returns the flags in \a other that are not set in this field
79 inline FlagField unsupported_flags_of (FlagField const & other) const { return ~(_flags | ~other._flags); }
81 /// Set all flags that are set in \a other
82 inline FlagField & operator+= (FlagField const & other) { _flags |= other._flags; return *this; }
84 /** Checks whether this field has all the flags set that are set in \a other
85 * NOTE: Can NOT be used for strict weak ordering!
86 * \return \a true if \a other has flags set that this field does not
88 inline bool operator< (FlagField const & other) const { return unsupported_flags_of (other); }
90 iterator begin() const
92 iterator it (*this, 0);
93 if (!*this) { return end(); }
94 if (!has (0)) { ++it; }
97 iterator end() const { iterator it (*this, max()); return it; }
100 FlagField(storage_type flags) : _flags (flags) {}
101 static Flag max() { return CHAR_BIT * sizeof (storage_type) + 1; }
108 #endif // AUDIOGRAPHER_FLAG_FIELD_H