1 /*! 2 @file 3 Defines `boost::hana::zip_with`. 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_ZIP_WITH_HPP 11 #define BOOST_HANA_ZIP_WITH_HPP 12 13 #include <boost/hana/fwd/zip_with.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/fast_and.hpp> 21 #include <boost/hana/length.hpp> 22 23 #include <cstddef> 24 #include <utility> 25 26 27 BOOST_HANA_NAMESPACE_BEGIN 28 //! @cond 29 template <typename F, typename Xs, typename ...Ys> operator ()(F && f,Xs && xs,Ys &&...ys) const30 constexpr auto zip_with_t::operator()(F&& f, Xs&& xs, Ys&& ...ys) const { 31 #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS 32 static_assert(detail::fast_and< 33 hana::Sequence<Xs>::value, hana::Sequence<Ys>::value... 34 >::value, 35 "hana::zip_with(f, xs, ys...) requires 'xs' and 'ys...' to be Sequences"); 36 #endif 37 38 return zip_with_impl<typename hana::tag_of<Xs>::type>::apply( 39 static_cast<F&&>(f), 40 static_cast<Xs&&>(xs), 41 static_cast<Ys&&>(ys)... 42 ); 43 } 44 //! @endcond 45 46 template <typename S> 47 struct zip_with_impl<S, when<Sequence<S>::value>> { 48 template <std::size_t N, typename F, typename ...Xs> transversezip_with_impl49 static constexpr decltype(auto) transverse(F&& f, Xs&& ...xs) { 50 return static_cast<F&&>(f)(hana::at_c<N>(static_cast<Xs&&>(xs))...); 51 } 52 53 template <std::size_t ...N, typename F, typename ...Xs> 54 static constexpr auto zip_helperzip_with_impl55 zip_helper(std::index_sequence<N...>, F&& f, Xs&& ...xs) { 56 return hana::make<S>(transverse<N>(f, xs...)...); 57 } 58 59 template <typename F, typename X, typename ...Xs> 60 static constexpr auto applyzip_with_impl61 apply(F&& f, X&& x, Xs&& ...xs) { 62 constexpr std::size_t N = decltype(hana::length(x))::value; 63 return zip_helper(std::make_index_sequence<N>{}, 64 static_cast<F&&>(f), 65 static_cast<X&&>(x), static_cast<Xs&&>(xs)...); 66 } 67 }; 68 BOOST_HANA_NAMESPACE_END 69 70 #endif // !BOOST_HANA_ZIP_WITH_HPP 71