diff --git a/include/etl/compare.h b/include/etl/compare.h index 5a28c83df..1c3fa3c3f 100644 --- a/include/etl/compare.h +++ b/include/etl/compare.h @@ -40,70 +40,63 @@ SOFTWARE. /// Comparisons only using less than operator ///\ingroup utilities //***************************************************************************** - namespace etl { + struct compare_types + { + typedef bool result_type; + + enum cmp_result + { + Less = 0, + Equal = 1, + Greater = 2 + }; + }; + //*************************************************************************** /// Defines <=, >, >=, ==, !=, <=> in terms of < - /// Default + /// Default implementation of TLess is etl::less //*************************************************************************** template > - struct compare + struct compare : public compare_types { typedef typename etl::parameter_type::type first_argument_type; typedef typename etl::parameter_type::type second_argument_type; - typedef bool result_type; - - enum cmp_result - { - LESS = -1, - EQUAL = 0, - GREATER = 1 - }; - static result_type lt(first_argument_type lhs, second_argument_type rhs) + static ETL_CONSTEXPR result_type lt(first_argument_type lhs, second_argument_type rhs) { return TLess()(lhs, rhs); } - static result_type gt(first_argument_type lhs, second_argument_type rhs) + static ETL_CONSTEXPR result_type gt(first_argument_type lhs, second_argument_type rhs) { return TLess()(rhs, lhs); } - static result_type lte(first_argument_type lhs, second_argument_type rhs) + static ETL_CONSTEXPR result_type lte(first_argument_type lhs, second_argument_type rhs) { return !gt(lhs, rhs); } - static result_type gte(first_argument_type lhs, second_argument_type rhs) + static ETL_CONSTEXPR result_type gte(first_argument_type lhs, second_argument_type rhs) { return !lt(lhs, rhs); } - static result_type eq(first_argument_type lhs, second_argument_type rhs) + static ETL_CONSTEXPR result_type eq(first_argument_type lhs, second_argument_type rhs) { return gte(lhs, rhs) && lte(lhs, rhs); } - static result_type ne(first_argument_type lhs, second_argument_type rhs) + static ETL_CONSTEXPR result_type ne(first_argument_type lhs, second_argument_type rhs) { return !eq(lhs, rhs); } - static cmp_result cmp(first_argument_type lhs, second_argument_type rhs) + static ETL_CONSTEXPR cmp_result cmp(first_argument_type lhs, second_argument_type rhs) { - if (lt(lhs, rhs)) - { - return LESS; - } - - if (gt(lhs, rhs)) - { - return GREATER; - } - - return EQUAL; + return lt(lhs, rhs) ? Less : gt(lhs, rhs) ? Greater : Equal; } }; } diff --git a/test/test_compare.cpp b/test/test_compare.cpp index 5e666f574..f0de4b266 100644 --- a/test/test_compare.cpp +++ b/test/test_compare.cpp @@ -47,37 +47,37 @@ namespace Object tb = { 2, 3 }; //*********************************** - bool operator <(const Object& lhs, const Object& rhs) + bool constexpr operator <(const Object& lhs, const Object& rhs) { return (lhs.a + lhs.b) < (rhs.a + rhs.b); } //*********************************** - bool operator >(const Object& lhs, const Object& rhs) + bool constexpr operator >(const Object& lhs, const Object& rhs) { return (lhs.a + lhs.b) > (rhs.a + rhs.b); } //*********************************** - bool operator <=(const Object& lhs, const Object& rhs) + bool constexpr operator <=(const Object& lhs, const Object& rhs) { return (lhs.a + lhs.b) <= (rhs.a + rhs.b); } //*********************************** - bool operator >=(const Object& lhs, const Object& rhs) + bool constexpr operator >=(const Object& lhs, const Object& rhs) { return (lhs.a + lhs.b) >= (rhs.a + rhs.b); } //*********************************** - bool operator ==(const Object& lhs, const Object& rhs) + bool constexpr operator ==(const Object& lhs, const Object& rhs) { return (lhs.a + lhs.b) == (rhs.a + rhs.b); } //*********************************** - bool operator !=(const Object& lhs, const Object& rhs) + bool constexpr operator !=(const Object& lhs, const Object& rhs) { return (lhs.a + lhs.b) != (rhs.a + rhs.b); } @@ -85,7 +85,7 @@ namespace //*********************************** struct LessTest { - bool operator()(const Object& lhs, const Object& rhs) const + bool constexpr operator()(const Object& lhs, const Object& rhs) const { return (lhs.a + lhs.b) < (rhs.a + rhs.b); } @@ -97,10 +97,10 @@ namespace { //************************************************************************* TEST(test_lt) - { - CHECK_EQUAL(a < b, (CompareInt::lt(a, b))); - CHECK_EQUAL(b < a, (CompareInt::lt(b, a))); - CHECK_EQUAL(a < a, (CompareInt::lt(a, a))); + { + CHECK_EQUAL(a < b, (CompareInt::lt(a, b))); + CHECK_EQUAL(b < a, (CompareInt::lt(b, a))); + CHECK_EQUAL(a < a, (CompareInt::lt(a, a))); CHECK_EQUAL(ta < tb, (CompareTest::lt(ta, tb))); CHECK_EQUAL(tb < ta, (CompareTest::lt(tb, ta))); CHECK_EQUAL(ta < ta, (CompareTest::lt(ta, ta))); @@ -109,9 +109,9 @@ namespace //************************************************************************* TEST(test_lte) { - CHECK_EQUAL(a <= b, (CompareInt::lte(a, b))); - CHECK_EQUAL(b <= a, (CompareInt::lte(b, a))); - CHECK_EQUAL(a <= a, (CompareInt::lte(a, a))); + CHECK_EQUAL(a <= b, (CompareInt::lte(a, b))); + CHECK_EQUAL(b <= a, (CompareInt::lte(b, a))); + CHECK_EQUAL(a <= a, (CompareInt::lte(a, a))); CHECK_EQUAL(ta <= tb, (CompareTest::lte(ta, tb))); CHECK_EQUAL(tb <= ta, (CompareTest::lte(tb, ta))); CHECK_EQUAL(ta <= ta, (CompareTest::lte(ta, ta))); @@ -120,9 +120,9 @@ namespace //************************************************************************* TEST(test_gt) { - CHECK_EQUAL(a > b, (CompareInt::gt(a, b))); - CHECK_EQUAL(b > a, (CompareInt::gt(b, a))); - CHECK_EQUAL(a > a, (CompareInt::gt(a, a))); + CHECK_EQUAL(a > b, (CompareInt::gt(a, b))); + CHECK_EQUAL(b > a, (CompareInt::gt(b, a))); + CHECK_EQUAL(a > a, (CompareInt::gt(a, a))); CHECK_EQUAL(ta > tb, (CompareTest::gt(ta, tb))); CHECK_EQUAL(tb > ta, (CompareTest::gt(tb, ta))); CHECK_EQUAL(ta > ta, (CompareTest::gt(ta, ta))); @@ -131,9 +131,9 @@ namespace //************************************************************************* TEST(test_gte) { - CHECK_EQUAL(a >= b, (CompareInt::gte(a, b))); - CHECK_EQUAL(b >= a, (CompareInt::gte(b, a))); - CHECK_EQUAL(a >= a, (CompareInt::gte(a, a))); + CHECK_EQUAL(a >= b, (CompareInt::gte(a, b))); + CHECK_EQUAL(b >= a, (CompareInt::gte(b, a))); + CHECK_EQUAL(a >= a, (CompareInt::gte(a, a))); CHECK_EQUAL(ta >= tb, (CompareTest::gte(ta, tb))); CHECK_EQUAL(tb >= ta, (CompareTest::gte(tb, ta))); CHECK_EQUAL(ta >= ta, (CompareTest::gte(ta, ta))); @@ -142,9 +142,9 @@ namespace //************************************************************************* TEST(test_eq) { - CHECK_EQUAL(a == b, (CompareInt::eq(a, b))); - CHECK_EQUAL(b == a, (CompareInt::eq(b, a))); - CHECK_EQUAL(a == a, (CompareInt::eq(a, a))); + CHECK_EQUAL(a == b, (CompareInt::eq(a, b))); + CHECK_EQUAL(b == a, (CompareInt::eq(b, a))); + CHECK_EQUAL(a == a, (CompareInt::eq(a, a))); CHECK_EQUAL(ta == tb, (CompareTest::eq(ta, tb))); CHECK_EQUAL(tb == ta, (CompareTest::eq(tb, ta))); CHECK_EQUAL(ta == ta, (CompareTest::eq(ta, ta))); @@ -153,9 +153,9 @@ namespace //************************************************************************* TEST(test_ne) { - CHECK_EQUAL(a != b, (CompareInt::ne(a, b))); - CHECK_EQUAL(b != a, (CompareInt::ne(b, a))); - CHECK_EQUAL(a != a, (CompareInt::ne(a, a))); + CHECK_EQUAL(a != b, (CompareInt::ne(a, b))); + CHECK_EQUAL(b != a, (CompareInt::ne(b, a))); + CHECK_EQUAL(a != a, (CompareInt::ne(a, a))); CHECK_EQUAL(ta != tb, (CompareTest::ne(ta, tb))); CHECK_EQUAL(tb != ta, (CompareTest::ne(tb, ta))); CHECK_EQUAL(ta != ta, (CompareTest::ne(ta, ta))); @@ -164,12 +164,32 @@ namespace //************************************************************************* TEST(test_cmp) { - CHECK_EQUAL(CompareInt::LESS, (CompareInt::cmp(2, 4))); - CHECK_EQUAL(CompareInt::GREATER, (CompareInt::cmp(4, 2))); - CHECK_EQUAL(CompareInt::EQUAL, (CompareInt::cmp(0, 0))); - CHECK_EQUAL(CompareTest::LESS, (CompareTest::cmp(Object(0, 1), Object(2, 4)))); - CHECK_EQUAL(CompareTest::GREATER, (CompareTest::cmp(Object(2, 4), Object(0, 1)))); - CHECK_EQUAL(CompareTest::EQUAL, (CompareTest::cmp(Object(2, 4), Object(2, 4)))); + CHECK_EQUAL(CompareInt::Less, (CompareInt::cmp(2, 4))); + CHECK_EQUAL(CompareInt::Greater, (CompareInt::cmp(4, 2))); + CHECK_EQUAL(CompareInt::Equal, (CompareInt::cmp(0, 0))); + CHECK_EQUAL(CompareTest::Less, (CompareTest::cmp(Object{ 0, 1 }, Object{ 2, 4 }))); + CHECK_EQUAL(CompareTest::Greater, (CompareTest::cmp(Object{ 2, 4 }, Object{ 0, 1 }))); + CHECK_EQUAL(CompareTest::Equal, (CompareTest::cmp(Object{ 2, 4 }, Object{ 2, 4 }))); + } + + //************************************************************************* + TEST(test_constexpr_cmp) + { + constexpr int cmp_less = CompareInt::cmp(2, 4); + constexpr int cmp_greater = CompareInt::cmp(4, 2); + constexpr int cmp_equal = CompareInt::cmp(0, 0); + + constexpr int cmp_test_less = CompareTest::cmp(Object{ 0, 1 }, Object{ 2, 4 }); + constexpr int cmp_test_greater = CompareTest::cmp(Object{ 2, 4 }, Object{ 0, 1 }); + constexpr int cmp_test_equal = CompareTest::cmp(Object{ 2, 4 }, Object{ 2, 4 }); + + CHECK_EQUAL(CompareInt::Less, cmp_less); + CHECK_EQUAL(CompareInt::Greater, cmp_greater); + CHECK_EQUAL(CompareInt::Equal, cmp_equal); + + CHECK_EQUAL(CompareInt::Less, cmp_test_less); + CHECK_EQUAL(CompareInt::Greater, cmp_test_greater); + CHECK_EQUAL(CompareInt::Equal, cmp_test_equal); } }; }