diff --git a/include/boost/mp11/algorithm.hpp b/include/boost/mp11/algorithm.hpp index e4640f9..3a4d8b8 100644 --- a/include/boost/mp11/algorithm.hpp +++ b/include/boost/mp11/algorithm.hpp @@ -497,10 +497,127 @@ template class L, class T1, class... T, template cl template class P> using mp_sort = typename detail::mp_sort_impl::type; -// mp_find -// mp_find_if // mp_find_index +namespace detail +{ + +template struct mp_find_index_impl; + +#if !defined( BOOST_NO_CXX11_CONSTEXPR ) + +template class L, class V> struct mp_find_index_impl, V> +{ + using type = mp_size_t<0>; +}; + +constexpr std::size_t cx_find_index( bool const * first, bool const * last ) +{ + return first == last || *first? 0: 1 + cx_find_index( first + 1, last ); +} + +template class L, class... T, class V> struct mp_find_index_impl, V> +{ + static constexpr bool _v[] = { std::is_same::value... }; + using type = mp_size_t< cx_find_index( _v, _v + sizeof...(T) ) >; +}; + +#else + +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1800 ) + +template class L, class... T, class V> struct mp_find_index_impl, V> +{ + static_assert( sizeof...(T) == 0, "T... must be empty" ); + using type = mp_size_t<0>; +}; + +#else + +template class L, class V> struct mp_find_index_impl, V> +{ + using type = mp_size_t<0>; +}; + +#endif + +template class L, class... T, class V> struct mp_find_index_impl, V> +{ + using type = mp_size_t<0>; +}; + +template class L, class T1, class... T, class V> struct mp_find_index_impl, V> +{ + using _r = typename mp_find_index_impl, V>::type; + using type = mp_size_t<1 + _r::value>; +}; + +#endif + +} // namespace detail + +template using mp_find_index = typename detail::mp_find_index_impl::type; + // mp_find_index_if +namespace detail +{ + +template class P> struct mp_find_index_if_impl; + +#if !defined( BOOST_NO_CXX11_CONSTEXPR ) + +template class L, template class P> struct mp_find_index_if_impl, P> +{ + using type = mp_size_t<0>; +}; + +template class L, class... T, template class P> struct mp_find_index_if_impl, P> +{ + static constexpr bool _v[] = { P::value... }; + using type = mp_size_t< cx_find_index( _v, _v + sizeof...(T) ) >; +}; + +#else + +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1800 ) + +template class L, class... T, template class P> struct mp_find_index_if_impl, P> +{ + static_assert( sizeof...(T) == 0, "T... must be empty" ); + using type = mp_size_t<0>; +}; + +#else + +template class L, template class P> struct mp_find_index_if_impl, P> +{ + using type = mp_size_t<0>; +}; + +#endif + +template class P> struct mp_find_index_if_impl_2 +{ + using _r = typename mp_find_index_if_impl::type; + using type = mp_size_t<1 + _r::value>; +}; + +template class L, class T1, class... T, template class P> struct mp_find_index_if_impl, P> +{ + using type = typename mp_if, mp_identity>, mp_find_index_if_impl_2, P>>::type; +}; + +#endif + +} // namespace detail + +template class P> using mp_find_index_if = typename detail::mp_find_index_if_impl::type; + +// mp_find +template using mp_find = mp_drop>; + +// mp_find_if +template class P> using mp_find_if = mp_drop>; + // mp_reverse // mp_fold // mp_reverse_fold diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index d344063..395aa0d 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -44,6 +44,10 @@ run mp_copy_if.cpp : : : $(REQ) ; run mp_remove_if.cpp : : : $(REQ) ; run mp_partition.cpp : : : $(REQ) ; run mp_sort.cpp : : : $(REQ) ; +run mp_find_index.cpp : : : $(REQ) ; +run mp_find_index_if.cpp : : : $(REQ) ; +run mp_find.cpp : : : $(REQ) ; +run mp_find_if.cpp : : : $(REQ) ; # integral run integral.cpp : : : $(REQ) ; diff --git a/test/mp_find.cpp b/test/mp_find.cpp new file mode 100644 index 0000000..b9b3b2e --- /dev/null +++ b/test/mp_find.cpp @@ -0,0 +1,54 @@ + +// 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 +#include + +struct X1 {}; +struct X2 {}; +struct X3 {}; + +int main() +{ + using boost::mp_list; + using boost::mp_find; + + { + 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<>>)); + 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 L3 = std::tuple<>; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L3>)); + + using L4 = std::tuple; + + BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L4>)); + 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_find_if.cpp b/test/mp_find_if.cpp new file mode 100644 index 0000000..72fc9e0 --- /dev/null +++ b/test/mp_find_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 +#include +#include + +struct X1 {}; + +int main() +{ + using boost::mp_list; + using boost::mp_find_if; + + { + 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<>>)); + 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, std::tuple<>>)); + 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_find_index.cpp b/test/mp_find_index.cpp new file mode 100644 index 0000000..570f641 --- /dev/null +++ b/test/mp_find_index.cpp @@ -0,0 +1,63 @@ + +// 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 +#include + +struct X1 {}; +struct X2 {}; +struct X3 {}; + +int main() +{ + using boost::mp_list; + using boost::mp_find_index; + using boost::mp_size_t; + + { + using L1 = mp_list<>; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<0>>)); + + using L2 = mp_list; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<6>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<0>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<1>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<3>>)); + } + + { + using L3 = std::tuple<>; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<0>>)); + + using L4 = std::tuple; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<6>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<0>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<1>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<3>>)); + } + + { + using L5 = std::pair; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<0>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<1>>)); + } + + return boost::report_errors(); +} diff --git a/test/mp_find_index_if.cpp b/test/mp_find_index_if.cpp new file mode 100644 index 0000000..3544f0b --- /dev/null +++ b/test/mp_find_index_if.cpp @@ -0,0 +1,59 @@ + +// 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 +#include + +struct X1 {}; + +int main() +{ + using boost::mp_list; + using boost::mp_find_index_if; + using boost::mp_size_t; + + { + using L1 = mp_list<>; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<0>>)); + + using L2 = mp_list; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<6>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<1>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<3>>)); + } + + { + using L1 = std::tuple<>; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<0>>)); + + using L2 = std::tuple; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<6>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<1>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<3>>)); + } + + { + using L2 = std::pair; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<0>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<1>>)); + } + + return boost::report_errors(); +}