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.

82 lines
2.9KB

  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_ACTION_SPLIT_WHEN_HPP
  14. #define RANGES_V3_ACTION_SPLIT_WHEN_HPP
  15. #include <vector>
  16. #include <meta/meta.hpp>
  17. #include <range/v3/range_fwd.hpp>
  18. #include <range/v3/action/action.hpp>
  19. #include <range/v3/action/concepts.hpp>
  20. #include <range/v3/functional/invoke.hpp>
  21. #include <range/v3/iterator/concepts.hpp>
  22. #include <range/v3/iterator/traits.hpp>
  23. #include <range/v3/range/conversion.hpp>
  24. #include <range/v3/utility/static_const.hpp>
  25. #include <range/v3/view/split_when.hpp>
  26. #include <range/v3/view/transform.hpp>
  27. namespace ranges
  28. {
  29. /// \addtogroup group-actions
  30. /// @{
  31. namespace actions
  32. {
  33. struct split_when_fn
  34. {
  35. private:
  36. template<typename Rng>
  37. using split_value_t = meta::if_c<(bool)ranges::container<Rng>, uncvref_t<Rng>,
  38. std::vector<range_value_t<Rng>>>;
  39. public:
  40. // BUGBUG something is not right with the actions. It should be possible
  41. // to move a container into a split and have elements moved into the result.
  42. template<typename Rng, typename Fun>
  43. auto operator()(Rng && rng, Fun fun) const //
  44. -> CPP_ret(std::vector<split_value_t<Rng>>)( //
  45. requires forward_range<Rng> && //
  46. invocable<Fun &, iterator_t<Rng>, sentinel_t<Rng>> && invocable<
  47. Fun &, iterator_t<Rng>, iterator_t<Rng>> &&
  48. copy_constructible<Fun> && convertible_to<
  49. invoke_result_t<Fun &, iterator_t<Rng>, sentinel_t<Rng>>,
  50. std::pair<bool, iterator_t<Rng>>>)
  51. {
  52. return views::split_when(rng, std::move(fun)) |
  53. views::transform(to<split_value_t<Rng>>()) | to_vector;
  54. }
  55. template<typename Rng, typename Fun>
  56. auto operator()(Rng && rng, Fun fun) const
  57. -> CPP_ret(std::vector<split_value_t<Rng>>)( //
  58. requires forward_range<Rng> && predicate<
  59. Fun const &, range_reference_t<Rng>> && copy_constructible<Fun>)
  60. {
  61. return views::split_when(rng, std::move(fun)) |
  62. views::transform(to<split_value_t<Rng>>()) | to_vector;
  63. }
  64. };
  65. /// \ingroup group-actions
  66. /// \relates split_fn
  67. /// \sa action
  68. RANGES_INLINE_VARIABLE(action<split_when_fn>, split_when)
  69. } // namespace actions
  70. /// @}
  71. } // namespace ranges
  72. #endif