Skip to content

Commit f5fc494

Browse files
committed
Update sum_types.md
Tests for maybe
1 parent a515572 commit f5fc494

File tree

4 files changed

+96
-3
lines changed

4 files changed

+96
-3
lines changed

GNUmakefile

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
CXX=clang++
22
CPPFLAGS=-std=c++20 -nostdinc
3-
CXXFLAGS=-fprebuilt-module-path=.pcm
3+
CXXFLAGS=-fprebuilt-module-path=.pcm -g -O0
44

55
PRECOMPILE.cc=$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -x c++-module --precompile
66

@@ -12,13 +12,22 @@ clean:
1212
-$(RM) .obj/*
1313
-$(RM) .pcm/*
1414

15-
test: .bin/list_test
15+
test: list_test maybe_test
16+
17+
list_test: .bin/list_test
1618
.bin/list_test
1719

18-
.bin/list_test: .obj/list_test.o .obj/funcpp.o .obj/funcpp-list.o .obj/funcpp-maybe.o .obj/funcpp-common.o
20+
maybe_test: .bin/maybe_test
21+
.bin/maybe_test
22+
23+
.bin/list_test: .obj/list_test.o .obj/funcpp.o .obj/funcpp-list.o .obj/funcpp-common.o
1924

2025
.obj/list_test.o: .pcm/funcpp.pcm
2126

27+
.bin/maybe_test: .obj/maybe_test.o .obj/funcpp.o .obj/funcpp-maybe.o .obj/funcpp-common.o
28+
29+
.obj/maybe_test.o: .pcm/funcpp.pcm
30+
2231
.obj/funcpp.o .pcm/funcpp.pcm: .pcm/funcpp-common.pcm .pcm/funcpp-list.pcm .pcm/funcpp-maybe.pcm
2332

2433
.obj/funcpp-list.o .pcm/funcpp-list.pcm: .pcm/funcpp-common.pcm

src/funcpp-maybe.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,18 @@ namespace funcpp {
2626
struct _some {
2727
/// @brief Reproduces `A`
2828
using type = A;
29+
/// @brief A value of type `A`
30+
type value;
31+
32+
friend bool operator==(_some a, _some b) = default;
33+
34+
friend auto operator==(_some s, type a) {
35+
return s.value == a;
36+
}
37+
38+
friend auto operator==(type a, _some s) {
39+
return a == s.value;
40+
}
2941
};
3042
/// @endcond
3143

src/funcpp.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
export module funcpp;
77
export import :common;
88
export import :list;
9+
export import :maybe;
910

1011
/**
1112
* @brief Functional C++

test/maybe.cc

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import funcpp;
2+
3+
using namespace funcpp;
4+
5+
template<typename A>
6+
class maybe_var {
7+
using n_type = typename nothing::type;
8+
using s_type = typename some<A>::type;
9+
enum {is_n, is_s} d = is_n;
10+
union {n_type n; s_type s;};
11+
12+
public:
13+
maybe_var() : d{is_n} {
14+
}
15+
16+
maybe_var(A a) : d{is_s}, s{a} {
17+
}
18+
19+
~maybe_var() {
20+
if (d == is_s) s.~s_type();
21+
}
22+
23+
operator bool() {
24+
return d == is_s;
25+
}
26+
27+
friend bool operator==(maybe_var m, maybe_var n) {
28+
if (m.d == is_n) return n.d == is_n;
29+
return n.d == is_s and m.s == n.s;
30+
}
31+
32+
friend bool operator==(maybe_var m, A a) {
33+
return m.d == is_s and m.s == a;
34+
}
35+
36+
friend bool operator==(A a, maybe_var m) {
37+
return m.d == is_s and a == m.s;
38+
}
39+
40+
template<template<typename> typename F, typename... Args>
41+
friend auto invoke(F<A> f, maybe_var m, Args&&...args) {
42+
return m ? f(m.s, args...) : f(m.n, args...);
43+
}
44+
};
45+
46+
template<typename A>
47+
struct maybe_is7 {
48+
bool operator()(nothing::type) { return false; }
49+
bool operator()(some<A>::type s) { return s == 7; }
50+
};
51+
52+
template<typename A>
53+
bool is7(maybe_var<A> m) {
54+
return invoke(maybe_is7<A>{}, m);
55+
}
56+
57+
int main() {
58+
maybe_var<int> none;
59+
maybe_var<int> some = 0;
60+
int err = 0;
61+
++err; if (none) return err;
62+
++err; if (!some) return err;
63+
++err; if (some != 0) return err;
64+
some = 7;
65+
++err; if (some != 7) return err;
66+
++err; if (!is7(some)) return err;
67+
++err; if (some == none) return err;
68+
some = {};
69+
++err; if (some != none) return err;
70+
return 0;
71+
}

0 commit comments

Comments
 (0)