Skip to content

Commit

Permalink
Merge pull request #13 from njlr/improvement/comparison
Browse files Browse the repository at this point in the history
improvement/comparison
  • Loading branch information
njlr authored Sep 25, 2017
2 parents 2632bf4 + b7973a6 commit 377aeed
Show file tree
Hide file tree
Showing 8 changed files with 169 additions and 62 deletions.
4 changes: 4 additions & 0 deletions .buckconfig
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
[project]
ignore = .git, .buckd

[cxx]
cxxflags = -std=c++14
gtest_dep = google.gtest//:gtest
25 changes: 25 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
language: cpp
sudo: true
dist: trusty

addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-5

before_install:
- cd /usr/bin/ && sudo rm g++ && sudo ln -s g++-5 g++ && cd -
- g++ --version
- sudo apt-get install default-jdk
- wget -O buck.deb https://github.com/facebook/buck/releases/download/v2017.09.04.02/buck-2017.09.04.02_all.deb
- sudo dpkg -i buck.deb
- wget -O buckaroo.deb https://github.com/LoopPerfect/buckaroo/releases/download/v1.3.1/buckaroo_1.3.1_amd64.deb
- sudo dpkg -i buckaroo.deb

script:
- buckaroo install
- buck build //:neither
- buck build //:test#linux-x86_64
- buck run //:test#linux-x86_64
11 changes: 9 additions & 2 deletions BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,20 @@ cxx_library(
exported_headers = subdir_glob([
('neither/include', '**/*.hpp'),
]),
visibility = ['PUBLIC']
visibility = [
'PUBLIC',
],
)

cxx_test(
name = 'test',
deps = [':neither'],
srcs = glob([
'neither/tests/**/*.cpp',
]),
platform_compiler_flags = [
('^linux.*', [ '-lpthread' ]),
],
deps = [
':neither',
],
)
61 changes: 36 additions & 25 deletions neither/include/either.hpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
#ifndef NEITHER_EITHER_HPP
#define NEITHER_EITHER_HPP

#include <neither/traits.hpp>
#include <neither/maybe.hpp>
#include <memory>
#include <type_traits>

#include <neither/traits.hpp>
#include <neither/maybe.hpp>

