Skip to content

Commit

Permalink
Add predicates
Browse files Browse the repository at this point in the history
  • Loading branch information
TartanLlama committed Dec 8, 2024
1 parent 265da61 commit 8d3d0ad
Show file tree
Hide file tree
Showing 2 changed files with 248 additions and 0 deletions.
97 changes: 97 additions & 0 deletions include/tl/functional/predicates.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#ifndef TL_RANGES_PREDICATES_HPP
#define TL_RANGES_PREDICATES_HPP

namespace tl {
inline constexpr auto equal_to = [](auto&& x) {
return [x = std::forward<decltype(x)>(x)](auto&& y) {
return x == y;
};
};
inline constexpr auto not_equal_to = [](auto&& x) {
return [x = std::forward<decltype(x)>(x)](auto&& y) {
return x != y;
};
};
inline constexpr auto less_than = [](auto&& x) {
return [x = std::forward<decltype(x)>(x)](auto&& y) {
return y < x;
};
};
inline constexpr auto greater_than = [](auto&& x) {
return [x = std::forward<decltype(x)>(x)](auto&& y) {
return y > x;
};
};
inline constexpr auto less_than_or_equal_to = [](auto&& x) {
return [x = std::forward<decltype(x)>(x)](auto&& y) {
return y <= x;
};
};
inline constexpr auto greater_than_or_equal_to = [](auto&& x) {
return [x = std::forward<decltype(x)>(x)](auto&& y) {
return y >= x;
};
};
inline constexpr auto is_even = [](auto&& x) {
return x % 2 == 0;
};
inline constexpr auto is_odd = [](auto&& x) {
return x % 2 != 0;
};
inline constexpr auto is_positive = [](auto&& x) {
return x > 0;
};
inline constexpr auto is_negative = [](auto&& x) {
return x < 0;
};
inline constexpr auto is_zero = [](auto&& x) {
return x == 0;
};
inline constexpr auto is_nonzero = [](auto&& x) {
return x != 0;
};
inline constexpr auto is_true = [](auto&& x) {
return x;
};
inline constexpr auto is_false = [](auto&& x) {
return !x;
};
inline constexpr auto is_null = [](auto&& x) {
return x == nullptr;
};
inline constexpr auto is_not_null = [](auto&& x) {
return x != nullptr;
};
inline constexpr auto is_empty = [](auto&& x) {
return x.empty();
};
inline constexpr auto is_not_empty = [](auto&& x) {
return !x.empty();
};
inline constexpr auto conjunction = [](auto&&... predicates) {
return [predicates = std::make_tuple(std::forward<decltype(predicates)>(predicates)...)](auto&& x) {
return std::apply([&x](auto&&... predicates) {
return (predicates(x) && ...);
}, predicates);
};
};
inline constexpr auto disjunction = [](auto&&... predicates) {
return [predicates = std::make_tuple(std::forward<decltype(predicates)>(predicates)...)](auto&& x) {
return std::apply([&x](auto&&... predicates) {
return (predicates(x) || ...);
}, predicates);
};
};
inline constexpr auto negation = [](auto&& predicate) {
return [predicate = std::forward<decltype(predicate)>(predicate)](auto&& x) {
return !predicate(x);
};
};
inline constexpr auto is_between = [](auto&& lower, auto&& upper) {
return [lower = std::forward<decltype(lower)>(lower), upper = std::forward<decltype(upper)>(upper)](auto&& x) {
return lower <= x && x <= upper;
};
};
}

#endif
151 changes: 151 additions & 0 deletions tests/predicates.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
#include <catch2/catch.hpp>
#include "tl/functional/predicates.hpp"

TEST_CASE("equal_to") {
auto eq = tl::equal_to(5);
REQUIRE(eq(5));
REQUIRE_FALSE(eq(6));
}

TEST_CASE("not_equal_to") {
auto neq = tl::not_equal_to(5);
REQUIRE_FALSE(neq(5));
REQUIRE(neq(6));
}

