Skip to content

Commit bb0111a

Browse files
committed
added Boolean
1 parent c86dc2e commit bb0111a

2 files changed

Lines changed: 117 additions & 0 deletions

File tree

include/oryx/crt/boolean.hpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#pragma once
2+
3+
#include <functional>
4+
#include <utility>
5+
6+
namespace oryx::crt {
7+
8+
class Boolean {
9+
public:
10+
constexpr Boolean() = default;
11+
12+
constexpr Boolean(bool value)
13+
: value_(value) {}
14+
15+
operator bool() const { return value_; }
16+
17+
template <typename F>
18+
requires std::invocable<F>
19+
constexpr auto AndThen(F&& f) const -> Boolean {
20+
if (value_) {
21+
return std::invoke(std::forward<F>(f));
22+
}
23+
24+
return *this;
25+
}
26+
27+
template <typename F>
28+
requires std::invocable<F>
29+
constexpr auto OrElse(F&& f) const -> Boolean {
30+
if (!value_) {
31+
return std::invoke(std::forward<F>(f));
32+
}
33+
34+
return *this;
35+
}
36+
37+
template <typename F>
38+
requires std::invocable<F, bool>
39+
constexpr auto Transform(F&& f) const {
40+
return std::invoke(std::forward<F>(f), value_);
41+
}
42+
43+
constexpr auto operator==(const Boolean& other) const -> bool { return value_ == other.value_; }
44+
constexpr auto operator!=(const Boolean& other) const -> bool { return value_ != other.value_; }
45+
constexpr auto operator&&(const Boolean& other) const -> Boolean { return value_ && other.value_; }
46+
constexpr auto operator||(const Boolean& other) const -> Boolean { return value_ || other.value_; }
47+
constexpr auto operator!() const -> Boolean { return !value_; }
48+
49+
constexpr auto value() const -> bool { return value_; }
50+
51+
private:
52+
bool value_{};
53+
};
54+
55+
} // namespace oryx::crt

tests/boolean_test.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#include "doctest.hpp"
2+
3+
#include <oryx/crt/boolean.hpp>
4+
5+
using namespace oryx::crt;
6+
7+
TEST_CASE("Default constructor is false") {
8+
Boolean b{};
9+
CHECK_FALSE(b);
10+
}
11+
12+
TEST_CASE("AndThen chaining") {
13+
Boolean b = true;
14+
15+
int counter{};
16+
auto increment = [&] {
17+
counter++;
18+
return true;
19+
};
20+
21+
b.AndThen(increment).AndThen(increment).AndThen([] { return false; }).AndThen(increment);
22+
CHECK_EQ(counter, 2);
23+
}
24+
25+
TEST_CASE("OrElse chaining") {
26+
Boolean b{};
27+
28+
int counter{};
29+
auto increment = [&] {
30+
counter++;
31+
return false;
32+
};
33+
b.OrElse(increment).OrElse(increment).OrElse([] { return true; }).OrElse(increment);
34+
CHECK_EQ(counter, 2);
35+
}
36+
37+
TEST_CASE("AndThen and OrElse") {
38+
Boolean b{};
39+
40+
int counter{};
41+
auto increment = [&] {
42+
counter++;
43+
return false;
44+
};
45+
b.OrElse(increment).OrElse([] { return true; }).AndThen(increment);
46+
CHECK_EQ(counter, 2);
47+
}
48+
49+
TEST_CASE("Transform") {
50+
Boolean b{};
51+
52+
int r = b.Transform([](bool b) { return b ? 1 : 0; });
53+
CHECK_EQ(r, 0);
54+
}
55+
56+
TEST_CASE("Operators") {
57+
Boolean b{};
58+
59+
CHECK_EQ(Boolean{true}, Boolean{true});
60+
CHECK_EQ(Boolean{false} || Boolean{true}, Boolean{true});
61+
CHECK_EQ(Boolean{false} && Boolean{true}, Boolean{false});
62+
}

0 commit comments

Comments
 (0)