diff --git a/algo/search.hpp b/algo/search.hpp index 1d3320f4..bfcba7d2 100644 --- a/algo/search.hpp +++ b/algo/search.hpp @@ -48,7 +48,7 @@ namespace cruft::search { ) { using value_type = typename std::iterator_traits::value_type; using score_t = std::invoke_result_t; - static_assert (::cruft::is_orderable_v); + static_assert (::cruft::is_less_than_comparable_v); auto best_score = std::invoke (func, args..., *first); auto best_item = first; diff --git a/debug.hpp b/debug.hpp index aed3c5c0..03ef4372 100644 --- a/debug.hpp +++ b/debug.hpp @@ -166,7 +166,7 @@ const auto &__a = (A); \ const auto &__b = (B); \ \ - if (__a > __b) { \ + if (!(__a <= __b)) { \ std::cerr << "expected less than or equal\n" \ "__a: " << #A << " is " << __a << "\n" \ "__b: " << #B << " is " << __b << "\n"; \ diff --git a/types/traits.hpp b/types/traits.hpp index 1826889d..6ff9c167 100644 --- a/types/traits.hpp +++ b/types/traits.hpp @@ -481,29 +481,58 @@ namespace cruft { /////////////////////////////////////////////////////////////////////////// - /// Tests if a type is orderable; ie, if it supports the less than operator - /// - /// We use void_t to detect the presence of an appropriate operator< + /// A trait class that models the concept LessThanComparable. template < - typename ValueT, + typename ValueA, + typename ValueB, typename = std::void_t<> - > - struct is_orderable : public std::false_type {}; + > struct is_less_than_comparable : public std::false_type {}; //------------------------------------------------------------------------- - template - struct is_orderable< - ValueT, + template < + typename ValueA, + typename ValueB + > struct is_less_than_comparable< + ValueA, + ValueB, + std::void_t< + decltype(std::declval () < std::declval ()) + > + > : public std::true_type {}; + + + //------------------------------------------------------------------------- + template + constexpr auto is_less_than_comparable_v = is_less_than_comparable::value; + + + /////////////////////////////////////////////////////////////////////////// + /// Tests if a type is orderable; ie, if it supports the '<=' operator + /// + /// We use void_t to detect the presence of an appropriate operator<= + template < + typename ValueA, + typename ValueB, + typename = std::void_t<> + > + struct is_lteq_orderable : public std::false_type {}; + + + //------------------------------------------------------------------------- + template + struct is_lteq_orderable< + ValueA, + ValueB, std::void_t< decltype ( - std::declval () < std::declval () + std::declval () <= std::declval () ) > > : std::true_type {}; //----------------------------------------------------------------------------------- - template - constexpr auto is_orderable_v = is_orderable::value; + template + constexpr auto is_lteq_orderable_v = is_lteq_orderable::value; }; diff --git a/view.hpp b/view.hpp index 0a0a21f9..72bb8dea 100644 --- a/view.hpp +++ b/view.hpp @@ -43,7 +43,7 @@ namespace cruft { m_begin (first), m_end (last) { - if constexpr (cruft::is_orderable_v && cruft::is_orderable_v) { + if constexpr (cruft::is_lteq_orderable_v) { CHECK_LE (m_begin, m_end); } }