TEST_CASE("less_than") {
auto lt = tl::less_than(5);
REQUIRE(lt(4));
REQUIRE_FALSE(lt(5));
REQUIRE_FALSE(lt(6));
}

TEST_CASE("greater_than") {
auto gt = tl::greater_than(5);
REQUIRE_FALSE(gt(4));
REQUIRE_FALSE(gt(5));
REQUIRE(gt(6));
}

TEST_CASE("less_than_or_equal_to") {
auto lte = tl::less_than_or_equal_to(5);
REQUIRE(lte(4));
REQUIRE(lte(5));
REQUIRE_FALSE(lte(6));
}

TEST_CASE("greater_than_or_equal_to") {
auto gte = tl::greater_than_or_equal_to(5);
REQUIRE_FALSE(gte(4));
REQUIRE(gte(5));
REQUIRE(gte(6));
}

TEST_CASE("is_even") {
auto ie = tl::is_even;
REQUIRE(ie(0));
REQUIRE(ie(2));
REQUIRE(ie(4));
REQUIRE_FALSE(ie(1));
REQUIRE_FALSE(ie(3));
REQUIRE_FALSE(ie(5));
}

TEST_CASE("is_odd") {
auto io = tl::is_odd;
REQUIRE(io(1));
REQUIRE(io(3));
REQUIRE(io(5));
REQUIRE_FALSE(io(0));
REQUIRE_FALSE(io(2));
REQUIRE_FALSE(io(4));
}

TEST_CASE("is_positive") {
auto ip = tl::is_positive;
REQUIRE(ip(1));
REQUIRE(ip(2));
REQUIRE(ip(3));
REQUIRE_FALSE(ip(0));
REQUIRE_FALSE(ip(-1));
REQUIRE_FALSE(ip(-2));
REQUIRE_FALSE(ip(-3));
}

TEST_CASE("is_negative") {
auto in = tl::is_negative;
REQUIRE_FALSE(in(1));
REQUIRE_FALSE(in(2));
REQUIRE_FALSE(in(3));
REQUIRE_FALSE(in(0));
REQUIRE(in(-1));
REQUIRE(in(-2));
REQUIRE(in(-3));
}

TEST_CASE("is_zero") {
auto iz = tl::is_zero;
REQUIRE(iz(0));
REQUIRE_FALSE(iz(1));
REQUIRE_FALSE(iz(-1));
}

TEST_CASE("is_nonzero") {
auto inz = tl::is_nonzero;
REQUIRE_FALSE(inz(0));
REQUIRE(inz(1));
REQUIRE(inz(-1));
}

TEST_CASE("is_true") {
auto it = tl::is_true;
REQUIRE(it(true));
REQUIRE_FALSE(it(false));
}

TEST_CASE("is_false") {
auto iff = tl::is_false;
REQUIRE_FALSE(iff(true));
REQUIRE(iff(false));
}

TEST_CASE("is_null") {
auto in = tl::is_null;
REQUIRE(in(nullptr));
REQUIRE_FALSE(in(&in));
}

TEST_CASE("is_not_null") {
auto inn = tl::is_not_null;
REQUIRE_FALSE(inn(nullptr));
REQUIRE(inn(&inn));
}

TEST_CASE("conjunction") {
auto c = tl::conjunction(tl::is_even, tl::is_positive);
REQUIRE_FALSE(c(0));
REQUIRE_FALSE(c(1));
REQUIRE(c(2));
REQUIRE(c(4));
}

TEST_CASE("disjunction") {
auto d = tl::disjunction(tl::is_even, tl::is_positive);
REQUIRE(d(0));
REQUIRE(d(1));
REQUIRE(d(2));
REQUIRE(d(4));
REQUIRE_FALSE(d(-1));
REQUIRE(d(-2));
}

TEST_CASE("negation") {
auto n = tl::negation(tl::is_even);
REQUIRE(n(1));
REQUIRE(n(3));
REQUIRE(n(5));
REQUIRE_FALSE(n(0));
REQUIRE_FALSE(n(2));
REQUIRE_FALSE(n(4));
}

0 comments on commit 8d3d0ad

Please sign in to comment.