Commit 1bd8b4f5 authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook Github Bot

comparsion-to-predicate adapters

Summary: [Folly] comparison-to-predicate adapters for comparisons which return `ordering`.

Reviewed By: stevegury

Differential Revision: D7596712

fbshipit-source-id: 1aeccf0d38eec27cfa88af2908f3114523d6b6b5
parent a047388c
......@@ -25,4 +25,48 @@ constexpr ordering to_ordering(T c) {
return c < T(0) ? ordering::lt : c > T(0) ? ordering::gt : ordering::eq;
}
namespace detail {
template <typename C, ordering o, bool ne>
struct cmp_pred : private C {
using C::C;
template <typename A, typename B>
constexpr bool operator()(A&& a, B&& b) const {
return ne ^ (C::operator()(static_cast<A&&>(a), static_cast<B&&>(b)) == o);
}
};
} // namespace detail
template <typename C>
struct compare_equal_to : detail::cmp_pred<C, ordering::eq, 0> {
using detail::cmp_pred<C, ordering::eq, 0>::cmp_pred;
};
template <typename C>
struct compare_not_equal_to : detail::cmp_pred<C, ordering::eq, 1> {
using detail::cmp_pred<C, ordering::eq, 1>::cmp_pred;
};
template <typename C>
struct compare_less : detail::cmp_pred<C, ordering::lt, 0> {
using detail::cmp_pred<C, ordering::lt, 0>::cmp_pred;
};
template <typename C>
struct compare_less_equal : detail::cmp_pred<C, ordering::gt, 1> {
using detail::cmp_pred<C, ordering::gt, 1>::cmp_pred;
};
template <typename C>
struct compare_greater : detail::cmp_pred<C, ordering::gt, 0> {
using detail::cmp_pred<C, ordering::gt, 0>::cmp_pred;
};
template <typename C>
struct compare_greater_equal : detail::cmp_pred<C, ordering::lt, 1> {
using detail::cmp_pred<C, ordering::lt, 1>::cmp_pred;
};
} // namespace folly
......@@ -20,6 +20,13 @@
using namespace folly;
template <typename T>
struct OddCompare {
constexpr ordering operator()(T const& a, T const& b) const {
return b < a ? ordering::lt : a < b ? ordering::gt : ordering::eq;
}
};
class OrderingTest : public testing::Test {};
TEST_F(OrderingTest, ordering) {
......@@ -37,3 +44,45 @@ TEST_F(OrderingTest, to_ordering) {
EXPECT_EQ(ordering::eq, to_ordering(0));
EXPECT_EQ(ordering::gt, to_ordering(+44));
}
TEST_F(OrderingTest, compare_equal_to) {
compare_equal_to<OddCompare<int>> op;
EXPECT_FALSE(op(3, 4));
EXPECT_TRUE(op(3, 3));
EXPECT_FALSE(op(4, 3));
}
TEST_F(OrderingTest, compare_not_equal_to) {
compare_not_equal_to<OddCompare<int>> op;
EXPECT_TRUE(op(3, 4));
EXPECT_FALSE(op(3, 3));
EXPECT_TRUE(op(4, 3));
}
TEST_F(OrderingTest, compare_less) {
compare_less<OddCompare<int>> op;
EXPECT_FALSE(op(3, 4));
EXPECT_FALSE(op(3, 3));
EXPECT_TRUE(op(4, 3));
}
TEST_F(OrderingTest, compare_less_equal) {
compare_less_equal<OddCompare<int>> op;
EXPECT_FALSE(op(3, 4));
EXPECT_TRUE(op(3, 3));
EXPECT_TRUE(op(4, 3));
}
TEST_F(OrderingTest, compare_greater) {
compare_greater<OddCompare<int>> op;
EXPECT_TRUE(op(3, 4));
EXPECT_FALSE(op(3, 3));
EXPECT_FALSE(op(4, 3));
}
TEST_F(OrderingTest, compare_greater_equal) {
compare_greater_equal<OddCompare<int>> op;
EXPECT_TRUE(op(3, 4));
EXPECT_TRUE(op(3, 3));
EXPECT_FALSE(op(4, 3));
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment