File indexing completed on 2025-01-18 09:38:03
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_HANA_INTERSPERSE_HPP
0011 #define BOOST_HANA_INTERSPERSE_HPP
0012
0013 #include <boost/hana/fwd/intersperse.hpp>
0014
0015 #include <boost/hana/at.hpp>
0016 #include <boost/hana/bool.hpp>
0017 #include <boost/hana/concept/sequence.hpp>
0018 #include <boost/hana/config.hpp>
0019 #include <boost/hana/core/dispatch.hpp>
0020 #include <boost/hana/core/make.hpp>
0021 #include <boost/hana/length.hpp>
0022
0023 #include <cstddef>
0024 #include <utility>
0025
0026
0027 namespace boost { namespace hana {
0028
0029 template <typename Xs, typename Z>
0030 constexpr auto intersperse_t::operator()(Xs&& xs, Z&& z) const {
0031 using S = typename hana::tag_of<Xs>::type;
0032 using Intersperse = BOOST_HANA_DISPATCH_IF(intersperse_impl<S>,
0033 hana::Sequence<S>::value
0034 );
0035
0036 #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
0037 static_assert(hana::Sequence<S>::value,
0038 "hana::intersperse(xs, z) requires 'xs' to be a Sequence");
0039 #endif
0040
0041 return Intersperse::apply(static_cast<Xs&&>(xs), static_cast<Z&&>(z));
0042 }
0043
0044
0045 template <typename S, bool condition>
0046 struct intersperse_impl<S, when<condition>> : default_ {
0047 template <std::size_t i, typename Xs, typename Z>
0048 static constexpr decltype(auto)
0049 pick(Xs&&, Z&& z, hana::false_ )
0050 { return static_cast<Z&&>(z); }
0051
0052 template <std::size_t i, typename Xs, typename Z>
0053 static constexpr decltype(auto)
0054 pick(Xs&& xs, Z&&, hana::true_ )
0055 { return hana::at_c<(i + 1) / 2>(static_cast<Xs&&>(xs)); }
0056
0057 template <typename Xs, typename Z, std::size_t ...i>
0058 static constexpr auto
0059 intersperse_helper(Xs&& xs, Z&& z, std::index_sequence<i...>) {
0060 return hana::make<S>(
0061 pick<i>(static_cast<Xs&&>(xs), static_cast<Z&&>(z),
0062 hana::bool_c<(i % 2 == 0)>)...
0063 );
0064 }
0065
0066 template <typename Xs, typename Z>
0067 static constexpr auto apply(Xs&& xs, Z&& z) {
0068 constexpr std::size_t size = decltype(hana::length(xs))::value;
0069 constexpr std::size_t new_size = size == 0 ? 0 : (size * 2) - 1;
0070 return intersperse_helper(static_cast<Xs&&>(xs), static_cast<Z&&>(z),
0071 std::make_index_sequence<new_size>{});
0072 }
0073 };
0074 }}
0075
0076 #endif