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::intersperse`.
0004 
0005 Copyright Louis Dionne 2013-2022
0006 Distributed under the Boost Software License, Version 1.0.
0007 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
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     //! @cond
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     //! @endcond
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_ /* odd index */)
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_ /* even index */)
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 }} // end namespace boost::hana
0075 
0076 #endif // !BOOST_HANA_INTERSPERSE_HPP