You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

157 lines
5.1KB

  1. /// \file
  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. #ifndef RANGES_V3_VIEW_ZIP_HPP
  14. #define RANGES_V3_VIEW_ZIP_HPP
  15. #include <tuple>
  16. #include <utility>
  17. #include <meta/meta.hpp>
  18. #include <range/v3/range_fwd.hpp>
  19. #include <range/v3/iterator/concepts.hpp>
  20. #include <range/v3/iterator/traits.hpp>
  21. #include <range/v3/utility/common_tuple.hpp>
  22. #include <range/v3/view/all.hpp>
  23. #include <range/v3/view/empty.hpp>
  24. #include <range/v3/view/zip_with.hpp>
  25. RANGES_DISABLE_WARNINGS
  26. namespace ranges
  27. {
  28. /// \cond
  29. namespace detail
  30. {
  31. struct indirect_zip_fn_
  32. {
  33. // tuple value
  34. template<typename... Its>
  35. [[noreturn]] auto operator()(copy_tag, Its...) const
  36. -> CPP_ret(std::tuple<iter_value_t<Its>...>)( //
  37. requires and_v<readable<Its>...> && (sizeof...(Its) != 2))
  38. {
  39. RANGES_EXPECT(false);
  40. }
  41. // tuple reference
  42. template<typename... Its>
  43. auto operator()(Its const &... its) const
  44. noexcept(meta::and_c<noexcept(iter_reference_t<Its>(*its))...>::value)
  45. -> CPP_ret(common_tuple<iter_reference_t<Its>...>)( //
  46. requires and_v<readable<Its>...> && (sizeof...(Its) != 2))
  47. {
  48. return common_tuple<iter_reference_t<Its>...>{*its...};
  49. }
  50. // tuple rvalue reference
  51. template<typename... Its>
  52. auto operator()(move_tag, Its const &... its) const
  53. noexcept(meta::and_c<noexcept(
  54. iter_rvalue_reference_t<Its>(iter_move(its)))...>::value)
  55. -> CPP_ret(common_tuple<iter_rvalue_reference_t<Its>...>)( //
  56. requires and_v<readable<Its>...> && (sizeof...(Its) != 2))
  57. {
  58. return common_tuple<iter_rvalue_reference_t<Its>...>{iter_move(its)...};
  59. }
  60. // pair value
  61. template<typename It1, typename It2>
  62. [[noreturn]] auto operator()(copy_tag, It1, It2) const
  63. -> CPP_ret(std::pair<iter_value_t<It1>, iter_value_t<It2>>)( //
  64. requires readable<It1> && readable<It2>)
  65. {
  66. RANGES_EXPECT(false);
  67. }
  68. // pair reference
  69. template<typename It1, typename It2>
  70. auto operator()(It1 const & it1, It2 const & it2) const noexcept(
  71. noexcept(iter_reference_t<It1>(*it1)) &&
  72. noexcept(iter_reference_t<It2>(*it2)))
  73. -> CPP_ret(common_pair<iter_reference_t<It1>, iter_reference_t<It2>>)( //
  74. requires readable<It1> && readable<It2>)
  75. {
  76. return {*it1, *it2};
  77. }
  78. // pair rvalue reference
  79. template<typename It1, typename It2>
  80. auto operator()(move_tag, It1 const & it1, It2 const & it2) const
  81. noexcept(noexcept(iter_rvalue_reference_t<It1>(iter_move(it1))) &&
  82. noexcept(iter_rvalue_reference_t<It2>(iter_move(it2))))
  83. -> CPP_ret(common_pair<iter_rvalue_reference_t<It1>,
  84. iter_rvalue_reference_t<It2>>)( //
  85. requires readable<It1> && readable<It2>)
  86. {
  87. return {iter_move(it1), iter_move(it2)};
  88. }
  89. };
  90. } // namespace detail
  91. /// \endcond
  92. /// \addtogroup group-views
  93. /// @{
  94. template<typename... Rngs>
  95. struct zip_view : iter_zip_with_view<detail::indirect_zip_fn_, Rngs...>
  96. {
  97. CPP_assert(sizeof...(Rngs) != 0);
  98. zip_view() = default;
  99. explicit zip_view(Rngs... rngs)
  100. : iter_zip_with_view<detail::indirect_zip_fn_, Rngs...>{
  101. detail::indirect_zip_fn_{},
  102. std::move(rngs)...}
  103. {}
  104. };
  105. #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
  106. template<typename... Rng>
  107. zip_view(Rng &&...)->zip_view<views::all_t<Rng>...>;
  108. #endif
  109. namespace views
  110. {
  111. struct zip_fn
  112. {
  113. template<typename... Rngs>
  114. auto operator()(Rngs &&... rngs) const -> CPP_ret(
  115. zip_view<all_t<Rngs>...>)( //
  116. requires and_v<viewable_range<Rngs>...> && and_v<input_range<Rngs>...> &&
  117. (sizeof...(Rngs) != 0))
  118. {
  119. return zip_view<all_t<Rngs>...>{all(static_cast<Rngs &&>(rngs))...};
  120. }
  121. constexpr empty_view<std::tuple<>> operator()() const noexcept
  122. {
  123. return {};
  124. }
  125. };
  126. /// \relates zip_fn
  127. /// \ingroup group-views
  128. RANGES_INLINE_VARIABLE(zip_fn, zip)
  129. } // namespace views
  130. /// @}
  131. } // namespace ranges
  132. RANGES_RE_ENABLE_WARNINGS
  133. #include <range/v3/detail/satisfy_boost_range.hpp>
  134. RANGES_SATISFY_BOOST_RANGE(::ranges::zip_view)
  135. #endif