Skip to content

Commit

Permalink
use metal::less as default ordering for metal::sort
Browse files Browse the repository at this point in the history
  • Loading branch information
ecrypa committed Oct 20, 2019
1 parent b827598 commit 2eaf8c9
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 3 deletions.
5 changes: 5 additions & 0 deletions example/src/list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,11 @@ IS_SAME(
metal::sort<l, metal::lambda<not_bigger>>, // non-stable sorting
metal::list<uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t>
);

IS_SAME(
metal::sort<metal::numbers<7, -8, -3, 2>>, // use default ordering
metal::sort<metal::numbers<7, -8, -3, 2>, metal::lambda<metal::less>>
);
/// [sort]
)

Expand Down
18 changes: 15 additions & 3 deletions include/metal/list/sort.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@

#include "../config.hpp"
#include "../detail/sfinae.hpp"
#include "../lambda/lambda.hpp"
#include "../list/list.hpp"
#include "../number/if.hpp"
#include "../number/less.hpp"

namespace metal {
/// \cond
namespace detail {
template<class lbd>
template<class lbd = metal::lambda<metal::less>>
struct _sort;
}
/// \endcond
Expand All @@ -19,7 +21,7 @@ namespace metal {
/// ### Description
/// Sorts the elements of a \list according to an ordering relation.
///
/// \tip{The sorting is [stable] if the ordering relation is [strict].}
/// \note{The sorting is [stable] if the ordering relation is [strict].}
/// [stable]: https://en.wikipedia.org/wiki/Sorting_algorithm#Stability
/// [strict]: https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings
///
Expand All @@ -41,15 +43,25 @@ namespace metal {
/// such that `metal::invoke<lbd, val_i, val_i+1>{} != false` for all
/// `i` in `[0, m-2]`.
///
/// \tip{`lbd` may be omitted, in which case it defaults to `metal::lambda<metal::less>`.}
///
/// ### Example
/// \snippet list.cpp sort
///
/// ### See Also
/// \see list, reverse, rotate
template<class seq, class lbd>
#if !defined(METAL_WORKAROUND)
template<class seq, class lbd = metal::lambda<metal::less>>
using sort = detail::call<
detail::_sort<lbd>::template type,
metal::if_<metal::is_list<seq>, seq>>;
#else
// MSVC 14 has shabby SFINAE support in case of default alias template args
template<class seq, class... lbd>
using sort = detail::call<
detail::_sort<lbd...>::template type,
metal::if_<metal::is_list<seq>, seq>>;
#endif
}

#include "../lambda/lambda.hpp"
Expand Down
18 changes: 18 additions & 0 deletions test/unit/src/metal/list/sort.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,47 +3,63 @@
#include "test.hpp"

#define MATRIX(M, N) \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, VALUE(M)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, VALUE(M), VALUE(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, VALUE(M), NUMBER(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, VALUE(M), PAIR(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, VALUE(M), LIST(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, VALUE(M), MAP(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, VALUE(M), LAMBDA(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, NUMBER(M)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, NUMBER(M), VALUE(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, NUMBER(M), NUMBER(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, NUMBER(M), PAIR(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, NUMBER(M), LIST(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, NUMBER(M), MAP(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, NUMBER(M), LAMBDA(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, NUMBER(M), LAMBDA(_)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, PAIR(M)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, PAIR(M), VALUE(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, PAIR(M), NUMBER(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, PAIR(M), PAIR(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, PAIR(M), LIST(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, PAIR(M), MAP(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, PAIR(M), LAMBDA(N)>), (BOOL(N == 2))); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, PAIR(M), LAMBDA(_)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, LIST(M)>), (BOOL(M < 2))); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, LIST(M), VALUE(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, LIST(M), NUMBER(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, LIST(M), PAIR(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, LIST(M), LIST(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, LIST(M), MAP(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, LIST(M), LAMBDA(N)>), (BOOL(N == 2 || M < 2))); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, LIST(M), LAMBDA(_)>), (BOOL(M < 2))); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, MAP(M)>), (BOOL(M < 2))); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, MAP(M), VALUE(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, MAP(M), NUMBER(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, MAP(M), PAIR(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, MAP(M), LIST(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, MAP(M), MAP(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, MAP(M), LAMBDA(N)>), (BOOL(N == 2 || M < 2))); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, MAP(M), LAMBDA(_)>), (BOOL(M < 2))); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, metal::list<NUMBERS(M)>>), (TRUE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, metal::list<NUMBERS(M)>, VALUE(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, metal::list<NUMBERS(M)>, NUMBER(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, metal::list<NUMBERS(M)>, PAIR(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, metal::list<NUMBERS(M)>, LIST(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, metal::list<NUMBERS(M)>, MAP(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, metal::list<NUMBERS(M)>, metal::list<NUMBERS(N)>>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, metal::list<NUMBERS(M)>, LAMBDA(N)>), (BOOL(N == 2 || M < 2))); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, metal::list<NUMBERS(M)>, LAMBDA(_)>), (BOOL(M < 2))); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, LAMBDA(M)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, LAMBDA(M), VALUE(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, LAMBDA(M), NUMBER(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, LAMBDA(M), PAIR(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, LAMBDA(M), LIST(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, LAMBDA(M), MAP(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, LAMBDA(M), LAMBDA(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, LAMBDA(M), LAMBDA(_)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, LAMBDA(_)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, LAMBDA(_), VALUE(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, LAMBDA(_), NUMBER(N)>), (FALSE)); \
CHECK((metal::is_invocable<metal::lambda<metal::sort>, LAMBDA(_), PAIR(N)>), (FALSE)); \
Expand All @@ -53,7 +69,9 @@
CHECK((metal::is_invocable<metal::lambda<metal::sort>, LAMBDA(_), LAMBDA(_)>), (FALSE)); \
CHECK((metal::sort<metal::list<NUMBERSX20(M)>, metal::lambda<metal::greater>>), (metal::list<RENUM(M, FWD, NUMBERX20)>)); \
CHECK((metal::sort<metal::list<NUMBERSX20(M)>, metal::lambda<metal::less>>), (metal::list<NUMBERSX20(M)>)); \
CHECK((metal::sort<metal::list<NUMBERSX20(M)>>), (metal::list<NUMBERSX20(M)>)); \
CHECK((metal::sort<metal::list<ENUM(INC(N), NUMBERS FIX(INC(M)))>, metal::lambda<metal::less>>), (metal::list<ENUM(INC(M), FWD, RENUM(INC(N), NUMBER NIL))>)); \
CHECK((metal::sort<metal::list<ENUM(INC(N), NUMBERS FIX(INC(M)))>>), (metal::list<ENUM(INC(M), FWD, RENUM(INC(N), NUMBER NIL))>)); \
/**/

GEN(MATRIX)

0 comments on commit 2eaf8c9

Please # to comment.