Skip to content

Commit ebe80e6

Browse files
committed
Merge branch 'master' of github.com:LoopPerfect/neither into improvement/single-include
2 parents 9422d97 + 377aeed commit ebe80e6

9 files changed

Lines changed: 217 additions & 61 deletions

File tree

.buckconfig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
1+
[project]
2+
ignore = .git, .buckd
3+
14
[cxx]
5+
cxxflags = -std=c++14
26
gtest_dep = google.gtest//:gtest

.travis.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
language: cpp
2+
sudo: true
3+
dist: trusty
4+
5+
addons:
6+
apt:
7+
sources:
8+
- ubuntu-toolchain-r-test
9+
packages:
10+
- g++-5
11+
12+
before_install:
13+
- cd /usr/bin/ && sudo rm g++ && sudo ln -s g++-5 g++ && cd -
14+
- g++ --version
15+
- sudo apt-get install default-jdk
16+
- wget -O buck.deb https://github.com/facebook/buck/releases/download/v2017.09.04.02/buck-2017.09.04.02_all.deb
17+
- sudo dpkg -i buck.deb
18+
- wget -O buckaroo.deb https://github.com/LoopPerfect/buckaroo/releases/download/v1.3.1/buckaroo_1.3.1_amd64.deb
19+
- sudo dpkg -i buckaroo.deb
20+
21+
script:
22+
- buckaroo install
23+
- buck build //:neither
24+
- buck build //:test#linux-x86_64
25+
- buck run //:test#linux-x86_64

BUCK

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ cxx_library(
55
('neither/include', '**/*.hpp'),
66
]),
77
visibility = [
8-
'PUBLIC'
8+
'PUBLIC',
99
],
1010
)
1111

@@ -14,6 +14,9 @@ cxx_test(
1414
srcs = glob([
1515
'neither/tests/**/*.cpp',
1616
]),
17+
platform_compiler_flags = [
18+
('^linux.*', [ '-lpthread' ]),
19+
],
1720
deps = [
1821
':neither',
1922
],

buckaroo.lock.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"google/gtest": {
3+
"source": {
4+
"url": "https://github.com/google/googletest/archive/ec44c6c1675c25b9827aacd08c02433cccde7780.zip",
5+
"sha256": "bc258fff04a6511e7106a1575bb514a185935041b2c16affb799e0567393ec30",
6+
"subPath": "googletest-ec44c6c1675c25b9827aacd08c02433cccde7780"
7+
},
8+
"buck": {
9+
"url": "https://raw.githubusercontent.com/nikhedonia/googletest/665327f0141d4a4fc4f2496e781dce436d742645/BUCK",
10+
"sha256": "d976069f5b47fd8fc57201f47026a70dee4e47b3141ac23567b8a0c56bf9288c"
11+
}
12+
}
13+
}

neither/include/either.hpp

Lines changed: 51 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
#include <neither/traits.hpp>
77
#include <neither/maybe.hpp>
88