namespace neither {

template<class T>
Expand All @@ -25,7 +26,7 @@ constexpr Left<T> left(T const& x) {

template<class T>
Left<T> left(T&& x) {
return {std::move(x)};
return { std::move(x) };
}

template<class T>
Expand All @@ -41,12 +42,9 @@ constexpr Right<T> right(T const& x) {

template<class T>
Right<T> right(T&& x) {
return {std::move(x)};
return { std::move(x) };
}




template<class L, class R>
struct Either {

Expand Down Expand Up @@ -104,18 +102,17 @@ struct Either {
}

constexpr auto left() const -> Maybe<L> {
if (!isLeft)
return maybe();
return maybe(leftValue);
return isLeft ?
maybe(leftValue) :
maybe();
}

constexpr auto right() const -> Maybe<R> {
if(isLeft)
return maybe();
return maybe(rightValue);
return isLeft ?
maybe() :
maybe(rightValue);
}


static constexpr auto leftOf( L const& l ) {
return Either<L, R>{ neither::left(l) };
}
Expand All @@ -124,7 +121,6 @@ struct Either {
return Either<L, R>{ neither::right(r) };
}


static constexpr auto leftOf( L && l ) {
return Either<L, R>{ neither::left(std::move(l)) };
}
Expand All @@ -133,7 +129,6 @@ struct Either {
return Either<L, R>{ neither::right(std::move(r)) };
}


template<
class L2 = L,
class R2 = R>
Expand All @@ -142,26 +137,25 @@ struct Either {
isCopyable((L2)leftValue, (R2)rightValue),
std::declval<std::common_type_t<L2, R2>>()
) {
return isLeft? leftValue : rightValue;
return isLeft ? leftValue : rightValue;
}


template<
class L2 = L,
class R2 = R>
auto join()&&
-> std::common_type_t<L2, R2> {
return isLeft? std::move(leftValue) : std::move(rightValue);
return isLeft ? std::move(leftValue) : std::move(rightValue);
}

template<class LeftF, class RightF>
constexpr auto join(LeftF const& leftCase, RightF const& rightCase) const
-> decltype( isLeft? leftCase( leftValue ) : rightCase( rightValue ) ) {
return isLeft? leftCase( leftValue ) : rightCase( rightValue );
return isLeft ? leftCase( leftValue ) : rightCase( rightValue );
}

template<class F, class L2=L, class R2=R>
constexpr auto leftMap(F const& leftCase) const&
constexpr auto leftMap(F const& leftCase) const&
-> Either<decltype(leftCase( isCopyable((L2)leftValue, (R2)rightValue) )), R2> {
using NextEither = Either<decltype(leftCase(leftValue)), R2>;
return isLeft ?
Expand Down Expand Up @@ -205,7 +199,7 @@ struct Either {
return NextEither::rightOf(rightValue);
}

template<class RightCase, class L2=L, class R2=R>
template<class RightCase, class L2 = L, class R2 = R>
constexpr auto rightFlatMap(RightCase const& rightCase) const&
-> decltype( ensureEitherLeft(rightCase(isCopyable((R2)rightValue)), isCopyable((L2)leftValue))) {
using NextEither = decltype(rightCase(rightValue));
Expand All @@ -217,9 +211,7 @@ struct Either {
return NextEither::leftOf(leftValue);
}



template<class LeftCase, class L2=L, class R2=R>
template<class LeftCase, class L2 = L, class R2 = R>
auto leftFlatMap(LeftCase const& leftCase)&&
-> decltype( ensureEitherRight(leftCase(std::move(leftValue)), std::move(rightValue))) {
using NextEither = decltype(leftCase(std::move(leftValue)));
Expand All @@ -246,6 +238,25 @@ struct Either {
constexpr operator bool()const { return !isLeft; }
};

template <typename L, typename R>
bool operator == (Either<L, R> const& a, Either<L, R> const& b) {
if (a.isLeft) {
if (b.isLeft) {
return a.left() == b.left();
}
} else {
if (!b.isLeft) {
return a.right() == b.right();
}
}
return false;
}

template <typename L, typename R>
bool operator != (Either<L, R> const& a, Either<L, R> const& b) {
return !(a == b);
}

}

#endif
23 changes: 20 additions & 3 deletions neither/include/maybe.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ template <class T> struct Maybe {
union {
T value;
};

bool const hasValue = 0;

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

constexpr operator bool()const { return hasValue; }
constexpr operator bool() const { return hasValue; }
};

template <class T> auto maybe(T value) -> Maybe<T> { return {value}; }
template <typename T>
auto maybe(T value) -> Maybe<T> { return {value}; }

template <typename T = void>
auto maybe() -> Maybe<T> { return {}; }

template <typename T>
bool operator == (Maybe<T> const& a, Maybe<T> const& b) {
if (a.hasValue) {
return b.hasValue && a.value == b.value;
}
return !b.hasValue;
}

template <typename T>
bool operator != (Maybe<T> const& a, Maybe<T> const& b) {
return !(a == b);
}

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

#endif
22 changes: 11 additions & 11 deletions neither/include/traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,50 +8,50 @@ struct Either;

template<class T>
struct Maybe;

template<class L,class...Xs>
auto isCopyable (L l, Xs...) -> L {
return l;
}

template<class L, class R>
auto ensureEither ( Either<L,R> const& e) -> Either<L,R> {
return e;
}

template<class L, class R>
auto ensureEither ( Either<L,R> && e) -> Either<L,R> {
return e;
}

template<class L, class R>
auto ensureEitherRight ( Either<L,R> const& e, R) -> Either<L, R> {
return e;
}


template<class L, class R>
auto ensureEitherRight ( Either<L,R>&& e, R&&) -> Either<L, R> {
return e;
}


template<class L, class R>
auto ensureEitherLeft ( Either<L,R> const& e, L) -> Either<L, R> {
return e;
}

template<class L, class R>
auto ensureEitherLeft ( Either<L,R>&& e, L&& ) -> Either<L, R> {
return e;
}


template<class T>
auto ensureMaybe ( Maybe<T> const& e) -> Maybe<T> {
return e;
}

}

#endif
Loading

0 comments on commit 377aeed

Please sign in to comment.