File indexing completed on 2025-01-18 10:09:59
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef RANGES_V3_VIEW_ZIP_HPP
0015 #define RANGES_V3_VIEW_ZIP_HPP
0016
0017 #include <tuple>
0018 #include <utility>
0019
0020 #include <meta/meta.hpp>
0021
0022 #include <range/v3/range_fwd.hpp>
0023
0024 #include <range/v3/iterator/concepts.hpp>
0025 #include <range/v3/iterator/traits.hpp>
0026 #include <range/v3/utility/common_tuple.hpp>
0027 #include <range/v3/view/all.hpp>
0028 #include <range/v3/view/empty.hpp>
0029 #include <range/v3/view/zip_with.hpp>
0030
0031 #include <range/v3/detail/prologue.hpp>
0032
0033 namespace ranges
0034 {
0035
0036 namespace detail
0037 {
0038 struct indirect_zip_fn_
0039 {
0040
0041 template(typename... Its)(
0042 requires (sizeof...(Its) != 2) AND and_v<indirectly_readable<Its>...>)
0043 std::tuple<iter_value_t<Its>...> operator()(copy_tag, Its...) const
0044 {
0045 RANGES_EXPECT(false);
0046 }
0047
0048
0049 template(typename... Its)(
0050 requires (sizeof...(Its) != 2) AND and_v<indirectly_readable<Its>...>)
0051 common_tuple<iter_reference_t<Its>...>
0052 operator()(Its const &... its) const
0053 noexcept(meta::and_c<noexcept(iter_reference_t<Its>(*its))...>::value)
0054 {
0055 return common_tuple<iter_reference_t<Its>...>{*its...};
0056 }
0057
0058
0059 template(typename... Its)(
0060 requires (sizeof...(Its) != 2) AND and_v<indirectly_readable<Its>...>)
0061 common_tuple<iter_rvalue_reference_t<Its>...>
0062 operator()(move_tag, Its const &... its) const
0063 noexcept(meta::and_c<noexcept(
0064 iter_rvalue_reference_t<Its>(iter_move(its)))...>::value)
0065 {
0066 return common_tuple<iter_rvalue_reference_t<Its>...>{iter_move(its)...};
0067 }
0068
0069
0070 template(typename It1, typename It2)(
0071 requires indirectly_readable<It1> AND indirectly_readable<It2>)
0072 std::pair<iter_value_t<It1>, iter_value_t<It2>>
0073 operator()(copy_tag, It1, It2) const
0074 {
0075 RANGES_EXPECT(false);
0076 }
0077
0078
0079 template(typename It1, typename It2)(
0080 requires indirectly_readable<It1> AND indirectly_readable<It2>)
0081 common_pair<iter_reference_t<It1>, iter_reference_t<It2>>
0082 operator()(It1 const & it1, It2 const & it2) const
0083 noexcept(
0084 noexcept(iter_reference_t<It1>(*it1)) &&
0085 noexcept(iter_reference_t<It2>(*it2)))
0086 {
0087 return {*it1, *it2};
0088 }
0089
0090
0091 template(typename It1, typename It2)(
0092 requires indirectly_readable<It1> AND indirectly_readable<It2>)
0093 common_pair<iter_rvalue_reference_t<It1>, iter_rvalue_reference_t<It2>>
0094 operator()(move_tag, It1 const & it1, It2 const & it2) const
0095 noexcept(noexcept(iter_rvalue_reference_t<It1>(iter_move(it1))) &&
0096 noexcept(iter_rvalue_reference_t<It2>(iter_move(it2))))
0097 {
0098 return {iter_move(it1), iter_move(it2)};
0099 }
0100 };
0101 }
0102
0103
0104
0105
0106 template<typename... Rngs>
0107 struct zip_view : iter_zip_with_view<detail::indirect_zip_fn_, Rngs...>
0108 {
0109 CPP_assert(sizeof...(Rngs) != 0);
0110
0111 zip_view() = default;
0112 explicit zip_view(Rngs... rngs)
0113 : iter_zip_with_view<detail::indirect_zip_fn_, Rngs...>{
0114 detail::indirect_zip_fn_{},
0115 std::move(rngs)...}
0116 {}
0117 };
0118
0119 template<typename... Rng>
0120 RANGES_INLINE_VAR constexpr bool enable_borrowed_range<zip_view<Rng...>> =
0121 and_v<enable_borrowed_range<Rng>...>;
0122
0123 #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
0124 template<typename... Rng>
0125 zip_view(Rng &&...)
0126 -> zip_view<views::all_t<Rng>...>;
0127 #endif
0128
0129 namespace views
0130 {
0131 struct zip_fn
0132 {
0133 constexpr empty_view<std::tuple<>> operator()() const noexcept
0134 {
0135 return {};
0136 }
0137 template(typename... Rngs)(
0138 requires and_v<viewable_range<Rngs>...> AND
0139 and_v<input_range<Rngs>...> AND
0140 (sizeof...(Rngs) != 0))
0141 zip_view<all_t<Rngs>...> operator()(Rngs &&... rngs) const
0142 {
0143 return zip_view<all_t<Rngs>...>{all(static_cast<Rngs &&>(rngs))...};
0144 }
0145 #if defined(_MSC_VER)
0146 template(typename Rng0)(
0147 requires input_range<Rng0> AND viewable_range<Rng0>)
0148 constexpr zip_view<all_t<Rng0>> operator()(Rng0 && rng0) const
0149 {
0150 return zip_view<all_t<Rng0>>{all(static_cast<Rng0 &&>(rng0))};
0151 }
0152 template(typename Rng0, typename Rng1)(
0153 requires input_range<Rng0> AND viewable_range<Rng0> AND
0154 input_range<Rng1> AND viewable_range<Rng1>)
0155 constexpr zip_view<all_t<Rng0>, all_t<Rng1>>
0156 operator()(Rng0 && rng0, Rng1 && rng1) const
0157 {
0158 return zip_view<all_t<Rng0>, all_t<Rng1>>{
0159 all(static_cast<Rng0 &&>(rng0)),
0160 all(static_cast<Rng1 &&>(rng1))};
0161 }
0162 template(typename Rng0, typename Rng1, typename Rng2)(
0163 requires input_range<Rng0> AND viewable_range<Rng0> AND
0164 input_range<Rng1> AND viewable_range<Rng1> AND
0165 input_range<Rng2> AND viewable_range<Rng2>)
0166 constexpr zip_view<all_t<Rng0>, all_t<Rng1>, all_t<Rng2>>
0167 operator()(Rng0 && rng0, Rng1 && rng1, Rng2 && rng2) const
0168 {
0169 return zip_view<all_t<Rng0>, all_t<Rng1>, all_t<Rng2>>{
0170 all(static_cast<Rng0 &&>(rng0)),
0171 all(static_cast<Rng1 &&>(rng1)),
0172 all(static_cast<Rng2 &&>(rng2))};
0173 }
0174 #endif
0175 };
0176
0177
0178
0179 RANGES_INLINE_VARIABLE(zip_fn, zip)
0180 }
0181
0182 }
0183
0184 #include <range/v3/detail/satisfy_boost_range.hpp>
0185 RANGES_SATISFY_BOOST_RANGE(::ranges::zip_view)
0186
0187 #include <range/v3/detail/epilogue.hpp>
0188
0189 #endif