From 2eaf8c94b80aeb7b49c38f9786ac17c64ea39b12 Mon Sep 17 00:00:00 2001 From: ecrypa <> Date: Sun, 20 Oct 2019 17:38:33 +0200 Subject: [PATCH] use metal::less as default ordering for metal::sort --- example/src/list.cpp | 5 +++++ include/metal/list/sort.hpp | 18 +++++++++++++++--- test/unit/src/metal/list/sort.cpp | 18 ++++++++++++++++++ 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/example/src/list.cpp b/example/src/list.cpp index 97f790b0..8a579e6c 100644 --- a/example/src/list.cpp +++ b/example/src/list.cpp @@ -537,6 +537,11 @@ IS_SAME( metal::sort>, // non-stable sorting metal::list ); + +IS_SAME( + metal::sort>, // use default ordering + metal::sort, metal::lambda> +); /// [sort] ) diff --git a/include/metal/list/sort.hpp b/include/metal/list/sort.hpp index b8ac5572..c10e05f8 100644 --- a/include/metal/list/sort.hpp +++ b/include/metal/list/sort.hpp @@ -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 + template> struct _sort; } /// \endcond @@ -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 /// @@ -41,15 +43,25 @@ namespace metal { /// such that `metal::invoke{} != false` for all /// `i` in `[0, m-2]`. /// + /// \tip{`lbd` may be omitted, in which case it defaults to `metal::lambda`.} + /// /// ### Example /// \snippet list.cpp sort /// /// ### See Also /// \see list, reverse, rotate - template +#if !defined(METAL_WORKAROUND) + template> using sort = detail::call< detail::_sort::template type, metal::if_, seq>>; +#else + // MSVC 14 has shabby SFINAE support in case of default alias template args + template + using sort = detail::call< + detail::_sort::template type, + metal::if_, seq>>; +#endif } #include "../lambda/lambda.hpp" diff --git a/test/unit/src/metal/list/sort.cpp b/test/unit/src/metal/list/sort.cpp index 14865bd9..63aafa03 100644 --- a/test/unit/src/metal/list/sort.cpp +++ b/test/unit/src/metal/list/sort.cpp @@ -3,12 +3,14 @@ #include "test.hpp" #define MATRIX(M, N) \ + CHECK((metal::is_invocable, VALUE(M)>), (FALSE)); \ CHECK((metal::is_invocable, VALUE(M), VALUE(N)>), (FALSE)); \ CHECK((metal::is_invocable, VALUE(M), NUMBER(N)>), (FALSE)); \ CHECK((metal::is_invocable, VALUE(M), PAIR(N)>), (FALSE)); \ CHECK((metal::is_invocable, VALUE(M), LIST(N)>), (FALSE)); \ CHECK((metal::is_invocable, VALUE(M), MAP(N)>), (FALSE)); \ CHECK((metal::is_invocable, VALUE(M), LAMBDA(N)>), (FALSE)); \ + CHECK((metal::is_invocable, NUMBER(M)>), (FALSE)); \ CHECK((metal::is_invocable, NUMBER(M), VALUE(N)>), (FALSE)); \ CHECK((metal::is_invocable, NUMBER(M), NUMBER(N)>), (FALSE)); \ CHECK((metal::is_invocable, NUMBER(M), PAIR(N)>), (FALSE)); \ @@ -16,6 +18,7 @@ CHECK((metal::is_invocable, NUMBER(M), MAP(N)>), (FALSE)); \ CHECK((metal::is_invocable, NUMBER(M), LAMBDA(N)>), (FALSE)); \ CHECK((metal::is_invocable, NUMBER(M), LAMBDA(_)>), (FALSE)); \ + CHECK((metal::is_invocable, PAIR(M)>), (FALSE)); \ CHECK((metal::is_invocable, PAIR(M), VALUE(N)>), (FALSE)); \ CHECK((metal::is_invocable, PAIR(M), NUMBER(N)>), (FALSE)); \ CHECK((metal::is_invocable, PAIR(M), PAIR(N)>), (FALSE)); \ @@ -23,6 +26,7 @@ CHECK((metal::is_invocable, PAIR(M), MAP(N)>), (FALSE)); \ CHECK((metal::is_invocable, PAIR(M), LAMBDA(N)>), (BOOL(N == 2))); \ CHECK((metal::is_invocable, PAIR(M), LAMBDA(_)>), (FALSE)); \ + CHECK((metal::is_invocable, LIST(M)>), (BOOL(M < 2))); \ CHECK((metal::is_invocable, LIST(M), VALUE(N)>), (FALSE)); \ CHECK((metal::is_invocable, LIST(M), NUMBER(N)>), (FALSE)); \ CHECK((metal::is_invocable, LIST(M), PAIR(N)>), (FALSE)); \ @@ -30,6 +34,7 @@ CHECK((metal::is_invocable, LIST(M), MAP(N)>), (FALSE)); \ CHECK((metal::is_invocable, LIST(M), LAMBDA(N)>), (BOOL(N == 2 || M < 2))); \ CHECK((metal::is_invocable, LIST(M), LAMBDA(_)>), (BOOL(M < 2))); \ + CHECK((metal::is_invocable, MAP(M)>), (BOOL(M < 2))); \ CHECK((metal::is_invocable, MAP(M), VALUE(N)>), (FALSE)); \ CHECK((metal::is_invocable, MAP(M), NUMBER(N)>), (FALSE)); \ CHECK((metal::is_invocable, MAP(M), PAIR(N)>), (FALSE)); \ @@ -37,6 +42,16 @@ CHECK((metal::is_invocable, MAP(M), MAP(N)>), (FALSE)); \ CHECK((metal::is_invocable, MAP(M), LAMBDA(N)>), (BOOL(N == 2 || M < 2))); \ CHECK((metal::is_invocable, MAP(M), LAMBDA(_)>), (BOOL(M < 2))); \ + CHECK((metal::is_invocable, metal::list>), (TRUE)); \ + CHECK((metal::is_invocable, metal::list, VALUE(N)>), (FALSE)); \ + CHECK((metal::is_invocable, metal::list, NUMBER(N)>), (FALSE)); \ + CHECK((metal::is_invocable, metal::list, PAIR(N)>), (FALSE)); \ + CHECK((metal::is_invocable, metal::list, LIST(N)>), (FALSE)); \ + CHECK((metal::is_invocable, metal::list, MAP(N)>), (FALSE)); \ + CHECK((metal::is_invocable, metal::list, metal::list>), (FALSE)); \ + CHECK((metal::is_invocable, metal::list, LAMBDA(N)>), (BOOL(N == 2 || M < 2))); \ + CHECK((metal::is_invocable, metal::list, LAMBDA(_)>), (BOOL(M < 2))); \ + CHECK((metal::is_invocable, LAMBDA(M)>), (FALSE)); \ CHECK((metal::is_invocable, LAMBDA(M), VALUE(N)>), (FALSE)); \ CHECK((metal::is_invocable, LAMBDA(M), NUMBER(N)>), (FALSE)); \ CHECK((metal::is_invocable, LAMBDA(M), PAIR(N)>), (FALSE)); \ @@ -44,6 +59,7 @@ CHECK((metal::is_invocable, LAMBDA(M), MAP(N)>), (FALSE)); \ CHECK((metal::is_invocable, LAMBDA(M), LAMBDA(N)>), (FALSE)); \ CHECK((metal::is_invocable, LAMBDA(M), LAMBDA(_)>), (FALSE)); \ + CHECK((metal::is_invocable, LAMBDA(_)>), (FALSE)); \ CHECK((metal::is_invocable, LAMBDA(_), VALUE(N)>), (FALSE)); \ CHECK((metal::is_invocable, LAMBDA(_), NUMBER(N)>), (FALSE)); \ CHECK((metal::is_invocable, LAMBDA(_), PAIR(N)>), (FALSE)); \ @@ -53,7 +69,9 @@ CHECK((metal::is_invocable, LAMBDA(_), LAMBDA(_)>), (FALSE)); \ CHECK((metal::sort, metal::lambda>), (metal::list)); \ CHECK((metal::sort, metal::lambda>), (metal::list)); \ + CHECK((metal::sort>), (metal::list)); \ CHECK((metal::sort, metal::lambda>), (metal::list)); \ + CHECK((metal::sort>), (metal::list)); \ /**/ GEN(MATRIX)