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 value_type = typename std::iterator_traits<ForwardT>::value_type;
using score_t = std::invoke_result_t<FunctionT, Args..., 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_score = std::invoke (func, args..., *first);
auto best_item = first; auto best_item = first;

View File

@ -166,7 +166,7 @@
const auto &__a = (A); \ const auto &__a = (A); \
const auto &__b = (B); \ const auto &__b = (B); \
\ \
if (__a > __b) { \ if (!(__a <= __b)) { \
std::cerr << "expected less than or equal\n" \ std::cerr << "expected less than or equal\n" \
"__a: " << #A << " is " << __a << "\n" \ "__a: " << #A << " is " << __a << "\n" \
"__b: " << #B << " is " << __b << "\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 /// A trait class that models the concept LessThanComparable.
///
/// We use void_t to detect the presence of an appropriate operator<
template < template <
typename ValueT, typename ValueA,
typename ValueB,
typename = std::void_t<> typename = std::void_t<>
> > struct is_less_than_comparable : public std::false_type {};
struct is_orderable : public std::false_type {};
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <typename ValueT> template <
struct is_orderable< typename ValueA,
ValueT, 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< std::void_t<
decltype ( decltype (
std::declval<ValueT> () < std::declval<ValueT> () std::declval<ValueA> () <= std::declval<ValueB> ()
) )
> >
> : std::true_type {}; > : std::true_type {};
//----------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------
template <typename ValueT> template <typename ValueA, typename ValueB>
constexpr auto is_orderable_v = is_orderable<ValueT>::value; constexpr auto is_lteq_orderable_v = is_lteq_orderable<ValueA,ValueB>::value;
}; };

View File

@ -43,7 +43,7 @@ namespace cruft {
m_begin (first), m_begin (first),
m_end (last) 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); CHECK_LE (m_begin, m_end);
} }
} }