1 /*! 2 @file 3 Defines `boost::hana::span`. 4 5 @copyright Louis Dionne 2013-2017 6 Distributed under the Boost Software License, Version 1.0. 7 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) 8 */ 9 10 #ifndef BOOST_HANA_SPAN_HPP 11 #define BOOST_HANA_SPAN_HPP 12 13 #include <boost/hana/fwd/span.hpp> 14 15 #include <boost/hana/at.hpp> 16 #include <boost/hana/concept/sequence.hpp> 17 #include <boost/hana/config.hpp> 18 #include <boost/hana/core/dispatch.hpp> 19 #include <boost/hana/core/make.hpp> 20 #include <boost/hana/detail/nested_by.hpp> // required by fwd decl 21 #include <boost/hana/detail/first_unsatisfied_index.hpp> 22 #include <boost/hana/length.hpp> 23 #include <boost/hana/pair.hpp> 24 #include <boost/hana/unpack.hpp> 25 26 #include <cstddef> 27 #include <utility> 28 29 30 BOOST_HANA_NAMESPACE_BEGIN 31 //! @cond 32 template <typename Xs, typename Pred> operator ()(Xs && xs,Pred && pred) const33 constexpr auto span_t::operator()(Xs&& xs, Pred&& pred) const { 34 using S = typename hana::tag_of<Xs>::type; 35 using Span = BOOST_HANA_DISPATCH_IF(span_impl<S>, 36 hana::Sequence<S>::value 37 ); 38 39 #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS 40 static_assert(hana::Sequence<S>::value, 41 "hana::span(xs, pred) requires 'xs' to be a Sequence"); 42 #endif 43 44 return Span::apply(static_cast<Xs&&>(xs), static_cast<Pred&&>(pred)); 45 } 46 //! @endcond 47 48 template <typename S, bool condition> 49 struct span_impl<S, when<condition>> : default_ { 50 template <typename Xs, std::size_t ...before, std::size_t ...after> span_helperspan_impl51 static constexpr auto span_helper(Xs&& xs, std::index_sequence<before...>, 52 std::index_sequence<after...>) 53 { 54 return hana::make_pair( 55 hana::make<S>(hana::at_c<before>(static_cast<Xs&&>(xs))...), 56 hana::make<S>(hana::at_c<sizeof...(before) + after>(static_cast<Xs&&>(xs))...) 57 ); 58 } 59 60 template <typename Xs, typename Pred> applyspan_impl61 static constexpr auto apply(Xs&& xs, Pred&&) { 62 using FirstUnsatisfied = decltype( 63 hana::unpack(static_cast<Xs&&>(xs), 64 detail::first_unsatisfied_index<Pred&&>{}) 65 ); 66 constexpr std::size_t breakpoint = FirstUnsatisfied::value; 67 constexpr std::size_t N = decltype(hana::length(xs))::value; 68 return span_helper(static_cast<Xs&&>(xs), 69 std::make_index_sequence<breakpoint>{}, 70 std::make_index_sequence<N - breakpoint>{}); 71 } 72 }; 73 BOOST_HANA_NAMESPACE_END 74 75 #endif // !BOOST_HANA_SPAN_HPP 76