Horizon
zip.hpp
Go to the documentation of this file.
1 // 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 
22 #include <range/v3/range_fwd.hpp>
23 
27 #include <range/v3/view/all.hpp>
28 #include <range/v3/view/empty.hpp>
30 
31 #include <range/v3/detail/prologue.hpp>
32 
33 namespace 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)(
147  requires input_range<Rng0> AND viewable_range<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)(
153  requires input_range<Rng0> AND viewable_range<Rng0> AND
154  input_range<Rng1> AND viewable_range<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)(
163  requires input_range<Rng0> AND viewable_range<Rng0> AND
164  input_range<Rng1> AND viewable_range<Rng1> AND
165  input_range<Rng2> AND viewable_range<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 
180  } // namespace views
182 } // namespace ranges
183 
184 #include <range/v3/detail/satisfy_boost_range.hpp>
185 RANGES_SATISFY_BOOST_RANGE(::ranges::zip_view)
186 
187 #include <range/v3/detail/epilogue.hpp>
188 
189 #endif
RANGES_INLINE_VARIABLE(detail::to_container_fn< detail::from_range< std::vector >>, to_vector) template< template< typename... > class ContT > auto to(RANGES_HIDDEN_DETAIL(detail
For initializing a container of the specified type with the elements of an Range.
Definition: conversion.hpp:399
transpose< ListOfLists > zip
Given a list of lists of types ListOfLists, construct a new list by grouping the elements from the li...
Definition: meta.hpp:2930
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