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.

135 lines
3.6KB

  1. /// \file
  2. // Range v3 library
  3. //
  4. // Copyright Eric Niebler 2014-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_FOR_EACH_HPP
  14. #define RANGES_V3_VIEW_FOR_EACH_HPP
  15. #include <utility>
  16. #include <meta/meta.hpp>
  17. #include <range/v3/range_fwd.hpp>
  18. #include <range/v3/functional/bind_back.hpp>
  19. #include <range/v3/functional/invoke.hpp>
  20. #include <range/v3/utility/static_const.hpp>
  21. #include <range/v3/view/all.hpp>
  22. #include <range/v3/view/generate_n.hpp>
  23. #include <range/v3/view/join.hpp>
  24. #include <range/v3/view/repeat_n.hpp>
  25. #include <range/v3/view/single.hpp>
  26. #include <range/v3/view/transform.hpp>
  27. #include <range/v3/view/view.hpp>
  28. namespace ranges
  29. {
  30. namespace views
  31. {
  32. /// Lazily applies an unary function to each element in the source
  33. /// range that returns another range (possibly empty), flattening
  34. /// the result.
  35. struct for_each_fn
  36. {
  37. private:
  38. friend view_access;
  39. template<typename Fun>
  40. static constexpr auto bind(for_each_fn for_each, Fun fun)
  41. {
  42. return make_pipeable(bind_back(for_each, std::move(fun)));
  43. }
  44. public:
  45. template<typename Rng, typename Fun>
  46. constexpr auto CPP_fun(operator())(Rng && rng, Fun fun)(
  47. const requires viewable_range<Rng> && transformable_range<Rng, Fun> &&
  48. joinable_range<transform_view<all_t<Rng>, Fun>>)
  49. {
  50. return join(transform(static_cast<Rng &&>(rng), std::move(fun)));
  51. }
  52. };
  53. /// \relates for_each_fn
  54. /// \ingroup group-views
  55. RANGES_INLINE_VARIABLE(view<for_each_fn>, for_each)
  56. } // namespace views
  57. struct yield_fn
  58. {
  59. template<typename V>
  60. auto operator()(V v) const -> CPP_ret(single_view<V>)( //
  61. requires copy_constructible<V>)
  62. {
  63. return views::single(std::move(v));
  64. }
  65. };
  66. /// \relates yield_fn
  67. /// \ingroup group-views
  68. RANGES_INLINE_VARIABLE(yield_fn, yield)
  69. struct yield_from_fn
  70. {
  71. template<typename Rng>
  72. auto operator()(Rng rng) const -> CPP_ret(Rng)( //
  73. requires view_<Rng>)
  74. {
  75. return rng;
  76. }
  77. };
  78. /// \relates yield_from_fn
  79. /// \ingroup group-views
  80. RANGES_INLINE_VARIABLE(yield_from_fn, yield_from)
  81. struct yield_if_fn
  82. {
  83. template<typename V>
  84. repeat_n_view<V> operator()(bool b, V v) const
  85. {
  86. return views::repeat_n(std::move(v), b ? 1 : 0);
  87. }
  88. };
  89. /// \relates yield_if_fn
  90. /// \ingroup group-views
  91. RANGES_INLINE_VARIABLE(yield_if_fn, yield_if)
  92. struct lazy_yield_if_fn
  93. {
  94. template<typename F>
  95. auto operator()(bool b, F f) const -> CPP_ret(generate_n_view<F>)( //
  96. requires invocable<F &>)
  97. {
  98. return views::generate_n(std::move(f), b ? 1 : 0);
  99. }
  100. };
  101. /// \relates lazy_yield_if_fn
  102. /// \ingroup group-views
  103. RANGES_INLINE_VARIABLE(lazy_yield_if_fn, lazy_yield_if)
  104. /// @}
  105. /// \cond
  106. CPP_template(typename Rng, typename Fun)( //
  107. requires viewable_range<Rng> && views::transformable_range<Rng, Fun> &&
  108. input_range<invoke_result_t<Fun &, range_reference_t<Rng>>>) //
  109. auto
  110. operator>>=(Rng && rng, Fun fun)
  111. {
  112. return views::for_each(static_cast<Rng &&>(rng), std::move(fun));
  113. }
  114. /// \endcond
  115. } // namespace ranges
  116. #endif