@@ -15,7 +15,7 @@ namespace flags {
1515
1616
1717constexpr struct empty_t {
18- constexpr empty_t () noexcept {}
18+ constexpr empty_t () noexcept {}
1919} empty;
2020
2121
@@ -97,9 +97,17 @@ template <class E> struct flags {
9797
9898 constexpr bool operator !() const noexcept { return !val_; }
9999
100- flags operator ~() const noexcept { return flags (~val_); }
100+ friend constexpr bool operator ==(flags fl1, flags fl2) {
101+ return fl1.val_ == fl2.val_ ;
102+ }
103+
104+ friend constexpr bool operator !=(flags fl1, flags fl2) {
105+ return fl1.val_ != fl2.val_ ;
106+ }
101107
102108
109+ constexpr flags operator ~() const noexcept { return flags (~val_); }
110+
103111 flags &operator |=(const flags &fl) noexcept {
104112 val_ |= fl.val_ ;
105113 return *this ;
@@ -131,6 +139,18 @@ template <class E> struct flags {
131139 return *this ;
132140 }
133141
142+ friend constexpr flags operator |(flags f1, flags f2) noexcept {
143+ return flags{f1.val_ | f2.val_ };
144+ }
145+
146+ friend constexpr flags operator &(flags f1, flags f2) noexcept {
147+ return flags{f1.val_ & f2.val_ };
148+ }
149+
150+ friend constexpr flags operator ^(flags f1, flags f2) noexcept {
151+ return flags{f1.val_ ^ f2.val_ };
152+ }
153+
134154
135155 void swap (flags &fl) noexcept { std::swap (val_, fl.val_ ); }
136156
@@ -153,7 +173,7 @@ template <class E> struct flags {
153173 }
154174
155175
156- bool empty () const noexcept { return !val_; }
176+ constexpr bool empty () const noexcept { return !val_; }
157177
158178 size_type size () const noexcept {
159179 return std::distance (this ->begin (), this ->end ());
@@ -165,13 +185,13 @@ template <class E> struct flags {
165185 iterator begin () const noexcept { return cbegin (); }
166186 iterator cbegin () const noexcept { return iterator{val_}; }
167187
168- iterator end () const noexcept { return cend (); }
169- iterator cend () const noexcept { return {}; }
188+ constexpr iterator end () const noexcept { return cend (); }
189+ constexpr iterator cend () const noexcept { return {}; }
170190
171191
172- iterator find (enum_type e) const noexcept { return {val_, e}; }
192+ constexpr iterator find (enum_type e) const noexcept { return {val_, e}; }
173193
174- size_type count (enum_type e) const noexcept {
194+ constexpr size_type count (enum_type e) const noexcept {
175195 return find (e) != end () ? 1 : 0 ;
176196 }
177197
@@ -256,67 +276,7 @@ template <class E> struct flags {
256276
257277
258278template <class E >
259- constexpr flags<E> operator |(flags<E> f1, flags<E> f2) noexcept {
260- return f1 |= f2;
261- }
262-
263- template <class E >
264- constexpr flags<E> operator |(flags<E> f, E e) noexcept {
265- return f |= e;
266- }
267-
268- template <class E >
269- constexpr flags<E> operator |(E e, flags<E> f) noexcept {
270- return f |= e;
271- }
272-
273-
274- template <class E >
275- constexpr flags<E> operator &(flags<E> f1, flags<E> f2) noexcept {
276- return f1 &= f2;
277- }
278-
279- template <class E >
280- constexpr flags<E> operator &(flags<E> f, E e) noexcept {
281- return f &= e;
282- }
283-
284- template <class E >
285- constexpr flags<E> operator &(E e, flags<E> f) noexcept {;
286- return f &= e;
287- }
288-
289-
290- template <class E >
291- constexpr flags<E> operator ^(flags<E> f1, flags<E> f2) noexcept {
292- return f1 ^= f2;
293- }
294-
295- template <class E >
296- constexpr flags<E> operator ^(flags<E> f, E e) noexcept {
297- return f ^= e;
298- }
299-
300- template <class E >
301- constexpr flags<E> operator ^(E e, flags<E> f) noexcept {
302- return f ^= e;
303- }
304-
305-
306- template <class E >
307- constexpr bool operator ==(const flags<E> &fl1, const flags<E> &fl2) noexcept {
308- return fl1.underlying_value () == fl2.underlying_value ();
309- }
310-
311-
312- template <class E >
313- constexpr bool operator !=(const flags<E> &fl1, const flags<E> &fl2) noexcept {
314- return fl1.underlying_value () != fl2.underlying_value ();
315- }
316-
317-
318- template <class E >
319- constexpr void swap (flags<E> &fl1, flags<E> &fl2) noexcept { fl1.swap (fl2); }
279+ void swap (flags<E> &fl1, flags<E> &fl2) noexcept { fl1.swap (fl2); }
320280
321281
322282} // namespace flags
@@ -326,23 +286,23 @@ template <class E>
326286constexpr auto operator |(E e1 , E e2 ) noexcept
327287-> typename std::enable_if<flags::is_flags<E>::value,
328288 flags::flags<E>>::type {
329- return flags::flags<E>{ e1 } |= e2 ;
289+ return flags::flags<E>( e1 ) | e2 ;
330290}
331291
332292
333293template <class E >
334294constexpr auto operator &(E e1 , E e2 ) noexcept
335295-> typename std::enable_if<flags::is_flags<E>::value,
336296 flags::flags<E>>::type {
337- return flags::flags<E>{ e1 } &= e2 ;
297+ return flags::flags<E>( e1 ) & e2 ;
338298}
339299
340300
341301template <class E >
342302constexpr auto operator ^(E e1 , E e2 ) noexcept
343303-> typename std::enable_if<flags::is_flags<E>::value,
344304 flags::flags<E>>::type {
345- return flags::flags<E>{ e1 } ^= e2 ;
305+ return flags::flags<E>( e1 ) ^ e2 ;
346306}
347307
348308
0 commit comments