#include "either.hpp" namespace neither { template constexpr bool hasValue(Either const& e) { return e; } template constexpr bool hasValue(Maybe const& m) { return m; } template constexpr bool hasValue(T) { return true; } template constexpr R unpack(Either const& e) { return e.rightValue; } template constexpr T unpack(Maybe const& m) { return m.value; } template constexpr T unpack(T const& x) { return x; } constexpr auto allTrue(bool x=true, bool y=true) { return x && y; } template auto allTrue(X x, Xs...xs) { return allTrue(x, allTrue(xs...)); } template auto lift(F const& f) { return [f](auto...x) -> decltype(maybe(f(unpack(x)...))) { if ( allTrue(hasValue(x)...) ) { return f(unpack(x)...); } return maybe(); }; } }