types/traits: use LessThanComparable more consistently

This commit is contained in:
Danny Robson 2019-02-03 17:28:53 +11:00
parent fd1fda9145
commit 4a4d5f297a
4 changed files with 44 additions and 15 deletions

View File

@ -48,7 +48,7 @@ namespace cruft::search {
) {
using value_type = typename std::iterator_traits<ForwardT>::value_type;
using score_t = std::invoke_result_t<FunctionT, Args..., value_type>;
static_assert (::cruft::is_orderable_v<score_t>);
static_assert (::cruft::is_less_than_comparable_v<score_t,score_t>);
auto best_score = std::invoke (func, args..., *first);
auto best_item = first;

View File

@ -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"; \

View File

@ -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 <typename ValueT>
struct is_orderable<
ValueT,
template <
typename ValueA,
typename ValueB
> struct is_less_than_comparable<
ValueA,
ValueB,
std::void_t<
decltype(std::declval<ValueA> () < std::declval<ValueB> ())
>
> : public std::true_type {};
//-------------------------------------------------------------------------
template <typename ValueA, typename ValueB>
constexpr auto is_less_than_comparable_v = is_less_than_comparable<ValueA,ValueB>::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 <typename ValueA, typename ValueB>
struct is_lteq_orderable<
ValueA,
ValueB,
std::void_t<
decltype (
std::declval<ValueT> () < std::declval<ValueT> ()
std::declval<ValueA> () <= std::declval<ValueB> ()
)
>
> : std::true_type {};
//-----------------------------------------------------------------------------------
template <typename ValueT>
constexpr auto is_orderable_v = is_orderable<ValueT>::value;
template <typename ValueA, typename ValueB>
constexpr auto is_lteq_orderable_v = is_lteq_orderable<ValueA,ValueB>::value;
};

View File

@ -43,7 +43,7 @@ namespace cruft {
m_begin (first),
m_end (last)
{
if constexpr (cruft::is_orderable_v<BeginT> && cruft::is_orderable_v<EndT>) {
if constexpr (cruft::is_lteq_orderable_v<BeginT,EndT>) {
CHECK_LE (m_begin, m_end);
}
}