• R/O
  • SSH

posixpp: Commit

The main posixpp library and associated tests.


Commit MetaInfo

Revision1b9e82800e24bff5f615cd13cb1b246aa9d26807 (tree)
Time2021-01-20 11:43:57
AuthorEric Hopper <hopper@omni...>
CommiterEric Hopper

Log Message

Completely rework flagset into being a factory for flagset types.

Change Summary

Incremental Difference

diff -r 66c686689061 -r 1b9e82800e24 pubincludes/pppbase/flagset.h
--- a/pubincludes/pppbase/flagset.h Fri Jan 15 23:41:49 2021 -0800
+++ b/pubincludes/pppbase/flagset.h Tue Jan 19 18:43:57 2021 -0800
@@ -1,6 +1,7 @@
11 #pragma once /*-*-c++-*-*/
22
33 #include <cstdint>
4+#include <concepts>
45
56 // Copyright 2021 by Eric Hopper
67 // Can be distributed under the terms of the LGPL v3.
@@ -8,69 +9,122 @@
89 namespace pppbase {
910
1011 //! A set of boolean flags, may not be modified after creation.
11-class flagset {
12+class flagset_base {
13+ protected:
14+ using bitvec_t = ::std::uintmax_t;
15+
1216 public:
13- explicit constexpr flagset(::std::uintmax_t bits = 0)
17+ constexpr explicit flagset_base(bitvec_t bits = 0)
1418 : bits_{bits}
1519 {}
1620
1721 constexpr explicit operator bool() const { return bits_; }
1822
19- constexpr
20- flagset intersection(flagset const &b) const {
21- return flagset{bits_ & b.bits_};
23+ [[nodiscard]] constexpr
24+ flagset_base intersection(flagset_base const &b) const {
25+ return flagset_base{bits_ & b.bits_};
2226 }
23- constexpr
24- flagset setunion(flagset const &b) const {
25- return flagset{bits_ | b.bits_};
27+ [[nodiscard]] constexpr
28+ flagset_base setunion(flagset_base const &b) const {
29+ return flagset_base{bits_ | b.bits_};
2630 }
27- constexpr
28- flagset symmetric_difference(flagset const &b) const {
29- return flagset{bits_ ^ b.bits_};
31+ [[nodiscard]] constexpr
32+ flagset_base symmetric_difference(flagset_base const &b) const {
33+ return flagset_base{bits_ ^ b.bits_};
3034 }
31- constexpr
32- flagset minus(flagset const &b) const {
33- return flagset{bits_ & ~b.bits_};
35+ [[nodiscard]] constexpr
36+ flagset_base minus(flagset_base const &b) const {
37+ return flagset_base{bits_ & ~b.bits_};
3438 }
3539
36- constexpr
37- bool is_equal(flagset const &b) const {
40+ [[nodiscard]] constexpr
41+ bool is_equal(flagset_base const &b) const {
3842 return bits_ == b.bits_;
3943 }
4044
45+ [[nodiscard]] constexpr
46+ bitvec_t getbits() const { return bits_; }
47+
4148 private:
42- ::std::uintmax_t bits_;
49+ bitvec_t bits_;
4350 };
4451
45-constexpr
46-bool operator ==(flagset const &a, flagset const &b)
52+
53+template <typename T>
54+concept supports_flagset = requires(T const &x) {
55+ bool{x};
56+ {x.intersection(x)} -> ::std::same_as<T>;
57+ {x.setunion(x)} -> ::std::same_as<T>;
58+ {x.symmetric_difference(x)} -> ::std::same_as<T>;
59+ {x.minus(x)} -> ::std::same_as<T>;
60+ {x.is_equal(x)} -> ::std::same_as<bool>;
61+};
62+
63+
64+template <typename Derived>
65+class specific_flagset_crtp : private flagset_base {
66+ protected:
67+ using flagset_base::bitvec_t;
68+ using flagset_base::getbits;
69+ constexpr explicit specific_flagset_crtp(bitvec_t bits=0)
70+ : flagset_base(bits) {
71+ }
72+
73+ public:
74+ using flagset_base::operator bool;
75+
76+ [[nodiscard]] constexpr
77+ Derived intersection(Derived const &b) const {
78+ return Derived{flagset_base::intersection(b).getbits()};
79+ }
80+ [[nodiscard]] constexpr
81+ Derived setunion(Derived const &b) const {
82+ return Derived{flagset_base::setunion(b).getbits()};
83+ }
84+ [[nodiscard]] constexpr
85+ Derived symmetric_difference(Derived const &b) const {
86+ return Derived{flagset_base::symmetric_difference(b).getbits()};
87+ }
88+ [[nodiscard]] constexpr
89+ Derived minus(Derived const &b) const {
90+ return Derived{flagset_base::minus(b).getbits()};
91+ }
92+
93+ [[nodiscard]] constexpr
94+ bool is_equal(Derived const &b) const {
95+ return flagset_base::is_equal(b);
96+ }
97+};
98+
99+template <supports_flagset T> constexpr
100+bool operator ==(T const &a, T const &b)
47101 {
48102 return a.is_equal(b);
49103 }
50104
51-constexpr
52-bool operator !=(flagset const &a, flagset const &b)
105+template <supports_flagset T> constexpr
106+bool operator !=(T const &a, T const &b)
53107 {
54108 return !a.is_equal(b);
55109 }
56110
57-constexpr
58-flagset operator &(flagset const &a, flagset const &b) {
111+template <supports_flagset T> constexpr
112+T operator &(T const &a, T const &b) {
59113 return a.intersection(b);
60114 }
61115
62-constexpr
63-flagset operator |(flagset const &a, flagset const &b) {
116+template <supports_flagset T> constexpr
117+T operator |(T const &a, T const &b) {
64118 return a.setunion(b);
65119 }
66120
67-constexpr
68-flagset operator ^(flagset const &a, flagset const &b) {
121+template <supports_flagset T> constexpr
122+T operator ^(T const &a, T const &b) {
69123 return a.symmetric_difference(b);
70124 }
71125
72-constexpr
73-flagset operator -(flagset const &a, flagset const &b) {
126+template <supports_flagset T> constexpr
127+T operator -(T const &a, T const &b) {
74128 return a.minus(b);
75129 }
76130
diff -r 66c686689061 -r 1b9e82800e24 tests/flagset.cpp
--- a/tests/flagset.cpp Fri Jan 15 23:41:49 2021 -0800
+++ b/tests/flagset.cpp Tue Jan 19 18:43:57 2021 -0800
@@ -1,15 +1,25 @@
11 #include <pppbase/flagset.h>
22 #include <catch2/catch.hpp>
33
4+class test_flagset : public ::pppbase::specific_flagset_crtp<test_flagset> {
5+ using base_t = ::pppbase::specific_flagset_crtp<test_flagset>;
6+ public:
7+ using bitvec_t = base_t::bitvec_t;
8+ constexpr explicit test_flagset(bitvec_t bits = 0) : base_t(bits) {}
9+
10+ using base_t::getbits;
11+};
12+
13+
414 SCENARIO("flagsets support all required operations correctly")
515 {
616 GIVEN("A three carefully chosen flagsets.")
717 {
8- using ::pppbase::flagset;
9- flagset f0;
10- flagset f1{1};
11- flagset f2{2};
12- flagset f3{3};
18+ using ::pppbase::flagset_base;
19+ test_flagset f0;
20+ test_flagset f1{1};
21+ test_flagset f2{2};
22+ test_flagset f3{3};
1323
1424 WHEN("Each is tested for truth") {
1525 THEN("f0 is false") {
Show on old repository browser