diff --git a/include/boost/mp11/algorithm.hpp b/include/boost/mp11/algorithm.hpp index 95d0e7f..e4640f9 100644 --- a/include/boost/mp11/algorithm.hpp +++ b/include/boost/mp11/algorithm.hpp @@ -354,17 +354,156 @@ template class P, class W> struct mp_replace_if_impl template class P, class W> using mp_replace_if = typename detail::mp_replace_if_impl::type; +// mp_copy_if +namespace detail +{ + +template class P> struct mp_copy_if_impl; + +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1800 ) + +template class L, class... T, template class P> struct mp_copy_if_impl, P> +{ + static_assert( sizeof...(T) == 0, "T... must be empty" ); + using type = L<>; +}; + +#else + +template class L, template class P> struct mp_copy_if_impl, P> +{ + using type = L<>; +}; + +#endif + +template class L, class T1, class... T, template class P> struct mp_copy_if_impl, P> +{ + using rest = typename mp_copy_if_impl, P>::type; + using type = mp_if, mp_push_front, rest>; +}; + +} // namespace detail + +template class P> using mp_copy_if = typename detail::mp_copy_if_impl::type; + +// mp_remove_if +namespace detail +{ + +template class P> struct mp_remove_if_impl; + +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1800 ) + +template class L, class... T, template class P> struct mp_remove_if_impl, P> +{ + static_assert( sizeof...(T) == 0, "T... must be empty" ); + using type = L<>; +}; + +#else + +template class L, template class P> struct mp_remove_if_impl, P> +{ + using type = L<>; +}; + +#endif + +template class L, class T1, class... T, template class P> struct mp_remove_if_impl, P> +{ + using rest = typename mp_remove_if_impl, P>::type; + using type = mp_if, rest, mp_push_front>; +}; + +} // namespace detail + +template class P> using mp_remove_if = typename detail::mp_remove_if_impl::type; + +// mp_partition +namespace detail +{ + +template class P> struct mp_partition_impl; + +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1800 ) + +template class L, class... T, template class P> struct mp_partition_impl, P> +{ + static_assert( sizeof...(T) == 0, "T... must be empty" ); + using type = L, L<>>; +}; + +#else + +template class L, template class P> struct mp_partition_impl, P> +{ + using type = L, L<>>; +}; + +#endif + +template class L, class T1, class... T, template class P> struct mp_partition_impl, P> +{ + using rest = typename mp_partition_impl, P>::type; + using type = mp_if, L, T1>, mp_second>, L, mp_push_front, T1>>>; +}; + +} // namespace detail + +template class P> using mp_partition = typename detail::mp_partition_impl::type; + +// mp_sort +namespace detail +{ + +template class P> struct mp_sort_impl; + +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1800 ) + +template class L, class... T, template class P> struct mp_sort_impl, P> +{ + static_assert( sizeof...(T) == 0, "T... must be empty" ); + using type = L<>; +}; + +#else + +template class L, template class P> struct mp_sort_impl, P> +{ + using type = L<>; +}; + +#endif + +template class L, class T1, template class P> struct mp_sort_impl, P> +{ + using type = L; +}; + +template class L, class T1, class... T, template class P> struct mp_sort_impl, P> +{ + template using F = P; + + using part = mp_partition, F>; + + using S1 = typename mp_sort_impl, P>::type; + using S2 = typename mp_sort_impl, P>::type; + + using type = mp_append, S2>; +}; + +} // namespace detail + +template class P> using mp_sort = typename detail::mp_sort_impl::type; + // mp_find // mp_find_if // mp_find_index // mp_find_index_if // mp_reverse -// mp_copy_if -// mp_remove_if // mp_fold // mp_reverse_fold -// mp_partition -// mp_sort } // namespace boost diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 9118ff4..d344063 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -40,6 +40,10 @@ run mp_at.cpp : : : $(REQ) ; run mp_take.cpp : : : $(REQ) ; run mp_replace.cpp : : : $(REQ) ; run mp_replace_if.cpp : : : $(REQ) ; +run mp_copy_if.cpp : : : $(REQ) ; +run mp_remove_if.cpp : : : $(REQ) ; +run mp_partition.cpp : : : $(REQ) ; +run mp_sort.cpp : : : $(REQ) ; # integral run integral.cpp : : : $(REQ) ; diff --git a/test/mp_copy_if.cpp b/test/mp_copy_if.cpp new file mode 100644 index 0000000..d67f120 --- /dev/null +++ b/test/mp_copy_if.cpp @@ -0,0 +1,50 @@ + +// Copyright 2015 Peter Dimov. +// +// Distributed under the Boost Software License, Version 1.0. +// +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt + + +#include +#include +#include +#include +#include + +struct X1 {}; +struct X2 {}; +struct X3 {}; + +int main() +{ + using boost::mp_list; + using boost::mp_copy_if; + + { + using L1 = mp_list<>; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L1>)); + + using L2 = mp_list; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L1>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>)); + } + + { + using L1 = std::tuple<>; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L1>)); + + using L2 = std::tuple; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L1>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple>)); + } + + return boost::report_errors(); +} diff --git a/test/mp_partition.cpp b/test/mp_partition.cpp new file mode 100644 index 0000000..461645e --- /dev/null +++ b/test/mp_partition.cpp @@ -0,0 +1,50 @@ + +// Copyright 2015 Peter Dimov. +// +// Distributed under the Boost Software License, Version 1.0. +// +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt + + +#include +#include +#include +#include +#include + +struct X1 {}; +struct X2 {}; +struct X3 {}; + +int main() +{ + using boost::mp_list; + using boost::mp_partition; + + { + using L1 = mp_list<>; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>)); + + using L2 = mp_list; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list, mp_list>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list, mp_list>>)); + } + + { + using L1 = std::tuple<>; + + BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple>)); + + using L2 = std::tuple; + + BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple, std::tuple>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple, std::tuple>>)); + } + + return boost::report_errors(); +} diff --git a/test/mp_remove_if.cpp b/test/mp_remove_if.cpp new file mode 100644 index 0000000..f1fdfc9 --- /dev/null +++ b/test/mp_remove_if.cpp @@ -0,0 +1,50 @@ + +// Copyright 2015 Peter Dimov. +// +// Distributed under the Boost Software License, Version 1.0. +// +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt + + +#include +#include +#include +#include +#include + +struct X1 {}; +struct X2 {}; +struct X3 {}; + +int main() +{ + using boost::mp_list; + using boost::mp_remove_if; + + { + using L1 = mp_list<>; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L1>)); + + using L2 = mp_list; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L2>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>)); + } + + { + using L1 = std::tuple<>; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L1>)); + + using L2 = std::tuple; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L2>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple>)); + } + + return boost::report_errors(); +} diff --git a/test/mp_sort.cpp b/test/mp_sort.cpp new file mode 100644 index 0000000..d339d29 --- /dev/null +++ b/test/mp_sort.cpp @@ -0,0 +1,55 @@ + +// Copyright 2015 Peter Dimov. +// +// Distributed under the Boost Software License, Version 1.0. +// +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt + + +#include +#include +#include +#include +#include +#include + +using boost::mp_bool; + +template using sizeof_less = mp_bool<(sizeof(T) < sizeof(U))>; + +int main() +{ + using boost::mp_list; + using boost::mp_sort; + + { + using L1 = mp_list<>; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L1>)); + + using L2 = mp_list; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>)); + + using L3 = mp_list; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>)); + } + + { + using L1 = std::tuple<>; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L1>)); + + using L2 = std::tuple; + + BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple>)); + + using L3 = std::tuple; + + BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple>)); + } + + return boost::report_errors(); +}