/// \file // Range v3 library // // Copyright Eric Niebler 2013-present // // Use, modification and distribution is subject to the // Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Project home: https://github.com/ericniebler/range-v3 // #ifndef RANGES_V3_VIEW_ZIP_HPP #define RANGES_V3_VIEW_ZIP_HPP #include #include #include #include #include #include #include #include #include #include #include namespace ranges { /// \cond namespace detail { struct indirect_zip_fn_ { // tuple value template(typename... Its)( requires (sizeof...(Its) != 2) AND and_v...>) std::tuple...> operator()(copy_tag, Its...) const { RANGES_EXPECT(false); } // tuple reference template(typename... Its)( requires (sizeof...(Its) != 2) AND and_v...>) common_tuple...> operator()(Its const &... its) const // noexcept(meta::and_c(*its))...>::value) { return common_tuple...>{*its...}; } // tuple rvalue reference template(typename... Its)( requires (sizeof...(Its) != 2) AND and_v...>) common_tuple...> // operator()(move_tag, Its const &... its) const // noexcept(meta::and_c(iter_move(its)))...>::value) { return common_tuple...>{iter_move(its)...}; } // pair value template(typename It1, typename It2)( requires indirectly_readable AND indirectly_readable) std::pair, iter_value_t> // operator()(copy_tag, It1, It2) const { RANGES_EXPECT(false); } // pair reference template(typename It1, typename It2)( requires indirectly_readable AND indirectly_readable) common_pair, iter_reference_t> operator()(It1 const & it1, It2 const & it2) const // noexcept( // noexcept(iter_reference_t(*it1)) && // noexcept(iter_reference_t(*it2))) { return {*it1, *it2}; } // pair rvalue reference template(typename It1, typename It2)( requires indirectly_readable AND indirectly_readable) common_pair, iter_rvalue_reference_t> operator()(move_tag, It1 const & it1, It2 const & it2) const noexcept(noexcept(iter_rvalue_reference_t(iter_move(it1))) && noexcept(iter_rvalue_reference_t(iter_move(it2)))) { return {iter_move(it1), iter_move(it2)}; } }; } // namespace detail /// \endcond /// \addtogroup group-views /// @{ template struct zip_view : iter_zip_with_view { CPP_assert(sizeof...(Rngs) != 0); zip_view() = default; explicit zip_view(Rngs... rngs) : iter_zip_with_view{ detail::indirect_zip_fn_{}, std::move(rngs)...} {} }; template RANGES_INLINE_VAR constexpr bool enable_borrowed_range> = and_v...>; #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17 template zip_view(Rng &&...) // -> zip_view...>; #endif namespace views { struct zip_fn { constexpr empty_view> operator()() const noexcept { return {}; } template(typename... Rngs)( requires and_v...> AND and_v...> AND (sizeof...(Rngs) != 0)) // zip_view...> operator()(Rngs &&... rngs) const { return zip_view...>{all(static_cast(rngs))...}; } #if defined(_MSC_VER) template(typename Rng0)( requires input_range AND viewable_range) constexpr zip_view> operator()(Rng0 && rng0) const { return zip_view>{all(static_cast(rng0))}; } template(typename Rng0, typename Rng1)( requires input_range AND viewable_range AND input_range AND viewable_range) constexpr zip_view, all_t> // operator()(Rng0 && rng0, Rng1 && rng1) const { return zip_view, all_t>{ // all(static_cast(rng0)), // all(static_cast(rng1))}; } template(typename Rng0, typename Rng1, typename Rng2)( requires input_range AND viewable_range AND input_range AND viewable_range AND input_range AND viewable_range) constexpr zip_view, all_t, all_t> // operator()(Rng0 && rng0, Rng1 && rng1, Rng2 && rng2) const { return zip_view, all_t, all_t>{ // all(static_cast(rng0)), // all(static_cast(rng1)), // all(static_cast(rng2))}; } #endif }; /// \relates zip_fn /// \ingroup group-views RANGES_INLINE_VARIABLE(zip_fn, zip) } // namespace views /// @} } // namespace ranges #include RANGES_SATISFY_BOOST_RANGE(::ranges::zip_view) #include #endif