11#ifndef NEITHER_EITHER_HPP
22#define NEITHER_EITHER_HPP
33
4- #include < neither/traits.hpp>
5- #include < neither/maybe.hpp>
64#include < memory>
75#include < type_traits>
86
7+ #include < neither/traits.hpp>
8+ #include < neither/maybe.hpp>
9+
910namespace neither {
1011
1112template <class T >
@@ -25,7 +26,7 @@ constexpr Left<T> left(T const& x) {
2526
2627template <class T >
2728Left<T> left (T&& x) {
28- return {std::move (x)};
29+ return { std::move (x) };
2930}
3031
3132template <class T >
@@ -41,12 +42,9 @@ constexpr Right<T> right(T const& x) {
4142
4243template <class T >
4344Right<T> right (T&& x) {
44- return {std::move (x)};
45+ return { std::move (x) };
4546}
4647
47-
48-
49-
5048template <class L , class R >
5149struct Either {
5250
@@ -104,18 +102,17 @@ struct Either {
104102 }
105103
106104 constexpr auto left () const -> Maybe<L> {
107- if (! isLeft)
108- return maybe ();
109- return maybe (leftValue );
105+ return isLeft ?
106+ maybe (leftValue) :
107+ maybe ();
110108 }
111109
112110 constexpr auto right () const -> Maybe<R> {
113- if ( isLeft)
114- return maybe ();
115- return maybe (rightValue);
111+ return isLeft ?
112+ maybe () :
113+ maybe (rightValue);
116114 }
117115
118-
119116 static constexpr auto leftOf ( L const & l ) {
120117 return Either<L, R>{ neither::left (l) };
121118 }
@@ -124,7 +121,6 @@ struct Either {
124121 return Either<L, R>{ neither::right (r) };
125122 }
126123
127-
128124 static constexpr auto leftOf ( L && l ) {
129125 return Either<L, R>{ neither::left (std::move (l)) };
130126 }
@@ -133,7 +129,6 @@ struct Either {
133129 return Either<L, R>{ neither::right (std::move (r)) };
134130 }
135131
136-
137132 template <
138133 class L2 = L,
139134 class R2 = R>
@@ -142,26 +137,25 @@ struct Either {
142137 isCopyable ((L2)leftValue, (R2)rightValue),
143138 std::declval<std::common_type_t<L2, R2>>()
144139 ) {
145- return isLeft? leftValue : rightValue;
140+ return isLeft ? leftValue : rightValue;
146141 }
147142
148-
149143 template <
150144 class L2 = L,
151145 class R2 = R>
152146 auto join ()&&
153147 -> std::common_type_t<L2, R2> {
154- return isLeft? std::move (leftValue) : std::move (rightValue);
148+ return isLeft ? std::move (leftValue) : std::move (rightValue);
155149 }
156150
157151 template <class LeftF , class RightF >
158152 constexpr auto join (LeftF const & leftCase, RightF const & rightCase) const
159153 -> decltype( isLeft? leftCase( leftValue ) : rightCase( rightValue ) ) {
160- return isLeft? leftCase ( leftValue ) : rightCase ( rightValue );
154+ return isLeft ? leftCase ( leftValue ) : rightCase ( rightValue );
161155 }
162156
163157 template <class F , class L2 =L, class R2 =R>
164- constexpr auto leftMap (F const & leftCase) const &
158+ constexpr auto leftMap (F const & leftCase) const &
165159 -> Either<decltype(leftCase( isCopyable((L2)leftValue, (R2)rightValue) )), R2> {
166160 using NextEither = Either<decltype (leftCase (leftValue)), R2>;
167161 return isLeft ?
@@ -205,7 +199,7 @@ struct Either {
205199 return NextEither::rightOf (rightValue);
206200 }
207201
208- template <class RightCase , class L2 = L, class R2 = R>
202+ template <class RightCase , class L2 = L, class R2 = R>
209203 constexpr auto rightFlatMap (RightCase const & rightCase) const &
210204 -> decltype( ensureEitherLeft(rightCase(isCopyable((R2)rightValue)), isCopyable((L2)leftValue))) {
211205 using NextEither = decltype (rightCase (rightValue));
@@ -217,9 +211,7 @@ struct Either {
217211 return NextEither::leftOf (leftValue);
218212 }
219213
220-
221-
222- template <class LeftCase , class L2 =L, class R2 =R>
214+ template <class LeftCase , class L2 = L, class R2 = R>
223215 auto leftFlatMap (LeftCase const & leftCase)&&
224216 -> decltype( ensureEitherRight(leftCase(std::move(leftValue)), std::move(rightValue))) {
225217 using NextEither = decltype (leftCase (std::move (leftValue)));
@@ -246,6 +238,25 @@ struct Either {
246238 constexpr operator bool ()const { return !isLeft; }
247239};
248240
241+ template <typename L, typename R>
242+ bool operator == (Either<L, R> const & a, Either<L, R> const & b) {
243+ if (a.isLeft ) {
244+ if (b.isLeft ) {
245+ return a.left () == b.left ();
246+ }
247+ } else {
248+ if (!b.isLeft ) {
249+ return a.right () == b.right ();
250+ }
251+ }
252+ return false ;
253+ }
254+
255+ template <typename L, typename R>
256+ bool operator != (Either<L, R> const & a, Either<L, R> const & b) {
257+ return !(a == b);
258+ }
259+
249260}
250261
251262#endif
0 commit comments