Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:03

0001 /*!
0002 @file
0003 Defines `boost::hana::index_if`.
0004 
0005 Copyright Louis Dionne 2013-2022
0006 Copyright Jason Rice 2017
0007 Distributed under the Boost Software License, Version 1.0.
0008 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
0009  */
0010 
0011 #ifndef BOOST_HANA_INDEX_IF_HPP
0012 #define BOOST_HANA_INDEX_IF_HPP
0013 
0014 #include <boost/hana/concept/foldable.hpp>
0015 #include <boost/hana/concept/iterable.hpp>
0016 #include <boost/hana/config.hpp>
0017 #include <boost/hana/detail/decay.hpp>
0018 #include <boost/hana/detail/index_if.hpp>
0019 #include <boost/hana/fwd/at.hpp>
0020 #include <boost/hana/fwd/basic_tuple.hpp>
0021 #include <boost/hana/fwd/index_if.hpp>
0022 #include <boost/hana/integral_constant.hpp>
0023 #include <boost/hana/length.hpp>
0024 #include <boost/hana/optional.hpp>
0025 
0026 #include <cstddef>
0027 #include <utility>
0028 
0029 
0030 namespace boost { namespace hana {
0031     //! @cond
0032     template <typename Xs, typename Pred>
0033     constexpr auto index_if_t::operator()(Xs&& xs, Pred&& pred) const {
0034         using S = typename hana::tag_of<Xs>::type;
0035         using IndexIf = BOOST_HANA_DISPATCH_IF(index_if_impl<S>,
0036             hana::Iterable<S>::value
0037         );
0038 
0039     #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
0040         static_assert(hana::Iterable<S>::value,
0041         "hana::index_if(xs, pred) requires 'xs' to be a Iterable");
0042     #endif
0043 
0044         return IndexIf::apply(static_cast<Xs&&>(xs), static_cast<Pred&&>(pred));
0045     }
0046     //! @endcond
0047 
0048     namespace detail {
0049         template <std::size_t i, std::size_t N, bool Done>
0050         struct iterate_while;
0051 
0052         template <std::size_t i, std::size_t N>
0053         struct iterate_while<i, N, false> {
0054             template <typename Xs, typename Pred>
0055             using f = typename iterate_while<i + 1, N,
0056                 static_cast<bool>(detail::decay<decltype(
0057                     std::declval<Pred>()(
0058                       hana::at(std::declval<Xs>(), hana::size_c<i>)))>::type::value)
0059             >::template f<Xs, Pred>;
0060         };
0061 
0062         template <std::size_t N>
0063         struct iterate_while<N, N, false> {
0064             template <typename Xs, typename Pred>
0065             using f = hana::optional<>;
0066         };
0067 
0068         template <std::size_t i, std::size_t N>
0069         struct iterate_while<i, N, true> {
0070             template <typename Xs, typename Pred>
0071             using f = hana::optional<hana::size_t<i - 1>>;
0072         };
0073     }
0074 
0075     template <typename Tag>
0076     struct index_if_impl<Tag, when<Foldable<Tag>::value>> {
0077         template <typename Xs, typename Pred>
0078         static constexpr auto apply(Xs const& xs, Pred const&)
0079             -> typename detail::iterate_while<0,
0080                 decltype(hana::length(xs))::value, false>
0081                     ::template f<Xs, Pred>
0082         { return {}; }
0083     };
0084 
0085     template <typename It>
0086     struct index_if_impl<It, when<!Foldable<It>::value>> {
0087         template <typename Xs, typename Pred>
0088         static constexpr auto apply(Xs const&, Pred const&)
0089             -> typename detail::iterate_while<0,
0090                 static_cast<std::size_t>(-1), false>
0091                     ::template f<Xs, Pred>
0092         { return {}; }
0093     };
0094 
0095     // basic_tuple is implemented here to solve circular dependency issues.
0096     template <>
0097     struct index_if_impl<basic_tuple_tag> {
0098         template <typename ...Xs, typename Pred>
0099         static constexpr auto apply(basic_tuple<Xs...> const&, Pred const&)
0100             -> typename detail::index_if<Pred, Xs...>::type
0101         { return {}; }
0102     };
0103 }} // end namespace boost::hana
0104 
0105 #endif // !BOOST_HANA_INDEX_IF_HPP