Skip to content

Commit 92a63be

Browse files
committed
Merge pull request #4 from grisumbras/development
Development
2 parents feef6e8 + 58ecac6 commit 92a63be

27 files changed

+375
-81
lines changed

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ if (mask1 & Value2) { // if Value2 flag is set
4040
```
4141
4242
## Description
43+
44+
**Disclaimer: docs are currently out of sync a little bit**
45+
4346
``` c++
4447
template <class E> class flags;
4548
```
@@ -56,7 +59,8 @@ underlying_type|The integer type that is used as representation of `flags`|Equiv
5659
#### Constructors and assignment operators
5760
Name |Description
5861
-----------------------------|-----------
59-
`flags()` |Default contructor (all flags are unset)
62+
`flags()` |Default contructor, keeps object uninitialized (note: object may contain garbage)
63+
`flags(empty_t)` |Unsets all flags
6064
`flags(flags::enum_type)` |Sets flag denoted by the parameter
6165
`flags(const flags&)` |Copy constructor
6266
`flags(flags&&)` |Move constructor

include/flags/flags.hpp

Lines changed: 31 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace flags {
1515

1616

1717
constexpr 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

258278
template <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>
326286
constexpr 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

333293
template <class E>
334294
constexpr 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

341301
template <class E>
342302
constexpr 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

include/flags/iterator.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class FlagsIterator {
6060
using impl_type = typename flags_type::impl_type;
6161

6262

63-
explicit FlagsIterator(impl_type uv) noexcept : mask_(1), uvalue_(uv) {
63+
explicit FlagsIterator(impl_type uv) noexcept : uvalue_(uv), mask_(1) {
6464
if (!(mask_ & uvalue_)) { nextMask(); }
6565
}
6666

test/Jamroot

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import testing ;
22

3+
34
project flags_tests
45
: requirements <warnings>all
56
<cxxflags>-std=c++11
@@ -18,4 +19,12 @@ unit-test main-test
1819
: main-test.cpp boost_utf
1920
: <define>BOOST_TEST_DYN_LINK
2021
<define>BOOST_TEST_MODULE=enum_flags
21-
;
22+
;
23+
24+
25+
compile should-compile.cpp ;
26+
27+
28+
for src in [ glob shouldnt-compile/*.cpp ] {
29+
compile-fail $(src) ;
30+
}

test/common.hpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#ifndef ENUM_CLASS_TEST_COMMON_HPP
2+
#define ENUM_CLASS_TEST_COMMON_HPP
3+
4+
5+
#include <flags/flags.hpp>
6+
7+
8+
enum class Enum : int {One = 1, Two = 2, Four = 4, Eight = 8};
9+
ALLOW_FLAGS_FOR_ENUM(Enum)
10+
11+
using Enums = flags::flags<Enum>;
12+
13+
14+
#endif // ENUM_CLASS_TEST_COMMON_HPP

test/main-test.cpp

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,10 @@
1-
#include <flags/flags.hpp>
1+
#include "common.hpp"
22

33
#include <vector>
44

55
#include <boost/test/unit_test.hpp>
66

77

8-
enum class Enum : int {One = 1, Two = 2, Four = 4, Eight = 8};
9-
ALLOW_FLAGS_FOR_ENUM(Enum)
10-
11-
using Enums = flags::flags<Enum>;
12-
13-
148
BOOST_AUTO_TEST_CASE(set_underlying_value) {
159
Enums result;
1610
constexpr int random_number = 87;

0 commit comments

Comments
 (0)