diff --git a/include/boost/mp11/algorithm.hpp b/include/boost/mp11/algorithm.hpp index 7b06d13..3db3507 100644 --- a/include/boost/mp11/algorithm.hpp +++ b/include/boost/mp11/algorithm.hpp @@ -558,6 +558,60 @@ template class L, class T1, class... T, class V> struct mp_fi 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 // mp_find_if diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 5deab2a..2dd97a8 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -45,6 +45,7 @@ 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) ; # integral run integral.cpp : : : $(REQ) ; 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(); +}