/*! @file Defines `boost::hana::index_if`. @copyright Louis Dionne 2013-2017 @copyright Jason Rice 2017 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) */ #ifndef BOOST_HANA_INDEX_IF_HPP #define BOOST_HANA_INDEX_IF_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include BOOST_HANA_NAMESPACE_BEGIN //! @cond template constexpr auto index_if_t::operator()(Xs&& xs, Pred&& pred) const { using S = typename hana::tag_of::type; using IndexIf = BOOST_HANA_DISPATCH_IF(index_if_impl, hana::Iterable::value ); #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS static_assert(hana::Iterable::value, "hana::index_if(xs, pred) requires 'xs' to be a Iterable"); #endif return IndexIf::apply(static_cast(xs), static_cast(pred)); } //! @endcond namespace detail { template struct iterate_while; template struct iterate_while { template using f = typename iterate_while(detail::decay()( hana::at(std::declval(), hana::size_c)))>::type::value) >::template f; }; template struct iterate_while { template using f = hana::optional<>; }; template struct iterate_while { template using f = hana::optional>; }; } template struct index_if_impl::value>> { template static constexpr auto apply(Xs const& xs, Pred const&) -> typename detail::iterate_while<0, decltype(hana::length(xs))::value, false> ::template f { return {}; } }; template struct index_if_impl::value>> { template static constexpr auto apply(Xs const&, Pred const&) -> typename detail::iterate_while<0, static_cast(-1), false> ::template f { return {}; } }; // basic_tuple is implemented here to solve circular dependency issues. template <> struct index_if_impl { template static constexpr auto apply(basic_tuple const&, Pred const&) -> typename detail::index_if::type { return {}; } }; BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_INDEX_IF_HPP