1 /*! 2 @file 3 Defines `boost::hana::detail::index_if`. 4 5 @copyright Louis Dionne 2013-2017 6 @copyright Jason Rice 2017 7 Distributed under the Boost Software License, Version 1.0. 8 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) 9 */ 10 11 #ifndef BOOST_HANA_DETAIL_INDEX_IF_HPP 12 #define BOOST_HANA_DETAIL_INDEX_IF_HPP 13 14 #include <boost/hana/config.hpp> 15 #include <boost/hana/detail/decay.hpp> 16 #include <boost/hana/integral_constant.hpp> 17 #include <boost/hana/optional.hpp> 18 19 #include <cstddef> 20 #include <utility> 21 22 23 BOOST_HANA_NAMESPACE_BEGIN namespace detail { 24 template <std::size_t i, std::size_t N, bool Done> 25 struct index_if_helper; 26 27 template <std::size_t i, std::size_t N> 28 struct index_if_helper<i, N, false> { 29 template <typename Pred, typename X1, typename ...Xs> 30 using f = typename index_if_helper<i + 1, N, 31 static_cast<bool>(detail::decay<decltype( 32 std::declval<Pred>()(std::declval<X1>()))>::type::value) 33 >::template f<Pred, Xs...>; 34 }; 35 36 template <std::size_t N> 37 struct index_if_helper<N, N, false> { 38 template <typename ...> 39 using f = hana::optional<>; 40 }; 41 42 template <std::size_t i, std::size_t N> 43 struct index_if_helper<i, N, true> { 44 template <typename ...> 45 using f = hana::optional<hana::size_t<i - 1>>; 46 }; 47 48 template <typename Pred, typename ...Xs> 49 struct index_if { 50 using type = typename index_if_helper<0, sizeof...(Xs), false> 51 ::template f<Pred, Xs...>; 52 }; 53 } BOOST_HANA_NAMESPACE_END 54 55 #endif // !BOOST_HANA_DETAIL_INDEX_IF_HPP 56