Horizon
Loading...
Searching...
No Matches
zip.hpp
Go to the documentation of this file.
1
2// Range v3 library
3//
4// Copyright Eric Niebler 2013-present
5//
6// Use, modification and distribution is subject to the
7// Boost Software License, Version 1.0. (See accompanying
8// file LICENSE_1_0.txt or copy at
9// http://www.boost.org/LICENSE_1_0.txt)
10//
11// Project home: https://github.com/ericniebler/range-v3
12//
13
14#ifndef RANGES_V3_VIEW_ZIP_HPP
15#define RANGES_V3_VIEW_ZIP_HPP
16
17#include <tuple>
18#include <utility>
19
20#include <meta/meta.hpp>
21
23
27#include <range/v3/view/all.hpp>
30
31#include <range/v3/detail/prologue.hpp>
32
33namespace ranges
34{
36 namespace detail
37 {
38 struct indirect_zip_fn_
39 {
40 // tuple value
41 template(typename... Its)(
42 requires (sizeof...(Its) != 2) AND and_v<indirectly_readable<Its>...>)
43 std::tuple<iter_value_t<Its>...> operator()(copy_tag, Its...) const
44 {
45 RANGES_EXPECT(false);
46 }
47
48 // tuple reference
49 template(typename... Its)(
50 requires (sizeof...(Its) != 2) AND and_v<indirectly_readable<Its>...>)
51 common_tuple<iter_reference_t<Its>...>
52 operator()(Its const &... its) const //
53 noexcept(meta::and_c<noexcept(iter_reference_t<Its>(*its))...>::value)
54 {
55 return common_tuple<iter_reference_t<Its>...>{*its...};
56 }
57
58 // tuple rvalue reference
59 template(typename... Its)(
60 requires (sizeof...(Its) != 2) AND and_v<indirectly_readable<Its>...>)
61 common_tuple<iter_rvalue_reference_t<Its>...> //
62 operator()(move_tag, Its const &... its) const //
63 noexcept(meta::and_c<noexcept(
64 iter_rvalue_reference_t<Its>(iter_move(its)))...>::value)
65 {
66 return common_tuple<iter_rvalue_reference_t<Its>...>{iter_move(its)...};
67 }
68
69 // pair value
70 template(typename It1, typename It2)(
71 requires indirectly_readable<It1> AND indirectly_readable<It2>)
72 std::pair<iter_value_t<It1>, iter_value_t<It2>> //
73 operator()(copy_tag, It1, It2) const
74 {
75 RANGES_EXPECT(false);
76 }
77
78 // pair reference
79 template(typename It1, typename It2)(
80 requires indirectly_readable<It1> AND indirectly_readable<It2>)
81 common_pair<iter_reference_t<It1>, iter_reference_t<It2>>
82 operator()(It1 const & it1, It2 const & it2) const //
83 noexcept( //
84 noexcept(iter_reference_t<It1>(*it1)) && //
85 noexcept(iter_reference_t<It2>(*it2)))
86 {
87 return {*it1, *it2};
88 }
89
90 // pair rvalue reference
91 template(typename It1, typename It2)(
92 requires indirectly_readable<It1> AND indirectly_readable<It2>)
93 common_pair<iter_rvalue_reference_t<It1>, iter_rvalue_reference_t<It2>>
94 operator()(move_tag, It1 const & it1, It2 const & it2) const
95 noexcept(noexcept(iter_rvalue_reference_t<It1>(iter_move(it1))) &&
96 noexcept(iter_rvalue_reference_t<It2>(iter_move(it2))))
97 {
98 return {iter_move(it1), iter_move(it2)};
99 }
100 };
101 } // namespace detail
103
106 template<typename... Rngs>
107 struct zip_view : iter_zip_with_view<detail::indirect_zip_fn_, Rngs...>
108 {
109 CPP_assert(sizeof...(Rngs) != 0);
110
111 zip_view() = default;
112 explicit zip_view(Rngs... rngs)
113 : iter_zip_with_view<detail::indirect_zip_fn_, Rngs...>{
114 detail::indirect_zip_fn_{},
115 std::move(rngs)...}
116 {}
117 };
118
119 template<typename... Rng>
120 RANGES_INLINE_VAR constexpr bool enable_borrowed_range<zip_view<Rng...>> =
121 and_v<enable_borrowed_range<Rng>...>;
122
123#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
124 template<typename... Rng>
125 zip_view(Rng &&...) //
127#endif
128
129 namespace views
130 {
131 struct zip_fn
132 {
133 constexpr empty_view<std::tuple<>> operator()() const noexcept
134 {
135 return {};
136 }
137 template(typename... Rngs)(
138 requires and_v<viewable_range<Rngs>...> AND
139 and_v<input_range<Rngs>...> AND
140 (sizeof...(Rngs) != 0)) //
141 zip_view<all_t<Rngs>...> operator()(Rngs &&... rngs) const
142 {
143 return zip_view<all_t<Rngs>...>{all(static_cast<Rngs &&>(rngs))...};
144 }
145#if defined(_MSC_VER)
146 template(typename Rng0)(
148 constexpr zip_view<all_t<Rng0>> operator()(Rng0 && rng0) const
149 {
150 return zip_view<all_t<Rng0>>{all(static_cast<Rng0 &&>(rng0))};
151 }
152 template(typename Rng0, typename Rng1)(
155 constexpr zip_view<all_t<Rng0>, all_t<Rng1>> //
156 operator()(Rng0 && rng0, Rng1 && rng1) const
157 {
158 return zip_view<all_t<Rng0>, all_t<Rng1>>{ //
159 all(static_cast<Rng0 &&>(rng0)), //
160 all(static_cast<Rng1 &&>(rng1))};
161 }
162 template(typename Rng0, typename Rng1, typename Rng2)(
166 constexpr zip_view<all_t<Rng0>, all_t<Rng1>, all_t<Rng2>> //
167 operator()(Rng0 && rng0, Rng1 && rng1, Rng2 && rng2) const
168 {
169 return zip_view<all_t<Rng0>, all_t<Rng1>, all_t<Rng2>>{ //
170 all(static_cast<Rng0 &&>(rng0)), //
171 all(static_cast<Rng1 &&>(rng1)), //
172 all(static_cast<Rng2 &&>(rng2))};
173 }
174#endif
175 };
176
179 RANGES_INLINE_VARIABLE(zip_fn, zip)
180 } // namespace views
182} // namespace ranges
183
184#include <range/v3/detail/satisfy_boost_range.hpp>
185RANGES_SATISFY_BOOST_RANGE(::ranges::zip_view)
186
187#include <range/v3/detail/epilogue.hpp>
188
189#endif
The input_range concept.
The viewable_range concept.
Tiny meta-programming library.
Definition meta.hpp:1383
Definition empty.hpp:29
Definition zip_with.hpp:167
Definition zip.hpp:132
Definition zip.hpp:108