9+
#include <neither/traits.hpp>
10+
#include <neither/maybe.hpp>
11+
912
namespace neither {
1013

1114
template<class T>
@@ -25,7 +28,7 @@ constexpr Left<T> left(T const& x) {
2528

2629
template<class T>
2730
Left<T> left(T&& x) {
28-
return {std::move(x)};
31+
return { std::move(x) };
2932
}
3033

3134
template<class T>
@@ -41,12 +44,9 @@ constexpr Right<T> right(T const& x) {
4144

4245
template<class T>
4346
Right<T> right(T&& x) {
44-
return {std::move(x)};
47+
return { std::move(x) };
4548
}
4649

47-
48-
49-
5050
template<class L, class R>
5151
struct Either {
5252

@@ -104,18 +104,17 @@ struct Either {
104104
}
105105

106106
constexpr auto left() const -> Maybe<L> {
107-
if (!isLeft)
108-
return maybe();
109-
return maybe(leftValue);
107+
return isLeft ?
108+
maybe(leftValue) :
109+
maybe();
110110
}
111111

112112
constexpr auto right() const -> Maybe<R> {
113-
if(isLeft)
114-
return maybe();
115-
return maybe(rightValue);
113+
return isLeft ?
114+
maybe() :
115+
maybe(rightValue);
116116
}
117117

118-
119118
static constexpr auto leftOf( L const& l ) {
120119
return Either<L, R>{ neither::left(l) };
121120
}
@@ -124,7 +123,6 @@ struct Either {
124123
return Either<L, R>{ neither::right(r) };
125124
}
126125

127-
128126
static constexpr auto leftOf( L && l ) {
129127
return Either<L, R>{ neither::left(std::move(l)) };
130128
}
@@ -133,68 +131,67 @@ struct Either {
133131
return Either<L, R>{ neither::right(std::move(r)) };
134132
}
135133

136-
137134
template<
138135
class L2 = L,
139136
class R2 = R>
140137
constexpr auto join() const
141138
-> decltype(
142-
isCopyable(leftValue, rightValue),
139+
isCopyable((L2)leftValue, (R2)rightValue),
143140
std::declval<std::common_type_t<L2, R2>>()
144141
) {
145-
return isLeft? leftValue : rightValue;
142+
return isLeft ? leftValue : rightValue;
146143
}
147144

148-
149145
template<
150146
class L2 = L,
151147
class R2 = R>
152148
auto join()&&
153149
-> std::common_type_t<L2, R2> {
154-
return isLeft? std::move(leftValue) : std::move(rightValue);
150+
return isLeft ? std::move(leftValue) : std::move(rightValue);
155151
}
156152

157153
template<class LeftF, class RightF>
158154
constexpr auto join(LeftF const& leftCase, RightF const& rightCase) const
159155
-> decltype( isLeft? leftCase( leftValue ) : rightCase( rightValue ) ) {
160-
return isLeft? leftCase( leftValue ) : rightCase( rightValue );
156+
return isLeft ? leftCase( leftValue ) : rightCase( rightValue );
161157
}
162158

163-
template<class F>
164-
constexpr auto leftMap(F const& leftCase) const& -> Either<decltype(leftCase( isCopyable(leftValue, rightValue) )), R> {
165-
using NextEither = Either<decltype(leftCase(leftValue)), R>;
159+
template<class F, class L2=L, class R2=R>
160+
constexpr auto leftMap(F const& leftCase) const&
161+
-> Either<decltype(leftCase( isCopyable((L2)leftValue, (R2)rightValue) )), R2> {
162+
using NextEither = Either<decltype(leftCase(leftValue)), R2>;
166163
return isLeft ?
167164
NextEither::leftOf( leftCase( leftValue ) ) :
168165
NextEither::rightOf( rightValue );
169166
}
170167

171-
template<class F>
172-
auto leftMap(F const& leftCase)&& -> Either<decltype(leftCase(std::move(leftValue))), R> {
173-
using NextEither = Either<decltype(leftCase(std::move(leftValue))), R>;
168+
template<class F, class L2=L, class R2=R>
169+
auto leftMap(F const& leftCase)&& -> Either<decltype(leftCase(std::move(leftValue))), R2> {
170+
using NextEither = Either<decltype(leftCase(std::move(leftValue))), R2>;
174171
return isLeft ?
175172
NextEither::leftOf(leftCase(std::move(leftValue))) :
176173
NextEither::rightOf( std::move(rightValue) );
177174
}
178175

179-
template<class F>
180-
constexpr auto rightMap(F const& rightCase) const& -> Either<L, decltype(rightCase(isCopyable(rightValue, leftValue)))> {
176+
template<class F, class L2=L, class R2=R>
177+
constexpr auto rightMap(F const& rightCase) const& -> Either<L, decltype(rightCase(isCopyable((R2)rightValue, (L2)leftValue)))> {
181178
using NextEither = Either<L, decltype(rightCase(rightValue))>;
182179
return isLeft ?
183180
NextEither::leftOf( leftValue ) :
184181
NextEither::rightOf( rightCase( rightValue ) );
185182
}
186183

187-
template<class F>
188-
auto rightMap(F const& rightCase)&& -> Either<L, decltype(rightCase(std::move(rightValue)))> {
184+
template<class F, class L2=L, class R2=R>
185+
auto rightMap(F const& rightCase)&& -> Either<L2, decltype(rightCase(std::move((R2)rightValue)))> {
189186
using NextEither = Either<L, decltype(rightCase(std::move(rightValue)))>;
190187
return isLeft ?
191188
NextEither::leftOf( std::move(leftValue) ) :
192189
NextEither::rightOf( rightCase( std::move(rightValue) ) );
193190
}
194191

195-
template<class LeftCase>
192+
template<class LeftCase, class L2=L, class R2=R>
196193
constexpr auto leftFlatMap(LeftCase const& leftCase) const&
197-
-> decltype( ensureEitherRight(leftCase(isCopyable(leftValue)), isCopyable(rightValue))) {
194+
-> decltype( ensureEitherRight(leftCase(isCopyable((L2)leftValue)), isCopyable((R2)rightValue))) {
198195
using NextEither = decltype(leftCase(leftValue));
199196

200197
if (!*this) {
@@ -204,9 +201,9 @@ struct Either {
204201
return NextEither::rightOf(rightValue);
205202
}
206203

207-
template<class RightCase>
204+
template<class RightCase, class L2 = L, class R2 = R>
208205
constexpr auto rightFlatMap(RightCase const& rightCase) const&
209-
-> decltype( ensureEitherLeft(rightCase(isCopyable(rightValue)), isCopyable(leftValue))) {
206+
-> decltype( ensureEitherLeft(rightCase(isCopyable((R2)rightValue)), isCopyable((L2)leftValue))) {
210207
using NextEither = decltype(rightCase(rightValue));
211208

212209
if (*this) {
@@ -216,9 +213,7 @@ struct Either {
216213
return NextEither::leftOf(leftValue);
217214
}
218215

219-
220-
221-
template<class LeftCase>
216+
template<class LeftCase, class L2 = L, class R2 = R>
222217
auto leftFlatMap(LeftCase const& leftCase)&&
223218
-> decltype( ensureEitherRight(leftCase(std::move(leftValue)), std::move(rightValue))) {
224219
using NextEither = decltype(leftCase(std::move(leftValue)));
@@ -230,7 +225,7 @@ struct Either {
230225
return NextEither::rightOf(std::move(rightValue));
231226
}
232227

233-
template<class RightCase>
228+
template<class RightCase, class L2=L, class R2=R>
234229
auto rightFlatMap(RightCase const& rightCase)&&
235230
-> decltype( ensureEitherLeft(rightCase(std::move(rightValue)), std::move(leftValue))) {
236231
using NextEither = decltype(rightCase(std::move(rightValue)));
@@ -245,6 +240,25 @@ struct Either {
245240
constexpr operator bool()const { return !isLeft; }
246241
};
247242

243+
template <typename L, typename R>
244+
bool operator == (Either<L, R> const& a, Either<L, R> const& b) {
245+
if (a.isLeft) {
246+
if (b.isLeft) {
247+
return a.left() == b.left();
248+
}
249+
} else {
250+
if (!b.isLeft) {
251+
return a.right() == b.right();
252+
}
253+
}
254+
return false;
255+
}
256+
257+
template <typename L, typename R>
258+
bool operator != (Either<L, R> const& a, Either<L, R> const& b) {
259+
return !(a == b);
260+
}
261+
248262
}
249263

250264
#endif

neither/include/maybe.hpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ template <class T> struct Maybe {
1515
union {
1616
T value;
1717
};
18+
1819
bool const hasValue = 0;
1920

2021
constexpr Maybe() : hasValue{0} {}
@@ -85,12 +86,28 @@ template <class T> struct Maybe {
8586
return f(std::move(value));
8687
}
8788

88-
constexpr operator bool()const { return hasValue; }
89+
constexpr operator bool() const { return hasValue; }
8990
};
9091

91-
template <class T> auto maybe(T value) -> Maybe<T> { return {value}; }
92+
template <typename T>
93+
auto maybe(T value) -> Maybe<T> { return {value}; }
94+
95+
template <typename T = void>
96+
auto maybe() -> Maybe<T> { return {}; }
97+
98+
template <typename T>
99+
bool operator == (Maybe<T> const& a, Maybe<T> const& b) {
100+
if (a.hasValue) {
101+
return b.hasValue && a.value == b.value;
102+
}
103+
return !b.hasValue;
104+
}
105+
106+
template <typename T>
107+
bool operator != (Maybe<T> const& a, Maybe<T> const& b) {
108+
return !(a == b);
109+
}
92110

93-
template <class T = void> auto maybe() -> Maybe<T> { return {}; }
94111
}
95112

96113
#endif

neither/include/traits.hpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#ifndef NEITHER_TRAITS_HPP
2+
#define NEITHER_TRAITS_HPP
3+
4+
namespace neither {
5+
6+
template<class L, class R>
7+
struct Either;
8+
9+
template<class T>
10+
struct Maybe;
11+
12+
template<class L,class...Xs>
13+
auto isCopyable (L l, Xs...) -> L {
14+
return l;
15+
}
16+
17+
template<class L, class R>
18+
auto ensureEither ( Either<L,R> const& e) -> Either<L,R> {
19+
return e;
20+
}
21+
22+
template<class L, class R>
23+
auto ensureEither ( Either<L,R> && e) -> Either<L,R> {
24+
return e;
25+
}
26+
27+
template<class L, class R>
28+
auto ensureEitherRight ( Either<L,R> const& e, R) -> Either<L, R> {
29+
return e;
30+
}
31+
32+
33+
template<class L, class R>
34+
auto ensureEitherRight ( Either<L,R>&& e, R&&) -> Either<L, R> {
35+
return e;
36+
}
37+
38+
39+
template<class L, class R>
40+
auto ensureEitherLeft ( Either<L,R> const& e, L) -> Either<L, R> {
41+
return e;
42+
}
43+
44+
template<class L, class R>
45+
auto ensureEitherLeft ( Either<L,R>&& e, L&& ) -> Either<L, R> {
46+
return e;
47+
}
48+
49+
50+
template<class T>
51+
auto ensureMaybe ( Maybe<T> const& e) -> Maybe<T> {
52+
return e;
53+
}
54+
55+
}
56+
57+
#endif

0 commit comments

Comments
 (0)